-
Notifications
You must be signed in to change notification settings - Fork 13
Fix QueryFilter IN/NOT_IN serialization #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v1.0.0-alpha.4
Are you sure you want to change the base?
Conversation
…192) The IN and NOT_IN filters were stripping type metadata from list items, causing CloudKit Web Services to reject queries with HTTP 400 errors. Changes: - Fix FilterBuilder to use CustomFieldValuePayload preserving types - Re-enable GUID queries in CelestraCloud ArticleSyncService - Optimize ArticleCloudKitService to combine filters at query time - Update tests to reflect server-side filtering behavior All tests passing: MistKit (311/311), CelestraCloud (115/115) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## v1.0.0-alpha.4 #205 +/- ##
==================================================
- Coverage 14.31% 14.27% -0.05%
==================================================
Files 67 67
Lines 7179 7179
==================================================
- Hits 1028 1025 -3
- Misses 6151 6154 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
PR Review: Fix QueryFilter IN/NOT_IN serialization (#205)SummaryThis PR fixes a critical bug in the ✅ Code Quality & Best PracticesStrengths:
Minor Observations:
🐛 Potential IssuesNone identified - The implementation appears solid. However, consider:
⚡ Performance ConsiderationsPositive Impact:
No Performance Regressions Identified 🔒 Security ConcernsLow Risk:
Recommendation: None - security posture is good. 🧪 Test CoverageStrengths:
Suggestions:
📝 Additional Notes
✨ VerdictLGTM - This is a well-executed bug fix with proper test coverage and documentation. The core fix is minimal (2 lines changed in FilterBuilder), which reduces risk. The removal of workaround code and re-enabling of GUID queries demonstrates the fix's effectiveness. Recommendation: Approve and merge after CI passes. Code Quality: ⭐⭐⭐⭐⭐ 5/5 Great work fixing this issue! 🎉 |
PR Review: Fix QueryFilter IN/NOT_IN serialization (#205)SummaryThis PR fixes a critical bug (#192) where the ✅ Code Quality & Best PracticesStrengths
Minor Concerns
🐛 Potential Bugs & IssuesCriticalNone identified - The fix appears sound and is validated by passing tests. Minor Observations
⚡ Performance ConsiderationsImprovements
No Regressions
🔒 Security ConcernsNone identified - This is a serialization bug fix with no security implications:
🧪 Test CoverageExcellent Coverage
Recommendations
📋 Architectural ConsiderationsPositive Impacts
Alignment with CLAUDE.md✅ Follows project conventions:
🎯 RecommendationsHigh Priority
Medium Priority
Low Priority
✨ Overall AssessmentVerdict: Excellent fix - Ready to merge ✅ This is a high-quality bug fix that:
The code is clean, focused, and well-tested. The only suggestions are minor enhancements to documentation and test coverage that can be addressed in follow-up PRs if needed. Great work solving this tricky serialization issue! 🎉 References
|
PR Review: Fix QueryFilter IN/NOT_IN serializationSummaryThis PR fixes a critical bug where IN and NOT_IN filters were stripping type metadata from list items, causing CloudKit Web Services to reject queries with HTTP 400 errors. The fix properly preserves type information by using Code Quality ✅Strengths:
Code Review Notes:FilterBuilder.swift (Lines 183-192, 199-207): // BEFORE: Stripped type metadata
value: .listValue(values.map { Components.Schemas.FieldValue(from: $0).value })
// AFTER: Preserves type metadata
value: .listValue(values.map { CustomFieldValue.CustomFieldValuePayload($0) })This is the correct fix. The old code was calling Potential Issues
|
Pull Request Review: Fix QueryFilter IN/NOT_IN SerializationSummaryThis PR fixes a critical bug where IN and NOT_IN filters were stripping type metadata from list items, causing CloudKit Web Services to reject queries with HTTP 400 errors. The fix is minimal, focused, and correct. Code Quality & Best Practices ✅FilterBuilder.swift Changes (Lines 188, 204) Components.Schemas.FieldValue(from: $0).valuewith: CustomFieldValue.CustomFieldValuePayload($0)Why this works:
Code Quality:
Test Coverage ✅ArticleCloudKitService+Query.swift:
Test Results:
Implementation Quality ✅ArticleCloudKitService.swift:
ArticleSyncService.swift:
Performance Considerations ✅Before:
After:
Security Concerns ✅No security issues identified:
Potential Issues & RecommendationsMinor Concerns:
Suggested Addition:// IN/NOT_IN filters must preserve type metadata for CloudKit Web Services.
// Use CustomFieldValuePayload directly rather than extracting .value from
// Components.Schemas.FieldValue to maintain type information in list items.
internal static func `in`(_ field: String, _ values: [FieldValue]) -> Components.Schemas.Filter {
// ...
}Verdict: ✅ APPROVEThis is an exemplary bug fix:
Recommendation: Merge after addressing the optional documentation suggestion above (not blocking). Additional NotesThe fix demonstrates good understanding of CloudKit Web Services requirements and the MistKit type system. The decision to use
Great work! 🎉 |
Code Review: Fix QueryFilter IN/NOT_IN serializationSummaryThis PR successfully fixes a critical bug where IN and NOT_IN filters were stripping type metadata from list items, causing CloudKit Web Services to reject queries with HTTP 400 errors. The fix is clean, well-tested, and enables important functionality that was previously disabled. ✅ Positive Aspects1. Root Cause Fix is CorrectThe core issue in Before: .listValue(values.map { Components.Schemas.FieldValue(from: $0).value })After: .listValue(values.map { CustomFieldValue.CustomFieldValuePayload($0) })The problem was that 2. Excellent Impact
3. Clean Code Changes
4. Proper Test UpdatesThe test changes in
🔍 Observations & Minor Concerns1. Test Coverage GapThe current test at line 113 ( mock.queryRecordsResult = .success([
createMockRecordInfo(recordName: "article-1", fields: matchingFields)
])The mock returns only the matching article, simulating server-side filtering. However, this doesn't verify that:
Recommendation: Consider adding an integration test (or at least a comment) that validates the actual serialized JSON includes type information like: {
"fieldName": "guid",
"comparator": "IN",
"fieldValue": {
"type": "LIST",
"value": [{"type": "STRING", "value": "guid-1"}, ...]
}
}2. Old Code Still PresentWhile the PR updates // CloudKit Web Services has issues with combining .in() with other filters.
// Current approach: Use .in() ONLY for GUID filtering (single filter, no combinations).
// Feed filtering is done in-memory (line 135-136) to avoid the .in() + filter issue.This comment is outdated and contradicts the fix. It should be removed since the issue is now resolved. 3. Test Assertion Comment MismatchIn the updated test file (line 127), the comment says: // Should have 2 filters: IN for GUID + EQUALS for feedRecordName
#expect(mock.queryCalls[0].filters?.count == 2)But looking at the current
This is concerning - the test expects 2 filters but the implementation only sends 1. 🐛 Critical Issue FoundAfter reviewing the diff more carefully, I notice the Lines 113-122 in the PR: // Query articles by GUID using the IN filter.
// Now that issue #192 is fixed, we can combine .in() with other filters.
// If feedRecordName is specified, we filter at query time for efficiency.
var filters: [QueryFilter] = [.in("guid", guids.map { FieldValue.string($0) })]
if let feedName = feedRecordName {
filters.append(.equals("feedRecordName", FieldValue.string(feedName)))
}This is correct and matches the test expectations! The old code I saw was from reading the file at HEAD, not from the PR diff. 🎯 Final AssessmentCode Quality: ⭐⭐⭐⭐½ (4.5/5)
Bug Risk: ⭐⭐⭐⭐⭐ (5/5)
Performance: ⭐⭐⭐⭐⭐ (5/5)
Security: ✅ No concerns
📋 RecommendationsMust Fix Before Merge:None - the code is ready to merge. Nice to Have:
Example comment suggestion for FilterBuilder.swift:// IMPORTANT: Use CustomFieldValuePayload directly to preserve type metadata.
// CloudKit requires both the value AND type information for each list item.
// Extracting .value would strip the type, causing 400 errors from the API.
.listValue(values.map { CustomFieldValue.CustomFieldValuePayload($0) })✅ ApprovalLGTM - This PR successfully fixes a critical bug and is well-tested. The changes are minimal, focused, and correct. Great work diagnosing and fixing this issue! The only minor improvement would be additional test coverage for the serialization format, but the existing tests are sufficient to verify functionality. Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com |
PR Review: Fix QueryFilter IN/NOT_IN serializationSummaryThis PR fixes a critical bug where the ✅ Code Quality & Best PracticesExcellent Changes
🔍 Potential Issues & Concerns1. Incomplete Test Coverage
|
Pull Request Review: Fix QueryFilter IN/NOT_IN serialization (#205)✅ Overall AssessmentRecommendation: Approve with minor suggestions This is an excellent fix that resolves a critical bug (#192) preventing CloudKit Web Services from accepting 🎯 Code Quality & Best PracticesStrengths:
Observations:
🐛 Potential IssuesMinor Concerns:
⚡ Performance ConsiderationsImprovements:
Potential Concerns:
🔒 Security ConcernsNo significant security issues identified. The changes are purely related to data serialization and don't introduce:
The use of strongly-typed 🧪 Test CoverageStrengths:
Gaps:
Recommendations: Add a test like: @Test("IN filter preserves type metadata in serialization")
internal func inFilterPreservesTypes() async throws {
let values: [FieldValue] = [.int64(1), .int64(2), .int64(3)]
let filter = FilterBuilder.in("id", values)
// Serialize to JSON
let encoder = JSONEncoder()
let data = try encoder.encode(filter)
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
// Verify type metadata is present
let fieldValue = json?["fieldValue"] as? [String: Any]
let listItems = fieldValue?["value"] as? [[String: Any]]
#expect(fieldValue?["type"] as? String == "LIST")
#expect(listItems?[0]["type"] as? String == "INT64")
#expect(listItems?[0]["value"] as? Int == 1)
}📊 Code Changes Summary
Total: +23/-36 (net reduction, good!) 🎓 Suggestions & Best Practices
✨ HighlightsWhat This PR Does Well:
Final Verdict: This is high-quality work that demonstrates solid debugging and problem-solving. The fix is architecturally correct, using MistKit's custom type system as designed. Once the minor concerns about the initializer are verified, this should be merged. 🚀 Next StepsBefore Merge:
Future Enhancements:
Great work solving this issue! The fix is clean, targeted, and restores important functionality. 🎉 |
Code Review: Fix QueryFilter IN/NOT_IN serializationSummaryThis PR fixes a critical bug where IN and NOT_IN query filters were stripping type metadata from list items, causing CloudKit Web Services to reject queries with HTTP 400 errors. The fix enables proper GUID-based queries and allows combining filters as originally intended. ✅ Positive Findings1. Core Fix is Sound (FilterBuilder.swift:188, 204)The change from: .listValue(values.map { Components.Schemas.FieldValue(from: $0).value })to: .listValue(values.map { CustomFieldValue.CustomFieldValuePayload($0) })This is the correct approach because:
2. Appropriate Use of Existing InfrastructureThe fix leverages 3. Re-enabled Functionality is Well-Justified (ArticleSyncService.swift:75-79)Re-enabling GUID queries makes sense now that the underlying issue is fixed. The removal of the workaround comment and restoration of proper querying is appropriate. 4. Improved Query Efficiency (ArticleCloudKitService.swift:115-117)Moving from in-memory filtering to server-side filtering when combining GUID + feedRecordName queries is a significant optimization:
5. Test Updates Reflect Reality (ArticleCloudKitService+Query.swift:117-137)The test updates correctly reflect that filtering now happens server-side rather than client-side:
6. All Tests PassThe PR description confirms: MistKit (311/311), CelestraCloud (115/115) ✓ 🔍 Potential Concerns & Questions1. Missing Unit Tests for the Core FixThe FilterBuilder changes (lines 188, 204) lack dedicated tests verifying the type preservation behavior. Consider adding a test like: @Test("FilterBuilder IN filter preserves type metadata")
internal func inFilterPreservesTypes() {
let values: [FieldValue] = [.string("guid-1"), .string("guid-2")]
let filter = FilterBuilder.in("guid", values)
// Verify type is preserved in list items
if case .listValue(let list) = filter.fieldValue?.value {
for item in list {
if case .stringValue = item {
// Type preserved ✓
} else {
Issue.record("Type metadata not preserved in list item")
}
}
}
}Rationale: The existing tests (FilterBuilderTests.swift:125-162) only verify the filter structure, not the type preservation within list items. 2. Backwards Compatibility with Existing QueriesQuestion: Have any queries been deployed to production that might have worked around this issue? The serialization format change could theoretically affect existing saved queries or subscriptions. Recommendation: Document in release notes that this fixes a regression and may change query behavior for any workarounds. 3. Error Handling DocumentationThe original issue manifested as HTTP 400 errors from CloudKit. Consider adding a comment explaining why 4. Performance Consideration: Multiple Filter CombinationsWhile the optimization in
Recommendation: Add a comment documenting tested limits or CloudKit guidelines. 🔒 Security & PrivacyNo concerns identified. The changes are internal query construction improvements with no security implications. 📊 PerformanceImproved: Server-side filtering reduces:
🎯 Code QualityStrengths:
Minor Style Notes:
✏️ RecommendationsHigh Priority:
Medium Priority:
Low Priority:
🎉 ConclusionRecommendation: APPROVE with minor suggestions This is a well-crafted fix that addresses the root cause correctly. The core change is minimal, focused, and leverages existing infrastructure appropriately. The re-enabled functionality and optimizations are logical follow-ups to the fix. The main gap is additional test coverage for the specific type preservation behavior, which would prevent regression. The other suggestions are documentation improvements that would help future maintainers. Great work identifying and fixing the root cause rather than working around it! The change from stripping types to preserving them is exactly right for CloudKit Web Services requirements. |
…(#192)
The IN and NOT_IN filters were stripping type metadata from list items, causing CloudKit Web Services to reject queries with HTTP 400 errors.
Changes:
All tests passing: MistKit (311/311), CelestraCloud (115/115)
Perform an AI-assisted review on