chore: initial import

This commit is contained in:
2026-07-24 21:37:03 +02:00
commit 45bc449ea0
53 changed files with 12329 additions and 0 deletions
+141
View File
@@ -0,0 +1,141 @@
# Stammdaten aufräumen
Führt doppelte Zutaten, Einheiten und Schlagworte zusammen und findet
Karteileichen.
## Bitte einmal lesen, bevor du es benutzt
Tandoors `merge` hängt alle Verweise der Quelle auf das Ziel um und **löscht
die Quelle**. Das ist nicht umkehrbar. Im Tandoor-Quelltext steht dazu:
```python
# TODO these checks could be improved to merge existing properties and
# conversion in a smart way. For now it will just loose them to prevent
# duplicates
if isinstance(source, Food):
source.properties.all().delete()
```
Die Nährwerte des Quelleintrags gehen also verloren. Dieses Werkzeug rettet
sie deshalb vorher: Werte, die nur die Quelle hat, werden zuerst ans Ziel
geschrieben. Abschaltbar über das Häkchen bzw. `--ohne-rettung`.
## Was vorgeschlagen wird — und was nicht
**Sichere Dubletten** (vorausgewählt) bei praktisch sicheren Fällen:
* gleicher Name (`Zwiebel` / `zwiebel`, `Olivenöl` / `Olivenoel`)
* Singular/Plural (`Zwiebel` / `Zwiebeln`, `Tomate` / `Tomaten`)
**Ähnlich** — anhakbar, aber nie vorausgewählt und mit Pflicht zur
Richtungswahl:
* echte Wort-Teilmengen (`Mehl` / `Mehl Type 550`, `Olivenöl` /
`Olivenöl nativ extra`) — jedes Wort der kürzeren Seite kommt als
ganzes Wort in der längeren vor
Der Unterschied ist Absicht. `Rote Zwiebel` sieht `Zwiebel` sehr ähnlich, ist
aber etwas anderes — deshalb entscheidet hier der Mensch, ob und in welche
Richtung zusammengeführt wird, statt dass etwas vorausgewählt ist.
**Bekannte Lücke:** unregelmäßige Plurale mit Umlaut (`Ei` / `Eier`,
`Apfel` / `Äpfel`) erkennt die Heuristik nicht. Die tauchen in keiner der
beiden Listen auf.
**Löschen** wird grundsätzlich nicht vorausgewählt — manches hebt man
absichtlich auf.
## Welcher Eintrag bleibt
Ziel ist der Eintrag, der am meisten zu verlieren hätte, in dieser Reihenfolge:
die meisten Rezepte → die meisten Nährwerte → gepflegter Plural →
Supermarkt-Kategorie → kürzerer Name.
## Ablauf
1. **Prüfen** — schreibt eine Plandatei. Verändert nichts.
2. Plan durchsehen, Häkchen setzen.
3. **Trockenübung** — zeigt Zeile für Zeile, was passieren würde.
4. **Ausführen** — erst dann wird es ernst. Vor jedem Schritt wird der
Zustand der betroffenen Einträge gesichert.
Zusammengeführt wird vor dem Löschen: eine Zusammenführung kann einen Eintrag
erst unbenutzt machen.
## Ohne Suite
export TANDOOR_URL=https://kitchen.example.de
export TANDOOR_TOKEN=...
python3 plugins/tandoor-cleanup/tool/cleanup.py pruefen
python3 plugins/tandoor-cleanup/tool/cleanup.py pruefen --arten food
python3 plugins/tandoor-cleanup/tool/cleanup.py ausfuehren \
--plan data/tandoor-cleanup/plaene/<datei>.json # Trockenübung
python3 plugins/tandoor-cleanup/tool/cleanup.py ausfuehren \
--plan data/tandoor-cleanup/plaene/<datei>.json --apply # ernst
## Dateien
data/tandoor-cleanup/plaene/<zeit>.json Plan
data/tandoor-cleanup/laeufe/<zeit>/ Sicherungen + ausgeführter Plan
## Bessere Ähnlich-Erkennung (Wort-Teilmenge statt Zeichenkette)
Früher galt schon eine bloße Zeichenketten-Enthaltung als „Teilwort“. Das
erzeugte Fehlpaare wie `Mango` ~ `Mangold`, `Buchweizen` ~ `Buchweizenmehl`
oder `getrocknete Tomate` ~ `getrocknete Tomaten in Öl`. Jetzt zählt nur eine
echte **Wort-Teilmenge**: jedes Wort der kürzeren Seite muss als *ganzes* Wort
in der längeren vorkommen. Dadurch verschwinden diese Fehlpaare, während echte
Untertypen (`Mehl` / `Mehl Type 550`) erhalten bleiben.
## Plurale pflegen (Zutaten und Einheiten)
Eigener Abschnitt „Plurale“ je Art — für **Zutaten und Einheiten**. Er zeigt
alle Einträge mit ihrem aktuellen Plural in einem editierbaren Feld; fehlende
stehen oben und sind hervorgehoben. Ein Filterfeld macht große Listen
bedienbar. Bearbeiten hakt die Zeile automatisch an. Geschrieben wird nur, was
sich gegenüber dem Ist-Stand geändert hat — Unverändertes wird übersprungen.
Setzen und Ändern sind nicht destruktiv und **voll rückspielbar**.
## KI-Vorauswahl für ähnliche Paare (ChatGPT)
Das Finden der Paare bleibt die Heuristik. Ist beim Prüfen „Ähnliche Paare per
KI vorfiltern“ aktiv (Vorgabe an, sobald ein `OPENAI_API_KEY` hinterlegt ist),
ordnet ChatGPT jedes gefundene Paar in drei Töpfe:
* **gleich** zweifelsfrei dasselbe (Schreibvarianten, fehlendes Leerzeichen,
Groß/Klein, Singular/Plural). Wird **angehakt** und die Richtung vorgewählt
(der allgemeinere bzw. korrekt geschriebene Name bleibt).
* **unklar** könnte dasselbe sein. Wird angezeigt, aber nicht vorgewählt —
du entscheidest.
* **verschieden** zweifelsfrei verschiedene Sorten/Produkte (Weizenmehl 550
vs. 1050, Frischkäse vs. körniger Frischkäse). Standardmäßig **ausgeblendet**.
Ein Filter über der Liste schaltet zwischen **„Nur KI-Treffer“** (gleich +
unklar) und **„Alle“** (auch die verschiedenen) um.
So sind die eindeutigen Fälle mit einem Blick abgehakt, die strittigen bleiben
sichtbar, und der Lärm ist weg. Nichts wird ausgeführt — du prüfst und startest
selbst; Zusammenführen bleibt gesichert und rückspielbar. Kommandozeile:
`pruefen --ki-filter`. Fällt die KI aus, bleiben alle Paare unverändert stehen.
## Plurale per KI (ChatGPT)
Getrennt davon schlägt ChatGPT auf Wunsch die **Plurale** von Zutaten und
Einheiten vor — auch die Umlaut-Fälle (`Apfel``Äpfel`), die die Heuristik
nicht kann (`vorbelegen --plan <datei>`, Knopf „Plurale vorschlagen“).
Standardmäßig nur dort, wo noch kein Plural gepflegt ist; `--alle-plurale` nimmt
auch bestehende. Einträge, die durch eine angehakte Zusammenführung ohnehin
verschwinden, werden übersprungen. Auch das ist nur ein Vorschlag und voll
rückspielbar. Verbindung prüfen: `probe` bzw. „OpenAI testen“.
## Hinweis: Einheiten-Plurale und Tandoor-Serverfehler
Manche Tandoor-Versionen stürzen beim Ändern einer **Einheit** über einen
schlichten Teil-PATCH mit „HTTP 500“ ab (Zutaten sind nicht betroffen). Das
Werkzeug setzt Einheiten-Plurale deshalb robust: zuerst per vollständigem PUT
(anderer Code-Pfad, alle vorhandenen Felder bleiben erhalten), danach mit
mitgesendetem Namen, zuletzt der schlichte Weg. Lehnt der Server alle Wege ab,
werden die restlichen Einheiten-Plurale übersprungen (mit klarer Meldung) statt
sie einzeln durchzuprobieren — dann bitte in der Tandoor-Oberfläche setzen.
Zutaten-Plurale laufen davon unberührt weiter.