mitai-jinkendo/.claude/docs/functional/BLS_FOOD_REFERENCE.md
Lars fa542e0fb9
All checks were successful
Deploy Development / deploy (push) Successful in 1m7s
Build Test / pytest-backend (push) Successful in 5s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 22s
feat: Listen-Dialog mit Mengen/Einheiten, Mitai ohne Kochrezepte
Roh-Kombinationen statt Rezept-Sprache; Zutaten suchen, EL/TL/Prise auf Gramm. Gekochte Gerichte und Ausbeute bleiben Tandoor.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-12 18:23:01 +02:00

56 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# BLS-Lebensmittelreferenz und FDDB-Mapping
**Stand:** 2026-09-12 · **Status:** Phase 1 (Umsetzung)
## WAS
Optionale Grundlage für verlässliche Nährwerte: offizieller Bundeslebensmittelschlüssel (BLS) 4.0 plus manuelle Katalogerweiterung, lernendes Mapping von FDDB-Bezeichnern, persistierte Tagebuchzeilen. Reine Tagesmakros bleiben First Class.
## Zuordnung (UX)
Offene Zuordnungen zeigen **Vorschläge in der Zeile** (z. B. Haferflocken → Hafer Flocken); Bestätigen ohne Dialog. Mehrere nahe Treffer werden gekennzeichnet. Fehlt ein Treffer, **Lebensmittel oder Liste**. Ein Lebensmittel wird ein Katalogeintrag. Eine **Liste / Kombination** öffnet den Dialog: Zutaten per Suche aus bereits gemappten Namen oder dem Katalog (Fettgehalt wie Joghurt 10 %). Jede Zutat hat **Menge + Einheit** (g, ml, EL, TL, Prise, Stück, …). Standardeinheit für Nährwerte ist Gramm; Haushaltsmaße werden umgerechnet (EL 15 g, TL 5 g, Prise 0,3 g, oder Gramm pro Stück am Mapping). Fehlt der Faktor, bleibt die Einheit erhalten und ist später umrechenbar. Katalogtreffer werden beim Speichern zugeordnet. Freitext-Zutaten bleiben offen und erscheinen in der Offene-Liste (Kennzeichnung „Listenzutat“) — dort nur als Lebensmittel zuordenbar. Nicht-Gramm-Einheiten (Stück, EL, TL, …) bekommen ein **Gramm-pro-Einheit**-Feld am Mapping. Vorschläge und Katalogsuche laufen nur für die sichtbare Arbeit. Die Offene-Liste startet bei den **letzten 4 Wochen**; ältere Namen bleiben unter „Alle“.
## Listen / Kombinationen (Mitai) vs. Gerichte (Tandoor)
**Mitai speichert nur Roh-Kombinationen** — einen Namen für eine Zutatenliste ohne Kochvorgang (Müsli, Bowl, Smoothie). Summe der Zutatengramm = gegessene Gramm. Tabelle bleibt `food_recipes` (kein Rename).
**Gekochte Familienrezepte** liegen in **Tandoor**. Kein zweites Rezeptbuch in Mitai. Kochschwund (Wasserverlust beim Köcheln) darf die Rohzutaten nicht 1:1 auf die gegessene Menge skalieren.
Spätere Ausbeute (nicht in Phase 1):
- `ingredients_g` = Summe der auf Gramm aufgelösten Zutaten
- `cooked_yield_g` = gewogenes Fertiggewicht nach dem Kochen
- `yield_factor = cooked_yield_g / ingredients_g` (oft 0,50,9 bei langem Köcheln)
- Nährwerte **pro 100 g fertig** = `Summe(Zutat_Nährwerte) / cooked_yield_g × 100`
- Gegessen: `portion_g / 100 × Werte_pro_100g`
Ohne Fertiggewicht: nicht raten — FDDB-Makros oder Marke „unvollständig“. Für Listen gilt implizit `cooked_yield_g = ingredients_g` (Faktor 1). Tandoor liefert Zutaten und Schritte; die Ausbeute und die **pro-100-g**-Rechnung führt Mitai. Importiertes Gericht wird ein Katalogeintrag (`catalog_kind` z. B. `recipe_cooked`), keine zweite Wertetabelle.
## FDDB-Listen
FDDB-Tagebuchexport fasst selbst angelegte Listen oft zu **einer Zeile** (Listenname + Menge) zusammen. Die Zutaten stehen in einem **separaten Listen-Export** (`lists_*.csv`, Spalte `produkte`). Ablauf: Listen importieren → passende Tagebuchzeilen werden als Liste verknüpft → **Zutaten** zuordnen, nicht die Liste als Ganzes. Unvollständige Zutaten-Mappings fallen auf die FDDB-Makros der Tagebuchzeile zurück.
Gelernte Zuordnungen und Listen lassen sich als **JSON sichern** und auf einer anderen Instanz (Dev → Prod) wieder einspielen. Offizielle Lebensmittel werden über den BLS-Code gefunden — der BLS-Katalog muss auf dem Ziel bereits importiert sein.
## Fachliche Regeln
- BLS-Code (`bls_code`, Stoff-`attr_key`) bleibt die stabile Identität bei Reimports.
- BLS 4.0 (~7140 Lebensmittel) ist frei nutzbar (MRI / blsdb.de); Dateien nicht im Git.
- Mapping ohne KI: Normalisierung + exakter Lookup (User vor Global) + Bestätigung neuer Namen.
- Gelernte Zuordnungen bleiben dauerhaft, sind aber änder- und löschbar.
- Ungemappte / Fertiggerichte: FDDB-Makros, keine erfundenen Mikros.
- Fasten und „unvollständig“ sind explizite Marken, kein Auto-Schluss aus fehlendem Import.
- Import-Policy (Profil): nachfragen / Katalog überschreiben / FDDB überschreiben / Makros behalten.
## Manuelle Lebensmittel / Supplemente
Eigene Einträge (z. B. Norsan Omega-3 + EPA) speichern **dieselben Stoffwerte** wie BLS-Lebensmittel (`food_attribute_values`, immer pro 100 g). Beim Anlegen: Makros plus Suche nach weiteren Stoffen (EPA, DHA, Omega-3). Etikett „pro 8 ml“ → Portionsgröße in g angeben, Umrechnung auf 100 g erfolgt serverseitig. Einheit des Stoffs beachten (oft **g**, Etikett in mg: 1100 mg = 1,1 g). Fehlt ein Stoff im Katalog: Admin → Stoffe & Attribute.
Weitere Quellen (USDA, Schweizer Nährwertdatenbank) kommen später als zusätzliche Katalogherkunft, nicht als zweite Wertetabelle.
## Später
Platzhalter (Registry) für Mikros, Esszeitpunkte (`logged_at`), Fasten; Bezug Gitea #106 (Grundlage) und #75 (Folge).
**Tandoor:** Familienrezepte bleiben dort. Später: Import/Verknüpfung, Zutaten gegen Mitai-Mappings, `cooked_yield_g`, Katalogeintrag Fertiggericht pro 100 g. Kein Connector in Phase 1.