# Sprint 7 — Verification **Sprint:** Fix webui "empty meal plan" (date-semantics mismatch) **Status:** code complete, awaiting deploy. **Approach:** Option C — align orchestrator + frontend on "this week" = upcoming Monday; migrate the existing Friday-keyed plan to its equivalent Monday. **Date of handoff:** 2026-06-05. --- ## What changed (recap) | Layer | File | Change | |---|---|---| | Backend | `backend/app/services/orchestrator/runner.py:20-35` | `_current_week_start()` returns the **upcoming Monday** (today if Mon). | | Frontend | `frontend/src/lib/utils.ts:43-83` | `isoMonday` → `upcomingMonday` (new logic). `isoMonday` kept as a deprecated alias. New `formatWeekRange(mondayIso)` helper. | | Frontend | `frontend/src/components/WeekRangeNav.tsx` (NEW) | Shared component. Renders `[<] Jun 8 — Jun 14 [>]` with clickable chevrons + a clickable range label (jump home) + an optional `This week` chip. | | Frontend | `frontend/src/pages/Dashboard.tsx` | Import + 3 call-site updates. Replaces inline segmented control with ``. | | Frontend | `frontend/src/pages/ShoppingList.tsx` | Same: import + 5 call-site updates, replaces both inline segmented controls (header + empty-state) with ``. | | Data | `backend/scripts/fix_2026_06_05_to_2026_06_08.sql` (NEW) | Guarded `UPDATE meal_plan SET week_start_date='2026-06-08' WHERE week_start_date='2026-06-05';` with a `SELECT COUNT(*)` and a final verification `SELECT`. Optional commented-out block for 2026-05-29. | | Docs | `Review/ui-nielsen-audit.md` + `fix-ui-audit.md` + `Review/handoff-ui-audit.md` + `docs/HANDOFF.md` + `.agent/plan.md` + `.agent/context.md` | All updated with Sprint 7 status blocks. | **No new dependencies. No backend migration. Frontend + backend rebuild only, plus the one-time SQL data fix.** --- ## Deploy commands Run on the deployment host (`100.108.224.12`): ```bash # 1. Pull cd ~/MealPlanner git pull # 2. SQL data fix (the user's 3-pending-items plan moves to 2026-06-08) docker compose exec -T db psql -U mealplanner -d mealplanner \ -f /dev/stdin < backend/scripts/fix_2026_06_05_to_2026_06_08.sql # Expected output: # rows_to_migrate # ---------------- # 1 # UPDATE 1 # COMMIT # If you also uncomment the 2026-05-29 block, you'll see another UPDATE 1. # 3. Rebuild backend + frontend docker compose -f docker-compose.yml up -d --build backend frontend # 4. (Optional) Verify the new function on the running backend docker compose exec backend python -c " from datetime import date from app.services.orchestrator.runner import _current_week_start print('_current_week_start() →', _current_week_start()) " # Should print the upcoming Monday's date (e.g. 2026-06-08 if today is Fri 2026-06-05). ``` **Order matters.** Pull → SQL fix → rebuild. The SQL fix is idempotent (re-running is a no-op once 2026-06-05 has no rows), so it's safe to retry. --- ## Smoke checklist (browser, on `http://100.108.208.56:8082/`) | # | Action | Expected | |---|---|---| | 1 | Open `/` (Dashboard) with no `?week=` query param. | URL is just `/`. Header shows the new week-range nav: `[<] Jun 8 — Jun 14 [>]` for week 2026-06-08. Three meal cards visible (Chicken Fajitas Mon, Garlic Shrimp Scampi Wed, Breakfast-for-Dinner Veggie Scramble Fri). Plan status badge: `draft`. Total cost ~$188.98. | | 2 | Click the range label (`Jun 8 — Jun 14`). | URL is still `/` (jump home goes to the default week). The `This week` chip is **not** visible (we're already on the upcoming week). | | 3 | Click the right chevron (`[>`). | URL becomes `/?week=2026-06-15`. Header shows `Jun 15 — Jun 21`. Empty state appears (no plan for next-next week). | | 4 | Click the left chevron (`[<`). | URL becomes `/?week=2026-06-08`. Header shows `Jun 8 — Jun 14`. Three meal cards reappear. | | 5 | Click the `This week` chip (visible only when off the upcoming week). | URL clears the `?week=` param. Header shows the upcoming week again. | | 6 | Open `/shopping-list` (no `?week=`). | Header shows the same `[<] Jun 8 — Jun 14 [>]` nav. The "Add N to pantry" + "Reset" + "Print List" buttons are still in their normal positions. | | 7 | Click a checkbox in the shopping list. The "Add N to pantry" button shows. | Button works as in Sprint 6 (no regression). | | 8 | Open `/shopping-list?week=2026-06-15`. | Empty state: "No plan for that week. Go to the Dashboard and generate one, or pick a different week." The week-nav is still clickable. | | 9 | Open `/` with `?week=2026-06-01` (a Mon that has no plan). | Empty state with "Plan the week" dropdown (F4). The week-nav shows `Jun 1 — Jun 7` with the `This week` chip visible (because we're not on the upcoming week). | | 10 | Reload the page after each navigation. | URL is preserved; the same week is shown. (F5 URL persistence still works.) | | 11 | Press `g d` (Sprint 5 keyboard shortcut). | Navigates to `/` with the default (upcoming) week. | | 12 | Press `?` (Sprint 5 help shortcut). | ShortcutHelpBanner slides down with the keyboard help text. (No regression.) | If any item fails, **stop and report** with the URL you were on, the action you took, and the observed vs expected behavior. --- ## API smoke (curl, on the deployment host) ```bash # (a) The user's just-migrated plan lives at the upcoming Monday's key curl -s "http://100.108.208.56:8082/api/meals?week_start=2026-06-08" | python3 -m json.tool | head -30 # Expect: 3 items, all status=pending, total ~$188.98 # (b) The old Friday-keyed date now returns null (post-migration) curl -s "http://100.108.208.56:8082/api/meals?week_start=2026-06-05" # Expect: null # (c) The current calendar week has no plan (was always the case) curl -s "http://100.108.208.56:8082/api/meals?week_start=2026-06-01" # Expect: null # (d) The shopping list is also keyed by the upcoming Monday now curl -s "http://100.108.208.56:8082/api/shopping-list?week_start=2026-06-08" | python3 -c " import sys, json d = json.load(sys.stdin) print('items:', len(d.get('items', []))) print('week:', d.get('week_start_date')) print('total:', d.get('total_estimated_cost')) " # Expect: items around 20, week=2026-06-08, total ~$27.35 ``` --- ## Things to look for - **The webui is no longer empty.** This is the user's original complaint. - **The week-range label is scannable.** The header shows `Jun 8 — Jun 14` (or whatever the upcoming week is) — the user requested this format. - **The chevron brackets are clickable.** Mouse or keyboard, they step the week by 7 days. - **The `This week` chip appears only when off the upcoming week.** Clean visual signal. - **URL persistence still works.** `?week=YYYY-MM-DD` in the URL is respected. - **Keyboard shortcuts (Sprint 5) still work.** `g d`, `g r`, `g p`, `g s` navigate; `/` focuses search; `?` shows help. - **Plan-the-week (Sprint 6) still works.** The "Plan the week" button is at the same position with the same dropdown. - **Bulk pantry add (Sprint 6) still works.** The "Add N to pantry" button on the shopping list is unchanged. --- ## Rollback (if needed) The Sprint 7 change is small and easy to revert: 1. Revert `runner._current_week_start()` to return the most recent Friday (the original 5-line body). 2. Revert `upcomingMonday()` to return the current calendar week's Monday. 3. Revert the frontend `WeekRangeNav` swap (put the inline segmented control back in Dashboard and ShoppingList). 4. Re-run the SQL in reverse: `UPDATE meal_plan SET week_start_date='2026-06-05' WHERE week_start_date='2026-06-08';` (and similarly for 2026-05-29 if you migrated it). 5. `git revert` is also clean — all Sprint 7 work is in one or two commits if squashed. The pre-Sprint 7 behavior is what the user reported as broken. Only revert if a regression appears that wasn't there before Sprint 7. --- ## Verification log (Filled in by the operator after deploy + smoke.) - [ ] `git pull` on deployment host → success - [ ] SQL fix script ran → expected row count - [ ] Backend rebuild → success - [ ] Frontend rebuild → success - [ ] Browser: `/` shows 3 meals on the upcoming week - [ ] Browser: `[<]` and `[>]` chevrons step the week - [ ] Browser: `This week` chip is visible only when off the upcoming week - [ ] API: `/api/meals?week_start=2026-06-08` returns 3 items - [ ] API: `/api/meals?week_start=2026-06-05` returns null - [ ] No regression in Sprints 1-6 --- **Last updated: 2026-06-05** — code complete, awaiting deploy.