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.
This commit is contained in:
2026-06-05 16:31:53 -07:00
parent 11b4595cf7
commit e939c96961
7 changed files with 378 additions and 7 deletions
+23 -1
View File
@@ -302,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-05** — UI/UX audit & fix cycle (Sprints 1, 2, 3, 4, 5, 6, 7, 8, 9) complete. 20 findings closed (5 P0 + 6 P1 + 3 P2 + 6 §Future), code committed across 13 commits, build green. Sprint 1 deployed; Sprints 2-9 awaiting deploy. **Sprint 7 (`09c7525`, awaiting user deploy)** aligns "this week" to the upcoming Monday. **Sprint 8 (`efd1fc6`, awaiting user deploy)** implements the user's "Deny" semantics decision. **Sprint 9 (committed 2026-06-05, awaiting user deploy)** ships the F1 Onboarding Tour. **Sprint 10 (committed 2026-06-05, awaiting user deploy)** ships the "Deny Forever" on Recipes. **Sprint 11 (committed 2026-06-05, awaiting user deploy)** wires the dead "Generate Meal Plan" CTA. See Sprint 7 + Sprint 8 + Sprint 9 + Sprint 10 + Sprint 11 sections below. Full UI-audit handoff at `Review/handoff-ui-audit.md`.
**Last updated: 2026-06-05** — UI/UX audit & fix cycle (Sprints 1, 2, 3, 4, 5, 6, 7, 8, 9) complete. 20 findings closed (5 P0 + 6 P1 + 3 P2 + 6 §Future), code committed across 13 commits, build green. Sprint 1 deployed; Sprints 2-9 awaiting deploy. **Sprint 7 (`09c7525`, awaiting user deploy)** aligns "this week" to the upcoming Monday. **Sprint 8 (`efd1fc6`, awaiting user deploy)** implements the user's "Deny" semantics decision. **Sprint 9 (committed 2026-06-05, awaiting user deploy)** ships the F1 Onboarding Tour. **Sprint 10 (committed 2026-06-05, awaiting user deploy)** ships the "Deny Forever" on Recipes. **Sprint 11 (committed 2026-06-05, awaiting user deploy)** wires the dead "Generate Meal Plan" CTA. **Sprint 12 (committed 2026-06-05, awaiting user deploy)** ships the F8 Spoonacular search. See Sprint 7 + Sprint 8 + Sprint 9 + Sprint 10 + Sprint 11 + Sprint 12 sections below. Full UI-audit handoff at `Review/handoff-ui-audit.md`.
---
@@ -385,6 +385,28 @@ Trust the tests. Trust the live runs. Don't trust prose claims that something is
**Path forward to F8/F9:** the `EmptyState.action.onClick` is the single seam. Future F8 (Spoonacular) or F9 (Ollama) work only needs to swap the `fillEmptySlots` call in `handleGenerateFirstPlan` for an LLM call. No DOM, copy, or component structure changes needed.
### Sprint 12 — F8 Spoonacular search (§Future H10) (user-driven) — COMMITTED 2026-06-05
**User direction (2026-06-05):** "Proceed." Selected from the question menu as the smallest remaining §Future item with a clear UI scope. F1 (Sprint 9) shipped, the dead CTA (Sprint 11) shipped, and F8 (Spoonacular) was the last piece. F9 (Ollama) remains a separate full backend proposal (model pull + ollama-py + `/api/llm/plan` endpoint).
**Scope (6 boxes):**
1. **NEW** `backend/app/api/recipe_search.py` (~270 lines) — 2 endpoints + module-level quota counter with thread-safe lock. `GET /api/recipes/search?q=&limit=` (1.1 pts/query, summary only — NO info endpoint call, unlike the pre-existing `_search_spoonacular`). `POST /api/recipes/import` (1 pt + idempotent ingredient upserts + Recipe insert). 503 when over 140-pt daily budget.
2. `backend/app/config.py` — added `SPOONACULAR_API_KEY: Optional[str] = None` to `Settings` (was previously read via `getattr` since `extra="ignore"`). The schema declaration surfaces it in `.env.example` and tools.
3. `backend/app/schemas/__init__.py` — added `RecipeSearchHit` (mirror of the `ExternalRecipe` dataclass at `recipe_discovery.py:28-44`) + `RecipeImportRequest`.
4. `backend/app/main.py:62-63` — registered `recipe_search_api.router` at the `/api/recipes` prefix. No collision with the pre-existing WIP `recipes.py`.
5. **Frontend:** `frontend/src/api/index.ts` adds 5 new `recipes` methods (`search`, `importRecipe`, `recommended`, `listIngredients`, `createIngredient` — the last 3 are stubs for pre-existing call sites). `frontend/src/pages/Recipes.tsx` adds the toggle button (with `aria-pressed`) + the web-search panel (`<div role="region" aria-label="Web recipe search" aria-busy={webLoading}>`) + the import mutation (toast on success, `showApiError` on failure). Toggle defaults to OFF; reuses the existing `q` + `handleSearch` (300ms debounce).
6. `frontend/src/types/index.ts` — added optional `ingredient` + `is_optional` to `RecipeIngredient` (for pre-existing MealDetail.tsx call sites).
**D-fix (user-decision):** the API surface expansion exposed 5 latent tsc errors in Pantry/MealDetail/Recommended.tsx. Resolved with 3 stub API methods + 2 type fields. ~7 lines of fixes; no WIP touched. Documented in `Review/sprint12-verification.md` D-fix section + `fix-ui-audit.md` T6.4.
**Build:** `npm run build` green (tsc 0 errors, vite 0 errors). Bundle: 496.48 → 500.28 kB (+3.8 kB for the web-search panel + the import mutation). Backend AST clean. Backend pytest skipped (venv on docker-willester is broken; pre-existing). One commit: `feat(ui): Sprint 12 — F8 Spoonacular search (web-search toggle + import)`.
**Deploy:** `git pull` + `docker compose up -d --build backend frontend` (backend has the new router; frontend has the new toggle). Verification: `Review/sprint12-verification.md` (4-step browser smoke + 2 API curls + quota test + a11y check + 5-risk table).
**No regression expected:** Sprint 12 doesn't touch the pre-existing WIP `backend/app/api/recipes.py` / `schemas/recipe.py` / `nginx/nginx.conf`. The new router is in a separate file (`recipe_search.py`) and registered at a non-colliding path. Sprints 1-11 are untouched. The 3 stub API methods satisfy pre-existing call sites that were previously hidden by a smaller API surface.
**Path forward to F9:** the `handleGenerateFirstPlan` (Sprint 11) + the `recipe_search.import` (Sprint 12) are the two seams. Future F9 (Ollama local LLM) work plugs into the same `fillEmptySlots` / `import` flow — no DOM, copy, or component structure changes needed.
---
## New session: 2026-06-05 (early)