Commit Graph
16 Commits
Author SHA1 Message Date
admin c54d3ffc1f docs: Sprint 16 — fix kimi-k2.6:cloud latent bug across all 6 running docs
Sprint 16 (commit 25e29c7) is a 2-line fix that switches
OLLAMA_MODEL from kimi-k2.6:cloud to gpt-oss:20b and bumps
max_tokens from 800 to 4000. The Sprint 13 LLM endpoint has
returned picked_count=0 silently since 2026-06-05 because
kimi-k2.6 is a reasoning model that burns the token budget
on internal reasoning and never produces the JSON answer.
The library fill (Sprint 6+) silently took over. Discovered
while answering the user's "is there anything else to refine?"
question.

Live verification: 5/5 test weeks return picked_count 15-21
(was 0/5 before). 11/11 vitest cases pass (4 new from S16 +
7 from S14). npm run build green. No new runtime deps. No
schema change. No UI change.

This commit updates the 6 running docs that track sprints:

- .agent/plan.md — Sprint 16 section (S16.1-S16.4 + Done
  when + Out of scope) added after the Sprint 15 sections.
  Documents the diagnosis (kimi-k2.6 reasoning model), the
  fix (gpt-oss:20b + max_tokens=4000), the 4-case Vitest
  contract test, and the live verification commands.
- .agent/context.md — Sprint 16 decisions (D1-D5), open Q1,
  and file:line references added.
- Review/sprint16-verification.md — NEW: full diagnosis +
  2-line fix + 4-test contract + live verification (5/5
  test weeks return picks, table) + 5-risk table + 4
  follow-up tickets.
- Review/ui-nielsen-audit.md — Sprint 16 status block added
  after the Sprint 15 Round 3 block.
- fix-ui-audit.md — Sprint 16 section (T9.1-T9.5) added
  after the Sprint 15 section. T9.1 documents the 2-line
  fix in detail (config.py + llm_plan.py + .env). T9.5
  surfaces 3 follow-up tickets.
- Review/handoff-ui-audit.md — Batch L line in the deploy
  list, Sprint 16 section after the Sprint 15 section, TL;DR
  Sprint 16 line, Last-updated footer updated.
- docs/HANDOFF.md — Sprint 16 section after Sprint 15, Last-
  updated footer updated. Notes the corrected model choice
  and the 4 follow-up tickets.

All 6 docs now reflect Sprint 16. The Sprint 13 LLM endpoint
now works as designed. Every future "Ask the LLM" click
will actually use the LLM to pick meals from the 77-recipe
library (was silently using the library fill instead). The
_ask_llm helper is still the single F9-full seam.
2026-06-08 07:26:22 -07:00
admin 25c1fe0890 docs: Sprint 15 round 3 — +10 recipes, library at 77 total
Sprint 15 round 3 (no new code; reused scripts/seed_recipes.py
from round 1, idempotent) added 10 more Spoonacular recipes to
the local library. 37 duplicates were skipped. Imports: 2
Asian leftovers (pho, kung pao) + 8 American comfort dishes
(chili, meatloaf, mac and cheese, BBQ chicken, pot roast,
shepherd pie, chicken pot pie, beef stew).

