Commit graph

5 commits

Author SHA1 Message Date
12ab63e2fb feat: corrections router (#73) + Magpie flywheel hook (#28)
Corrections router (kiwi#73):
- Wire make_corrections_router() from cf-core at /api/v1/corrections
- Add get_db() dependency in session.py yielding store.conn (raw
  sqlite3.Connection as cf-core expects); cloud-aware via get_session
- Migration 040: corrections table + indexes (copied from cf-core DDL)
- Feeds Avocet SFT training pipeline via GET /corrections/export JSONL

Magpie flywheel hook (kiwi#28):
- app/services/magpie_hook.py: async fire_recipe_signal() that reads
  magpie_opt_in setting, checks external_id, POSTs anonymized payload
  to MAGPIE_INGEST_URL; stubs gracefully when URL unset or Magpie
  unreachable (DEBUG log, never raises)
- Hooks into save_recipe and update_saved_recipe as background tasks
- MAGPIE_INGEST_URL config key added to Settings
- SettingsView: "Data Sharing" toggle for magpie_opt_in, cloud-only
  (v-if VITE_CLOUD_MODE), plain-language consent label
2026-04-25 23:31:20 -07:00
9350719516 feat(recipes): LLM style classifier (#27) + cooked leftovers shelf-life (#112)
Some checks are pending
CI / Backend (Python) (push) Waiting to run
CI / Frontend (Vue) (push) Waiting to run
Mirror / mirror (push) Waiting to run
Release / release (push) Waiting to run
Style classifier (kiwi#27):
- app/services/recipe/style_classifier.py: LLM prompt with curated vocab,
  cf-orch/LLMRouter fallback, JSON + regex tag extraction
- POST /recipes/saved/{recipe_id}/classify-style: Paid/BYOK tier gate,
  fetches recipe from corpus, returns {suggested_tags:[...]}
- SaveRecipeModal.vue: "Suggest tags" button with loading state; merges
  LLM suggestions into existing tags without overwriting user's choices
- 403/empty list silently ignored — button is a no-op when tier not met

Cooked leftovers shelf-life (kiwi#112):
- app/services/leftovers_predictor.py: deterministic FDA/USDA lookup table
  with shortest-component-wins for proteins and dish-type override for
  assembled dishes; special entries for ceviche (2d, acid != heat),
  fermented/cured (kimchi 14d, confit/lardo 7d), soups, rice, pasta, etc.
- POST /recipes/{recipe_id}/leftovers: free tier, no gate
- RecipeDetailPanel.vue: shelf-life section appears after "I cooked this"
  with fridge/freeze days, freeze-by advice, per-instance dismiss; calm
  framing per no-panic UX policy
- LeftoversResponse Pydantic schema added to recipe.py
2026-04-25 23:18:16 -07:00
ed04b655be fix(saved-recipes): resolve FK constraint, null title, and load reliability
- Migration 039: drop saved_recipes.recipe_id FK (SQLite table rebuild).
  The FK referenced main.recipes but corpus lives in an ATTACH'd DB — caused
  500 on every POST /recipes/saved in cloud mode.
- _to_summary: row.get("title") or "" to handle corpus JOIN returning NULL
  title (e.g. placeholder recipe_id 99999).
- list_collections: return [] for Free tier instead of 403 — prevents
  Promise.all in savedStore.load() from aborting the saved-recipes fetch.
- savedStore.load(): switched to Promise.allSettled so a collections failure
  never blocks the saved list from populating.
- RecipesView: star indicator now reflects savedStore.isSaved() (server-side
  saved state) rather than localStorage bookmarks; changed to <span> since
  the star is now read-only visual feedback.
- Removed { immediate: true } from saved-tab watcher — premature bounce to
  Build Your Own before onMounted load() completes.
2026-04-25 21:44:10 -07:00
01aae2eec8 fix: recipe enrichment backfill, main_ingredient browser domain, bug batch
Some checks failed
CI / Backend (Python) (push) Has been cancelled
CI / Frontend (Vue) (push) Has been cancelled
CI / Backend (Python) (pull_request) Has been cancelled
CI / Frontend (Vue) (pull_request) Has been cancelled
Recipe corpus (#108):
- Add _MAIN_INGREDIENT_SIGNALS to tag_inferrer.py (Chicken/Beef/Pork/Fish/Pasta/
  Vegetables/Eggs/Legumes/Grains/Cheese) — infers main:* tags from ingredient names
- Update browser_domains.py main_ingredient categories to use main:* tag queries
  instead of raw food terms; recipe_browser_fts now has full 3.19M row coverage
  (was ~1.2K before backfill)

Bug fixes:
- Fix community posts response shape (#96): add total/page/page_size fields
- Fix export endpoint arg types (#92)
- Fix household invite store leak (#93)
- Fix receipts endpoint issues
- Fix saved_recipes endpoint
- Add session endpoint (app/api/endpoints/session.py)

Shopping list:
- Add migration 033_shopping_list.sql
- Add shopping schemas (app/models/schemas/shopping.py)
- Add ShoppingView.vue, ShoppingItemRow.vue, shopping.ts store

Frontend:
- InventoryList, RecipesView, RecipeDetailPanel polish
- App.vue routing updates for shopping view

Docs:
- Add user-facing docs under docs/ (getting-started, user-guide, reference)
- Add screenshots
2026-04-18 15:38:56 -07:00
793df1b5cf feat: saved recipes, recipe browser, and recipe detail panel
- Saved recipes: save/unsave, star rating, notes, tags, collections (migrations 018-020)
- Recipe browser: domain/category browsing with pantry match badges, pagination
- Recipe detail panel: full directions, ingredient checklist, swap candidates, prep notes
- Grocery links: affiliate links for missing ingredients
- Nutrition filters and display chips on recipe cards
- Bookmark toggle persisted to saved_recipes table
- Tier gates on saved recipes (paid) and collections (premium)
- Browser telemetry for domain/category click tracking
- Cloud compose: CLOUD_DATA_ROOT volume mount for per-user SQLite trees
- manage.sh: cf-orch agent sidecar in local stack
- README: updated feature list and stack description
2026-04-08 14:35:02 -07:00