docs(review): Sprint 6 verification log + plan/handoff/audit updates

Sprint 6 (F3 + F4) is now documented across the project:

- Review/sprint6-verification.md: new deploy + smoke-check doc.
  Backend + frontend deploy (no migration). 5 smoke-check
  sections: A) ShoppingList bulk-add end-to-end, B) F3 partial-
  failure edge case, C) F4 'Plan the week' button + dropdown,
  D) F4 edge cases (no empty slots, all recipes used, invalid
  meal_types), E) Sprints 1-5 regression spot-check. Rollback
  section covers revert (no migration to undo).

- fix-ui-audit.md: new Sprint 6 section (S6.1 F3, S6.2 F4,
  S6.3 verification gate). 'Done when' block updated to 6
  sprints / 10 commits / 20 findings closed.

- Review/handoff-ui-audit.md: updated to a 6-sprint cycle. TL;DR
  table includes the 8ad4ef6 row. File list includes sprint6-
  verification.md. File-level diff summary gains 8 new rows for
  Sprint 6 (F3 backend + F4 backend + 3 new schemas + 2 api
  bindings + 2 page changes). §Future list now strikethroughs
  F3 and F4. Follow-up tickets section added: the no-op
  'Generate Meal Plan' empty-state CTA, the (now-narrower) Pantry
  bulk-add ticket, and the 'Sprints 2-5 + Sprint 6 separate
  batch' deploy note.

- Review/ui-nielsen-audit.md: new Sprint 6 status block at the
  top. F3 + F4 documented with the design-decision context
  (ShoppingList-only scope; dropdown for All/Dinners; partial-
  success with detailed report).

- docs/HANDOFF.md: Last-updated line bumped to 6 sprints / 10
  commits / 20 findings / 6 §Future items. Header commit list
  gains the 8ad4ef6 row. New 'Sprint 6' subsection in the
  2026-06-04 session block. Commit table gained the 8ad4ef6 row.
  Files-modified + Files-added lists updated.

