Uh oh!
There was an error while loading. Please reload this page.
Add custom/shared zone support to the query path (#146) - #426
Conversation
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
ReviewReviewed the diff ( Code quality & design
Potential bugs / edge cases
PerformanceNo concerns — this only changes what gets serialized into an existing request body; no new allocations, requests, or pagination behavior beyond forwarding SecurityNo concerns. Test coverageThe new
I did not find a test for the NitThe PR description states the wire-level behavior change (dropping the always-present Overall: solid, well-tested, well-documented fix that matches established codebase conventions ( |
Review: PR #426 — Custom/shared zone support for the query path Nice, focused change with strong justification for the design calls. Went through the diff plus the surrounding codebase for consistency. Code quality / correctness
Potential issues
Test coverage Security / performance Docs Overall: solid, well-scoped implementation matching established codebase conventions. The memory-file scope creep is the only thing worth asking about before merging. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@## v1.0.0-beta.4 #426 +/- ##
================================================
Coverage ? 80.60% ================================================
Files ? 177 Lines ? 4366 Branches ? 0 ================================================
Hits ? 3519 Misses ? 847 Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Review: Add custom/shared zone support to the query path (#146)Reviewed against Strengths
Issues
Minor
Performance / SecurityNo concerns on either front. The added parameter is optional and zero-cost when omitted, and zone name/owner are opaque identifiers passed straight through to CloudKit with no new attack surface (same handling as the existing 🤖 Generated with Claude Code |
eafd796 to
6937cfbCompareReview: #146 — custom/shared zone support for the query pathOverall this is a clean, well-scoped change. The Code quality / correctness
Minor observations (non-blocking)
Test coverageGood coverage on the MistKit side (body-level assertions for omission, custom zone, shared-zone Security / performanceNo concerns — this only threads an optional identifier into an existing JSON request body; no new external input parsing beyond the existing Nice work — approving from a code standpoint modulo the minor nits above. 🤖 Generated with Claude Code |
6937cfb to
4d420ebCompareleogdion
commented
Aug 25, 2026
Review/merge order noteProposed order for the This PR should go after #424. It's small (+334/−19), but it carries the one hard conflict with the deprecated-API removal. Blocker: rebase onto #424 firstThis PR adds +6 lines to Three other files overlap with #424 and want the same treatment:
Note that #424 rewrites the TestingIt also adds a requirement to The design rationale in the description ( |
Captures the approved plan for landing #426 on the current `origin/v1.0.0-beta.4`: the seven expected rebase conflicts and their decided resolutions (notably `git rm` on the deprecated-overload file #424 deleted, and taking beta.4 wholesale for `QueryRecordsPhase`), the response to review comment 5371619875, and the design of a private-only `CustomZoneQueryPhase` integration phase. Docs only — no source changes, so CI is skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QJtVSbJZTvbo2X8QRoaaxt
`queryRecords` hard-coded `zoneID: .init(zoneName: "_defaultZone")` into the `records/query` request body, which made custom and shared zones unqueryable. Thread an optional `zoneID: ZoneID? = nil` through the query path: - `queryRecords(_:limit:desiredKeys:continuationMarker:zoneID:…)` — the `Query` primitive that builds the request body - both deprecated `queryRecords(recordType:…)` overloads - `queryAllRecords(…)` — forwarded on every page it fetches - `fetchExistingRecordNames(…)` — so a pre-fetch can target the same zone as the `modifyRecords(_:zoneID:)` that follows it Use `ZoneID` rather than the bare `zoneName: String` the issue sketched, so shared zones can carry `ownerName`. This also matches the existing `modifyRecords(_:atomic:zoneID:…)` parameter. `nil` omits the `zoneID` key entirely and lets CloudKit resolve the database's default zone. That is not a silent policy default in the sense of `.claude/memory/feedback_no_silent_policy_defaults.md` — no credential or attribution semantics ride on it — and it keeps the change source-compatible. `database:` still has no default. `RecordManaging`'s query methods stay zone-unaware: that protocol is a deprecated, database-agnostic abstraction. No OpenAPI change was needed — `Components.Schemas.ZoneID` already models `zoneName` + `ownerName`, and `records/query` already references it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Wire zoneID and optional zone owner through QueryCommand, the query integration phase, and the web query path so #146 can be exercised live. Co-authored-by: Cursor <cursoragent@cursor.com>
Rebase follow-up: reject zoneOwner without zoneName at the web request boundary, update AGENTS.md and DocC links post-#424, and add CustomZoneQueryPhase to test-private for end-to-end zoneID coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
6100f43 to
04f2f35Compareleogdion
commented
Aug 28, 2026
Re: review comment #426 (comment) Rebased onto current Applied
Considered, left as-is
Follow-up (out of scope for this PR)
|
Query the default zone explicitly in CustomZoneQueryPhase isolation checks, skip timestamp verification for records that omit the field, and print copy-friendly failure messages instead of trapping on exit. Co-authored-by: Cursor <cursoragent@cursor.com>
MistDemo.swift imported Darwin to source exit(1), which broke the executable target on Linux, Windows, Android and WASI with "no such module 'Darwin'". Import Foundation instead, which vends exit on every supported platform and matches the idiom already used by the BushelCloud and CelestraCloud examples. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
* Add phone-number support to MistDemo web users/discover (#398) * Remove deprecated API, model server error codes, refactor FieldValue conversion, add cloud toolchain (#424, #421, #378, #358, #295) * Add confirmed zone metadata (syncToken, atomic) to zone schemas (#427) * Add records/resolve and records/accept share operations (#41, #42, #428) * Add custom/shared zone support to the query path (#146) (#426) * Add changes/database and changes/zone endpoints; deprecate zones/changes (#401, #47, #46) * Clear two Linux build warnings (#433) * modifyZones per-zone failures (#431) + zones/changes metaSyncToken (#430) (#443)
Summary
queryRecordshard-codedzoneID: .init(zoneName: "_defaultZone")into therecords/queryrequest body (CloudKitService+Operations.swift:85), making custom and shared zones unqueryable. This threads an optional zone through the whole query path.Rebased onto current
v1.0.0-beta.4(including #424 deprecated-API removal).Design decisions
ZoneIDrather thanzoneName: StringThe issue sketched
zoneName: String = "_defaultZone". I used the existingZoneIDtype instead:ZoneIDcarriesownerName, which a bare string cannot. Shared zones live in the owner's database and are unaddressable without it — so azoneName-only parameter would have left the issue's own "working with shared zones" use case unsolved.modifyRecords(_:atomic:zoneID:desiredKeys:numbersAsStrings:database:)already takeszoneID: ZoneID? = nil, with the sameComponents.Schemas.ZoneID(from:)conversion. Query and modify now name their zone the same way.ZoneID.defaultZoneremains available for callers who want to say "default zone" explicitly.Defaulted (
= nil) rather than requiredPer
.claude/memory/feedback_no_silent_policy_defaults.mdthis was a deliberate call, not an oversight:PublicAuthPreference), where a silent default caused records to be mis-attributed. Nothing comparable rides on zone selection — a wrong zone yields wrong-or-empty results, visibly, not a silent security/ownership mistake.nildoes not mean "quietly substitute_defaultZone". It means omit thezoneIDkey from the request entirely and let CloudKit resolve the default zone server-side. There is no client-side policy being invented.zoneID/desiredKeys/numbersAsStrings/zoneWideonmodifyRecordsandfetchRecordChangesare all optional-defaulted).database:still has no default, as CLAUDE.md requires — untouched.Surfaces updated
queryRecords(_:limit:desiredKeys:continuationMarker:zoneID:zoneWide:numbersAsStrings:database:)queryAllRecords(…)zoneIDon every page it fetchesfetchExistingRecordNames(…)modifyRecords(_:zoneID:)that follows it in the classify workflowRecordManaging.queryAllRecords(recordType:)is intentionally left zone-unaware — that protocol is a database-agnostic abstraction. Callers needing a zone should useCloudKitServicedirectly.No OpenAPI regeneration needed
Components.Schemas.ZoneIDalready models bothzoneNameandownerName, and therecords/queryrequest body already$refs it.openapi.yamlandSources/MistKitOpenAPI/are untouched.Source compatibility
Source-compatible. Every new parameter is defaulted, and each was inserted before the non-defaulted
database:, so existing call sites keep compiling unchanged.One behavioral change worth flagging: requests previously always carried
"zoneID": {"zoneName": "_defaultZone"}; they now omit the key when no zone is given. CloudKit resolves the same default zone either way, so this is wire-level-different but semantically equivalent. ThequeryOmitsZoneIDByDefaulttest pins the new behavior.Tests
Six new
@Tests inTests/MistKitTests/CloudKitService/Query/CloudKitServiceTests.Query+ZoneID.swift(Zone Selectionsuite). They assert against the serialized request body captured byMockTransport:zoneIDomitted when none is supplied (default-zone behavior unchanged)zoneNameforwarded, with no strayownerNameownerNameforwardedZoneID.defaultZoneforwarded explicitly when askedqueryAllRecordsforwards the zone on both pages of a paginated runfetchExistingRecordNamesforwards the zoneMistDemo web server: two new tests reject
zoneOwnerwithoutzoneName(400) and verify both zone fields forward to the backend.MistDemo integration (
test-private): newCustomZoneQueryPhasecreates a custom zone, writes two records, queries them back withzoneID:, verifies the default-zone query does not see them, and deletes the zone inline.Verification
swift buildswift testExamples/MistDemoswift build && swift test./Scripts/lint.shDocs
AGENTS.md(CLAUDE.mdsymlink): "Zone selection on queries (Feature: Add custom CloudKit zone support for queries #146)" section (updated post-Remove deprecated API, model server error codes, refactor FieldValue conversion, add cloud toolchain #424).WorkingWithRecords.md: "Querying a custom or shared zone" subsection.zoneID:across.doccarticles andQuery.swift.Closes#146