1. Enforce the 12h session lifetime server-side in requireAuth (reject a
session older than the TTL even if the sealed cookie is intact), so a
leaked cookie value can't be replayed indefinitely. Shared sessionTTL
const drives both the cookie MaxAge and the check.
2. Send X-Content-Type-Options: nosniff when serving user-uploaded
receipt/attachment bytes, so the browser won't sniff past the declared
(upload-time allowlisted) MIME type.
Update SPEC §2 and §6 accordingly; tests cover stale-session rejection.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a shared, free-form tag vocabulary attachable to a receipt at upload.
New tags/receipt_tags tables (case-insensitive label dedup); an in-page
chip-mosaic picker after "Who" with inline tag creation. Tags are
resolved/created only on successful submit, and shown on the confirm
page and recent lists. Documented as spec item 14.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Abbreviate "First Last" → "F. Last" in the recent list and nowrap the upload
timestamp, so rows fit on narrow phone screens instead of wrapping.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- New attachments table (FK to receipts), dual-write: file on disk + DB blob.
- On-disk layout split: receipts under <ROOT>/receipts/<YYYY>/..., attachments
under <ROOT>/attachments/<YYYY>/..., attachments named from the parent
receipt's date+amount stem (_att, _att_1, ...).
- Upload form gains an optional multi-file "Additional files" field; the files
ride along with POST /upload, saved after the receipt row exists. No AI runs
on attachments; primary-image auto-fill unchanged.
- GET /attachment/{id}/file serves blobs; confirm page lists them; recent list
links them. Adding attachments to an already-saved receipt is not yet supported.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Features (see spec.md v2):
- Wire receipt classification into the upload flow; cheap model (Haiku 4.5)
is now the default, shown as a footnote with per-scan cost in cents.
- Skip-AI toggle to enter fields by hand.
- Duplicate-transaction warning: live check on date+amount, gated submit.
- Tally tab: person x year totals with margins and grand total.
- Recent uploads / recent receipts tabs with paging and file serving.
- People reconcile on startup: merge stray partial names (e.g. "Jude" ->
"Jude Tremblay"), reassigning receipts; idempotent seeding.
- scripts/build.sh builds the binary; scripts/run.sh builds and runs with .env.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>