recipes.Grounder ties search, fetch/extract, Rank, the photo cache and
normalize_recipe together. Ground(ctx, dishName, query) reuses a stored
source_url among the top candidates without fetching, otherwise tries the
ranked recipes best first and stores the photo, recipe, ingredients and
steps in one transaction, returning Grounded{recipe_id, photo_id, method,
minutes_total, difficulty, source_url, site_name} or a typed
*ErrUngroundable listing every reason. GroundURL grounds a pasted URL the
same way; GroundMany grounds items 3 at a time with per-item results.
PhotoCache is split into DownloadPhoto (fetch, decode, size check, no
writes) and CachePhoto(ctx, tx, photo), which records the row in the
caller's transaction; RemovePhotoFiles cleans up after a rollback.
Migration 0007 adds photo_id, method, difficulty and minutes_total to
recipes, and api_key_last4 to recipe_search_settings. SearXNG is now
called at recipe_search_settings.base_url.
GET/PATCH /api/v1/settings/recipe-search (Brave key sealed with
secretbox, only api_key_set and api_key_last4 returned) and POST
/api/v1/settings/recipe-search/test (searches "chicken tikka masala",
returns the count, 409 not_configured or 502 search_failed).
Maestro task 53afd59c-6c35-4af7-904c-6c167d1ad69d.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
19 lines
1.1 KiB
SQL
19 lines
1.1 KiB
SQL
-- 0007_recipe_grounding: a grounded recipe keeps what recipes.Ground
|
|
-- returns, so a stored source_url is reused without fetching or normalizing
|
|
-- it again: its cached photo, and normalize_recipe's method, difficulty and
|
|
-- minutes_total (prep to table; total_minutes stays the page's own JSON-LD
|
|
-- total). Nothing wrote recipes before Ground did, so the columns are added
|
|
-- nullable rather than with a default no recipe has; Ground always sets
|
|
-- photo_id, method and difficulty and refuses to reuse a row without them.
|
|
--
|
|
-- recipe_search_settings gains api_key_last4, the last four characters of
|
|
-- the Brave API key, so the settings can show which key is stored without
|
|
-- ever returning it.
|
|
|
|
ALTER TABLE recipes ADD COLUMN photo_id TEXT REFERENCES photos (id);
|
|
ALTER TABLE recipes ADD COLUMN method TEXT CHECK (method IN ('stovetop', 'oven', 'crockpot', 'grill', 'other'));
|
|
ALTER TABLE recipes ADD COLUMN difficulty TEXT CHECK (difficulty IN ('easy', 'medium', 'hard'));
|
|
ALTER TABLE recipes ADD COLUMN minutes_total INTEGER;
|
|
|
|
ALTER TABLE recipe_search_settings ADD COLUMN api_key_last4 TEXT;
|