No code changes; the 3 pre-existing WIP files (backend/app/api/
recipes.py, schemas/recipe.py, nginx/nginx.conf) are deliberately
not staged.
This commit is contained in:
2026-06-04 14:05:51 -07:00
parent 8ad4ef67a9
commit a616138e7c
5 changed files with 211 additions and 9 deletions
+28 -1
View File
@@ -4,6 +4,7 @@ You are taking over a project in mid-flight. Read `docs/ORIENTATION.md` first fo
**Date of handoff: 2026-06-04. Last commits before handoff:**
```
8ad4ef6 feat(ui): bulk pantry add + plan-the-week button (Sprint 6 F3+F4)
f740f40 feat(ui): global keyboard shortcuts + shortcut help banner (Sprint 5 F2)
d78bd18 feat(ui): URL week selector + aisle-migration 0015 cast fix (Sprint 5 F5)
d71b67a feat(ui): global react-query error handler + plan-status a11y (Sprint 4 F7+F6)
@@ -301,7 +302,7 @@ Trust the tests. Trust the live runs. Don't trust prose claims that something is
**Current open proposals:**
- `docs/proposals/2026-05-23-feedback-driven-recipe-discovery.md` — pending user approval. No code yet (per the 2026-05-23 section below).
**Last updated: 2026-06-04** — UI/UX audit & fix cycle (Sprints 1, 2, 3, 4, 5) complete. 18 findings closed (5 P0 + 6 P1 + 3 P2 + 4 §Future), code committed across 9 commits (`f3e4a44`, `36038bb`, `ccc70aa`, `f5fb755`, `e90a9d6`, `427d8ac`, `d71b67a`, `d78bd18`, `f740f40`), build green. **CRITICAL: Sprint 2's deploy was blocked on a cast bug in migration 0015; that bug is fixed in `d78bd18`. Sprints 2-5 are now deployable as a single batch (Sprint 1 already live; Sprints 2-5 require backend rebuild + migration + frontend rebuild).** Full UI-audit handoff at `Review/handoff-ui-audit.md`.
**Last updated: 2026-06-04** — UI/UX audit & fix cycle (Sprints 1, 2, 3, 4, 5, 6) complete. 20 findings closed (5 P0 + 6 P1 + 3 P2 + 6 §Future), code committed across 10 commits (`f3e4a44`, `36038bb`, `ccc70aa`, `f5fb755`, `e90a9d6`, `427d8ac`, `d71b67a`, `d78bd18`, `f740f40`, `8ad4ef6`), build green. Sprint 1 deployed; Sprints 2-6 awaiting deploy. **Sprint 2's deploy was blocked on a cast bug in migration 0015; that bug is fixed in `d78bd18`.** Full UI-audit handoff at `Review/handoff-ui-audit.md`.
---
@@ -318,6 +319,7 @@ A full Nielsen-10-heuristics audit of the live deployment at `http://100.108.208
- `Review/sprint3-verification.md` — Sprint 3 deploy + smoke-check checklist (frontend only)
- `Review/sprint4-verification.md` — Sprint 4 deploy + smoke-check checklist (F7 + F6, frontend only)
- `Review/sprint5-verification.md` — Sprint 5 deploy + smoke-check (F5 + F2 + 0015 fix; backend + frontend)
- `Review/sprint6-verification.md` — Sprint 6 deploy + smoke-check (F3 + F4; backend + frontend, no migration)
- `Review/handoff-ui-audit.md` — focused handoff for a fresh agent continuing UI-audit work
**Commits on `main` (ahead of `origin/main` by 9 prior WIP commits plus these 7):**
@@ -333,6 +335,7 @@ A full Nielsen-10-heuristics audit of the live deployment at `http://100.108.208
| `d71b67a` | 4 | F7 global error handler (10 try/catch blocks deleted, QueryCache/MutationCache onError wired) + F6 plan-status aria-label |
| `d78bd18` | 5 | F5 URL week selector (backend `?week_start=`, frontend prev/next + `useSearchParams`) + **CRITICAL 0015 cast fix** (was blocking Sprint 2 deploy) |
| `f740f40` | 5 | F2 keyboard shortcuts (vim-style sequences, focus-search bus, help banner) + new `hooks/` and `components/ShortcutHelpBanner.tsx` |
| `8ad4ef6` | 6 | F3 bulk pantry add (POST /api/pantry/bulk + ShoppingList 'Add N to pantry' button) + F4 plan-the-week (POST /api/meals/{id}/fill-empty-slots + Dashboard dropdown) |
**Critical Sprint 2 deploy note:** the user must run on the deployment host *after* `git pull`:
@@ -410,6 +413,30 @@ docker compose -f docker-compose.yml up -d --build backend frontend
The order matters: backup → migration → rebuild. The migration will lock the `ingredient` and `grocery_item` tables for the duration; the persist script creates recoverable backups.
### Sprint 6 — F3 (bulk pantry add) + F4 (plan the whole week)
Third wave of §Future. Both M-L size, both with design decisions made by the user during planning.
**F3 — Bulk 'add checked to pantry' (ShoppingList):**
- Backend `POST /api/pantry/bulk` accepts `{items: HomePantryCreate[]}`; returns `HomePantryBulkResult { added, updated, skipped, results: [{ingredient_id, status, id, reason}] }`. Per-item failure model: unknown ingredient → `skipped` with reason, not a 4xx. Each item follows the same upsert semantics as the single-item endpoint.
- Frontend `mealPlannerApi.pantry.addBulk(items)`.
- ShoppingList gains a primary `Add N to pantry` button (next to the existing Reset button) that appears when `checked.size > 0`. Toast reports `added X, updated Y, skipped Z`. On success, only the items that landed in the pantry are removed from the checked Set; skipped items stay checked so the user can see what failed.
- **Scope decision:** ShoppingList only. Pantry does not have row-selection state, and adding multi-select to a 4-column table on mobile is a larger surface than Sprint 6's budget. The audit's F3 ticket can be re-scoped later.
**F4 — Plan the whole week (Dashboard):**
- Backend `POST /api/meals/{id}/fill-empty-slots` with body `{meal_types: [str, ...]}` returns `FillEmptySlotsResult { filled: [{day, meal_type, item}], failed: [{day, meal_type, reason}] }`. Iterates day 1..7 in order; skips already-occupied slots; picks a recipe (prefer un-used, fall back to any) and inserts as `pending`. Per-slot failure model — never aborts mid-batch. Invalid meal_type (e.g. `'brunch'`) returns immediately with a single FailedSlot explaining why.
- Frontend `mealPlannerApi.meals.fillEmptySlots(planId, mealTypes)`.
- Dashboard gets a primary `Plan the week` button (next to the Sprint 5 week-nav control) with a dropdown. Two options: `Dinners only` (sends `['dinner']`) and `All meals` (sends `['breakfast','lunch','dinner']`). Each option has a one-line secondary label.
- Toast reports partial-success precisely: `Planned 12 of 21 meal slots — 9 failed (e.g. <reason>)`. Query invalidated so new slots show up.
- **Scope decision:** dropdown (per design-call); partial-success (per design-call).
- **Out of scope:** the no-op `Generate Meal Plan` empty-state CTA at `Dashboard.tsx:415` (when the family has NO plan at all, distinct from the F4 case of "plan exists but slots are empty"). Routing that CTA needs a user-facing "create a new plan" path (orchestrator/admin flow), which is a different feature. Documented as a follow-up.
**Sprint 6 deploy (backend + frontend, no migration):**
```bash
git pull
docker compose -f docker-compose.yml up -d --build backend frontend
```
### Deployment-host vs dev-host (Tailscale gotcha)
This repo lives on a dev host (Tailscale `100.108.146.47`). The user's home server (Tailscale `100.108.224.12`) serves the live app at `100.108.208.56:8082`. The user's workflow is **commit locally, `git pull` on the deployment host, rebuild there**. Don't `docker compose up` on the local dev host expecting it to update the live site — it won't.