-- 0001: initial schema (SPEC.md §2) CREATE TABLE foods ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, brand TEXT, barcode TEXT UNIQUE, source TEXT NOT NULL CHECK (source IN ('openfoodfacts', 'manual', 'meal')), is_meal INTEGER NOT NULL DEFAULT 0, unit_type TEXT NOT NULL DEFAULT 'weight' CHECK (unit_type IN ('weight', 'count')), calories_per_unit REAL, protein_per_unit REAL, carbs_per_unit REAL, fat_per_unit REAL, fiber_per_unit REAL, saturated_fat_per_unit REAL, sugars_per_unit REAL, sodium_per_unit REAL, serving_size_g REAL, serving_name TEXT, off_data TEXT, deleted_at TEXT, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')), -- Meal nutrition is derived from components, never stored (spec §2.1) CHECK (is_meal = 1 OR calories_per_unit IS NOT NULL) ); CREATE TABLE meal_components ( id INTEGER PRIMARY KEY, meal_id INTEGER NOT NULL REFERENCES foods(id), food_id INTEGER NOT NULL REFERENCES foods(id), quantity REAL NOT NULL ); CREATE TABLE daily_log ( id INTEGER PRIMARY KEY, date TEXT NOT NULL, -- client-supplied YYYY-MM-DD (spec §8.1 rule 8) food_id INTEGER NOT NULL REFERENCES foods(id), quantity REAL NOT NULL, meal_slot TEXT CHECK (meal_slot IN ('breakfast', 'lunch', 'dinner', 'snack')), sort_order INTEGER NOT NULL DEFAULT 0, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) ); CREATE INDEX idx_daily_log_date ON daily_log(date); CREATE TABLE targets ( id INTEGER PRIMARY KEY, start_date TEXT NOT NULL, end_date TEXT, -- null = currently active calories INTEGER NOT NULL, protein_g REAL, carbs_g REAL, fat_g REAL );