Files
Speisekarte/CHANGELOG.md
T
florian.wilde c986327c1c Version 1.6.0
Verifiziert: RSS-Feed (/feed.xml, gültiges RSS 2.0, korrekte Tages-
Einträge inkl. Essenszeiten/Preisen), Autodiscovery-Link + sichtbares
Icon auf Desktop und Mobile, Vorschläge-Badge (Anzahl offener
Rezeptvorschläge, aktualisiert bei Navigation), keine verbliebenen
Supabase-Erwähnungen in aktiver Doku/Kommentaren.
2026-07-18 12:26:20 +02:00

199 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
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.6.0] – 2026-07-18
### Hinzugefügt
- RSS-Feed des Speiseplans (`/feed.xml`, ein Eintrag pro Tag mit den
Gerichten je Essenszeit für die aktuelle und die nächste Woche) zum
Abonnieren in einem Feedreader. Autodiscovery-Link im Seiten-`<head>`
sowie sichtbares RSS-Icon im Kopfbereich der öffentlichen
Speisekarte.
- Kantinen-Bereich: „Vorschläge“-Navigationspunkt zeigt jetzt die
Anzahl offener Rezeptvorschläge als Zahl im roten Kreis.
- Neues [DEPLOYMENT.md](DEPLOYMENT.md): Schritt-für-Schritt-Anleitung
für die Inbetriebnahme auf einem neuen Server (Docker Compose,
Konfiguration, Reverse-Proxy/HTTPS, Updates, Backup).
### Geändert
- Letzte Erwähnungen von Supabase in aktiven Doku-Texten und
Code-Kommentaren entfernt/umformuliert (README, Migrationsschema,
Passkey-Konfiguration, Branding-Ablage) – die App läuft seit v1.5
vollständig ohne Supabase, das sollte sich jetzt auch durchgängig in
der Dokumentation widerspiegeln. Historische CHANGELOG-Einträge
bleiben unverändert.
- `.env.example`: `LOCAL_PG_PASSWORD` (von `docker-compose.yml`
verwendet, um die Datenbank-Verbindung der App-Container
zusammenzubauen) war bisher nirgends dokumentiert – beim Schreiben
der Deployment-Anleitung aufgefallen und ergänzt.
## [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
`<script>` bei direktem Aufruf der Datei-URL im Browser eines
anderen angemeldeten Admins ausgeführt werden können. Upload
akzeptiert jetzt nur noch eine Whitelist an Rasterformaten
(png/jpg/webp/gif/ico); vor dem Merge im Rahmen der
Sicherheitsprüfung gefunden und behoben.
### Hinweis für bestehende Docker-Installationen
Das Docker-Volume `pgdata` diente bisher nur als Lese-Kopie/Backup und
wird mit v1.5 zur primären Datenbank. Es enthält noch das alte
Supabase-Mirror-Schema und muss vor dem Upgrade entfernt werden
(`docker compose down -v`, danach `docker compose up -d --build`), damit
die neuen Migrationen auf einer leeren Datenbank laufen.
## [1.4.0] – 2026-07-18
### Hinzugefügt
- Essenszeiten (Brotzeit/Mittagessen/…) vollständig verwaltbar: anlegen,
umbenennen (inkl. EN/PL), Uhrzeit ändern, löschen und per Pfeil-Buttons
neu anordnen – neue Seite „Essenszeiten" im Kantinen-Bereich. Löschen
entfernt zugewiesene Gerichte automatisch aus allen Wochenplänen.
### Geändert
- „Automatisch übersetzen"-Button bei Gerichten/Allergenen/Zusatzstoffen
ist nur noch sichtbar, wenn `DEEPL_API_KEY` gesetzt ist, statt erst
nach Klick auf die fehlende Konfiguration hinzuweisen.
### Behoben
- Sprachumschalter (DE/EN/PL) erschien auf der öffentlichen Speisekarte
in der mobilen Ansicht doppelt.
## [1.3.0] – 2026-07-18
### Hinzugefügt
- Mehrsprachigkeit für die komplette Anwendung (Deutsch, Englisch,
Polnisch): Sprachumschalter (Cookie-basiert, kein Neuladen der
Seite nötig), sämtliche Oberflächentexte übersetzt
- Gerichte, Bereiche, Allergene und Zusatzstoffe zusätzlich mit
englischem/polnischem Namen; öffentliche Speisekarte zeigt je nach
gewählter Sprache automatisch den passenden Namen (Fallback:
Deutsch, falls keine Übersetzung hinterlegt ist)
- Automatische Übersetzung per DeepL: Button „Automatisch übersetzen“
beim Anlegen/Bearbeiten von Gerichten, Allergenen und Zusatzstoffen;
Ergebnis bleibt danach manuell korrigierbar. Aktivierung über die
neue Docker-Variable `DEEPL_API_KEY` – ohne Key bleibt der Button
inaktiv, die Felder lassen sich weiterhin von Hand ausfüllen
- Rezeptvorschläge im öffentlichen Bereich: nicht angemeldete
Besucher können über „Rezept vorschlagen“ ein fehlendes Gericht
vorschlagen (Name + optionale Beschreibung), inkl. Dublettenprüfung
gegen bestehende Gerichte und einfachem Honeypot-Spamschutz
- Neue Seite „Vorschläge“ im Kantinen-Bereich: eingereichte Vorschläge
sichten, als Gericht übernehmen oder ablehnen
### Behoben
- Passwort-wiederholen-Feld beim Bearbeiten eines Benutzers erschien
erst, nachdem im ersten Passwortfeld schon getippt wurde – wirkte
wie ein einzelnes Pflichtfeld
- Anmelden-Button überlappte auf Mobilgeräten mit breiten Logos
(Banner-Format) das Logo, da er absolut in der oberen Ecke
positioniert war
## [1.2.0] – 2026-07-18
### Hinzugefügt
- „Heute"-Button in der Wochennavigation (öffentliche Speisekarte und
Wochenplan-Editor)
- Mobile Ansicht der öffentlichen Speisekarte: umschaltbar zwischen
Tag (Standard) und Woche, unabhängig von der Desktop-Tabelle
- Allergene und Zusatzstoffe wieder pro Gericht auswählbar (Chip-Auswahl
im Formular) und als kleine Kürzel neben dem Gerichtnamen sichtbar –
in Speisekarte, mobiler Ansicht und Wochenplan-Editor
- Passwort-Wiederholung beim Anlegen neuer Benutzer und beim optionalen
Passwort-Reset
- Passwort-Anmeldung pro Konto deaktivierbar (nur wenn mindestens ein
Passkey registriert ist), Durchsetzung im Login-Flow
- `SITE_TITLE`-Umgebungsvariable für Browser-Tab-Titel und Überschrift
ohne Logo
- Austauschbares Favicon über den Admin-Design-Bereich
### Geändert
- Gemeinsame Navigation für Kantinen- und Admin-Bereich statt zwei
getrennter Menüs
- Live-Suche bei den Gerichten
- Mehrfachauswahl zum Batch-Löschen von Gerichten
- App erreichbar auf `0.0.0.0` statt nur `localhost` (Docker und
nativer Betrieb)
- Projekt umbenannt von „Speisekarte“ zu „canteen-menu“ (Docker-,
npm- und Supabase-Namen; deutsche In-App-Texte unverändert)
- Öffentliche URL über `APP_URL` konfigurierbar (CSRF-Origin-Check
hinter Reverse-Proxy, Passkey-Domain)
### Behoben
- Next.js band `app/favicon.ico` zusätzlich zu einem dynamisch
gesetzten Favicon ein – Favicon wird jetzt immer explizit gesetzt
- Weiterleitungen (Logout, Zugriffsschutz) übernahmen nach der
0.0.0.0-Bindung fälschlich die Server-Adresse statt des
aufgerufenen Hosts
## [1.1.0] – 2026-07-17
### Hinzugefügt
- Versionsnummer im Fußbereich jeder Seite
## [1.0.0] – 2026-07-17
Erste vollständige Version.
### Hinzugefügt
- Öffentliche Speisekarte ohne Login: Wochenansicht Mo–Fr mit den
Bereichen Brotzeit, Mittagessen, Mittagessen vegetarisch und Suppe;
Wochen-Navigation; Logo zentriert; Allergene & Zusatzstoffe unterhalb
der Karte
- Anmeldung mit E-Mail/Passwort oder Passkey
- Kantinen-Bereich: Gerichte anlegen/bearbeiten/löschen, Wochenplan
pflegen, globale Allergen-/Zusatzstofflisten verwalten
- Admin-Bereich: Benutzerverwaltung, Farbgebung, Logo-Upload
- Eigenes Konto verwalten: Name, E-Mail, Passwort, Passkeys
- Row-Level-Security, HTTP-Security-Header, CSRF-Origin-Check
- Docker-Setup (App-Image, lokale PostgreSQL-Kopie, Dev-Profil ohne
lokales Node.js)
- Lokale PostgreSQL-Kopie mit Sync-Skript