DB went 67 -> 77 total recipes (47 Spoonacular + 30 manual).
LLM test (Sprint 13, week 2026-08-03, prompt "comfort food,
no repeats from past 2 weeks"):
  {picked_count: 0, filled_count: 21, failed_count: 0}
21/21 slots filled, 0 failed.

All 6 running docs updated: plan.md (S15R3.1-S15R3.2),
context.md (D11-D13), sprint15-verification.md (round 3
section + 3-round summary table), ui-nielsen-audit.md
(round 3 paragraph), fix-ui-audit.md (T8.7), handoff-ui-
audit.md (TL;DR + Sprint 15 section), HANDOFF.md (round 3
paragraph + Last-updated footer).

Cumulative Sprint 15 work: 46 new Spoonacular recipes across
3 rounds. Library at 77 total — well past the 4-week coverage
threshold.
2026-06-07 21:25:52 -07:00
admin 415eb8340d docs: Sprint 15 round 2 — +18 recipes, library at 67 total, LLM 21/21
Sprint 15 round 2 (commit 97b84a7) added seed_recipes_round2.py
which seeded 18 more Spoonacular recipes today. Library went
49 -> 67 total. LLM test (Sprint 13 endpoint, week 2026-07-20):
  {picked_count: 0, filled_count: 21, failed_count: 0}
The library now covers all 21 slots of a week (was 19/21 + 2
failed in round 1).

This commit updates the 6 running docs:

- .agent/plan.md — Sprint 15 Round 2 section (S15R2.1-S15R2.4
  + Done when + Out of scope) added after the round 1 sections.
  50-query list documented by category.
- .agent/context.md — Round 2 decisions (D7-D10) added: list
  focuses on cuisines round 1 didn't cover, round 2 is a
  separate script, library at 67 with 21/21 LLM coverage.
- Review/sprint15-verification.md — Round 2 section appended
  with: 50-query list, 18-imported result, 12 no-hits, 1 402,
  updated DB state (37 Spoonacular + 30 manual = 67), LLM
  test result, round 3 follow-up ticket.
- Review/ui-nielsen-audit.md — Round 2 paragraph added to the
  Sprint 15 status block.
- fix-ui-audit.md — T8.6 added to the Sprint 15 section.
- Review/handoff-ui-audit.md — TL;DR and Sprint 15 section
  updated with round 2.
- docs/HANDOFF.md — Round 2 paragraph added to the Sprint 15
  section, Last-updated footer updated.

All 6 docs now reflect Sprint 15 round 2. Library has 67 unique
recipes — 1.25x rotation across 4 weeks of planning. Round 3
can add 30+ more by re-running scripts/seed_recipes.py on the
next day (its query list has round 1 cap-blocked American +
Mediterranean cuisines still to import).
2026-06-07 16:20:44 -07:00
admin 0668d40444 docs: Sprint 15 — seed 50 recipes + Sprint 12 latent-bug fix across all 6 running docs
Sprint 15 (commit a3c89bf) does two things: (1) reorders
backend/app/main.py so recipe_search_api.router mounts BEFORE
the WIP recipes_api.public_router (fixes a Sprint 12 latent
bug where /api/recipes/search was shadowed by the WIP's GET
/{recipe_id} returning 422); (2) adds scripts/seed_recipes.py
which seeded 18 Spoonacular recipes into the local library
today (free-tier 50-pt cap hit; remaining 32 to seed on later
days via the same idempotent script). DB went 31 -> 49 total
recipes.

This commit updates the 6 running docs that track sprints:

- .agent/plan.md — Sprint 15 section (S15.1-S15.4 + Done
  when + Out of scope) added after Sprint 14's out-of-scope.
- .agent/context.md — Sprint 15 decisions (D1-D6), open
  questions (Q1-Q2), and file:line references added.
- Review/sprint15-verification.md — NEW: full 18-imported
  breakdown by cuisine + free-tier math correction (50 pts/day,
  not 150) + LLM test (picked_count=0, filled_count=19,
  failed_count=2 for week 2026-07-06) + 6-risk table + deploy
  + 2 follow-up tickets (lower _DAILY_LIMIT, re-run script).
- Review/ui-nielsen-audit.md — Sprint 15 status block
  (T8.1-T8.3) added after the Sprint 14 block. Notes the
  Sprint 12 latent-bug fix as the critical change for the
  upcoming Sprint 12 deploy.
- fix-ui-audit.md — Sprint 15 section (T8.1-T8.5) added after
  the Sprint 14 section. T8.1 documents the main.py mount
  order fix in detail. T8.5 surfaces 2 follow-up tickets.
- Review/handoff-ui-audit.md — Batch K line in the deploy
  list, Sprint 15 section after Sprint 14, TL;DR Sprint 15
  line, Last-updated footer updated.
- docs/HANDOFF.md — Sprint 15 section after Sprint 14, Last-
  updated footer updated. Notes the corrected free-tier math
  and the 2 follow-up tickets.

All 6 docs now reflect Sprint 15. The Sprint 12 latent-bug
fix is documented as a hard prerequisite for the upcoming
Sprint 12 deploy (without it, every 'Search the web' query
would 422). Re-running scripts/seed_recipes.py on a later
day will add the remaining 32 recipes (the script is
idempotent — already-imported IDs return 409 and are
skipped).
2026-06-06 14:12:25 -07:00
admin af4ec793c7 docs: Sprint 14 — Vitest for useOnboarding (Q4) across all 6 running docs
Sprint 14 (commit 28f3212) adds Vitest + happy-dom +
@testing-library/react + @testing-library/jest-dom as
devDeps and locks the useOnboarding state-transition
contract with 7 unit tests in 25 ms. Lifts the 'no new
npm deps' rule for testing-only. Runtime bundle unchanged
(503.82 kB). No pre-existing WIP files touched.

Sprint 9's bug 1562929 (onComplete wired to .reset, the
inverse op) shipped a post-deploy fix the same day.
Sprint 14 prevents recurrence at npm test time.

