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:
MealPlanner
2026-06-05 07:46:55 -07:00
parent a616138e7c
commit 09c7525a12
13 changed files with 679 additions and 96 deletions
+15 -3
View File
@@ -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):