diff --git a/.dockerignore b/.dockerignore index 3bf1d9e..af09176 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,7 +5,7 @@ node_modules .env* !.env.example ZUGANGSDATEN.md -supabase/local +data/branding Dockerfile docker-compose.yml README.md diff --git a/.env.example b/.env.example index 00f35de..a8b1b0a 100644 --- a/.env.example +++ b/.env.example @@ -1,25 +1,23 @@ # Vorlage für .env.local (Entwicklung) bzw. die Umgebungsvariablen # beim Hoster (Live-Betrieb). Echte Werte niemals committen! -# Supabase-Projekt-URL (Dashboard -> Project Settings -> API) -NEXT_PUBLIC_SUPABASE_URL=https://.supabase.co - -# Öffentlicher anon-Key (darf im Browser landen, RLS schützt die Daten) -NEXT_PUBLIC_SUPABASE_ANON_KEY= - -# Service-Role-Key (GEHEIM! Nur serverseitig, für die Benutzerverwaltung) -SUPABASE_SERVICE_ROLE_KEY= +# Verbindung zur (selbst gehosteten) PostgreSQL-Datenbank. +DATABASE_URL=postgres://postgres:@localhost:5432/canteen_menu # Öffentliche URL, unter der die App erreichbar ist (Schema + Domain). # Wird für den CSRF-Origin-Check hinter Reverse-Proxies genutzt und ist -# zugleich die Passkey-Domain: nach einer Änderung einmalig -# SUPABASE_ACCESS_TOKEN= node scripts/configure-passkeys.mjs -# ausführen, damit Passkeys auf der neuen Domain funktionieren. +# zugleich die Passkey-Domain (RP-ID/Origin werden direkt daraus +# abgeleitet, kein separater Konfigurationsschritt nötig). APP_URL=http://localhost:3000 # Titel im Browser-Tab und Überschrift, solange kein Logo hochgeladen ist. SITE_TITLE=Canteen Menu +# Optional: E-Mail-Adresse für den automatisch angelegten Admin-Erstnutzer +# (nur relevant, solange die users-Tabelle noch leer ist). Ohne Angabe +# wird admin@ verwendet. +ADMIN_EMAIL= + # Optional: DeepL-API-Key für automatische Übersetzung von Gerichten nach # Englisch/Polnisch (kostenloser Free-Tier unter deepl.com/de/pro-api, # Free-Keys enden auf ":fx"). Ohne Key bleibt "Automatisch übersetzen" diff --git a/CHANGELOG.md b/CHANGELOG.md index 005ebb5..3b79f83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,65 @@ Alle nennenswerten Änderungen an diesem Projekt werden hier dokumentiert. Format angelehnt an [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), Versionierung nach [Semantic Versioning](https://semver.org/lang/de/). +## [1.5.0] – 2026-07-18 + +### Hinzugefügt +- Wochenplan: „Mahlzeit hinzufügen" bietet jetzt ein Suchfeld mit + gefilterter Trefferliste statt einer langen Dropdown-Liste zum + Durchscrollen. +- `db/seed-demo.sql` (`npm run db:seed-demo`): spielt für lokale + Entwicklung/Demos den ursprünglichen Beispieldatensatz ein + (Essenszeiten, Allergene, Zusatzstoffe, Testgerichte, zwei + Beispielwochen) – kein Teil der automatischen Migrationen, frische + Deployments starten weiterhin leer. + +### Geändert +- **Supabase vollständig entfernt** – die App läuft jetzt komplett + selbst gehostet, einzige externe Abhängigkeit bleibt optional DeepL. + - Datenbank: selbst gehostetes PostgreSQL statt Supabase-Cloud-Postgres. + Schema in `db/migrations/*.sql`, wird beim Start automatisch und + idempotent angewendet (`db/migrate.mjs`). + - Anmeldung: eigene Session-Verwaltung (opake, in der DB gespeicherte + Tokens, `httpOnly`/`sameSite=lax`-Cookie) statt Supabase Auth. + Passwörter werden mit Node-eigenem `crypto.scrypt` gehasht (keine + neue Abhängigkeit). + - Passkeys: `@simplewebauthn` ersetzt Supabase's bisher experimentelles + WebAuthn-API. Die RP-Domain wird direkt aus `APP_URL` abgeleitet – + kein externer Konfigurationsschritt mehr nötig. + - Logo/Favicon: lokale Dateiablage (Docker-Volume) statt + Supabase-Storage-Bucket, ausgeliefert über `/branding/[filename]`. + - Autorisierung (öffentlich lesbar / Kantinen-Team schreibt / nur + Admin für Einstellungen & Benutzer) läuft jetzt in den API-Routen + statt über Postgres-Row-Level-Security. + - E-Mail-Änderung im eigenen Konto läuft direkt nach + Passwort-Bestätigung statt über eine Supabase-Bestätigungsmail + (kein SMTP-Server vorhanden). +- Datenbank startet beim allerersten Deployment leer; beim ersten Start + wird automatisch genau ein Admin-Benutzer mit zufällig generiertem + Passwort angelegt, die Zugangsdaten landen in `ZUGANGSDATEN.md`. + +### Behoben +- „Mindestens 1 Passkey nötig, um die Passwort-Anmeldung zu + deaktivieren" wurde bisher nur clientseitig geprüft; ein manuell + gebauter Request hätte die Passwort-Anmeldung auch ohne Passkey + deaktivieren können. Jetzt zusätzlich serverseitig erzwungen. +- Logo-/Favicon-Upload akzeptierte anhand des vom Browser gemeldeten + Dateityps auch SVG-Dateien. Da diese (anders als beim vorherigen + Supabase-Storage-Bucket auf fremder Domain) jetzt auf der eigenen + Origin ausgeliefert werden, hätte eine SVG mit eingebettetem + `