Build the Supply run screen at /plan/shopping (Feature 17)
CI / ci (push) Successful in 5m11s
CI / ci (pull_request) Successful in 5m1s

Render the week's shopping list per mocks 1l, 2b and 2f: the "Supply run"
kicker over the week label, the "Shopping list" title with the count still
to buy of all items, the helper line, and one surface card per dinner with
its Bagel name and day. Items toggle optimistically: a toggle is laid over
the server's Supply run while it is pending, toggles are sent one at a time
in one mutation scope, the counts follow the server's answers, and a
refused toggle puts the item and the count back and says why, with Retry.
From tablet up the cards sit in three masonry columns under the Archive
link and a Send to Google Chat action that stays unavailable until
Feature 19. Archived lists render read-only with an "Archived" tag. The
week shown is the Plan's default week, or the Monday given as ?week=.

Correct the Supply archive section of ARCHITECTURE.md: title jobs and
Freeze are ordered by the shopping service's RWMutex, so a freeze waits
for an in-flight title job to store its title or fail.

Maestro task 40cc2de5-6628-4b32-a491-ab8e02911d88.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 08:19:26 -04:00
co-authored by Claude Opus 5.5
parent 428e87674e
commit 23a1bc0312
8 changed files with 1240 additions and 7 deletions
+9 -3
View File
@@ -505,9 +505,15 @@ the Monday of the household's current week), so a week not yet ended is
frozen list does nothing. A list still untitled is titled first with
`archive_title` from the week's plan, as `Generate` titles it; a title
that cannot be written is logged and the list is frozen untitled, when its
week label stands in for good. A `title_supply_run` job still in flight
with the same scope shares that run (`harness.Run`); whichever stores the
title first wins, and a job storing after the freeze stores nothing. The
week label stands in for good. Titling and freezing are ordered by a
per-service `RWMutex`: a `title_supply_run` job holds it shared across
reading the list, the `archive_title` run and the title write, and `Freeze`
holds it exclusively from reading the list to freezing it. So a freeze
waits for a job in flight to store its title or fail for good; when the
job failed, the freeze finds the list still untitled and makes its own
`archive_title` attempt before freezing. A job that starts during a freeze
waits for it, then finds the list titled (that title stands) or frozen
untitled (the job fails `title_failed`), and stores nothing. The
`week_rollover` schedule is to call `Freeze` for last week.
## Recipe grounding