Skip to content

feat(today): Today dashboard, one-tap meal logging & meal verdicts (006) - #26

Merged
rghamilton3 merged 3 commits into
mainfrom
feat/006-today-logging
Jul 10, 2026
Merged

rghamilton3 merged 3 commits into
mainfrom
feat/006-today-logging

Conversation

@rghamilton3

Copy link
Copy Markdown
Contributor

Summary

Feature 006 — the last of the P1/MVP client work: /today becomes the app's home surface, meals get one-tap logging that closes the supply loop, and an optional three-way verdict (Again / It was fine / Not for me) makes good options resurface without re-deciding.

Full spec set in .specswarm/features/006-today-logging/ (spec, research, data-model, plan, contracts, quickstart, tasks). Quality analysis: .specswarm/quality-analysis-006-today-logging.md (score 91/100).

Database (migration 0009)

  • meal_logs: append-only with an annotation window — only verdict/notes mutable after insert (trigger-enforced, with a carve-out for the FKs' ON DELETE SET NULL so logged sources stay deletable), insert-time type↔reference validation (INV-XD-001/002), SECURITY DEFINER cross-user reference guard, owner-scoped default-deny RLS with no DELETE (policy withheld + explicit REVOKE)
  • portion_events.triggered_by (reserved in 0004 for exactly this) gains a real FK to meal_logs + ownership guard

Domain (src/lib/log/)

  • Discriminated MealLogDraft union, service, runes store with optimistic writes/rollback and a double-tap guard
  • logMeal orchestration: log first, then follow-ups — CONSUMED portion event through the existing ledger (attributed via triggered_by), and the first writer of the PLANNED → LOGGED transition shipped dormant in feature 003; partial follow-up failures keep the log and surface a calm notice
  • Pure, unit-tested derivations: slot windows/nudge, recents/keepers grouping, unrated recap, day coverage (reuses feature 004 fulfillment verbatim)

UI (per canonical mockups design/screens/*-today.html, mobile-log.html)

  • /today: greeting, day-coverage chips + calm headline, gentle mealtime nudge (client-side, "Not now" dismisses per day/slot via localStorage), meal cards with a single primary action (Log it / Add to list per fulfillment), quick actions, "How were these?" recap, expiring-prepped + low-stock attention list
  • Quick Log sheet: slot picker defaulting to the current mealtime, "I ate something" zero-detail log, prepped/recents/keepers groups — with proper dialog a11y (Escape, backdrop, focus restore, inert background)
  • Root redirect + nav now point at /today; three-way verdict supersedes the docs' 4-value MealRating per the mockups (recorded in spec Clarifications)

Housekeeping (second commit)

Testing

Robert Hamilton added 3 commits July 9, 2026 16:14
- meal_logs (0009): append-only with verdict/notes annotation window, insert-time
  type<->reference validation, cross-user source guards, no DELETE; portion_events
  triggered_by gains a real FK + ownership guard; 26 new pgTAP tests
- src/lib/log: types, service, runes store; one-tap orchestration reuses the portion
  ledger (CONSUMED events attributed to the log) and flips PLANNED->LOGGED (first
  writer of the transition shipped in 003)
- /today home surface per design/screens/*-today.html: coverage chips, gentle nudge
  with device-local dismissal, meal cards with single primary action, Quick Log sheet
  (proper dialog a11y: Escape/backdrop/focus-restore/inert), recap, attention list
- 3-way verdict (Again / Fine / Not for me) supersedes the 4-value MealRating per the
  canonical mockups; keepers/recents derived from logs at query time
- gates: check 0/0, lint clean, 266 unit (45 new), 99 pgTAP, 25 e2e (8 new), build ok;
  adversarial review criticals fixed (SET NULL cascade carve-out, triggered_by guard,
  sheet stays open on failed insert)
- CLAUDE.md said "early scaffold, no supabase/ directory" — replaced with the
  actual state (six shipped features, nine migrations, RLS+pgTAP throughout,
  /today home surface) plus the canonical-mockups rule. Closes #21.
- verify-queue T001-T003.pending pointed at the already-merged, deleted
  005-sub-picker-ui worktree. Closes #22.
…ge card

The coverage card's anatomy (floating rounded card, icon-in-circle, one
bold line) read as a dismissable toast when the day was fully covered —
a transient-notification shape for permanent page state. Covered days
now render a plain status line under the greeting, and DayCoverageCard
only mounts when there's something to look at: a fulfillment gap or an
empty day. New isDayCovered() helper in the log module with unit tests.
@rghamilton3
rghamilton3 merged commit e79330d into main Jul 10, 2026
2 of 3 checks passed
@rghamilton3
rghamilton3 deleted the feat/006-today-logging branch July 10, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant