217 lines
9.2 KiB
Markdown
217 lines
9.2 KiB
Markdown
# boehmitools
|
||
|
||
Ein Dashboard, unter dem alle Tools zusammenlaufen. Jedes Tool bleibt dabei
|
||
eigenständig — es liegt als Plugin in `plugins/<name>/`, hat sein eigenes
|
||
Backend und seinen eigenen Datenordner. Gemeinsam sind das Design, die
|
||
Zugangsdaten und das Dach.
|
||
|
||
```
|
||
Dashboard /
|
||
├── Trainingsplan- & Rezept-Editor /plugins/trainingsplan
|
||
├── Tandoor AI Import /plugins/tandoor-ai-import
|
||
├── Rezept-Inventur /plugins/tandoor-lint
|
||
├── Stammdaten aufräumen /plugins/tandoor-cleanup
|
||
├── Nährwerte vervollständigen /plugins/tandoor-nutrition
|
||
├── Zutaten-Kategorien /plugins/tandoor-categories
|
||
└── Einheiten-Umrechnungen /plugins/tandoor-conversions
|
||
```
|
||
|
||
---
|
||
|
||
## Starten
|
||
|
||
### Docker (empfohlen)
|
||
|
||
```bash
|
||
cd boehmitools
|
||
cp .env.example .env
|
||
nano .env # mindestens APP_PASSWORD setzen
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Dann im Browser: `http://<server-ip>:8080`
|
||
|
||
Port ändern: in der `.env` `APP_PORT=9090` setzen.
|
||
Logs: `docker compose logs -f` · Stoppen: `docker compose down`
|
||
|
||
### Direkt mit Python
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
python run.py # Standard-Port 8080
|
||
PORT=9090 python run.py # anderer Port
|
||
```
|
||
|
||
Für die Entwicklung mit automatischem Neuladen:
|
||
|
||
```bash
|
||
uvicorn core.app:app --reload --port 8080
|
||
```
|
||
|
||
## Einrichten
|
||
|
||
Nach dem ersten Start einmal auf **Einstellungen** (⚙ oben rechts):
|
||
|
||
| Gruppe | wird gebraucht von |
|
||
|---|---|
|
||
| **Tandoor** — URL, Token, Auth-Schema | AI Import, Rezept-Inventur, Stammdaten, Nährwerte |
|
||
| **OpenAI** — API-Key, Modell | AI Import |
|
||
| **Rezeptquellen** — TLS, Timeouts, private IPs | AI Import |
|
||
|
||
Die Werte landen in `data/settings.json` und werden den Tools als
|
||
Umgebungsvariablen übergeben — genau so, wie die Tools sie als Einzelprogramm
|
||
erwarten. Wer lieber alles in der `.env` pflegt, kann das weiterhin tun: Diese
|
||
Werte gelten als Vorgabe, solange in der Oberfläche nichts eingetragen ist.
|
||
|
||
> Ohne `APP_PASSWORD` ist die Oberfläche ungeschützt. Der Schutz gilt dann für
|
||
> das Dashboard und alle Tools gemeinsam.
|
||
|
||
## Die Tools
|
||
|
||
### 🏋 Trainingsplan- & Rezept-Editor
|
||
Der 8-Wochen-Calisthenics-Plan und die vier Rezeptsammlungen, im Browser
|
||
bearbeitbar und per Klick als PDF. Phasen anlegen, duplizieren, exportieren.
|
||
Der ReportLab-Renderer ist unverändert der aus dem Einzeltool — das Layout
|
||
bleibt identisch.
|
||
|
||
### 🥕 Tandoor AI Import (v1.1)
|
||
URL einfügen → Seite sicher auslesen → OpenAI strukturiert das Rezept →
|
||
Vorschau, Warnungen und Zuordnungen prüfen → bewusst importieren → Verifikation,
|
||
bei Fehlern Rollback. Jeder Durchlauf wird unter
|
||
`data/tandoor-ai-import/runs/<RUN-ID>/` protokolliert.
|
||
|
||
Jede Zutat hat ein **Dropdown** mit den passenden Tandoor-Einträgen, der beste
|
||
Treffer ist vorausgewählt. Gesucht wird über Singular, Plural und Teilwörter —
|
||
`Kartoffeln` findet `Kartoffel`. Passt nichts, lässt sich über das Textfeld mit
|
||
einem anderen Namen erneut suchen oder der Eintrag per `➕ Neu anlegen` beim
|
||
Import erzeugen. Scheitert der Import, werden Rezept **und** die in diesem Lauf
|
||
neu angelegten Stammdaten zurückgerollt.
|
||
|
||
### 🔍 Rezept-Inventur
|
||
Geht die Sammlung durch und meldet, was fehlt: Rezepte ohne Quelle, Bild,
|
||
Portionsangabe oder Arbeitszeit, Zutaten ohne Einheit oder Menge, Schritte ohne
|
||
Text, doppelte Rezeptnamen, verwaiste Zutaten/Einheiten/Schlagworte. **Liest
|
||
ausschließlich** — es gibt keinen schreibenden Endpunkt. Befunde filterbar,
|
||
Export als CSV.
|
||
|
||
### 🧹 Stammdaten aufräumen
|
||
Führt doppelte Zutaten, Einheiten und Schlagworte zusammen und findet
|
||
Karteileichen. Vorgeschlagen wird nur, was praktisch sicher dasselbe ist
|
||
(`Zwiebel`/`Zwiebeln`, `Vegan`/`vegan`); Grenzfälle wie `Sahne`/`Schlagsahne`
|
||
stehen nur zur Ansicht. Tandoor verwirft beim Zusammenführen die Nährwerte des
|
||
Quelleintrags — dieses Tool rettet sie vorher ans Ziel. Trockenübung,
|
||
Einzelfreigabe und Sicherung je Schritt. Löschen ist nie vorausgewählt.
|
||
|
||
### 🥑 Nährwerte vervollständigen
|
||
Zeigt, bei welchen Zutaten Eigenschaften fehlen (Abdeckung je Eigenschaft,
|
||
Lücken nach Rezeptzahl sortiert), lässt sie je 100 g schätzen und schreibt sie
|
||
nach Prüfung zurück. Jeder Wert ist vor dem Schreiben editierbar. Vorhandene
|
||
Werte bleiben unangetastet, fehlende Bezugsmengen werden mitgesetzt.
|
||
Die Zahlen sind Schätzungen eines Sprachmodells, keine Laboranalysen.
|
||
|
||
|
||
### 🏷 Zutaten-Kategorien
|
||
Ordnet Zutaten ohne Supermarkt-Kategorie einer der vorhandenen
|
||
Kategorien zu — auf Wunsch von ChatGPT vorgeschlagen. Es werden nur
|
||
bestehende Kategorien vergeben, jede Zuweisung ist freizugeben und voll
|
||
rückspielbar.
|
||
|
||
### 🔁 Einheiten-Umrechnungen
|
||
Findet Zutaten, die in Rezepten mit mehreren, nicht ohne Weiteres
|
||
umrechenbaren Einheiten vorkommen (z. B. Stück und g) und wofür noch
|
||
keine Umrechnung hinterlegt ist. ChatGPT schlägt sinnvolle Werte vor —
|
||
diese sind Schätzungen und vor dem Eintragen zu prüfen. Angelegte
|
||
Umrechnungen sind über die Sicherungen wieder löschbar.
|
||
## Ein neues Tool hinzufügen
|
||
|
||
Es gibt zwei Wege:
|
||
|
||
**Hochladen.** Das Plugin als ZIP packen und im Dashboard auf **„Plugin
|
||
importieren“** — fertig. Erkannt wird es an der `id` aus seiner `plugin.json`;
|
||
ist die schon vorhanden, wird jene Fassung aktualisiert. Dabei wird nur ergänzt
|
||
und überschrieben, **nie gelöscht**, und der Datenordner bleibt unberührt. Der
|
||
bisherige Stand wandert vorher in eine Sicherung unter
|
||
`data/_plugin-sicherungen/<id>/`.
|
||
|
||
**Direkt ablegen.** Ordner unter `plugins/<name>/` anlegen, `plugin.json` und
|
||
`backend.py` dazulegen und im Dashboard **„Plugins neu laden“** klicken — die
|
||
Karte erscheint sofort, ohne die Suite neu zu starten. Der Knopf liest `plugins/` neu
|
||
ein, hängt neue oder geänderte Tools frisch ein und entfernt gelöschte. (Nur
|
||
Änderungen unter `core/` selbst brauchen weiterhin einen echten Neustart.)
|
||
Die vollständige Bauanleitung samt Design-Bausteinen steht in
|
||
**[`plugins/README.md`](plugins/README.md)**.
|
||
|
||
## Aufbau
|
||
|
||
```
|
||
boehmitools/
|
||
├── run.py Start
|
||
├── core/ Host: Dashboard, Plugin-Lader, Einstellungen, Jobs
|
||
│ ├── app.py mountet jedes Plugin unter /plugins/<id>
|
||
│ ├── registry.py liest plugin.json, lädt backend.py
|
||
│ ├── settings.py data/settings.json ⇄ Umgebungsvariablen
|
||
│ ├── jobs.py Subprozess-Läufe mit Live-Protokoll (SSE)
|
||
│ ├── loader.py kollisionsfreier Import der Tool-Module
|
||
│ └── static/ Dashboard, Einstellungen, Läufe
|
||
├── shared/ das gemeinsame Aussehen
|
||
│ ├── boehmi.css Design-System (hell/dunkel)
|
||
│ ├── boehmi.js App-Bar, Tool-Umschalter, BT.api/BT.toast
|
||
│ └── boehmi-runner.js Protokoll-Ansicht für Kommandozeilen-Tools
|
||
├── plugins/ ein Ordner je Tool ← hier wächst der Baukasten
|
||
└── data/ alles Veränderliche (Volume)
|
||
├── settings.json
|
||
├── trainingsplan/plans/
|
||
├── tandoor-ai-import/runs/
|
||
├── tandoor-cleanup/laeufe/
|
||
└── tandoor-nutrition/laeufe/
|
||
```
|
||
|
||
Ein Backup ist das Sichern des Ordners `data/`.
|
||
|
||
## Tools weiterhin einzeln starten
|
||
|
||
Jedes Plugin ist für sich lauffähig geblieben:
|
||
|
||
```bash
|
||
cd plugins/trainingsplan && python app.py
|
||
cd plugins/tandoor-ai-import && uvicorn app.main:app --port 8091
|
||
```
|
||
|
||
Die Original-Anleitungen der Tools liegen als `TOOL-README.md` bzw.
|
||
`TOOL-README.txt` in den jeweiligen Plugin-Ordnern; beim AI-Import steht in
|
||
`TOOL-UPGRADE.md` zusätzlich, was v1.1 geändert hat.
|
||
|
||
## Hinweise
|
||
|
||
- Gedacht für das **lokale Netzwerk**. Wenn erreichbar: `APP_PASSWORD` setzen
|
||
oder einen Reverse Proxy davorsetzen.
|
||
- Die Tokens verlassen das Backend nicht; OpenAI bekommt ausschließlich die
|
||
extrahierten Rezeptdaten und die Quell-URL.
|
||
- Läuft die Suite hinter einem Reverse Proxy in einem Unterpfad, in den
|
||
HTML-Seiten `<meta name="bt-root" content="/unterpfad">` ergänzen.
|
||
|
||
|
||
## Sicherungen und Zurückspielen
|
||
|
||
Die beiden Plugins, die etwas in Tandoor verändern, schreiben vor jeder Änderung
|
||
eine Sicherung und lassen sich über einen Reiter „Sicherungen“ wieder
|
||
zurückspielen. Jeder Lauf, der wirklich schreibt, landet unter
|
||
`data/<plugin>/laeufe/<zeit>/` samt einer `manifest.json`, in der Schritt für
|
||
Schritt steht, was geändert wurde und wie der Zustand vorher war.
|
||
|
||
Wie weit ein Lauf zurückgeholt werden kann, hängt vom Eingriff ab und steht
|
||
ehrlich an jedem Lauf:
|
||
|
||
* **🥑 Nährwerte** – *vollständig rückspielbar.* Die alten Werte werden exakt
|
||
zurückgeschrieben. Wurde eine Zutat seither von Hand geändert, wird sie
|
||
erkannt und übersprungen.
|
||
* **🧹 Stammdaten** – *teilweise rückspielbar.* Zusammengeführte und gelöschte
|
||
Einträge werden neu angelegt und die aufgezeichneten Rezeptverweise
|
||
zurückgehängt. Die alte ID ist in Tandoor vergeben und kommt nicht zurück;
|
||
Einkaufslisten, Umrechnungen und Automatisierungen bleiben beim Ziel. Das
|
||
Werkzeug zeichnet dafür vor jedem Zusammenführen alle Rezeptverweise auf.
|
||
|
||
Zurückspielen gibt es immer als Trockenübung zuerst. Jeder Lauf, der schon
|
||
einmal zurückgespielt wurde, ist markiert und muss ausdrücklich bestätigt
|
||
werden.
|