# Speisekarte – Betriebskantine Digitale Speisekarte für eine Firmenkantine (ca. 250 Mitarbeiter) mit öffentlicher Wochenansicht, Kantinen-Bereich zur Pflege der Gerichte und Admin-Bereich für Benutzerverwaltung und Branding. **Stack:** Next.js 16 (App Router, TypeScript, Tailwind CSS) · Supabase (PostgreSQL, Auth inkl. Passkeys, Storage, Row Level Security) ## Funktionen | Bereich | Funktionen | | --- | --- | | Öffentlich (ohne Login) | Wochenplan Mo–Fr mit den Bereichen Brotzeit (09:00–10:00), Mittagessen, Mittagessen vegetarisch und Suppe (je 11:30–13:30); Navigation vorherige/nächste Woche; Logo zentriert über der Karte; Allergene & Zusatzstoffe unterhalb der Karte | | Kantinen-Team (`/intern`) | Gerichte anlegen/bearbeiten/löschen; Gerichte Tagen/Bereichen zuweisen (mehrere pro Zelle) und wieder entfernen; globale Allergen-/Zusatzstofflisten pflegen; eigene Passkeys verwalten | | Admin (`/admin`) | Kantinenmitarbeiter anlegen/bearbeiten/löschen (inkl. Passwort-Reset und Rollenvergabe); Farbgebung der Speisekarte anpassen; Logo hochladen/entfernen | Anmeldung mit E-Mail + Passwort oder alternativ per **Passkey** (Registrierung im Bereich „Passkeys“ nach dem ersten Login). ## Projektstruktur ``` app/ Next.js-Routen page.tsx Öffentliche Speisekarte login/ Login (Passwort + Passkey) intern/ Kantinen-Bereich (Rolle: staff oder admin) admin/ Verwaltung (Rolle: admin) api/admin/users/ Benutzerverwaltung (serverseitig, Service-Role-Key) components/ Client-Komponenten (WeekEditor, DishManager, …) lib/supabase/ Supabase-Clients (Browser / Server / Admin) lib/ Typen, Datums-/Formatierungshelfer proxy.ts Session-Refresh + Schutz von /intern und /admin supabase/migrations/ Schema & Seed-Daten (Referenz/Doku) supabase/local/ Skripte + Dumps für die lokale PostgreSQL-Kopie scripts/ Hilfsskripte (DB-Migration, lokaler Sync) ``` ## Entwicklung Voraussetzung in beiden Varianten: `.env.local` mit den Werten aus `.env.example` (liegt lokal bereits vor und ist per `.gitignore` vom Repo ausgeschlossen). **Variante A – Docker (nichts vorinstallieren außer Docker):** ```bash docker compose --env-file .env.local --profile dev up dev # http://localhost:3000 (Hot-Reload, Quellcode wird gemountet) ``` **Variante B – lokal installiertes Node.js:** ```bash npm install npm run dev # http://localhost:3000 ``` ## Umgebungsvariablen (Live-Betrieb) Beim Webserver/Hoster müssen genau diese drei Variablen hinterlegt werden (Werte: Supabase-Dashboard → Project Settings → API Keys): | Variable | Bedeutung | Geheim? | | --- | --- | --- | | `NEXT_PUBLIC_SUPABASE_URL` | URL des Supabase-Projekts, z. B. `https://hvzikwjoyhoakedlywhj.supabase.co` | nein | | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Öffentlicher anon-Key (RLS schützt die Daten) | nein | | `SUPABASE_SERVICE_ROLE_KEY` | Service-Role-Key für die Benutzerverwaltung | **ja – niemals im Browser/Repo!** | Build & Start auf dem Server – **mit Docker** (empfohlen, Node.js und PostgreSQL müssen nicht installiert sein): ```bash docker compose --env-file .env.local up -d --build # App: Port 3000 (hinter Reverse-Proxy mit HTTPS betreiben) # Lokale DB-Kopie: Port 5432 (Dienst "db", optional) ``` Oder klassisch ohne Docker: ```bash npm ci npm run build npm run start # Port 3000 (hinter Reverse-Proxy betreiben) ``` ### Passkeys für die Produktions-Domain freischalten Passkeys sind an die Domain gebunden. Aktuell ist `localhost` konfiguriert. Vor dem Livegang in der Supabase-Konfiguration (Management API oder Dashboard → Authentication → Settings) anpassen: - `webauthn_rp_id` = `speisekarte.example.de` (die echte Domain, ohne Protokoll) - `webauthn_rp_origins` = `https://speisekarte.example.de` - `passkey_enabled` = `true` (bereits aktiv) ## Datenbank ### Supabase (führende Datenbank) - Projekt-Ref: `hvzikwjoyhoakedlywhj` (Region `eu-central-1`, Frankfurt) - Schema und Seed-Daten: `supabase/migrations/0001_init.sql` und `0002_seed.sql` - Ausführen weiterer SQL-Dateien: `SUPABASE_ACCESS_TOKEN= node scripts/db-apply.mjs ` Sicherheitsmodell (Row Level Security): - `anon` darf ausschließlich lesen (Speisekarte, Bereiche, Allergene, Zusatzstoffe, Einstellungen). - `staff`/`admin` (Rolle im `profiles`-Eintrag) pflegen Gerichte, Wochenplan und Kennzeichnungen. - Nur `admin` ändert Einstellungen (Farben/Logo) und verwaltet Benutzer; das Anlegen/Löschen von Benutzern läuft serverseitig über den Service-Role-Key (`app/api/admin/users`). - Storage-Bucket `branding` (Logo): öffentlich lesbar, Schreibzugriff nur Admin. ### Lokale PostgreSQL-Kopie Die Datenbank `speisekarte` (Kopie von Schema + Daten aus Supabase, inkl. Minimal-Stubs für `auth`/`storage`) gibt es in zwei Varianten: **Per Docker:** Der Dienst `db` aus `docker-compose.yml` spielt die Skripte aus `supabase/local/` beim ersten Start automatisch ein (PostgreSQL 17, Port 5432, Passwort über `LOCAL_PG_PASSWORD`). **Nativ:** Auf dem Entwicklungsrechner läuft PostgreSQL 17 mit derselben Datenbank. Neu aufbauen bzw. aktualisieren: ```powershell $env:SUPABASE_DB_PASSWORD = "" $env:LOCAL_PG_PASSWORD = "" powershell -File scripts\sync-local-db.ps1 ``` Hinweis: Die lokale Kopie dient als Ablage/Backup und für Auswertungen. Logins (Passwort-Hashes, Passkeys) verbleiben ausschließlich in Supabase. ## Zugangsdaten Die Anmeldedaten (Admin, Demo-Mitarbeiter, Datenbank-Passwörter) stehen in `ZUGANGSDATEN.md` – diese Datei ist bewusst **nicht** im Repository (`.gitignore`). Nach dem ersten Login bitte die Startpasswörter ändern.