Public Access
fix(ui): align 'this week' to upcoming Monday (Sprint 7)
User report 2026-06-05: 'webui Meal Planner page is empty' on Friday
morning after the Friday email went out. Root cause: the orchestrator
keyed plans by the most-recent-Friday while the frontend's isoMonday()
returned the most-recent-Monday — a 7-day mismatch on Fridays.
Fixes (one semantic across the stack):
- runner._current_week_start() returns the upcoming Monday (today if
Mon, else the next Mon). The Friday email subject
('Meal plan for week of <date>') automatically picks up the new
value via run.week_start_date.
- frontend isoMonday -> upcomingMonday (same logic; renamed for
intent). isoMonday kept as a deprecated alias.
- New WeekRangeNav component (Dashboard + ShoppingList share it).
Renders [<] Jun 8 - Jun 14 [>] with clickable chevrons and a
clickable range label that jumps to the upcoming week. Replaces
the Sprint 5 inline segmented control on both pages.
- New formatWeekRange(mondayIso) helper (UTC-stable; uses
timeZone: 'UTC' so the rendered date matches the stored ISO date
regardless of viewer TZ; closes a latent bug in formatIsoDate too).
- New SQL fix script that retargets the user's 3-pending-items plan
from 2026-06-05 (Friday-keyed) to 2026-06-08 (upcoming Monday).
Idempotent + transaction-wrapped. Optional block for 2026-05-29.
No backend migration. No new dependencies. Deploy is git pull +
run the SQL fix + docker compose up -d --build backend frontend.
See Review/sprint7-verification.md for the full deploy + smoke flow.
Files:
- backend/app/services/orchestrator/runner.py:20-35
- backend/scripts/fix_2026_06_05_to_2026_06_08.sql (new)
- frontend/src/lib/utils.ts:43-130
- frontend/src/components/WeekRangeNav.tsx (new)
- frontend/src/pages/Dashboard.tsx (3 call sites + 1 segmented control)
- frontend/src/pages/ShoppingList.tsx (5 call sites + 2 segmented controls)
- Review/{sprint7-verification,ui-nielsen-audit,handoff-ui-audit}.md
- fix-ui-audit.md
- docs/HANDOFF.md
- .agent/{plan,context}.md
This commit is contained in:
@@ -18,10 +18,22 @@ STEPS = ("scrape", "generate", "email", "reminder", "deadline", "finalize")
|
||||
|
||||
|
||||
def _current_week_start() -> date:
|
||||
"""Return the most recent Friday (today if today is Friday)."""
|
||||
"""Return the upcoming Monday (today if today is Monday).
|
||||
|
||||
The Friday email advertises the upcoming Mon-Sun week; the plan is
|
||||
keyed by that Monday so the email subject ("Meal plan for week of
|
||||
<date>") matches the calendar week the meals are for. The frontend
|
||||
uses the same convention via `upcomingMonday()` in `lib/utils.ts`.
|
||||
|
||||
Paired with the Sprint 7 fix: see `Review/sprint7-verification.md`
|
||||
and the SQL migration script `backend/scripts/fix_2026_06_05_to_2026_06_08.sql`
|
||||
for the one-time data fix that retargets any pre-S7 Friday-keyed
|
||||
plan to the equivalent upcoming Monday.
|
||||
"""
|
||||
today = date.today()
|
||||
days_since_friday = (today.weekday() - 4) % 7
|
||||
return today - timedelta(days=days_since_friday)
|
||||
if today.weekday() == 0: # Monday
|
||||
return today
|
||||
return today + timedelta(days=(7 - today.weekday()))
|
||||
|
||||
|
||||
def _get_or_create_run(db, family_id, week_start_date: date):
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
-- Sprint 7 — One-time data fix: retarget Friday-keyed plan(s) to the
|
||||
-- equivalent upcoming Monday.
|
||||
--
|
||||
-- Background: pre-Sprint 7, the orchestrator's `_current_week_start()`
|
||||
-- returned the most recent Friday. The Friday email was sent for that
|
||||
-- date, and the plan was keyed by it. Sprint 7 changes the convention
|
||||
-- to "upcoming Monday" (Mon-Sun week). Existing plans keyed by a
|
||||
-- Friday are migrated to the equivalent upcoming Monday so:
|
||||
--
|
||||
-- 1. The user's just-voted-on plan (3 pending items, week of
|
||||
-- 2026-06-05) lives under the same date the new code will use.
|
||||
-- 2. The webui default (upcoming Monday) and the plan key line up.
|
||||
--
|
||||
-- This script is idempotent: re-running it is a no-op once 2026-06-05
|
||||
-- has no rows. The transaction wraps both the count and the UPDATE so
|
||||
-- a partial run can't leave the table in an inconsistent state.
|
||||
--
|
||||
-- Run on the deployment host (db is in a container, no host psql):
|
||||
--
|
||||
-- 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
|
||||
-- id | week_start_date
|
||||
-- ------------------------------------+-----------------
|
||||
-- <uuid-for-2026-05-15-plan> | 2026-05-11
|
||||
-- <uuid-for-2026-05-22-plan> | 2026-05-18
|
||||
-- <uuid-for-2026-05-29-plan> | 2026-05-25
|
||||
-- <uuid-for-2026-06-05-plan-NOW-2026-06-08> | 2026-06-08
|
||||
--
|
||||
-- COMMIT
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- (1) How many rows will be migrated? A count of 1 is the expected
|
||||
-- outcome for the 2026-06-05 plan. Zero is also safe (nothing to do).
|
||||
SELECT COUNT(*) AS rows_to_migrate
|
||||
FROM meal_plan
|
||||
WHERE week_start_date = DATE '2026-06-05';
|
||||
|
||||
-- (2) The actual migration. Single-row target; safe under concurrent
|
||||
-- readers (the row stays visible under the default REPEATABLE READ).
|
||||
UPDATE meal_plan
|
||||
SET week_start_date = DATE '2026-06-08'
|
||||
WHERE week_start_date = DATE '2026-06-05';
|
||||
|
||||
-- (3) Verify. Lists all plans ordered by week, so the operator can
|
||||
-- eyeball that the migration took effect and that the date keys are
|
||||
-- all Mondays (or Fridays, if a pre-2026-05-15 plan was missed).
|
||||
SELECT id, week_start_date
|
||||
FROM meal_plan
|
||||
ORDER BY week_start_date;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ---------------------------------------------------------------------
|
||||
-- Optional: also migrate the 2026-05-29 plan (and any other Friday-keyed
|
||||
-- plan) to the equivalent Monday. The 2026-05-29 plan contains 3
|
||||
-- approved items the family has already acted on; migrating it is
|
||||
-- cosmetic (the plan keeps the same items, just under a Monday key so
|
||||
-- the webui's "current calendar week" view -- if anyone navigates to
|
||||
-- it -- agrees with the calendar). Comment out the block below if
|
||||
-- you do NOT want to migrate older plans.
|
||||
--
|
||||
-- BEGIN;
|
||||
-- SELECT COUNT(*) AS rows_to_migrate_0529
|
||||
-- FROM meal_plan
|
||||
-- WHERE week_start_date = DATE '2026-05-29';
|
||||
-- UPDATE meal_plan
|
||||
-- SET week_start_date = DATE '2026-06-01'
|
||||
-- WHERE week_start_date = DATE '2026-05-29';
|
||||
-- COMMIT;
|
||||
Reference in New Issue
Block a user