Add phone-number support to MistDemo web users/discover (#398); survey finds no protocol-extension hazard (#399) - #425
Conversation
Adds two project memory files plus their MEMORY.md index entries: - project_beta4_worktree_layout: the branch/worktree split for the remaining v1.0.0-beta.4 issues, the grouping rule (shared openapi.yaml path family => shared branch, to avoid Sources/MistKitOpenAPI/ regeneration collisions), and why #407 was excluded. - project_419_fixed_in_beta3: #419 is already fixed by 5a58120 and verified building on macOS Swift 6.3.2; do not re-implement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Extends the MistDemo web demo's Discover panel to look up user
identities by phone number, alongside the existing email and user
record name lookups. `UserIdentityLookupInfo(phoneNumber:)` already
existed in MistKit, so no library change was needed.
- `WebRequests.DiscoverUsers` gains `phoneNumbers: [String]`, decoded
with `decodeIfPresent(...) ?? []` mirroring the other two lists.
- `WebBackend.webDiscoverUsers` and the `CloudKitService` conformance
accept `phoneNumbers` and append
`phoneNumbers.map { UserIdentityLookupInfo(phoneNumber: $0) }` to the
combined lookup-info array.
- Frontend adds a phone-numbers textarea, sends `phoneNumbers` in the
POST body, and loops `discoverUserIdentityWithPhoneNumber` in the
CloudKit JS parity path.
- `DiscoverUsersCall` and `usersDiscoverForwards` cover phone numbers.
Closes #398
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
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 |
Review: Add phone-number support to MistDemo web
|
|
REVIEW SUMMARY Reviewed the diff for PR 425 against CLAUDE.md conventions. This is a clean, well-scoped change. ISSUE 398 (phone-number support) - looks correct.
Minor, non-blocking observations:
ISSUE 399 (protocol-extension survey) - no code change, and that is the right call. SECURITY STYLE AND CONVENTIONS Nothing blocking here - looks ready to merge pending normal CI. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## v1.0.0-beta.4 #425 +/- ##
================================================
Coverage ? 75.93%
================================================
Files ? 158
Lines ? 3761
Branches ? 0
================================================
Hits ? 2856
Misses ? 905
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:
|
Two issues were assigned to this branch. #398 is implemented; #399 required no code change — the survey it asked for found no instances of the pattern. Details below.
#398 — MistDemo web: phone-number support for
/users/discoverPOST /api/users/discoveralready forwarded emails and user record names; the underlyingdiscoverUserIdentities(lookupInfos:)also accepts phone numbers viaUserIdentityLookupInfo(phoneNumber:), but the web demo didn't expose them. Implemented exactly the spec in the issue.No
Sources/MistKit/change was needed —UserIdentityLookupInfoalready has aphoneNumberproperty and aphoneNumber:initializer parameter. The whole change is confined toExamples/MistDemo.Server/WebRequests+Users.swiftDiscoverUsersgainsphoneNumbers: [String]+.phoneNumberscoding key, decoded withdecodeIfPresent(...) ?? []mirroringemails/userRecordNamesServer/WebBackend.swiftwebDiscoverUsersgains aphoneNumbers:parameterServer/CloudKitService+WebBackend+Users.swiftphoneNumbers.map { UserIdentityLookupInfo(phoneNumber: $0) }to the combined lookup-info arrayServer/WebServer+Users.swiftbody.phoneNumbers; doc comments updatedResources/index.htmlusers-discover-phone-numberstextarea in the Discover sectionResources/js/users.jsphoneNumbersin the POST body, validates "at least one email, phone number, or record name", and loopsdiscoverUserIdentityWithPhoneNumberin the CloudKit JS parity pathTests/.../MockBackend+Calls.swift,MockBackend+UserOperations.swiftDiscoverUsersCallcapturesphoneNumbers; the mock returns aUserIdentityper phone numberTests/.../WebServerTests+Users.swiftusersDiscoverForwardsposts a phone number, asserts 4 identities returned andcaptured?.phoneNumbers == ["+15555550123"]The stale
(phone-number support tracked in #398)comment inusers.jsis removed.Closes #398
#399 — "Fix Over Extension Use With Protocol Extension Implementation Pattern"
The issue body and comments are empty — only a title. I interpreted it as the classic anti-pattern: a protocol requirement implemented in a protocol extension rather than on the conforming type, which is statically dispatched and can silently shadow a conformer's implementation.
I surveyed every
protocoldeclaration inSources/MistKit/(excluding generatedSources/MistKitOpenAPI/), enumerated their declared requirements, and cross-referenced everyextension <Protocol>in the module.Survey results
RecordManagingqueryAllRecords(recordType:)RecordManagement/RecordManaging.swift:75AuthenticatordefaultStorageIdentifierAuthentication/Authenticator.swift:96RecordManagingsync<T>,list<T>,query<T>(_:where:)RecordManaging+Generic.swift:53,85,122RecordManaging where Self: CloudKitRecordCollectionsyncAllRecords,listAllRecords,deleteAllRecordsRecordManaging+RecordCollection.swift:62,94,141OperationInputPathinit(containerIdentifier:environment:database:)OpenAPI/OperationInputPath.swift:52ContainerOperationInputPathinit(containerIdentifier:environment:)OpenAPI/ContainerOperationInputPath.swift:49RecordTypeIteratingRecordTypeSetimplementsforEachdirectlyCloudKitRecord,CloudKitRecordCollection,OperationFailureTarget,CloudKitErrorConvertible,CloudKitResponseType,TokenStorage,TokenManagerFinding: nothing to fix
The hazard does not occur anywhere in
Sources/MistKit/. Every extension-provided member is either (a) a declared protocol requirement — so it dispatches through the witness table and a conformer's implementation correctly wins even through an existential, which is the supported "requirement + default implementation" pattern rather than the shadowing bug; or (b) a member with a genuinely different signature than anything the protocol declares, which can never shadow a requirement.The shadowing bug needs an extension member that is not declared as a requirement but matches a conformer's method. No instance of that shape exists in the module.
Two adjacent observations were noted but deliberately not acted on, since both would be breaking public-API changes rather than clear fixes:
RecordManaging.queryAllRecords's default is a semantic trap (delegates to the deprecated single-page query) already mitigated by an@available(*, deprecated)annotation, andAuthenticator.defaultStorageIdentifier's default is effectively dead code since all three concrete authenticators override it. Neither is the bug the title describes.Per the "report the evidence rather than manufacture a refactor" guidance, no code was changed for #399 and this PR does not carry
Closes #399. The full survey is posted as a comment on the issue: #399 (comment) — recommend closing it as "no instances found", or re-scoping with a concrete example.Note: the
CloudKitService+*extension file split was explicitly not treated as in scope — CLAUDE.md documents it as an intentional organizational pattern, and splitting a concrete type's methods across extension files is not a dispatch concern.Verification
All commands run locally on this branch.
swift buildswift testcd Examples/MistDemo && swift buildMistDemoAppSwiftUI targetcd Examples/MistDemo && swift testswift test --filter usersDiscoverForwardsmise exec -- swift-format -i -r Sources/ Tests/ Examples/MistDemo/…./Scripts/lint.shcd Examples/MistDemo && mise exec -- swiftlintLookupConfig.swift,ChangesRequestOptionsPhase.swift,LookupAllRecordsCommand.swift,DiscoverAllUserIdentitiesCommand.swift); none in any modified fileConventions honored: explicit access modifiers on every import (no new imports were added), explicit ACLs, swiftlint
type_contents_order, no hand-edits toSources/MistKitOpenAPI/. No subrepo Example (BushelCloud, CelestraCloud) was touched — MistDemo is not a subrepo, so these changes belong on this branch.🤖 Generated with Claude Code