Public Access
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).
This commit is contained in:
@@ -501,3 +501,34 @@ The Sprint 11 "Generate Meal Plan" CTA was library-only. Sprint 13 splits it int
|
||||
- `frontend/src/components/OnboardingTour.test.tsx` (NEW) — 6 cases (S14.3)
|
||||
- `frontend/package.json` (MODIFIED) — devDeps + scripts
|
||||
|
||||
---
|
||||
|
||||
## Sprint 15 — Seed 50 family-friendly recipes for 4-week planning (content op)
|
||||
|
||||
### Decisions
|
||||
|
||||
- **D1 — 50 recipes, not 100.** 4 weeks × 21 meals = 84 picks needed minimum. 50 unique recipes with 1.7× rotation is enough variety and fits in a single Spoonacular day (105 pts under 140 cap).
|
||||
- **D2 — Distribution: 5 cuisines × 10 each.** Italian + Mexican + Asian + American + Mediterranean/Middle Eastern. This gives 5/7 days of cuisine rotation per week, the family's stated preference.
|
||||
- **D3 — Use Sprint 12's `POST /api/recipes/import` endpoint directly.** No new code path, no schema change, no UI change. The endpoint already does the 1-pt `/information` call + ingredient upsert + Recipe insert.
|
||||
- **D4 — Pick the top hit per query, not curated.** I trust Spoonacular's ranking; if the top hit is a bad fit, the user can delete it via the existing UI. The 50-query list is curated; the per-query hit is Spoonacular's pick.
|
||||
- **D5 — 1-2 sec sleep between imports.** The 1-pt rate is fine on the free tier, but throttling keeps me well under the per-second rate limit and avoids a burst that could trigger Spoonacular's abuse detector.
|
||||
- **D6 — Run on the host, not locally.** The host has the live backend (`mealplanner-backend-1` up, healthy). Local backend would need its own DB connection + env. The script lives at `scripts/seed_recipes.py` and runs in the host's shell.
|
||||
|
||||
### Open questions
|
||||
|
||||
- **Q1 — Curate the queries or use my list as-is?** Default: use my list as-is. The user can re-run or pick more queries if the result set is biased.
|
||||
- **Q2 — After seeding, the 4-week plan is generated client-side or server-side?** Default: client-side via the existing Dashboard's "Generate Meal Plan" CTA. Server-side plan synthesis is a future sprint.
|
||||
|
||||
### Sprint 15 file:line references
|
||||
|
||||
- `backend/app/api/recipe_search.py:48-50` — `_DAILY_LIMIT: float = 140.0`, `_SEARCH_URL`, `_INFO_URL`. The quota gate.
|
||||
- `backend/app/api/recipe_search.py:55` — `_points_available()` (140 - `_points_used`).
|
||||
- `backend/app/api/recipe_search.py:100-148` — `search_recipes` endpoint (`GET /api/recipes/search?q=...&limit=10`).
|
||||
- `backend/app/api/recipe_search.py:194-308` — `import_recipe` endpoint (`POST /api/recipes/import`).
|
||||
- `backend/app/schemas/__init__.py:398-411` — `RecipeSearchHit` Pydantic model.
|
||||
- `backend/app/schemas/__init__.py:413-415` — `RecipeImportRequest` Pydantic model (`{external_id, external_source}`).
|
||||
- `backend/app/security.py:54-78` — `require_session` (the SESSION_PASSWORD auth that gates both endpoints).
|
||||
- `backend/app/models/__init__.py:162-197` — `Recipe` model (the destination table for the imports).
|
||||
- `scripts/seed_recipes.py` (NEW) — the 50-query one-shot Python script.
|
||||
- `Review/sprint15-verification.md` (NEW) — the deploy + curl flow.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user