# Anforderungen – svc-essensplanung > Stand: 13.09.2026 · Status: **Agreed Draft** (noch nicht in Code umgesetzt) Kurzes Mittagessen-Planer-Werkzeug: Gericht anlegen, „fertig/gegessen" abhaken, Reihenfolge anpassen, Wochentage markieren und bei Bedarf aus dem Archiv inspirieren lassen. Ein einzelner Nutzer, läuft im eigenen Homelab, mobil via Browser. ## 1. Kern-Entities ### Gericht (Eintrag) Ein Gericht ist die zentrale Dateneinheit. Felder: | Feld | Typ | Pflicht | Beschreibung | |------|-----|---------|--------------| | `id` | int (PK) | ja | Autogeneriert | | `name` | text | ja | z. B. „Spaghetti Bolognese" | | `notiz` | text | nein | Freie Anmerkung, z. B. „mit mehr Soße" | | `wochentage` | set (Mo–So) | nein | Beliebig viele, optional. **Nur zur Markierung/Gruppierung**, keine Automatik. | | `sort_order` | int | ja | Position in der Planungsliste (manuell per Drag & Drop) | | `status` | enum: `geplant` / `gegessen` | ja | `geplant` = aktiv in der Liste, `gegessen` = abgehakt → Archiv | | `gegessen_am` | date | nein | Setzt sich automatisch, wenn auf `gegessen` gesetzt | | `erstellt_am` | timestamp | ja | | | `aktualisiert_am` | timestamp | ja | | > **Wiederholungen über mehrere Tage** (z. B. Reste Mo+Di) werden **nicht** als > automische Dauer modelliert. Stattdessen decken die `wochentage`-Markierungen und > ggf. mehrere Einträge ab. „Erforderlich, dass jeder Tag abgedeckt ist" gilt **nicht** – > Tage dürfen frei stehen bleiben. ### Archiv - Das Archiv ist **keine eigene Tabelle**: Es ist die Sicht auf Einträge mit `status = gegessen`, geordnet nach `gegessen_am` (neueste zuerst). - Abhaken (`geplant → gegessen`) verschiebt den Eintrag automatisch in die Archivsicht. - Aufheben / „wieder einplanen" (`gegessen → geplant`) setzt `gegessen_am` zurück und fügt ihn der Planungsliste wieder hinzu. ## 2. Features (MVP) ### 2.1 Gericht verwalten - **Anlegen** (name, notiz, wochentage). - **Bearbeiten** (alle Felder). - **Löschen** (hart, mit Bestätigung). - **Reihenfolge ändern**: Drag & Drop in der Planungsliste → persistiert in `sort_order`. ### 2.2 Abhaken / Archiv - Pro Eintrag ein „Abhaken"-Aktion (Checkbox oder Button). - Abhaken: `status → gegessen`, `gegessen_am = heute`, Eintrag verschwindet aus der Planungsliste in die **Archivansicht**. - In der Archivansicht: Eintrag wieder in die Planung zurückstellen oder Löschen. ### 2.3 Inspiration - **Inspiration-Panel**, das **jeweils 5 Vorschläge** aus dem Archiv anzeigt. - Button „Weitere 5" → nächste 5, die noch nicht vorgeschlagen wurden. - **Auswahlkriterium (gewichteter Mix):** 1. **Lange nicht** gekocht (älteste `gegessen_am`) – primär, 2. **Seltene** (wenigste Auftritte insgesamt) – sekundär, 3. **Häufige** (beliebt) – drittens. Genauere Gewichtung bei der Implementierung festlegen (siehe ADR-005, offen). - Jeder Vorschlag hat einen **1-Klick-Button** → übernimmt das Gericht als **neuen `geplant`-Eintrag** in die Planungsliste (Kopie, `gegessen_am` wird leer). ### 2.4 Ansichten - **Planung** (Liste der `geplant`-Einträge, sortiert nach `sort_order`). - **Archiv** (Liste der `gegessen`-Einträge, sortiert nach `gegessen_am` absteigend). - **Inspiration** (Panel / eigener Bereich, siehe 2.3). - Wochentage werden je Eintrag **als Markierung** angezeigt (kein Filter nötig, aber optional als Gruppierung möglich). ## 3. Technische Vorgaben (aus der Diskussion) - **Backend:** PHP / **Symfony 7**, eigene JSON-Controller (keine ApiPlatform-Magie), als **API** nutzbar. - **Frontend:** Serverseitiges Rendering + **htmx** (CRUD + Listen + Formulare). Sortierbarkeit via **SortableJS** (~20 kB). **Kein Build-Step, kein Node im Runtime.** - **Datenbank:** **SQLite** (einfach, leicht zu backupn). - **Mobile:** Responsive + **PWA-Manifest** („Zum Homescreen hinzufügen"). - **Deployment:** Docker-Stack `svc-essensplanung` im Homelab, hängend an das bestehende Traefik-`infra-traefik_traefik-net`; **Domain:** `essen.ljh31.de` (ACME `letsencrypt`). Gleiche Deploy-Muster wie die anderen `svc-*`-Stacks. - **Auth:** Single User → **kein Login**. Optionaler Shared-Token, falls später von elsewhere (z. B. Home-Assistant) genutzt. ### 3.1 Home-Assistant-Integration (Phase 2, optional) - HA holt **„Was steht heute an?"** über dieselbe API. - Ziel: 1 Zeile im HA-Dashboard + ggf. Benachrichtigung „Heute: Bolognese". - Ist ein z**Add-on**, kein Teil des MVP. Siehe ADR-004 (offen, Phase 2). ## 4. Ausdrücklich NICHT im MVP - Mehrere Nutzer / Rechte. - Automatische Wiederholung pro Wochentag (Wochentag ist nur Label). - Einkaufslisten, Kalorien, Portionen-Logik. - Offline-First / lokale Sync (htmx braucht die API). - Export/import (vorerst). ## 5. Offene Punkte (bevor Code) - [x] `menge`: **weggelassen** im MVP (Name + Notiz + Wochentag reicht). - [ ] Soll **Löschen** hart sein oder auch auf archiviert? (vorerst: hart) - [ ] PWA: nur Add-to-Home, oder auch Push (braucht SW + Service-Worker)? - [ ] HA-Integration: konkret als Sensor (REST-Poll) via `rest`-Integration in HA — dazu braucht die API einen sauberen `GET /api/today`-Endpunkt. ## 6. Abnahmekriterien (Definition of Done, MVP) - [ ] Gericht anlegen/bearbeiten/löschen läuft via UI. - [ ] Reihenfolge per Drag & Drop persisted (übersteht Reload). - [ ] Abhaken verschiebt Eintrag in Archiv, Wiederherstellen bringt ihn zurück. - [ ] Inspiration zeigt 5, „Weitere 5" liefert neue 5, 1-Klick übernimmt. - [ ] Läuft auf `essen.ljh31.de` (https, ACME) und ist mobil + add-to-home. - [ ] Daten in SQLite, kein Build-Step im Deployment.