Initial commit (unpacked platform)

This commit is contained in:
Sven (AAMOS AI)
2026-08-05 19:21:11 +07:00
commit ac5340195a
314 changed files with 57584 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
# 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.