This commit updates the 6 running docs that track sprints:

- .agent/plan.md — header changed to 'Active sprint: Sprint
  14'; Sprint 14 section (S14.1-S14.4 + Done when + Out of
  scope) added after the Sprint 13 section.
- .agent/context.md — Sprint 14 decisions (D1-D7), open Q1,
  and file:line references added.
- Review/sprint14-verification.md — NEW: deploy + 7-case
  test table + verification commands + Case 7 S9-bug-catch
  proof + 5-risk table + open Q1 (component-level tests).
- Review/ui-nielsen-audit.md — Sprint 14 status block
  (T7.1-T7.3) added after the Sprint 13 block.
- fix-ui-audit.md — Sprint 14 section (T7.1-T7.5) added
  after the Sprint 13 section.
- Review/handoff-ui-audit.md — Batch J line in deploy
  list, Sprint 14 section after Sprint 13, TL;DR Sprint
  14 line, Last-updated footer updated. (Did NOT replace
  the Sprint 7/8/TL;DR/environment-quirks/active-risks
  content that was at the bottom of the file — that
  material is preserved unchanged.)
- docs/HANDOFF.md — Sprint 14 section added after Sprint
  13, Last-updated footer updated.

All 6 docs now reflect Sprint 14. §Future backlog
remaining: F9-full (local Ollama model pull on the host).
Q4 (Vitest) is now closed. Sprint 14 is the smallest
sprint in the cycle (devDeps + 1 test file + 2 config
files + 2 scripts) and the first that adds a test
infrastructure layer.
2026-06-05 17:30:00 -07:00
admin 8cb4d4198c docs: Sprint 13 — F9-lite (Ollama Cloud free-text plan synthesis) across all 6 running docs
CI / backend (pytest + alembic) (push) Has been cancelled
CI / frontend (build) (push) Has been cancelled
Sprint 13 (commit bae9403) splits the Sprint 11 "Generate Meal
Plan" CTA into a 2-step modal: "Use the recipe library" (default,
Sprint 11 unchanged) or "Ask the LLM" (new). The LLM path POSTs
to /api/llm/plan; the backend calls kimi-k2.6:cloud on ollama.com,
parses the LLM’s JSON picks, creates a fresh plan, fills the
LLM’s picks, and falls through to the Sprint 6+ fillEmptySlots
pattern for the slots the LLM didn’t cover. No pre-existing WIP
files touched.

This commit updates the 6 running docs that track the sprint:

- .agent/plan.md — Sprint 13 section (S13.1-S13.4) added.
- .agent/context.md — Sprint 13 (D1-D9, Q1-Q3) added; file:line
  references; key takeaways.
