feat: migrations 005-011 — fix receipts column bug + recipe engine tables
This commit is contained in:
parent
18fde9747f
commit
e56881d943
7 changed files with 148 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ CREATE TABLE receipts_new (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
filename TEXT NOT NULL,
|
filename TEXT NOT NULL,
|
||||||
original_path TEXT NOT NULL,
|
original_path TEXT NOT NULL,
|
||||||
|
processed_path TEXT,
|
||||||
status TEXT NOT NULL DEFAULT 'uploaded'
|
status TEXT NOT NULL DEFAULT 'uploaded'
|
||||||
CHECK (status IN (
|
CHECK (status IN (
|
||||||
'uploaded',
|
'uploaded',
|
||||||
|
|
|
||||||
48
app/db/migrations/006_element_profiles.sql
Normal file
48
app/db/migrations/006_element_profiles.sql
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
-- Migration 006: Ingredient element profiles + FlavorGraph molecule index.
|
||||||
|
|
||||||
|
CREATE TABLE ingredient_profiles (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
name_variants TEXT NOT NULL DEFAULT '[]', -- JSON array of aliases/alternate spellings
|
||||||
|
elements TEXT NOT NULL DEFAULT '[]', -- JSON array: ["Richness","Depth"]
|
||||||
|
-- Functional submetadata (from USDA FDC)
|
||||||
|
fat_pct REAL DEFAULT 0.0,
|
||||||
|
fat_saturated_pct REAL DEFAULT 0.0,
|
||||||
|
moisture_pct REAL DEFAULT 0.0,
|
||||||
|
protein_pct REAL DEFAULT 0.0,
|
||||||
|
starch_pct REAL DEFAULT 0.0,
|
||||||
|
binding_score INTEGER DEFAULT 0 CHECK (binding_score BETWEEN 0 AND 3),
|
||||||
|
glutamate_mg REAL DEFAULT 0.0,
|
||||||
|
ph_estimate REAL,
|
||||||
|
sodium_mg_per_100g REAL DEFAULT 0.0,
|
||||||
|
smoke_point_c REAL,
|
||||||
|
is_fermented INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_emulsifier INTEGER NOT NULL DEFAULT 0,
|
||||||
|
-- Aroma submetadata
|
||||||
|
flavor_molecule_ids TEXT NOT NULL DEFAULT '[]', -- JSON array of FlavorGraph compound IDs
|
||||||
|
heat_stable INTEGER NOT NULL DEFAULT 1,
|
||||||
|
add_timing TEXT NOT NULL DEFAULT 'any'
|
||||||
|
CHECK (add_timing IN ('early','finish','any')),
|
||||||
|
-- Brightness submetadata
|
||||||
|
acid_type TEXT CHECK (acid_type IN ('citric','acetic','lactic',NULL)),
|
||||||
|
-- Texture submetadata
|
||||||
|
texture_profile TEXT NOT NULL DEFAULT 'neutral',
|
||||||
|
water_activity REAL,
|
||||||
|
-- Source
|
||||||
|
usda_fdc_id TEXT,
|
||||||
|
source TEXT NOT NULL DEFAULT 'usda',
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX idx_ingredient_profiles_name ON ingredient_profiles (name);
|
||||||
|
CREATE INDEX idx_ingredient_profiles_elements ON ingredient_profiles (elements);
|
||||||
|
|
||||||
|
CREATE TABLE flavor_molecules (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
compound_id TEXT NOT NULL UNIQUE, -- FlavorGraph node ID
|
||||||
|
compound_name TEXT NOT NULL,
|
||||||
|
ingredient_names TEXT NOT NULL DEFAULT '[]', -- JSON array of ingredient names
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_flavor_molecules_compound_id ON flavor_molecules (compound_id);
|
||||||
24
app/db/migrations/007_recipe_corpus.sql
Normal file
24
app/db/migrations/007_recipe_corpus.sql
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
-- Migration 007: Recipe corpus index (food.com dataset).
|
||||||
|
|
||||||
|
CREATE TABLE recipes (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
external_id TEXT,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
ingredients TEXT NOT NULL DEFAULT '[]', -- JSON array of raw ingredient strings
|
||||||
|
ingredient_names TEXT NOT NULL DEFAULT '[]', -- JSON array of normalized names
|
||||||
|
directions TEXT NOT NULL DEFAULT '[]', -- JSON array of step strings
|
||||||
|
category TEXT,
|
||||||
|
keywords TEXT NOT NULL DEFAULT '[]', -- JSON array
|
||||||
|
calories REAL,
|
||||||
|
fat_g REAL,
|
||||||
|
protein_g REAL,
|
||||||
|
sodium_mg REAL,
|
||||||
|
-- Element coverage scores computed at import time
|
||||||
|
element_coverage TEXT NOT NULL DEFAULT '{}', -- JSON {element: 0.0-1.0}
|
||||||
|
source TEXT NOT NULL DEFAULT 'foodcom',
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_recipes_title ON recipes (title);
|
||||||
|
CREATE INDEX idx_recipes_category ON recipes (category);
|
||||||
|
CREATE INDEX idx_recipes_external_id ON recipes (external_id);
|
||||||
22
app/db/migrations/008_substitution_pairs.sql
Normal file
22
app/db/migrations/008_substitution_pairs.sql
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
-- Migration 008: Derived substitution pairs.
|
||||||
|
-- Source: diff of lishuyang/recipepairs (GPL-3.0 derivation — raw data not shipped).
|
||||||
|
|
||||||
|
CREATE TABLE substitution_pairs (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
original_name TEXT NOT NULL,
|
||||||
|
substitute_name TEXT NOT NULL,
|
||||||
|
constraint_label TEXT NOT NULL, -- 'vegan'|'vegetarian'|'dairy_free'|'gluten_free'|'low_fat'|'low_sodium'
|
||||||
|
fat_delta REAL DEFAULT 0.0,
|
||||||
|
moisture_delta REAL DEFAULT 0.0,
|
||||||
|
glutamate_delta REAL DEFAULT 0.0,
|
||||||
|
protein_delta REAL DEFAULT 0.0,
|
||||||
|
occurrence_count INTEGER DEFAULT 1,
|
||||||
|
compensation_hints TEXT NOT NULL DEFAULT '[]', -- JSON [{ingredient, reason, element}]
|
||||||
|
source TEXT NOT NULL DEFAULT 'derived',
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_substitution_pairs_original ON substitution_pairs (original_name);
|
||||||
|
CREATE INDEX idx_substitution_pairs_constraint ON substitution_pairs (constraint_label);
|
||||||
|
CREATE UNIQUE INDEX idx_substitution_pairs_pair
|
||||||
|
ON substitution_pairs (original_name, substitute_name, constraint_label);
|
||||||
27
app/db/migrations/009_staple_library.sql
Normal file
27
app/db/migrations/009_staple_library.sql
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
-- Migration 009: Staple library (bulk-preparable base components).
|
||||||
|
|
||||||
|
CREATE TABLE staples (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
slug TEXT NOT NULL UNIQUE,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
base_ingredients TEXT NOT NULL DEFAULT '[]', -- JSON array of ingredient strings
|
||||||
|
base_method TEXT,
|
||||||
|
base_time_minutes INTEGER,
|
||||||
|
yield_formats TEXT NOT NULL DEFAULT '{}', -- JSON {format_name: {elements, shelf_days, methods, texture}}
|
||||||
|
dietary_labels TEXT NOT NULL DEFAULT '[]', -- JSON ['vegan','high-protein']
|
||||||
|
compatible_styles TEXT NOT NULL DEFAULT '[]', -- JSON [style_id]
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE user_staples (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
staple_slug TEXT NOT NULL REFERENCES staples(slug) ON DELETE CASCADE,
|
||||||
|
active_format TEXT NOT NULL,
|
||||||
|
quantity_g REAL,
|
||||||
|
prepared_at TEXT,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_user_staples_slug ON user_staples (staple_slug);
|
||||||
15
app/db/migrations/010_recipe_feedback.sql
Normal file
15
app/db/migrations/010_recipe_feedback.sql
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
-- Migration 010: User substitution approval log (opt-in dataset moat).
|
||||||
|
|
||||||
|
CREATE TABLE substitution_feedback (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
original_name TEXT NOT NULL,
|
||||||
|
substitute_name TEXT NOT NULL,
|
||||||
|
constraint_label TEXT,
|
||||||
|
compensation_used TEXT NOT NULL DEFAULT '[]', -- JSON array of compensation ingredient names
|
||||||
|
approved INTEGER NOT NULL DEFAULT 0,
|
||||||
|
opted_in INTEGER NOT NULL DEFAULT 0, -- user consented to anonymized sharing
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_substitution_feedback_original ON substitution_feedback (original_name);
|
||||||
|
CREATE INDEX idx_substitution_feedback_opted_in ON substitution_feedback (opted_in);
|
||||||
11
app/db/migrations/011_rate_limits.sql
Normal file
11
app/db/migrations/011_rate_limits.sql
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
-- Migration 011: Daily rate limits (leftover mode: 5/day free tier).
|
||||||
|
|
||||||
|
CREATE TABLE rate_limits (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
feature TEXT NOT NULL,
|
||||||
|
window_date TEXT NOT NULL, -- YYYY-MM-DD
|
||||||
|
count INTEGER NOT NULL DEFAULT 0,
|
||||||
|
UNIQUE (feature, window_date)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_rate_limits_feature_date ON rate_limits (feature, window_date);
|
||||||
Loading…
Reference in a new issue