Conversation
Made-with: Cursor
Explain the app's purpose and day-counting model so the feature-level instructions capture the domain context as well as the project layout. Made-with: Cursor
Add the Where data module, shared UI test scheme, and the first day-level ledger model so the app can render a real dashboard from mergeable tracked and manual state records. Made-with: Cursor
Wire the app through local storage, background location monitoring, and evidence-backed corrections so the initial Where experience can track tax days end to end. Made-with: Cursor
Make it easier to backfill historical travel and recover from confusing local state by adding bulk/package manual imports alongside an in-app data reset path. Made-with: Cursor
|
cursor review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 60d1a5e. Configure here.
|
|
||
| guard | ||
| let administrativeArea = placemark.administrativeArea, | ||
| let state = USState(rawValue: administrativeArea.uppercased()) |
There was a problem hiding this comment.
Reverse geocoder always returns unknown for US states
High Severity
CLPlacemark.administrativeArea returns full state names like "California" or "New York", but USState(rawValue:) expects two-letter abbreviations like "CA" or "NY". Calling .uppercased() on the full name produces "CALIFORNIA", which never matches any USState raw value. Every US location will resolve to .unknown, making automatic jurisdiction tracking completely non-functional.
Reviewed by Cursor Bugbot for commit 60d1a5e. Configure here.
| } | ||
|
|
||
| self?.handle(refreshTask) | ||
| } |
There was a problem hiding this comment.
Background task never completed when self is nil
Medium Severity
In the register closure, if self is nil when the background task fires, self?.handle(refreshTask) silently no-ops without ever calling setTaskCompleted on the task. The system expects every delivered BGTask to be completed; failing to do so can cause the OS to throttle or stop scheduling future background refresh tasks for this app.
Reviewed by Cursor Bugbot for commit 60d1a5e. Configure here.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 60d1a5e2b8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| await attachmentRepository.save(attachment) | ||
| await fileStore.save(data, for: attachment) | ||
| return attachment |
There was a problem hiding this comment.
Verify single evidence writes before returning success
importEvidence(manualEntryID:...) saves attachment metadata first and then unconditionally returns the new attachment without confirming the blob write succeeded. If the file write fails (for example due to disk/full I/O issues), callers still see a successful import, but the attachment becomes unreadable later and the repository contains dangling metadata; this silently corrupts evidence state.
Useful? React with 👍 / 👎.
| let candidateURL = evidenceDirectory.appending(path: filename) | ||
| if FileManager.default.fileExists(atPath: candidateURL.path) { |
There was a problem hiding this comment.
Validate manifest evidence paths stay in package scope
Package evidence filenames are used directly with evidenceDirectory.appending(path: filename) and accepted based only on fileExists, so a manifest entry like ../secret.txt is treated as valid evidence. That allows path traversal outside the intended evidence/ folder (and potentially outside the package directory) and imports unintended local files.
Useful? React with 👍 / 👎.
| let interval = max(request.deliverAt.timeIntervalSinceNow, 1) | ||
| let trigger = UNTimeIntervalNotificationTrigger( | ||
| timeInterval: interval, | ||
| repeats: false, |
There was a problem hiding this comment.
Drop past-due reminder dates instead of firing instantly
Scheduling clamps negative intervals to 1 second, so any reminder date already in the past is delivered immediately. Because gap scheduling can generate one reminder per missed day, reopening after a long tracking gap can produce a burst of immediate notifications rather than a sensible future schedule.
Useful? React with 👍 / 👎.


Summary
Test plan
swift build./idexcodebuild -workspace Stuff.xcworkspace -scheme WhereCoreTests -destination 'platform=iOS Simulator,name=iPhone 17' testxcodebuild -workspace Stuff.xcworkspace -scheme WhereDataTests -destination 'platform=iOS Simulator,name=iPhone 17' testxcodebuild -workspace Stuff.xcworkspace -scheme Where -destination 'platform=iOS Simulator,name=iPhone 17' buildxcodebuild -workspace Stuff.xcworkspace -scheme Stuff-Workspace -destination 'platform=iOS Simulator,name=iPhone 17' -only-testing:WhereTests testxcodebuild -workspace Stuff.xcworkspace -scheme WhereUITests -destination 'platform=iOS Simulator,name=iPhone 17' testMade with Cursor
Note
High Risk
High risk because it introduces background location tracking, scheduled background refresh, local persistence, and notification scheduling—areas prone to privacy, battery, and data integrity issues.
Overview
Builds out the Where app foundation by introducing a new
WhereDatamodule and expandingWhereCorewith domain models/protocols for location samples, jurisdictions, manual entries/evidence, sync checkpoints, and tracking state.Adds ledger-based policies (
TaxDayCalculator,YearLedgerBuilder) plus controllers for year progress snapshots, exporting (plaintext + generated PDF), manual entry/evidence import (including package manifests/backfill), reset, sync checkpoints, and background tracking state management backed by JSON-on-disk repositories.Wires the iOS app to run background location monitoring and app refresh (
CLLocationManagerbridge,BGTaskSchedulercoordinator), schedules gap notifications, updates Info.plist for background modes/location usage, and adds new UI surfaces (dashboard/history/manual entry helpers) with extensive newWhereCoreTests/WhereDataTestsand updated project/package configuration (new product/target, macOS platform, shared test scheme).Reviewed by Cursor Bugbot for commit 60d1a5e. Bugbot is set up for automated code reviews on this repo. Configure here.