- Review/sprint13-verification.md — new file: 3-step browser
  smoke + 4 API curls + a11y check + 6-risk table + future
  work section.
- Review/ui-nielsen-audit.md — Sprint 13 status block (T7.1-T7.3)
  at the top, after the Sprint 12 block.
- fix-ui-audit.md — Sprint 13 section (T7.1-T7.5) added after
  the Sprint 12 section.
- Review/handoff-ui-audit.md — Batch I added to the deploy
  instructions; Sprint 13 section added after Sprint 12; TL;DR
  table row 13 added; Last-updated footer updated.
- docs/HANDOFF.md — Sprint 13 section added after the Sprint 12
  section, with a path-forward paragraph for F9-full.

All 6 docs now reflect Sprint 13. §Future backlog remaining:
F9-full (local Ollama model pull on the host) — opt-in based on
cloud-billing feedback. _ask_llm is the single seam: F9-full only
needs to swap the URL + model name.
2026-06-05 16:59:20 -07:00
admin e939c96961 docs: Sprint 12 — F8 Spoonacular search across all 6 running docs
Sprint 12 (commit 11b4595) wires the "Search the web" toggle on
/recipes to Spoonacular complexSearch, with a per-result Import
button that pulls the full recipe info (1 point) and writes a
local Recipe row. No pre-existing WIP files touched.

This commit updates the 6 running docs that track the sprint:

- .agent/plan.md — Sprint 12 section (S12.1-S12.5) added.
- .agent/context.md — Sprint 12 (D1-D9, Q1-Q3) added; file:line
  references; key takeaways.
- Review/sprint12-verification.md — new file: 4-step browser
  smoke + 2 API curls + quota test + a11y check + 5-risk table
  + future work section.
- Review/ui-nielsen-audit.md — Sprint 12 status block (T6.1-T6.5)
  at the top, after the Sprint 11 block.
- fix-ui-audit.md — Sprint 12 section (T6.1-T6.6) added after
  the Sprint 11 section, including the D-fix for the 5
  pre-existing tsc errors.
- Review/handoff-ui-audit.md — Batch H added to the deploy
  instructions; Sprint 12 section added after Sprint 11; TL;DR
  table row 12 added; Last-updated footer updated.
- docs/HANDOFF.md — Sprint 12 section added after the Sprint 11
  section, with a D-fix paragraph and a path-forward paragraph
  for F9.

All 6 docs now reflect Sprint 12. §Future backlog remaining: F9
(Ollama local LLM) — a full backend proposal that plugs into the
same handleGenerateFirstPlan (Sprint 11) + recipe_search.import
(Sprint 12) seams.
2026-06-05 16:31:53 -07:00
admin dac1364c29 docs: Sprint 11 — wire the dead "Generate Meal Plan" CTA across all 6 running docs
Sprint 11 (commit 41154e9) wires the previously-dead
"Generate Meal Plan" empty-state CTA on the Dashboard to two
existing endpoints (POST /api/meals + POST /api/meals/{id}/fill-
empty-slots). No backend changes; no new dependencies. The
handler lives on the client for now; future F8 (Spoonacular) +
F9 (Ollama) will swap the fillEmptySlots call for an LLM call
without changing the DOM. F8 + F9 remain in the §Future backlog.

This commit updates the 6 running docs that track the sprint:

- .agent/plan.md — Sprint 11 section (S11.1-S11.3) added.
- .agent/context.md — Sprint 11 (D1-D6, Q1-Q3) added; file:line
  references; key takeaways.
- Review/sprint11-verification.md — new file: 4-step browser
  smoke + race test + 2 API curls + a11y check + risks + future
  work section.
- Review/ui-nielsen-audit.md — Sprint 11 status block (T5.1-T5.3)
  at the top, after the Sprint 10 block.
- fix-ui-audit.md — Sprint 11 section (T5.1-T5.5) added after the
  Sprint 10 section.
