Files
Cibello-app/docs/07-datamodell.md
2026-08-05 19:21:11 +07:00

8.4 KiB
Raw Permalink Blame History

Del 7 Datamodell

Källa: packages/database/src/schema/ (Drizzle). Genererad SQL: infrastructure/migrations/0000_*.sql 54 tabeller, 38 enums, FK:er och index. Kör: pnpm db:generate (ny migration ur schemat), pnpm db:migrate, pnpm db:seed.

Domänöversikt (tabeller per fil)

Fil Tabeller Nyckelidéer
users.ts users, user_credentials, refresh_tokens, user_health_profiles, user_preferences, user_consents Hälsodata i EGEN tabell, exponeras aldrig via hushålls-API (§7/§56). Refresh-tokens hashade med familje-id → stöldskydd. Samtycken som (user, kind)-PK med tidsstämplar (§33).
households.ts households, household_members, storage_locations invite_code unik. portion_factor per medlem (§7). Platser = kyl/frys/skafferi/…/custom med sublocations[] (§8).
ingredients.ts canonical_ingredients, substitutions Navet för normalisering (§9). Näring per 100 med provenance-JSON (aldrig AI-påhitt). Diet-/allergiflaggor för deterministisk filtrering. shelf_life_guidance per platstyp (§13).
products.ts products Versionshantering: (gtin, version) unik, aktuell rad = valid_to IS NULL (§11, §61.12).
inventory.ts inventory_items, inventory_transactions Transaktioner är sanningen (§8): typade (+purchase/cook_use/discard/…), value_minor på discard → svinnvärde (§26). Saldo cachas på posten. Index på (household, best_before).
recipes.ts recipe_source_registry, recipes, recipe_ingredients, recipe_steps, recipe_ratings, recipe_favorites, recipe_cooks, recipe_similarities Source registry för juridik (§15). DNA som jsonb (§16). variant_of/forked_from (§16/§35). Status-flöde §35. Similarity-klassning §36. Steg med timer/temperatur för Cooking Mode.
meals.ts meals, meal_boxes Näring som snapshot-jsonb (historik ändras inte när recept ändras). Estimatintervall för tallriksfoto (§22). Matlådor med portions_remaining + recommended_use_by (§24).
planning.ts week_plans, week_plan_entries, shopping_lists, shopping_list_items Planpost kan peka på recept ELLER matlåda. reschedule_reason_sv för dynamisk omplanering (§25). Lista: store_section, origin (plan/manual/…) (§27).
receipts.ts receipts, receipt_lines, price_observations Kvittorader med confidence + verified (§12). Prishistorik → budget/prognoser.
scans.ts scan_jobs, ai_corrections Jobbstatus inkl. awaiting_confirmation. Korrigeringar med consent_snapshot → träningsdata endast med samtycke (§33). model/prompt_version på allt (§9).
memory.ts memory_items, taste_signals, food_memories Minnestyper §32, origin user_stated/observed/ai_inferred (§30), paused/verified per post.
seasons.ts season_events Datadrivna datumregler (fixed/range/computed: midsommar/påsk/advent) (§28).
subscriptions.ts subscriptions, subscription_events, store_transactions, store_notifications, trials, ai_usage_counters Backend source of truth (§47). (provider, original_transaction_id) unik → idempotent verifiering. Månadskvot för fair use (§4546).
platform.ts domain_events, feature_flags, audit_logs, idempotency_keys, notifications, push_tokens, creator_stats, creator_follows, ai_eval_cases, ai_eval_runs, waste_summaries Outbox-mönster (§55). Flaggor med rollout-procent. Audit (§56). Evals (§34).

Viktiga constraints & index (urval)

Unika: users.email; households.invite_code; recipes.slug; (recipe,user) i ratings; (provider, original_transaction_id) i subscriptions (partial, NOT NULL); (gtin, version) i products (partial); (user, month) i ai_usage_counters; refresh_tokens.token_hash. Prestanda: inventory(household, best_before) för utgångslistan; meals(user, date) för Min dag; domain_events(published_at, occurred_at) för outbox; scan_jobs(status); recipes(status), (cuisine), (total_time).

Regler för ändringar (spec §63)

  1. Ändra schema i packages/database/src/schema/pnpm db:generate → granska SQL:en.
  2. Ingen destruktiv ändring utan: backup (deploy.sh tar dump), migration, dokumenterad rollback, kontroll efteråt.
  3. Logga varje migration i tabellen nedan.

Migrationslogg

# Fil Datum Innehåll Rollback
0000 0000_dusty_lady_deathstrike.sql 2026-08-02 Initialt schema: 54 tabeller, 38 enums, samtliga index/FK Drop databasen (pre-launch)

i18n-tillägg (M1M6)

  • households.currency_code char(3) NOT NULL DEFAULT 'SEK' pengagränsen går vid hushållet.
  • Alla pengakolumner är integer i minor units (*_minor).
  • ingredient_translations (ingredient_id, language_tag, name, aliases[], source, status) unik per (ingrediens, språk).
  • unit_translations (unit_code, language_tag, abbreviation, name) PK (kod, språk).
  • recipe_translations (recipe_id, language_tag, title, description, storage_guidance, status draft_ai|in_review|published, source, verification jsonb).
  • recipe_step_translations (recipe_id, language_tag, step_number, instruction, tip) PK (recept, språk, steg).
  • nutrition_display_profiles (region_code PK, energy_display kcal|kj|both, salt_display salt|sodium, energy_label_key).
  • allergen_market_rules (region_code, allergen, must_highlight) PK (region, allergen).
  • Trigramindex (pg_trgm) på canonical_ingredients.name_sv, ingredient_translations.name, recipes.title_sv; unaccent för accentokänslig sök.