Zutaten von Hand zuordnen - und Vorrania merkt es sich
Der unscharfe Abgleich muss raten und wird das immer tun: "Lime Curd" hat
mit "Zitronencreme" kein Wort gemeinsam, und manchmal liegt er daneben.
Bisher war das eine Sackgasse - die Zutat blieb unzugeordnet, bei jedem
Aufruf neu.
Jetzt traegt jede Zutatenzeile einen Knopf "Zuordnen". Entschieden wird
gegen Artikel UND Gruppen, gemerkt unter dem normalisierten Namen des
Lebensmittels: "Schlagsahne", "schlagsahne" und "SCHLAGSAHNE " treffen
dieselbe Zeile. Ab dann gilt die Entscheidung fuer jedes Rezept, in dem
diese Zutat vorkommt - eine Zutat wird hoechstens einmal zugeordnet.
Schluessel ist der Name, nicht die Mealie-ID: IDs sind UUIDs, die beim
Neuanlegen eines Lebensmittels wechseln, und nur ueber den Namen greift
die Zuordnung auch fuer Zutaten ohne verknuepftes Lebensmittel ("2 Eier").
Im Auswahldialog stehen oben die Vorschlaege, die der Abgleich selbst
gefunden hat - meist ist der Richtige darunter, nur nicht an erster
Stelle -, darunter die freie Suche ueber alles. Die Basiseinheit steht
dabei, damit nicht wieder Milliliter auf ein Gramm-Produkt wandern.
Beim Raten bleiben Gegenstaende aussen vor; von Hand darf alles gewaehlt
werden ausser Einzelstuecken. Backpapier ist kein Lebensmittel und steht
trotzdem in Rezepten, waehrend ein Einzelstueck nie eine Zutat ist.
Zeigt das Ziel ins Leere, weil der Artikel geloescht wurde, faellt die
Zeile beim Laden still heraus: Auf SQLite greift kein Fremdschluessel,
und ein geloeschter Artikel darf kein Rezept mehr sprengen.
Die Zuordnungs-Routen stehen bewusst vor /recipes/{slug}, sonst liest
FastAPI "zuordnungen" als Rezept-Slug und fragt Mealie danach. Ein Test
wacht ueber die Reihenfolge, weil ein Umsortieren der Datei den Fehler
sonst still einbauen wuerde.
16 neue Tests, Suite bei 487.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2a56cca3c8
commit
8072e7f566
@@ -815,6 +815,42 @@ class IntegrationSecret(Base):
|
||||
)
|
||||
|
||||
|
||||
class MealieFoodMap(Base):
|
||||
"""Gemerkte Zuordnung: Mealie-Lebensmittel X ist bei uns Artikel/Gruppe Y.
|
||||
|
||||
Der unscharfe Abgleich in ``services/rezepte.py`` raet, dieser Tisch weiss.
|
||||
Jede Korrektur von Hand landet hier und gilt ab dann fuer jedes Rezept, in
|
||||
dem dasselbe Lebensmittel vorkommt — eine Zutat wird also hoechstens einmal
|
||||
im Leben zugeordnet.
|
||||
|
||||
Schluessel ist der **normalisierte** Name (``matching.normalisieren``), damit
|
||||
"Schlagsahne", "schlagsahne" und "SCHLAGSAHNE " dieselbe Zeile treffen.
|
||||
Daneben steht der Name, wie Mealie ihn schreibt — nur zur Anzeige in der
|
||||
Liste der gemerkten Zuordnungen.
|
||||
|
||||
Genau eines von ``product_id`` und ``group_id`` ist gesetzt; geprueft wird
|
||||
das beim Speichern (``services/zuordnung.py``), nicht in der Datenbank —
|
||||
dasselbe Muster wie bei den Bedarfszeilen. Verschwindet das Ziel spaeter,
|
||||
wird die Zeile beim Laden stillschweigend uebersprungen: Auf SQLite greift
|
||||
kein Fremdschluessel, und eine Zuordnung auf einen geloeschten Artikel darf
|
||||
den Rezeptabgleich nicht sprengen.
|
||||
"""
|
||||
|
||||
__tablename__ = "mealie_food_map"
|
||||
|
||||
food_key: Mapped[str] = mapped_column(String(200), primary_key=True)
|
||||
food_name: Mapped[str] = mapped_column(String(200), nullable=False)
|
||||
product_id: Mapped[int | None] = mapped_column(
|
||||
ForeignKey("products.id", ondelete="CASCADE"), nullable=True, index=True
|
||||
)
|
||||
group_id: Mapped[int | None] = mapped_column(
|
||||
ForeignKey("groups.id", ondelete="CASCADE"), nullable=True, index=True
|
||||
)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=_now, onupdate=_now
|
||||
)
|
||||
|
||||
|
||||
class Shop(Base):
|
||||
"""Bezugsquelle / Geschäft, aus dem ein Gegenstand stammt ("gekauft bei").
|
||||
|
||||
|
||||
Reference in New Issue
Block a user