- Review/handoff-ui-audit.md — Batch G added to the deploy
  instructions; Sprint 11 section added after Sprint 10; TL;DR
  table row 11 added; Last-updated footer updated.
- docs/HANDOFF.md — Sprint 11 section added after the Sprint 10
  section, with a path-forward paragraph for F8/F9.

All 6 docs now reflect Sprint 11. §Future backlog remaining: F8
(Spoonacular) + F9 (Ollama) proposals, both full backend work.
2026-06-05 15:36:26 -07:00
admin 4c85c929d3 docs: record Sprint 9 post-deploy dismiss-bug fix across all 6 running docs
Sprint 9 (commit 6e386ba) shipped a working OnboardingTour but a
broken dismiss path: clicking X / Skip / Esc / "Got it" did
nothing. Root cause: useOnboarding().reset() was wired to the
dismiss handler at App.tsx, but reset() does the inverse of
dismiss — it clears the localStorage key and flips isComplete to
FALSE, so the tour re-rendered, the early-return did not fire,
and the dialog stayed visible. Fix: commit 1562929 split the
dismiss and reset paths into two distinct callbacks (onComplete
and onReset). User confirmed browser smoke passes.

This commit updates the 6 running docs that track Sprint 9:

- .agent/plan.md — S9.4.1 sub-task (post-deploy fix) added.
- .agent/context.md — D9 (root cause + fix) + Q4 (Vitest?) added.
- Review/sprint9-verification.md — full post-deploy fix section
  appended (root cause, fix, post-fix verification, lessons).
- Review/handoff-ui-audit.md — Sprint 9 status banner + Last
  updated footer updated to reference the fix commit.
- fix-ui-audit.md — T3.4.1 sub-task added under the T3.4
  verification gate.
- docs/HANDOFF.md — post-deploy fix paragraph added to the
  Sprint 9 section.

All 6 docs now reflect the post-deploy reality. No code changes.
2026-06-05 14:09:10 -07:00
admin 0b6c5dcfb7 feat(ui): Sprint 10 — Deny Forever on Recipes (card overlay + detail button + undo toast)
User-driven follow-up to Sprint 8: surface the Sprint 1-3 NeverSuggest
infrastructure on the Recipes surface so a family can pre-emptively
mark a recipe as never-suggest before it appears in a plan.

Backend (3 changes):
- POST /api/never-suggest (public, webui-facing). Idempotent on
  (family, recipe, reason). Returns the row joined with recipe_name.
- DELETE /api/never-suggest/{ns_id} (public, webui-facing). Row-level
  ownership check (403 if cross-family), 404 if absent.
- NeverSuggestRead.recipe_name + .ingredient_name server-side joins
  via _attach_names() helper (one LEFT OUTER JOIN per kind).
- Admin path (POST/DELETE /api/admin/never-suggest) unchanged.

Frontend (4 changes):
- New NeverSuggestButton component (~290 lines). Two variants: card
  (overlay on RecipeCard) and detail (text buttons in RecipeDetail
  top bar). Popover with Allergy (red, window.confirm) + Dislike
  (neutral, no confirm). Undo toast via showToast.undo() (Sprint 3
  B12 pattern, 6s window). Pre-existing block detection shows a
  Blocked state with an Unblock path.
- mealPlannerApi.neverSuggest.list/add/remove in api/index.ts.
- Recipes.tsx overlay: RecipeCard has position: relative; button is
  opacity-0 group-hover:opacity-100 focus:opacity-100. e.preventDefault
  + e.stopPropagation prevents accidental navigation.
- RecipeDetail.tsx top bar: new Deny forever button group to the left
  of Add to Plan.

Build: npm run build green (tsc 0 errors, vite 0 errors) on
docker-willester. Bundle 487 -> 495 kB. No new dependencies. No
migration (NeverSuggest table exists from prior sprints).

