Skip to content

feat: shortlist, visited dates and notes (Plan 4) - #2

Open
Bogdan0708 wants to merge 24 commits into
mainfrom
worktree-pwa-04-collection
Open

Bogdan0708 wants to merge 24 commits into
mainfrom
worktree-pwa-04-collection

Conversation

@Bogdan0708

@Bogdan0708 Bogdan0708 commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

Plan 4 of the private SafeBite PWA: a household shortlist, visited dates and authored notes on restaurant records, plus a deletion safeguard, per-tab sign-out reset and change password. The design is spec §3.7, amended after the design review in planning/audits/2026-09-24-plan-4-design-review.md.

  • Shortlist and visited: one households/{hid}/collection/{rid} document per restaurant, versioned and attributed. The Saved tab defaults to the shortlist, with an "All records" filter and plain labels. The restaurant page has shortlist and visit-date controls; a visit-date draft keeps the version it was opened at, so a concurrent change surfaces as a conflict.
  • Notes: stored under restaurants/{rid}/notes, labelled as personal notes that are never evidence. Only the author can edit or delete. The page offers a conflict chooser ("Keep mine" / "Use theirs"), a delete confirmation tied to the note's version, and a text box locked while its save is in flight.
  • Deletion completion gate: the rules refuse the final restaurant delete until cleanupDone is set and the collection document is gone. Every sweep reads before it deletes, so concurrent or resumed finishers converge, and the merged Plan 3 client can no longer orphan notes or state.
  • Per-tab reset: every tab that had a user reloads when that user signs out or changes, so no Firestore cache survives an account change.
  • Change password in Settings: it reauthenticates first. A failure after the update request was sent is reported as uncertain, never as "your old password still works".

Validation

Local gate on the final code:

Check Result
Typecheck Pass
Web unit tests 361 passed
Functions and rules emulator tests 352 passed, including mixed-version deletion against the real rules
Emulator browser tests 42 passed
Browser tests ×3, no retries 126/126
Boot-guard / preview / upgrade (last full run before the audit fixes, unaffected by them) 1 / 4 / 7 passed

Review trail, committed under planning/audits/:

  • design review 2026-09-24 (F1–F3, amended);
  • per-task reviews and the final whole-branch review in 2026-09-24-plan-4-execution-ledger.md;
  • the independent implementation audit 2026-09-24-plan-4-implementation-audit.md (three P2 findings: stale visit-date base, note text lost during a save, uncertain password outcome), with its reproduction probes. All three are fixed with regression tests, and a scoped re-review found no remaining issues.

Hosted CI run 36061869768 passed on head 92904961 (web-and-functions, 6m12s); GitGuardian passed.

History note: before the first push, the branch history was rewritten to redact personal data (member emails and account IDs, billing account ID, key ID) from planning/specs/firebase-inventory.md. No code changed. Commit IDs cited in the audit files, such as 42e80c5, refer to the pre-redaction local history; the trees are otherwise identical.

Release boundary

This change does not deploy anything. Deploy Firestore rules and functions first, then hosting (README). The pilot project safebite-pilot-urfs3v is provisioned (O3–O6 recorded in spec §3.1), but no rules, functions or hosting have been deployed there. Plan 5's export and account deletion must include collection documents and notes. One deliberate deviation is recorded in the plan: the toggle-conflict browser test is replaced by unit, component and rules proofs plus a deterministic note-conflict browser test.

🤖 Generated with Claude Code

Bogdan0708 and others added 24 commits September 23, 2026 17:06
Add the staging alias for safebite-pilot-urfs3v, the verified inventory of
the legacy project, leaked key and new pilot project, and the owner ruling
that lets the primary assistant perform O3–O6 via the official CLIs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Record the owner rulings from the 2026-09-24 brainstorm: shortlist within
records, notes on the restaurant, household-wide visited, a separate
collection/{rid} state document, and change password in Settings. Align
the §2.3 data model rows and the §3.3 plan table.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
F1: rules-enforced deletion completion gate (cleanupDone + collection
exists check) so no client version can orphan notes or collection state;
read-before-delete sweeps that converge under concurrency.
F2: every tab that observed a signed-in UID resets on sign-out or UID
change, driven by the auth listener rather than the sign-out button.
F3: password-policy rejection, fallback error, success only after
updatePassword. Also joined read states, note confirmation identity,
conflict chooser semantics, and the corresponding acceptance tests.
Archive the design review.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ten tasks from spec §3.7 (amended f8edfc9): rules, the deletion
completion gate with mixed-version proof, the data layer, Saved page,
status block, notes, per-tab reset, change password, and two browser
tasks. Records one deliberate deviation (toggle-conflict browser test).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Restaurant delete now requires cleanupDone and no collection document, so
no client version can orphan notes or state; every deletion step reads
before it deletes. Mixed-version protocol proven against the rules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Finding 1: give the second search's results assertion in discover
scenario 7 an explicit 30s budget, since Functions emulator AUTO mode
can cold-spawn a worker while earlier magic-fixture searches still
hold others.

Finding 4: raise the signin-form visibility waits that follow a
navigation or reload (each spec's signIn helper, and signOutAndWait in
auth.spec.ts/records.spec.ts) from the 5s default to 15s.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ire current password

Finding 2: StatusBlock.saveDate now closes the date editor on any
save outcome, not just "ok", so a conflict (or other failure) reveals
the current visited state instead of hiding it behind the open editor.
Covered by a new StatusBlock test asserting the visited line is shown
after a conflicted date save.

Finding 3: ChangePasswordForm now checks for a blank current password
before validating the new password, showing "Enter your current
password." in pw-error without calling changePassword. Covered by a
new ChangePasswordForm test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Finding 5: note spec §3.7's deploy order (rules and functions before
hosting) under the web section's Guardrails, and that the deletion
completion gate protects older cached clients.

Finding 6: the Plan 4 NEW_STEPS mirror's cleanupDone step now carries
the same "deleting !== true -> notFound" guard as
web/src/records/repository.ts markCleanupDone, so the test mirror
can never mark a live restaurant either.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A live snapshot no longer rebases an open date draft, so a date the other
member saved meanwhile now returns a conflict instead of being
overwritten (audit F1). Unit and browser regressions (C8, C8b) cover an
existing document and a draft opened before the document existed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The composer and the edit box (Save and Keep mine) are read-only while
their write is pending, so text typed after the click can no longer be
dropped by the success path (audit F2). A failure unlocks the box with
the draft intact.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…fter the update

The Firebase SDK looks the account up after accounts:update succeeds, so
a later failure no longer claims the old password still works. Only
policy and recent-login rejections stay definitive in the update phase;
every other update-phase failure is "uncertain", clears the form and
explains how to recover (audit F3). Spec §3.7 amended to match. Unit and
browser regressions inject an internal error and a lost connection after
a real emulator update and check both credentials independently.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The existing change-password browser test now sets a window marker before
the change and checks it survives, proving the document was not
reloaded. README and the Playwright globalTimeout comment carry the
current unit and browser counts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T21:34:27.897474Z 9290496 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant