8de222072c3969100adb9f38558d8ae55e7ae6be
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
18481bbca0 |
Seitenzustand in die Adresszeile
Neu web/src/urlState.js mit useUrlWert/useUrlZahl/useUrlWerte. Zwei
Regeln stecken darin, beide damit die Adresszeile brauchbar bleibt:
geschrieben wird immer mit replace - sonst legt jeder Tastendruck in
einem Suchfeld einen Verlaufseintrag an und die Zurueck-Taste braeuchte
zwanzig Versuche, um die Seite zu verlassen -, und Vorgabewerte fliegen
aus der URL, sonst sammelt sich "?typ=&q=&kat=" an.
useUrlWerte gibt es, weil zwei getrennte Schreibvorgaenge im selben
Durchlauf einander ueberschreiben: Beide bekommen denselben
Ausgangsstand. Wo ein Klick zwei Dinge aendert ("Kategorie 12, Karte
Masse"), muss es ein Aufruf sein.
Damit wandern in die URL:
- Rezepte: Das Rezept steht jetzt im PFAD (/rezepte/<slug>), weil es
benennt, was man ansieht - so wie /products/:id und /i/:uid. Portionen
und Suchbegriff als Parameter. "Pfannkuchen fuer 12" ist damit ein
verschickbarer Link.
- Kategorien: Segment-Umschalter und die geoeffnete Seitenkarte
(?typ=food&kat=6&panel=masse). Gespeichert wird die Kennung, nicht das
Objekt - die Kategorien kommen erst vom Server.
- Gruppen: die geoeffnete Seitenkarte.
- Artikel: der Segment-Umschalter.
- Ein- und Auslagern: der gewaehlte Artikel als Kennung, nachgeladen beim
Aufruf. Eine halbfertige Buchung ueberlebt damit ein Neuladen.
Die Portionszahl landet NUR in der URL, wenn jemand sie selbst gestellt
hat. Die Vorbelegung aus dem Rezept bleibt draussen - sonst traegt jedes
geoeffnete Rezept ein ?portionen mit sich herum, das gar keine
Entscheidung ist.
Dazu im Backend: Ein unbekanntes Rezept ist jetzt 404 statt 502 und sagt
"Dieses Rezept gibt es in Mealie nicht (mehr)" statt "Mealie kennt
/api/recipes/x nicht". Das wurde noetig, weil ein Rezept seit diesem
Commit verlinkbar ist und ein alter Link irgendwann ins Leere zeigt -
eine gewoehnliche Auskunft, kein Gateway-Fehler.
Von Hand durchgeklickt: Rezept oeffnen und Portionen auf 12 ->
/rezepte/pfannkuchen?portionen=12, Neuladen bringt 250 g -> 750 g zurueck;
unbekannter Slug zeigt den klaren Hinweis und laesst die Liste stehen;
Kategorie-Karte und Segment ueberstehen F5, Schliessen raeumt die URL;
/checkin?artikel=1 laedt den Artikel nach, ?artikel=999 raeumt die
Adresse und zeigt die Suchmaske. 1 neuer Test, Suite bei 518.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
795e233a1b |
Einkaufsliste bekommt ein Gedaechtnis - und den Knopf aus dem Rezept
Die Einkaufsliste war vollstaendig GERECHNET: Artikel unter ihrem
Mindestbestand, Gruppen unter ihrem, Bedarfe je Lagerort. Das bleibt, es
ist die Staerke der Liste. Was fehlte, war ein Ort fuer "Milch gehoert
drauf, weil ich das sage" - und damit auch fuer "diese Zutaten fehlen mir
fuer das Rezept". Der Knopf konnte nirgends hinschreiben.
Zwei Tabellen dafuer, und die Trennung ist der Kern:
shopping_entries haelt, was jemand bewusst draufgesetzt hat. Genau eines
von Artikel, Gruppe oder Freitext - der Freitext ist unverzichtbar, denn
eine Rezeptzutat ohne Artikel ("Ras el Hanout") kommt nur so auf den
Zettel, und gerade die unbekannte Zutat ist die, die man vergisst.
shopping_checks haelt nur den HAKEN an einem gerechneten Posten, nicht
den Posten. Die gerechneten Vorschlaege duerfen keine Zeile bekommen: Sie
aendern sich mit jedem Einlagern, eine materialisierte Kopie waere sofort
falsch. Abhaken ging deshalb bisher nur im Browser und war nach dem
Neuladen weg - mitten im Supermarkt.
Aus einem Rezept uebernommen wird die FEHLMENGE, nicht die Rezeptmenge:
Wer 250 g braucht und 100 g hat, kauft 150 g. Gerechnet wird frisch mit
der Portionszahl, die auf dem Schirm steht. Je Rezept und Ziel gibt es
hoechstens einen offenen Eintrag - ein zweiter Druck nach dem Hochdrehen
der Portionen rechnet die Menge neu, statt die Liste zu verdoppeln. Ueber
verschiedene Rezepte hinweg bleiben es getrennte Zeilen, denn derselbe
Artikel kann zweimal fehlen. Ein abgehakter Eintrag blockiert nichts -
abgehakt heisst gekauft.
Mengen formatiert dieselbe Funktion wie beim Rezeptabgleich, damit die
Liste eine Sprache spricht: "2 Packungen" statt "1500 ml", aufgerundet,
weil man keine halbe Packung kauft.
In der Oberfläche eine eigene Karte "Selbst draufgesetzt" mit Eingabefeld,
Herkunftsangabe ("fuer Pfannkuchen") und "Erledigte entfernen", das beide
Quellen zusammen aufraeumt - fuer den Nutzer ist es eine Liste. Das
Abhaken wandert sofort und speichert im Hintergrund; schlaegt es fehl,
springt der Haken zurueck. Die Seite holt jetzt alles mit einem Aufruf
statt mit drei.
Von Hand geprueft gegen eine Mealie-Attrappe: Pfannkuchen fuer 48
Portionen ergibt 2 Packungen Mehl, 2 Packungen Milch, 3 Packungen Eier
und "Ras el Hanout" als Notiz; derselbe Knopf bei 96 Portionen
aktualisiert diese vier statt acht daraus zu machen; ein Haken
ueberlebt das Neuladen. 17 neue Tests, Suite bei 512.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
8072e7f566 |
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>
|
||
|
|
2247c8cf69 |
Rezepte aus Mealie gegen den Bestand pruefen
Neue Seite "Rezepte" (nur sichtbar, wenn Mealie eingerichtet ist): links
die Rezeptliste mit Suche, rechts das gewaehlte Rezept mit allen Zutaten
und der einen Frage, die zaehlt - kann ich das heute kochen, oder muss ich
vorher einkaufen? Je Zutat steht der Zustand: vorhanden, zu wenig, fehlt,
Menge unklar oder nicht zugeordnet; Fehlendes ist rot.
Die Portionenzahl laesst sich hochdrehen. Vorrania rechnet die Mengen dann
hoch, bevor es sie mit dem Bestand vergleicht - ein Rezept fuer 4, das man
fuer 8 kocht, braucht die doppelte Menge, und genau danach soll der
Abgleich gehen. Nennt das Rezept keine Portionszahl, wird nicht skaliert
und die Seite sagt das auch.
Drei Dinge entscheidet der Abgleich nacheinander (services/rezepte.py,
bewusst ohne HTTP, damit sich alles mit erfundenen Zutaten pruefen laesst):
1. Welcher Artikel ist gemeint? Unscharf ueber den Namen, gegen Artikel
UND Gruppen - "Milch" ist markenuebergreifend gemeint, und genau dafuer
gibt es Gruppen. Die Schwelle liegt hoeher als beim Kassenzettel: Dort
sieht ein Mensch die Vorschlaege durch, hier darf nicht stillschweigend
das Falsche als vorhanden gelten. Unter der Schwelle bleibt es bei
"nicht zugeordnet" samt Kandidatenliste.
2. Wie viel ist das in Gramm? Ueber die Einheiten und die Hausmasse der
Kategorie - "2 EL Zucker" wird zu 24 g. Fehlt das Mass fuer diese
Kategorie, meldet die Zutat genau das zurueck (Massname und
Kategorie-ID), damit daraus ein "Mass jetzt anlegen" werden kann.
3. Reicht der Bestand? Bei Gruppen ueber dieselbe gewichtete Summe wie in
der Einkaufsliste, damit Untergruppen und Zweiteinheiten gleich zaehlen.
Die Fuzzy-Heuristik lag in routers/products.py und ist nach
services/matching.py gezogen: Der Rezeptabgleich stellt dieselbe Frage, und
zwei Kopien waeren mit der Zeit auseinandergelaufen. Der Kassenzettel-Scan
nutzt sie unveraendert weiter, test_receipt_match.py bleibt gruen.
Dazu zwei Dinge aus deiner Rueckmeldung zur Einstellungs-Karte:
- Der verbundene Zustand bleibt jetzt stehen, statt nur als Meldung
aufzublitzen: Adresse, Version und "Dauertoken hinterlegt" samt den
Knoepfen Pruefen / Zugang aendern / Trennen. Das Formular erscheint nur,
solange nichts eingerichtet ist - ein Dauerzustand gehoert nicht in ein
Eingabefeld, sonst sieht man nie, ob es geklappt hat.
- Leere Felder melden sich auf Deutsch ("Bitte das Passwort eingeben.")
statt mit der rohen Schema-Meldung "String should have at least 1
character", die niemandem sagt, welches Feld gemeint ist.
Der Knopf "Fehlende zur Einkaufsliste" fehlt noch: Vorranias Einkaufsliste
wird heute vollstaendig aus Mindestbestaenden gerechnet und hat keinen Ort
fuer einen eigenen Eintrag. Das ist der naechste Schritt; die Seite sagt es
auch so.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|