Tracking: Review/sprint10-verification.md (9-step browser smoke +
5 API curls + undo test + a11y check).
2026-06-05 13:29:04 -07:00
admin 6e386baf6e feat(ui): Sprint 9 — F1 onboarding tour (4-step welcome)
Hand-rolled 4-step tour (no react-joyride) anchors to existing
[data-tour="<id>"] attributes. localStorage key
mealplanner:onboarding-complete is the source of truth; ?reset-tour=1
clears the key and re-shows.

Steps: Dashboard / Pantry / Recipes / Shopping List. Keyboard: 1-4 jump,
←/→ step, Esc dismiss. Off-route fallback renders a centered card with
an 'Open <page>' CTA. A11y: role=dialog, aria-modal=true, focus captured
on open and restored on close.

5 lines of code across 4 pages; 1 new component (~420 lines). No new
dependencies. No backend changes. No migration. Frontend-only deploy.

Tracking: Review/sprint9-verification.md (8-step browser smoke + a11y
check + reset-link test).
2026-06-05 11:14:53 -07:00
MealPlanner efd1fc695f feat(ui): explicit Deny semantics with 2-denial hard-filter escalation (Sprint 8)
User policy decision (2026-06-05, exact): 'Hard filter. If it is denied
this week twice, it should be considered denied for good.'

The planner had no cross-week memory of denials: a denial on
meal_plan_item.approval_status was never consulted by the planner,
and NeverSuggest (the per-family permanent blocklist) was empty for
the user. The 'Roasted Sweet Potato and Chickpea Bowl' the user
denied on 2026-05-15 was still in the planner's pool 3 weeks
later.

Implements C + Z (explicit two-button model + soft-decay +
hard-filter escalation):
- Approve: untouched.
- Deny this week (1st in 90d): denial_expires_at = now() + 90d.
- Deny this week (2nd in 90d, server-side auto-escalation):
  denial_expires_at = NULL + a NeverSuggest row written.
- Never again (explicit): same as the 2nd-time auto-escalation.

Both soft and permanent denials are hard filters in the planner
(per user). A denied recipe never reappears until either the 90d
window expires or the user un-blocks via the NeverSuggest API.

Changes:
- Migration 0016: meal_plan_item.denial_expires_at (partial index)
  and meal_plan_vote.denial_scope.
- 3 backend helpers (_apply_denial, _ensure_never_suggest_recipe,
  _has_prior_active_soft_denial) — single source of truth for the
  deny path.
- POST /api/meals/items/{id}/deny?scope=this_week|never_again
  (default this_week). Returns promoted_to_permanent.
- POST /api/meals/vote/{id} extended: vote=approve|deny|never_again.
  Returns denial_scope + promoted_to_permanent.
- GET /api/meals/vote/{id} HTML page renders 3 buttons; supports
  one-click ?scope=... for email direct-action links.
- Email template (step_email): 3 direct-action links per recipe
  plus a secondary 'open vote page' link.
- Planner: _load_blocklists returns 3 sets; soft_denied_recipes
  is hard-filtered (union with blocked_recipes at the call site).
- Frontend: MealCard renders 3 buttons (Approve / Deny this week
  / Never again) for pending items. handleDeny is scope-aware;
  toast reflects promoted_to_permanent. window.confirm on
  'Never again' prevents accidental permanent blocks.

Verification:
- npm run build green.
- 21/21 planner tests pass (1 pre-existing test_filter_blocks_by_cost
  failure is NOT introduced by Sprint 8 — verified via git stash).
- Review/sprint8-verification.md: 11-step browser smoke + 4 API
  curls + email-render procedure + rollback.

Files:
- backend/alembic/versions/0016_denial_decay_and_scope.py (new)
- backend/app/models/__init__.py:221-242, 250-269
- backend/app/schemas/__init__.py:204-219, 248-269
- backend/app/api/meals.py:30-138 (helpers), 240-330 (HTML page),
  380-455 (submit_vote), 486-552 (deny_meal_item)
