Migration 015 did a one-time rebuild of recipes_fts at creation time but
omitted triggers, so rows inserted after that point were invisible to MATCH
queries. Adds AFTER INSERT/UPDATE/DELETE triggers to 015 (fresh DBs / tests)
and migration 016 to backfill them on existing databases.
Fixes 3 failing tests: test_search_recipes_by_ingredient_names,
test_level1_returns_ranked_suggestions, test_level2_returns_swap_candidates.
- Style/category filter panel with active chip display
- Dismiss (excluded_ids) support — recipes don't reappear until next fresh search
- Load more appends next batch without full re-fetch
- Prep notes 'Before you start:' section above directions
- Nutrition macro chips (kcal, fat, protein, carbs, fiber, sugar, sodium)
- Composables extracted for reuse
_parse_json_from_text always returns a dict (never None), so the
previous `if parsed is not None` guard was permanently true — garbled
docuvision output would return an empty skeleton instead of falling
through to the local VLM. Replace the check with a meaningful-content
test (items or merchant present). Add two tests: one that asserts the
fallthrough behavior on an empty parse, one that confirms the fast path
is taken when parsing succeeds.
Introduces a thin HTTP client for the cf-docuvision service and wires it
as a fast path in VisionLanguageOCR.extract_receipt_data(). When CF_ORCH_URL
is set, the pipeline attempts docuvision allocation via CFOrchClient before
loading the heavy local VLM; falls back gracefully if unavailable.
- EditItemModal: replace all hardcoded colors (#eee, #f5f5f5, #2196F3, etc.) with CSS variable tokens; restyle modal header with display font, blur backdrop, and theme-aware form elements
- ReceiptsView: replace emoji headings, hardcoded spinner, and non-theme .button class with themed equivalents; all colors through var(--color-*) tokens
- RecipesView: fix broken --color-warning-rgb / --color-primary-rgb references (not defined in theme); use --color-warning-bg and --color-info-bg instead; apply section-title to heading
- SettingsView: apply section-title display-font class to heading for consistency
- InventoryList: remove three dead functions (formatDate, getDaysUntilExpiry, getExpiryClass) that caused TS6133 build errors
Vite builds with VITE_BASE_URL=/kiwi so assets are referenced as
/kiwi/assets/... in index.html. When accessed via Caddy at the /kiwi
path, Caddy strips the prefix and nginx gets /assets/... correctly.
When accessed directly at localhost:8515, nginx had no /kiwi/ route
so the JS/CSS 404'd and the SPA never booted (blank page on hard refresh).
Add location ^~ /kiwi/ { alias ...; } — ^~ prevents the regex
\.(js|css|...)$ location from intercepting /kiwi/ paths first.
- build_recipe_index.py: add _parse_r_vector() for food.com R format, add
_parse_allrecipes_text() for corbt/all-recipes text format, _row_to_fields()
dispatcher handles both columnar (food.com) and single-text (all-recipes)
- build_flavorgraph_index.py: switch from graph.json to nodes/edges CSVs
matching actual FlavorGraph repo structure
- download_datasets.py: switch recipe source to corbt/all-recipes (2.1M
recipes, 807MB) replacing near-empty AkashPS11/recipes_data_food.com
- 007_recipe_corpus.sql: add UNIQUE constraint on external_id to prevent
duplicate inserts on pipeline reruns
- RecipesView: level selector (1-4), constraints/allergies tag inputs,
hard day mode toggle, max missing input, expiry-first pantry extraction,
recipe cards with collapsible swaps/directions, grocery links, rate
limit banner
- SettingsView: cooking equipment tag input with quick-add chips, save
with confirmation feedback
- stores/recipes.ts: Pinia store for recipe state + suggest() action
- stores/settings.ts: Pinia store for cooking_equipment persistence
- api.ts: RecipeRequest/Result/Suggestion types + recipesAPI + settingsAPI
- App.vue: two new tabs (Recipes, Settings), lazy inventory load on tab switch
Add GroceryLink schema model and grocery_links field to RecipeResult.
Introduce GroceryLinkBuilder service (Amazon Fresh, Walmart, Instacart)
using env-var affiliate tags; no links emitted when tags are absent.
Wire link builder into RecipeEngine.suggest() for levels 1-2.
Add test_grocery_links_free_tier to verify structure contract.
35 tests passing.
Uses circuitforge_core.tasks.scheduler. VRAM detection via cf-orch when
available, falling back to unlimited. Adds expiry_llm_fallback task type
to background-predict expiry dates for items the LUT doesn't cover.