Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Delivers phases 5 through 8 of the native iOS parity plan (outing editing, species/WingDex parity, celebrations, appearance audit), alongside session hardening, retry-safe persistence, and tightened observability guarantees across web, iOS, and the Cloudflare Worker API.
Changes:
- Hardened observability and log safety by removing response/exception text from many logs, adding W3C trace propagation, and aligning handlers with
createRouteResponder. - Made web data mutations retry-safe and rollback-capable (photos, outings, observations), and added local-auth retry wrapper usage for selected fetches.
- Expanded iOS parity: outing detail editing (location/species/export), new error UI patterns, lifer celebration overlay, family sort, and token-aware session invalidation.
Reviewed changes
Copilot reviewed 66 out of 74 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/client-log.ts | Gate debug logs in prod; safer client failure summaries |
| src/hooks/use-wingdex-data.ts | Retry-safe optimistic writes with rollback and idempotency support |
| src/hooks/use-auth-gate.tsx | Use local-auth retry wrapper for finalize passkey |
| src/ErrorFallback.tsx | Structured logging for error boundary in dev |
| src/components/pages/SettingsPage.tsx | Local-auth retry for import preview; structured failure logging |
| src/components/pages/OutingsPage.tsx | Prevent double-add species; await mutation and surface errors |
| src/components/flows/OutingReview.tsx | Guard confirm; stable outing IDs; switch to debug logger |
| src/components/flows/AddPhotosFlow.tsx | Debug logger; async persistence; better error surfacing |
| src/App.tsx | Local-auth retry for linked providers fetch |
| src/tests/observability-compliance.test.ts | Tighten handler compliance expectations (fewer exemptions) |
| src/tests/client-log.test.ts | Update expected level/description for safer failure logging |
| ios/WingDexTests/TaxonomyOrderTests.swift | Unit tests for bundled taxonomic sort behavior |
| ios/WingDexTests/CelebrationTests.swift | Unit tests for celebration banner copy |
| ios/WingDexTests/AuthServiceTests.swift | Session validation, datastore reset, and AppError mapping tests |
| ios/WingDexTests/AuthIntegrationTests.swift | Integration coverage for Phase 5 outing editing roundtrip |
| ios/WingDex/Views/WingDexView.swift | Family sort, cached-refresh alert, and empty-state errors |
| ios/WingDex/Views/SpeciesDetailView.swift | Certainty/count metadata, notes section, attribution contrast |
| ios/WingDex/Views/SignInView.swift | One-time session-expired message consumption; safer auth errors |
| ios/WingDex/Views/SharedComponents.swift | Sighting metadata rows; dark-mode map snapshots; preview variants |
| ios/WingDex/Views/SettingsView.swift | Typed errors; celebration trigger after import; session-safe profile sync |
| ios/WingDex/Views/PasskeyManagementView.swift | Typed error mapping for passkey management |
| ios/WingDex/Views/OutingsView.swift | Cached-refresh alert + empty-state errors |
| ios/WingDex/Views/OutingDetailView.swift | Location edit, add/remove species, export CSV, typed alerts |
| ios/WingDex/Views/NativeErrorPreviews.swift | Previews for key native error UI states |
| ios/WingDex/Views/HomeView.swift | Cached-refresh alert + empty-state errors |
| ios/WingDex/Views/EBirdImportView.swift | Typed errors; callback with new-species names after import |
| ios/WingDex/Views/DataManagementView.swift | Typed error mapping for data deletion flows |
| ios/WingDex/Views/CelebrationOverlay.swift | Confetti + banner + accessibility announcement modifier |
| ios/WingDex/Views/AddPhotosFlow/PerPhotoConfirmView.swift | Avoid logging localized error details |
| ios/WingDex/Views/AddPhotosFlow/OutingReviewView.swift | Idempotent outing creation; typed error mapping; retry safety |
| ios/WingDex/Views/AddPhotosFlow/AddPhotosFlow.swift | Add Photos alert recovery + celebration trigger |
| ios/WingDex/ViewModels/AddPhotosViewModel.swift | Typed errors, retry-safe recovery state, new-species name tracking |
| ios/WingDex/Services/PasskeyService.swift | Centralized request instrumentation and timing logs |
| ios/WingDex/Services/DataStore.swift | Generation guards, typed errors, idempotent mutations with rollback |
| ios/WingDex/Services/DataService.swift | Safe HTTP errors, token-aware 401 invalidation, taxonomy search/export |
| ios/WingDex/Services/AuthService.swift | Session validation hardening; token-aware invalidation; one-time sign-in message |
| ios/WingDex/Services/AuthenticatedRequest.swift | Trace instrumentation + timed request wrapper; no response body logging |
| ios/WingDex/Preview Content/PreviewData.swift | Preview data enriched for counts/possible/notes |
| ios/WingDex/Models/AppError.swift | Central typed error mapping for UX-safe copy |
| ios/WingDex/Extensions/DateFormatting.swift | Taxonomic order lookup + comparator helpers |
| ios/WingDex/App/WingDexApp.swift | Foreground session validation; datastore reset on sign-out |
| ios/WingDex.xcodeproj/project.pbxproj | Add new Swift sources/tests; bump marketing version |
| functions/lib/auth.ts | Remove dev-only origin debug log block |
| functions/api/species/wiki-title.ts | Begin migration to shared route responder |
| functions/api/species/search.ts | Use route responder; improved 401 handling |
| functions/api/species/ebird-code.ts | Use route responder; improved 401 handling |
| functions/api/import/ebird-csv/confirm.ts | Safer 5xx logging detail (no exception text) |
| functions/api/import/ebird-csv.ts | Safer 5xx logging detail (no exception text) |
| functions/api/identify-bird.ts | Safer error reporting; clearer 4xx/5xx detail |
| functions/api/health.ts | Safer error reporting (no exception text) |
| functions/api/export/sightings.ts | Safer 5xx logging detail (no exception text) |
| functions/api/export/outing/[id].ts | Safer 5xx logging detail (no exception text) |
| functions/api/export/dex.ts | Safer 5xx logging detail (no exception text) |
| functions/api/data/photos.ts | Idempotent photo writes; conflict validation; safer 5xx logs |
| functions/api/data/outings/[id].ts | Safer 5xx logging detail (no exception text) |
| functions/api/data/outings.ts | Idempotent outing upsert; ID conflict validation; safer logs |
| functions/api/data/observations.ts | Idempotent observation writes; conflict validation; safer logs |
| functions/api/data/dex.ts | Safer 5xx logging detail; reduce sensitive properties |
| functions/api/data/clear.ts | Safer 5xx logging detail (no exception text) |
| functions/api/data/all.ts | Safer 5xx logging detail (no exception text) |
| functions/api/auth/linked-providers.ts | Safer 5xx logging detail (no exception text) |
| functions/api/auth/finalize-passkey.ts | Safer 403/5xx details; avoid leaking IDs in messages |
| functions/_middleware.ts | Safer completion/error logs; include duration on early rejects |
| docs/OBSERVABILITY.md | Expand safe-metadata policy and client-safety guidance |
| docs/IOS_APP_PLAN.md | Mark phases 5-8 as completed; document implemented behaviors |
| .github/AGENTS.md | Add iOS UI verification guidance and parity expectations |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 68 out of 76 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
functions/api/species/wiki-title.ts:8
routeis created but never used, which will typically failnoUnusedLocals/ lint and also means no route-scoped log entry is emitted. Either remove it or use it for a safe debug/info log (without including the raw species name).
Add a reusable celebration overlay that plays a confetti burst and a lifer banner with a success haptic when new species are added, wired into the AddPhotos done screen and the eBird import flow. Confetti and the banner slide are skipped under Reduce Motion, and the banner is announced to VoiceOver. Add a selection haptic on WingDex sort changes. Cover the banner message builder with unit tests.
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 73 out of 81 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
functions/api/data/photos.ts:104
- The
hasOwnedOutingscall arguments are not indented consistently, which reduces readability in this already complex validation/persistence flow.
const allOwned = await hasOwnedOutings(
context.env.DB,
userId,
body.map(photo => photo.outingId)
)
Comment on lines
106
to
108
| const failOutingIds = [...new Set(body.map(p => p.outingId))] | ||
| return route.fail(400, 'Invalid outing reference', `One or more outing IDs are not owned by user or do not exist`, { outingIds: failOutingIds }) | ||
| } |
Comment on lines
148
to
+152
| return Response.json( | ||
| body.map(photo => ({ | ||
| ...photo, | ||
| dataUrl: '', | ||
| thumbnail: '', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Completes the native iOS work tracked in phases 5 through 8:
200 null, token-aware 401 invalidation, foreground validation, account-data isolation, and stale-request guardsContentUnavailableView, system alerts, retry-safe Add Photos, optimistic rollback, and safe quota feedbackAutomated verification
npm run check: 40 test files, 713 tests passednpx playwright test --grep-invert @live --workers=1: 46 tests passednpm run build: Vite client and Cloudflare Worker compiled successfullyAuthIntegrationTestsexcluded from the combined run because repeated local anonymous sign-ins hit the dev limiter)git diff --check, workspace diagnostics, observability compliance tests, and static credential/content log searches are cleanThe local Worker became unresponsive when Playwright used four workers. The same complete suite passed serially against a freshly restarted Worker, so the local E2E evidence above uses
--workers=1.User regression matrix
Phase 5: outing detail editing
Phase 6: species and WingDex parity
Phase 7: celebrations and haptics
+N morebanner copyAmerican Black Duck, American Crow, American Robin +66 more...Phase 8: appearance, sessions, errors, observability
AppErrorXCTest and API/E2E coveragePending manual QA checklist
Phase 5: outing detail
Phase 6: external links
Phase 7: celebrations and haptics
Phase 8: sessions and failure recovery
Screenshots
Known local-only warnings
node:async_hooks/nodejs_compatwarning from Better Auth.