Files
mealplanner/docs/superpowers/specs/2026-04-14-mealplanner-design.md
Claude 660bcd1953 docs: add mealplanner design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:02:05 +00:00

7.2 KiB
Raw Blame History

Mealplanner — Design Spec

Datum: 2026-04-14 Domain: essen.kuns.dev Repo: kuns/mealplanner

Zusammenfassung

Webapp zur Wochenplanung von Mahlzeiten. Generiert automatisch einen Wochenplan (7 Tage, je 1 Hauptmahlzeit), der bearbeitbar ist. Aus dem Plan wird eine intelligente Einkaufsliste generiert (Zutaten zusammengefasst, abhakbar). Rezepte kommen aus einer externen API + eigene Rezepte.

Anforderungen

  • Haushalt: Feste Personenzahl in Einstellungen (Standard: 2)
  • Mahlzeiten: 1 pro Tag (Abendessen)
  • Wochenplan: Auto-generiert, voll editierbar (Gericht austauschen, neu generieren)
  • Rezepte: Externe DB (TheMealDB, kostenlos, kein API-Key nötig) + eigene Rezepte
  • Einkaufsliste: Zutaten aggregiert, nach Kategorie gruppiert, abhakbar
  • Ernährungspräferenzen: Keine
  • Auth: Zitadel (manueller OIDC PKCE Flow, kein oidc-client-ts)

Architektur