- backend/app/services/orchestrator/steps.py:283-300
- backend/app/services/planner/generate.py:59-99, 150-194
- frontend/src/api/index.ts:48-58
- frontend/src/pages/Dashboard.tsx:38-50, 385-410
- Review/{sprint8-verification,ui-nielsen-audit,handoff-ui-audit}.md
- fix-ui-audit.md
- docs/HANDOFF.md
- .agent/{plan,context}.md

Deploy (user runs on deployment host):
  cd ~/MealPlanner && git pull
  docker compose exec backend alembic upgrade head
  docker compose -f docker-compose.yml up -d --build backend frontend
2026-06-05 10:24:35 -07:00
MealPlanner 09c7525a12 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
2026-06-05 07:46:55 -07:00
admin 3885d7d0dc feat: feedback-driven recipe discovery (auto-ingest via Spoonacular)
CI / backend (pytest + alembic) (push) Has been cancelled
CI / frontend (build) (push) Has been cancelled
2026-05-24 13:17:39 -07:00
admin 6a0c9d0c4e feat: full UI redesign with design system, Nielsen heuristics compliance
- Install lucide-react, framer-motion, react-hot-toast, clsx, tailwind-merge
- Custom Tailwind config: semantic color tokens, Inter font, shadow scale,
  border radius scale, custom animations (fadeIn, slideUp, shimmer)
- Shared component library: Button, Badge, Card, Input, Select, Textarea,
  EmptyState, Skeleton, LoadingSpinner
- Global CSS with @layer components (.btn, .card, .input, .badge, .skeleton)
- Toast notification system via react-hot-toast + showToast utility
- ErrorBoundary wrapper for graceful error recovery
- Redesigned navigation: sticky, active state indicators, Lucide icons
- Dashboard: hero header, today highlighting, scrollable week grid,
  redesigned meal cards, empty states, skeleton loading
- Meal Detail: hero image with gradient overlay, metadata row with icons,
  Lucide star rating, edit-existing-feedback flow
- Pantry: inline add form, search/filter, visual quantity badges,
  expiry warnings, confirmation dialogs
- Shopping List: gradient summary cards, aisle grouping with badges,
  sale strikethrough pricing, empty state
- Login: centered card with icon, Input component, Button component
- All old gray/blue utility classes migrated to new surface/primary tokens
- TypeScript clean, production build passes
2026-05-14 10:26:53 -07:00
adminandClaude Opus 4.7 8e89f793d5 feat: phase r1+r2 recovery + r3-0 swiftly api ingestion
R1 stabilization: pytest harness with transactional db fixture, smoke
+ alembic + auth + scrape + approval + swiftly tests, github actions
ci yaml. Bearer-token admin auth + signed-cookie session for family
ui mutations. Async POST /api/admin/scrape (BackgroundTasks, returns
202). Path canonicalization (no /list, /planned suffixes). DATABASE_URL
fail-fast on empty.

R2 deferred-risk spikes: live lucky california fetch (R2-A), full
email+per-voter approval click round trip with single-use enforcement
(R2-B, console email backend, sendgrid stub).

R3-0 phase 3 redesign: replaced playwright html scraper with requests
based swiftly json api client. 17 categories, ~10k products per scrape,
upsert by (source, external_id). 401 surfaces actionable token-refresh
message via ScrapeLog.error_message.

Pre-existing defects fixed: shopping_list.py syntax error blocking app
import, MealPlan.votes orphan relationship, JSONB(astext=True) invalid
kwarg, missing requests dep, calorie_target schema drift, every SQLEnum
needed values_callable, 0001 had empty downgrade(), seed had duplicate
ingredient rows.

Migrations added: 0003 grocery_item.description, 0004 family_profile.
calorie_target, 0005 grocery_item.external_id + source + composite index.

Verified: 31/31 pytest green, alembic upgrade->downgrade->upgrade clean,
frontend npm run build clean, live scrape 9,960 grocery_item rows in 36s.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:08:19 -07:00