Mobile swap sheet (Feature 14) #118

Member

Task

Maestro task f231813c-992e-4a3b-a1a4-868cbad47415 — "Mobile swap sheet" (Feature 14, Weekly Plan Builder).

Done-condition

Tapping a day tile on the mobile draft board puts it in the swapping state (bg + 2 px grape inset ring, kicker "FRI · SWAPPING…", muted name) and opens a bottom Sheet with a "Quest log · N | Regulars · N" segmented control listing dinners (48 px photo, name, difficulty/minutes); choosing one calls PUT /plans/{weekStart}/days/{date} optimistically (rollback + ErrorBanner on failure), closes the sheet and updates the tile and NEW highlight. Dinners already in the week are marked "Already this week" and disabled. Vitest tests cover open/close, swapping state, successful swap, rollback on failure and disabled duplicates. Typecheck, test and build pass.

Scope

Mobile swap sheet only. Explicitly out of scope and left to later tasks: the tablet/desktop plan manager (4657cba1) and drag-and-drop / keyboard swapping (5c2842a8). No backend, migration, skill or API-contract change — the swap endpoint and both dinner lists already exist on the base.

Implementation notes

  • New SwapSheet built from the existing Sheet, Segmented, ListRow, Photo, Tag, Skeleton and ErrorBanner; lists come from the existing useQuestLog and useRegulars.
  • useSwapDay: an optimistic swap that lands the server's plan, rolls that day back on failure, and re-reads the Quest log when the swap settles.
  • Day tiles are buttons with a swapping state; one swap is sent at a time so a later reply cannot overwrite an in-flight one; a swap failure shows an ErrorBanner with Retry.
  • weekdayName added to web/src/plan/week.ts; QuestLogSheet now exports its details line so difficulty/minutes is written in one place.

Evidence (orchestrator-run pre-review gate at cd3771f9ec)

  • gofmt -l . — empty (no Go file changed)
  • cd web && npm run typecheck — PASS
  • cd web && npm test — PASS, 44 files / 690 tests (includes the colour-literal lint)
  • cd web && npm run build — PASS (includes lint:colors and check:dist-fonts)

Implementation commit: cd3771f9ec13a5c747afb7cc453861fa268196bb

Not verified in a real browser by the developer; behaviour is covered by jsdom tests with a mocked API.

## Task Maestro task `f231813c-992e-4a3b-a1a4-868cbad47415` — "Mobile swap sheet" (Feature 14, Weekly Plan Builder). ## Done-condition Tapping a day tile on the mobile draft board puts it in the swapping state (bg + 2 px grape inset ring, kicker "FRI · SWAPPING…", muted name) and opens a bottom Sheet with a "Quest log · N | Regulars · N" segmented control listing dinners (48 px photo, name, difficulty/minutes); choosing one calls `PUT /plans/{weekStart}/days/{date}` optimistically (rollback + ErrorBanner on failure), closes the sheet and updates the tile and NEW highlight. Dinners already in the week are marked "Already this week" and disabled. Vitest tests cover open/close, swapping state, successful swap, rollback on failure and disabled duplicates. Typecheck, test and build pass. ## Scope Mobile swap sheet only. Explicitly out of scope and left to later tasks: the tablet/desktop plan manager (`4657cba1`) and drag-and-drop / keyboard swapping (`5c2842a8`). No backend, migration, skill or API-contract change — the swap endpoint and both dinner lists already exist on the base. ## Implementation notes - New `SwapSheet` built from the existing `Sheet`, `Segmented`, `ListRow`, `Photo`, `Tag`, `Skeleton` and `ErrorBanner`; lists come from the existing `useQuestLog` and `useRegulars`. - `useSwapDay`: an optimistic swap that lands the server's plan, rolls that day back on failure, and re-reads the Quest log when the swap settles. - Day tiles are buttons with a swapping state; one swap is sent at a time so a later reply cannot overwrite an in-flight one; a swap failure shows an `ErrorBanner` with Retry. - `weekdayName` added to `web/src/plan/week.ts`; `QuestLogSheet` now exports its `details` line so difficulty/minutes is written in one place. ## Evidence (orchestrator-run pre-review gate at cd3771f9ec13a5c747afb7cc453861fa268196bb) - `gofmt -l .` — empty (no Go file changed) - `cd web && npm run typecheck` — PASS - `cd web && npm test` — PASS, 44 files / 690 tests (includes the colour-literal lint) - `cd web && npm run build` — PASS (includes `lint:colors` and `check:dist-fonts`) Implementation commit: `cd3771f9ec13a5c747afb7cc453861fa268196bb` Not verified in a real browser by the developer; behaviour is covered by jsdom tests with a mocked API.
orchestrator-agent added 1 commit 2026-10-07 12:55:15 -04:00
Add the mobile swap sheet to the Draft board
CI / ci (push) Successful in 3m14s
CI / ci (pull_request) Successful in 3m15s
cd3771f9ec
Tapping a day tile puts it in the swapping state and opens a bottom sheet
segmented "Quest log · N | Regulars · N". Choosing a dinner swaps the day
optimistically with PUT /api/v1/plans/{weekStart}/days/{date}, landing the
server's plan on success and rolling the day back with an ErrorBanner and
Retry on failure. Dinners already this week are marked and not selectable.

Maestro task f231813c-992e-4a3b-a1a4-868cbad47415.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-07 12:57:57 -04:00
Dismissed
review_agent left a comment
Member

Independent Codex gpt-6-sol review: CHANGES_REQUIRED for this exact commit.

Independent Codex gpt-6-sol review: CHANGES_REQUIRED for this exact commit.
overseer added 1 commit 2026-10-07 13:13:14 -04:00
Keep a week's swaps in the mutation cache, across remounts
CI / ci (push) Successful in 3m10s
CI / ci (pull_request) Successful in 3m13s
2164e24d9d
The Draft board's swap guard was its mounted useMutation observer, so
leaving the week and coming back let a second swap start while the first
PUT was still pending, and Rebuild week's reset() detached a pending swap,
hiding its failure.

The week's swaps now live in the mutation cache, keyed by week: the guard,
the failure shown and the success handler all read them from there. Only
the latest swap of the week writes the plan it is answered with, and only
its failure is the week's. Rebuild week waits for a pending swap (its tile
is disabled meanwhile), and dismissing settled swaps is refused while one
is pending. A failed swap puts its day back only while the day is still,
field for field, the day it wrote, so a newer plan read survives.

Maestro task f231813c-992e-4a3b-a1a4-868cbad47415.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent left a comment
Member

Independent Codex gpt-6-sol review: APPROVED for this exact commit.

Independent Codex gpt-6-sol review: APPROVED for this exact commit.
approver_agent merged commit 3aef21922b into feature/ca2a118d-0beb-49f9-b2ef-d5ed0ac1fa2a-weekly-plan-builder 2026-10-07 13:28:03 -04:00
Sign in to join this conversation.
No Reviewers
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Maniacs_Mansion/MealQuest#118