Vue 3 SPA (Tailwind 4, Bun, Vite)
       ↓ REST API (/api/*)
.NET 8 Web API
  ├── Auth (Zitadel JWT Bearer + NuGet-Paket)
  ├── RecipeService (TheMealDB Client + eigene Rezepte CRUD)
  ├── MealPlanService (Generierung + CRUD)
  └── ShoppingListService (Aggregation aus Wochenplan)
       ↓
Shared PostgreSQL (DB: mealplanner)

Projektstruktur

mealplanner/
├── backend/
│   ├── Controllers/
│   │   ├── RecipeController.cs
│   │   ├── MealPlanController.cs
│   │   ├── ShoppingListController.cs
│   │   └── SettingsController.cs
│   ├── Models/
│   │   ├── Recipe.cs
│   │   ├── MealPlan.cs
│   │   ├── MealPlanEntry.cs
│   │   ├── ShoppingItem.cs
│   │   └── UserSettings.cs
│   ├── Services/
│   │   ├── TheMealDbClient.cs
│   │   ├── RecipeService.cs
│   │   ├── MealPlanService.cs
│   │   └── ShoppingListService.cs
│   ├── Data/
│   │   └── AppDbContext.cs
│   ├── Program.cs
│   └── backend.csproj
├── frontend/
│   ├── src/
│   │   ├── views/
│   │   │   ├── WeekPlanView.vue      (Hauptansicht)
│   │   │   ├── ShoppingListView.vue
│   │   │   ├── RecipesView.vue        (Eigene Rezepte verwalten)
│   │   │   └── SettingsView.vue
│   │   ├── components/
│   │   │   ├── MealCard.vue
│   │   │   ├── RecipeDetail.vue
│   │   │   ├── ShoppingItem.vue
│   │   │   └── WeekDay.vue
│   │   ├── composables/
│   │   │   └── useApi.ts
│   │   ├── auth.ts                    (Manueller OIDC PKCE Flow)
│   │   ├── router.ts
│   │   ├── App.vue
│   │   └── main.ts
│   ├── index.html
│   └── package.json
├── Dockerfile
├── docker-compose.yml
└── docs/

Datenmodell

Recipe

Feld Typ Beschreibung
id UUID PK
user_id string Zitadel User ID (null = extern)
external_id string? TheMealDB ID
title string Name des Gerichts
instructions text Zubereitungsanleitung
image_url string? Bild-URL
source enum own, themealdb
created_at timestamp

RecipeIngredient

Feld Typ Beschreibung
id UUID PK
recipe_id UUID FK → Recipe
name string Zutat
amount decimal? Menge
unit string? Einheit (g, ml, Stück, etc.)
category string? Gemüse, Fleisch, Milch, etc.

MealPlan

Feld Typ Beschreibung
id UUID PK
user_id string Zitadel User ID
week_start date Montag der Woche
created_at timestamp

MealPlanEntry

Feld Typ Beschreibung
id UUID PK
meal_plan_id UUID FK → MealPlan
date date Tag
recipe_id UUID FK → Recipe

UserSettings

Feld Typ Beschreibung
user_id string PK, Zitadel User ID
household_size int Anzahl Personen (Default: 2)

API Endpoints

Wochenplan

  • POST /api/mealplan/generate — Neuen Wochenplan generieren (ab nächstem Montag)
  • GET /api/mealplan/current — Aktuellen Wochenplan laden
  • GET /api/mealplan/{weekStart} — Plan für bestimmte Woche
  • PUT /api/mealplan/{id}/entry/{date} — Gericht für einen Tag austauschen
  • POST /api/mealplan/{id}/entry/{date}/reroll — Neues zufälliges Gericht für Tag

Rezepte

  • GET /api/recipes — Eigene Rezepte auflisten
  • GET /api/recipes/{id} — Rezeptdetails
  • POST /api/recipes — Eigenes Rezept anlegen
  • PUT /api/recipes/{id} — Eigenes Rezept bearbeiten
  • DELETE /api/recipes/{id} — Eigenes Rezept löschen
  • GET /api/recipes/search?q= — Suche (eigene + TheMealDB)

Einkaufsliste

  • GET /api/shoppinglist/{mealPlanId} — Aggregierte Einkaufsliste für Wochenplan
  • PUT /api/shoppinglist/{mealPlanId}/check/{itemId} — Item abhaken/enthaken

Einstellungen

  • GET /api/settings — User-Einstellungen laden
  • PUT /api/settings — User-Einstellungen speichern

Wochenplan-Generierung

  1. Alle verfügbaren Rezepte sammeln (eigene + TheMealDB Random)
  2. 7 zufällige, unterschiedliche Gerichte auswählen
  3. Montag bis Sonntag zuweisen
  4. In DB speichern

Reroll: Einzelnes Gericht durch neues zufälliges ersetzen (nicht doppelt im Plan).

Einkaufslisten-Logik

  1. Alle Rezepte des Wochenplans laden
  2. Zutaten sammeln, gleiche Zutaten zusammenfassen (Name-Match, Mengen addieren)
  3. Mengen × Haushaltsgröße skalieren
  4. Nach Kategorie gruppieren (Gemüse, Fleisch, Milchprodukte, Gewürze, Sonstiges)
  5. Check-Status pro User in DB persistieren

Frontend Design

Theme: Dark Mode (wie task-scheduler-v2)

  • Hintergrund: zinc-950 (#09090b)
  • Cards: zinc-900 (#18181b)
  • Borders: zinc-800 (#27272a)
  • Primary Text: zinc-100 (#f5f5f5)
  • Secondary Text: zinc-500 (#71717a)
  • Accent: emerald (#10b981)
  • Accent Hover: #059669

Hauptansichten

  1. Wochenplan (Startseite) — 7 Cards (Mo-So), je mit Gerichtname + Bild. Buttons: "Austauschen" (Rezeptsuche), "Neu würfeln" (Random). Button oben: "Neue Woche generieren".
  2. Einkaufsliste — Gruppiert nach Kategorie, Checkboxen zum Abhaken. Badge mit Anzahl offener Items.
  3. Rezepte — Eigene Rezepte CRUD. Karten-Ansicht. Formular zum Anlegen/Bearbeiten mit dynamischer Zutatenliste.
  4. Einstellungen — Haushaltsgröße anpassen.

Navigation

Sidebar oder Bottom-Nav mit 4 Tabs: Wochenplan, Einkaufsliste, Rezepte, Einstellungen.

Deployment

  • Coolify via Git Push (wie alle anderen Projekte)
  • Dockerfile: Multi-stage (Bun Frontend Build → .NET Publish → Runtime)
  • DB: mealplanner auf Shared PostgreSQL
  • Domain: essen.kuns.dev
  • Env-Vars in Coolify: DATABASE_URL, ZITADEL_ISSUER, ZITADEL_CLIENT_ID

Externe Abhängigkeiten

  • TheMealDB API (www.themealdb.com/api/json/v1/1/) — kostenlos, kein Key nötig
    • random.php — Zufälliges Rezept
    • search.php?s= — Suche
    • lookup.php?i= — Details per ID
  • Rezepte auf Englisch — akzeptabel für MVP