From e939c96961d02f2750491f0a2b65e89528bc8f3f Mon Sep 17 00:00:00 2001 From: Peter Woolery Date: Fri, 5 Jun 2026 16:31:53 -0700 Subject: [PATCH] =?UTF-8?q?docs:=20Sprint=2012=20=E2=80=94=20F8=20Spoonacu?= =?UTF-8?q?lar=20search=20across=20all=206=20running=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .agent/context.md | 66 ++++++++++++++++ .agent/plan.md | 84 +++++++++++++++++++++ Review/handoff-ui-audit.md | 26 +++++-- Review/sprint12-verification.md | 128 ++++++++++++++++++++++++++++++++ Review/ui-nielsen-audit.md | 8 ++ docs/HANDOFF.md | 24 +++++- fix-ui-audit.md | 49 ++++++++++++ 7 files changed, 378 insertions(+), 7 deletions(-) create mode 100644 Review/sprint12-verification.md diff --git a/.agent/context.md b/.agent/context.md index 82faba8..e2d9e3f 100644 --- a/.agent/context.md +++ b/.agent/context.md @@ -342,3 +342,69 @@ User direction 2026-06-05: "Proceed." Selected from the question menu as the sma - `backend/app/schemas/__init__.py:227-247` — `MealPlanBase` + `MealPlanCreate` schemas - `Review/sprint11-verification.md` — new file (deploy + 4-step browser smoke + race test) +--- + +# Context — Sprint 12 (F8 Spoonacular search) + +## Why Sprint 12 exists + +User direction 2026-06-05: "Proceed." Selected from the question menu as the smallest remaining §Future item. F1 (Sprint 9) shipped, the dead CTA (Sprint 11) shipped, and F8 (Spoonacular search) is the last piece with a clear UI scope. F9 (Ollama local LLM) is a separate full backend proposal (model pull + ollama-py + `/api/llm/plan` endpoint) and remains in the §Future backlog. + +The user can browse ~150 local recipes on `/recipes` (admin seeds them) but has no path to find new ones without leaving the app. Sprint 12 adds a "Search the web" toggle on `/recipes` that hits the Spoonacular `complexSearch` API and lets the user import a result into the local library in one click. + +## Decisions (locked in for Sprint 12) + +- **D1. Reuse the pre-existing `RecipeDiscoveryService`.** `backend/app/services/recipe_discovery.py` (226 lines, already exists) has `_search_spoonacular()`, `_fetch_recipe_info()`, `_normalize_spoonacular()` and a 150/day free-tier quota gate. Sprint 12 does NOT re-implement the API client; it adds a thin HTTP layer in `backend/app/api/recipe_search.py` that calls the same `requests.get(SPOONACULAR_SEARCH_URL, ...)` pattern. +- **D2. Search endpoint = `complexSearch` only, NO info endpoint call.** The pre-existing `_search_spoonacular` calls the info endpoint (1 pt) for every result. For a 10-result search that's 10 extra points — the whole daily quota in one query. Sprint 12's `GET /api/recipes/search` uses just the `complexSearch` summary (1.1 pts/query) for browsing, and the **import** endpoint does the info call once (1 pt) only for the recipe the user actually wants. +- **D3. Ingredient resolution via the existing public `POST /api/ingredients` endpoint.** `backend/app/api/ingredients.py:58-103` is idempotent on `name_lower` + aliases. The import flow upserts each ingredient via this endpoint. No new ingredient-resolution helper needed. +- **D4. NEW endpoints, NOT modification of the pre-existing WIP.** `backend/app/api/recipes.py` (352 lines) and `backend/app/schemas/recipe.py` (93 lines) exist as WIP but are not registered in `main.py`. Sprint 12 does NOT touch them. It creates `backend/app/api/recipe_search.py` (new router) and adds the Pydantic models to `backend/app/schemas/__init__.py` (the canonical location used by all registered endpoints). +- **D5. UI toggle defaults to OFF.** The user explicitly asked for a "Search the web" toggle, not a permanent switch. The local-search UX is preserved for users who don't toggle. The toggle is a real `