Commit Graph

25 Commits

Author SHA1 Message Date
ulsklyc 152246185e a11y: Touch-Target System mit Token-basierter Sizing (Redesign Phase E)
- Neue Tokens: --target-sm (32px), --target-md (40px), --target-lg (48px)
- Globale min-height:44px Regel aus reset.css entfernt
- Alle 28 min-height:unset Overrides eliminiert
- Strategy A: Buttons, Nav-Items, Inputs → 48px mobile, 40px desktop
- Strategy B: Kleine Elemente (Checkboxen, Swatches, Delete-Buttons)
  → ::before Pseudo-Element expandiert Touch-Area auf 48×48px

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:43:12 +01:00
ulsklyc 73cd322a71 a11y: Skip-Link für Keyboard-Navigation (Redesign Phase D)
- Skip-Link "Zum Inhalt springen" als erstes Element im App-Shell
- .sr-only:focus-visible CSS: sichtbar bei Tab-Focus, fixed top-left

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:37:07 +01:00
ulsklyc c796d3ad6f feat: migrate remaining 5 modules to shared modal system
Migrate budget, contacts, notes, meals, calendar to use the shared
openModal/closeModal from components/modal.js. Each module now gets
focus-trap, escape-handler, overlay-click, focus-restore, scroll-lock.

Removed ~460 lines of duplicate modal CSS (.budget-modal-overlay,
.contact-modal-overlay, .note-modal-overlay, .meal-modal-overlay,
.event-modal-overlay and their children). Content-specific styles
(color-picker, autocomplete, ingredient-list, etc.) are preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:22:21 +01:00
ulsklyc 7e718e2422 feat: shared modal system + migrate tasks module
- Add public/components/modal.js with focus-trap, escape-handler,
  overlay-click, focus-restore, scroll-lock, aria-modal (Spec §5.1/§5.2)
- Migrate tasks.js from custom modal to shared openModal/closeModal API
- Remove .modal-backdrop/.modal/.modal__* styles from tasks.css
- Add .modal-panel--sm/--lg sizing variants to layout.css

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:04:57 +01:00
ulsklyc b51177b5e3 fix: WCAG AA color compliance (Redesign Phase A)
- Accent colors: #3478F6 → #2563EB (5.17:1), dark mode → #60A5FA
- Semantic colors: success #15803D, warning #B45309, danger #DC2626
- Text tertiary: #737370 (4.76:1), dark #A3A3A0
- Module calendar dark: #A78BFA (5.28:1)
- Greeting gradient: #1D4ED8 → #2563EB (both ≥ 4.5:1)
- Theme-color harmonized to #2563EB across meta/manifest/tokens
- --text-2xs: 0.625rem → 0.6875rem (11px)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 11:58:00 +01:00
ulsklyc e19df38e89 fix: Notizen-Leerstate zentrieren + FAB auf Desktop und Mobile einheitlich
- notes-empty: column-span:all für korrekte Zentrierung im Multicolumn-Layout
- Inline-Style grid-column entfernt (wirkte nicht bei CSS columns)
- FAB jetzt auch auf Desktop sichtbar (48px, unten rechts)
- Toolbar-"Neu"-Buttons auf allen Breakpoints versteckt — FAB ist einziger
  Erstellen-Button, kein Design-Bruch mehr zwischen Mobile und Desktop
- Service Worker Cache v15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 08:02:11 +01:00
ulsklyc b115b644c7 feat: FAB (Floating Action Button) auf allen Unterseiten für Mobile
- Einheitlicher blauer Plus-Button unten rechts auf Mobile (tasks, calendar,
  notes, contacts, budget) — konsistent mit Dashboard-FAB
- Toolbar-"Neu"-Buttons auf Mobile versteckt, auf Desktop weiterhin sichtbar
- Wiederverwendbare .page-fab CSS-Klasse in layout.css
- Dashboard-FAB Position an neue Nav-Höhe angepasst
- Service Worker Cache v13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:09:15 +01:00
ulsklyc a2adb2b94c feat: Mobile Bottom-Navigation mit Swipe und Dot-Indikator
- Alle 9 Menüpunkte jetzt auf Mobile erreichbar (2 Seiten)
- Horizontaler Scroll-Snap für seitenweises Swipen
- Dezente Dot-Indikatoren zeigen aktive Seite an
- Automatischer Scroll zur richtigen Seite bei Navigation zu Seite-2-Items
- Service Worker Cache v12

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:02:17 +01:00
ulsklyc f507ef8488 feat: Dark Mode Toggle + RRULE UI für wiederkehrende Aufgaben/Termine
Dark Mode: Manueller Theme-Switch (System/Hell/Dunkel) in Einstellungen
mit localStorage-Persistenz und Flash-Prevention via data-theme Attribut.

RRULE UI: Wiederholungs-Formular in Aufgaben- und Kalender-Modals mit
Frequenz (Täglich/Wöchentlich/Monatlich), Intervall, Wochentag-Auswahl
und optionalem Enddatum. Backend-Routen für is_recurring/recurrence_rule
in POST/PUT erweitert. Repeat-Icon auf wiederkehrenden Einträgen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 00:11:45 +01:00
ulsklyc 76165da592 design: Frontend-Redesign v2 — Design-System, kompaktere UI, Mikrointeraktionen
Umfassendes Redesign des gesamten Frontends in 9 Schritten:

1. Design-Tokens: Neutral-Farbskala (50–950), Modul-Akzentfarben,
   --text-2xs Token, Easing-Kurven, Z-Index-System, Dark-Mode-Overrides
2. Reset: Reduced-motion Query (prefers-reduced-motion)
3. Sidebar/Navigation: Flaches Design, Glassmorphismus Bottom-Nav,
   Akzentstreifen-Indikator, collapsed/expanded States
4. Layout-Grid: Master-Detail, Content-Aside, Sticky-Header-Primitives
5. Cards/Container: Einheitliches Card-Pattern, Modal-System (Bottom-Sheet
   mobil, zentriert Desktop), Skeleton-Loading, Empty-States
6. Dashboard: Kompaktere Widgets, Token-basierte Farben/Schatten,
   4-Spalten-Grid ab 1440px
7. Module: Mobile-first Kanban/Day-Slots/Budget-Summary, border-subtle
   für sekundäre Trennlinien, responsive Quick-Add, Token-Migration
   aller hardcoded px/rgba-Werte
8. Mikrointeraktionen: Page-out Fade, Checkbox-Pop-Animation,
   Hover-States für Filter/Tabs/Toggles, Toast-Ausblendung,
   done-State Opacity-Transition
9. Feinschliff: Print-Styles, --text-2xs Token für Micro-Labels,
   Konsistenz-Audit (alle 9/10/11px → Token)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:46:45 +01:00
ulsklyc 1bea4f1428 fix: Sidebar-Menüpunkte kompakter + Tiefeneffekte stark reduziert
- padding 6px statt space-3/space-2, min-height entfernt
- Hover: box-shadow 2px statt 4px (kaum sichtbar, subtil)
- Aktiv: inset 1px statt 3px (ganz leicht gedrückt)
- border-radius xs statt sm (weniger klobig)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 14:27:10 +01:00
ulsklyc a189e4be8d feat: Sidebar Neumorphismus-Redesign + responsives Kollabieren
- 1024–1279px: Icon-only Sidebar (64px), Logo als Akzent-Icon
- ≥ 1280px: Sidebar mit Labels (200px), Logo Gradient-Text
- Neumorphischer Hintergrund (--sidebar-bg), eigene Light/Dark-Schatten-Tokens
- Hover: raised box-shadow (konvex gehoben)
- Aktiv: inset box-shadow (konkav gedrückt) + Akzentstreifen links
- Sidebar-Schatten statt Border-right für Tiefentrennung
- Smooth transition bei Breakpoint-Wechsel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 14:20:29 +01:00
ulsklyc 60ecc1f3d9 feat: Dashboard-Widgets mit dynamischen Daten und neuem Design
- Begrüßungs-Widget mit Stats-Chips (dringende Aufgaben, heutige Termine, Mittagessen)
- Aufgaben- und Termine-Widgets mit Count-Badge im Header
- Essen-Widget als 4-Slot-Raster (Frühstück/Mittagessen/Abendessen/Snack) mit Lucide-Icons
- Notizen als Kachel-Grid statt Liste
- event-time-badge, widget__badge, greeting-chip, meal-slots, notes-grid-widget CSS
- Hover-Lift-Effekt auf Widgets (Desktop)
- Widget-Empty-States mit zentrierten Icons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 13:18:42 +01:00
ulsklyc 55a0371505 design: Desktop-UI modernisieren (Sidebar, Typografie, Shadows, Buttons)
- Sidebar: Logo mit Gradient, kompaktere Nav-Items (40px statt 44px),
  kleinere Icons (18px), 2px Gap, bessere Hover/Active-Zustände
- tokens.css: feinere Schatten, Inter im Font-Stack, Sidebar-Breite 256px
- layout.css: Desktop-Content mehr Luft (40px padding), Headings mit
  letter-spacing, Primary-Buttons mit subtiler Elevation
- router.js: Logo-Span für CSS-Gradient-Clip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 13:12:29 +01:00
ulsklyc 647348c2e7 fix: Lighthouse Accessibility 88 → 100, robots.txt hinzufügen
- Farbkontrast: --color-text-secondary #8E8E93 → #6C6C70 (5.2:1, WCAG AA)
- Farbkontrast Dark Mode: secondary → #AEAEB2 (4.6:1 auf #2C2C2E)
- Farbkontrast: --color-btn-primary #007AFF → #0066DB (5.0:1 für Buttons)
- Login-Seite: <main> als äußerstes Element für Landmark-Erkennung
- robots.txt: gültige Datei für self-hosted private App (Disallow: /)
- .gitignore: public/robots.txt explizit ausgenommen

Lighthouse-Ergebnis:
  Performance: 98  Accessibility: 100  Best Practices: 92  SEO: 63*
  *SEO blockiert absichtlich (private self-hosted App, kein öffentlicher Zugang)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 08:10:55 +01:00
ulsklyc 72d6d5126e feat: Schritte 14–15 — Google Calendar OAuth + Apple CalDAV Sync + Settings-Seite
- server/services/google-calendar.js: OAuth 2.0, bidirektionaler Sync via
  Google Calendar API v3, inkrementeller syncToken, 410-Fallback auf Vollsync
- server/services/apple-calendar.js: CalDAV via tsdav (dynamic ESM import),
  minimaler ICS-Parser + ICS-Builder, bidirektionaler Sync
- server/routes/calendar.js: 7 neue Sync-Routen (google/auth, google/callback,
  google/sync, google/status, google/disconnect, apple/status, apple/sync)
- server/db.js: Migration 2 — sync_config Tabelle + idx_calendar_external_id
- server/db-schema-test.js: MIGRATIONS_SQL[2] für Tests synchronisiert
- server/auth.js: PATCH /me/password Endpoint
- server/index.js: Auto-Sync-Scheduler (setInterval, SYNC_INTERVAL_MINUTES)
- public/pages/settings.js: vollständige Settings-Seite (Konto, Passwort,
  Kalender-Sync-Status + Aktionen, Familienmitglieder-Verwaltung)
- public/styles/settings.css: neue Stylesheet-Datei
- public/index.html + public/sw.js: settings.css eingebunden und gecacht
- .env.example: SYNC_INTERVAL_MINUTES ergänzt
- README.md: vollständige Setup-Anleitung, Google/Apple-Sync-Dokumentation,
  modernes GitHub-Layout mit Badges und aufklappbaren Abschnitten

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 22:53:44 +01:00
ulsklyc 3903df6445 feat: Swipe-Gesten für Task-Listenansicht (Mobil)
Swipe links = Status-Toggle (offen ↔ erledigt), Swipe rechts = Bearbeiten-Modal.

- renderSwipeRow(): Wrapper mit zwei Reveal-Panels hinter jeder Karte
- wireSwipeGestures(): Scroll/Swipe-Erkennung via Touch-Events
  · SWIPE_THRESHOLD = 80px für Aktion, frühe Scroll-Erkennung ab 12px vertikal
  · Dämpfung nach Threshold (elastischer Überschuss)
  · Reveal-Panels blenden proportional ein (0 → 1 über Threshold-Weg)
  · Haptic Feedback via navigator.vibrate (40ms links, 20ms rechts)
- tasks.css: .swipe-row, .swipe-reveal--done/--edit, .swipe-row--swiping

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:52:15 +01:00
ulsklyc 450ae37f42 feat: Phase 4 — Wetter-Widget, Wiederkehrende Aufgaben, Kanban-Ansicht, PWA
- server/routes/weather.js: OpenWeatherMap-Proxy (aktuelles Wetter + 3-Tage-Forecast,
  30-min-Cache, graceful fallback wenn kein API-Key gesetzt)
- public/pages/dashboard.js: Weather-Widget parallel mit Dashboard-Daten laden
- public/styles/dashboard.css: Weather-Widget-Styles (Gradient, Forecast-Strip)
- server/services/recurrence.js: RRULE-Parser (FREQ=DAILY/WEEKLY/MONTHLY, BYDAY,
  INTERVAL, UNTIL) + nextOccurrence()-Funktion
- server/routes/tasks.js: Bei PATCH /:id/status = done → nächste Instanz
  wiederkehrender Aufgaben automatisch anlegen
- public/pages/tasks.js: Kanban-Ansicht (3 Spalten: Offen/In Bearbeitung/Erledigt)
  mit HTML5 Drag & Drop, View-Toggle (Liste/Kanban)
- public/styles/tasks.css: Kanban-Board-Styles (Spalten, Cards, Drag-over-Highlight)
- public/sw.js: Cache-Version auf v2, alle Modul-CSS-Dateien im APP_SHELL-Cache

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:32:22 +01:00
ulsklyc 74b6e5f078 feat: Phase 3 Schritte 16–18 — Pinnwand, Kontakte, Budget-Tracker
Pinnwand (Notes):
- server/routes/notes.js: GET (sortiert: angeheftet zuerst), POST, PUT, PATCH /pin, DELETE
- public/pages/notes.js: Masonry-Grid, Markdown-Light-Renderer (fett/kursiv/Liste),
  Farb-Auswahl (8 Farben), helle/dunkle Textfarbe je nach Hintergrund, Pin-Toggle
- public/styles/notes.css: Masonry-Layout, Sticky-Note-Karten, Hover-Aktionen

Kontakte:
- server/routes/contacts.js: GET (Kategorie- + Volltextfilter), POST, PUT, DELETE, GET /meta
- public/pages/contacts.js: Kategorie-Filter-Chips, Echtzeit-Suche, Gruppenansicht,
  tel:/mailto:/maps-Links, CRUD-Modal
- public/styles/contacts.css: Toolbar mit Suche, Filter-Chips, Kontaktliste, Aktions-Buttons

Budget-Tracker:
- server/routes/budget.js: GET (Monatfilter), GET /summary (Einnahmen/Ausgaben/Saldo +
  Aufschlüsselung), GET /export (CSV mit BOM), POST, PUT, DELETE, GET /meta
- public/pages/budget.js: Monatsnavigation, 3 Zusammenfassungs-Karten, Kategorie-Balken
  (reines CSS, kein Canvas), Transaktionsliste, Einnahme/Ausgabe-Toggle, CSV-Download
- public/styles/budget.css: Summary-Cards, Balkendiagramm, Transaktionsliste, Modal

Tests: 34 neue Tests (10 Notes + 9 Contacts + 15 Budget), gesamt 146/146

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:24:08 +01:00
ulsklyc 43e7ed55a9 feat: Phase 3 Schritt 13 — Kalender-Modul (Monats-/Wochen-/Tages-/Agenda-Ansicht)
- server/routes/calendar.js: vollständige REST-API (GET Bereich, GET /upcoming,
  GET /:id, POST, PUT /:id, DELETE /:id) mit Datumsbereichs-Filter,
  assigned_to/source-Filter, external_source-Constraint
- public/pages/calendar.js: Monatsansicht (42-Tage-Raster), Wochenansicht
  (Stunden-Timeline, ganztägige Zeile, Jetzt-Linie), Tagesansicht, Agenda-Ansicht
  (30-Tage-Liste); Termin-Popup bei Klick; volles CRUD-Modal (Farb-Auswahl,
  Ganztägig-Toggle, Zuweisung an Familienmitglied)
- public/styles/calendar.css: Toolbar, Monatsraster, Wochen-/Tages-Spalten,
  Termin-Karten, Popup, Modal, Ganztags-Zeile
- test-calendar.js: 19 Tests (CRUD, Datumsbereich, mehrtägige Termine, Constraints,
  Index-Checks, Datumshelfer)
- package.json: test:calendar + Gesamt-Test-Suite erweitert
- public/index.html: calendar.css eingebunden

Gesamt: 112 Tests bestanden (29+8+17+17+22+19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:14:39 +01:00
ulsklyc c344d59d5a feat: Phase 2 Schritt 11+12 — Essensplan-Modul + Einkaufslisten-Integration
- server/routes/meals.js: vollständige REST-API (GET Woche, POST/PUT/DELETE Mahlzeit,
  POST/PATCH/DELETE Zutaten, GET Autocomplete-Suggestions, POST to-shopping-list,
  POST week-to-shopping-list)
- public/pages/meals.js: Wochengitter (Mo–So × 4 Mahlzeit-Typen), Navigations-Buttons,
  CRUD-Modal mit Autocomplete, Zutaten-Verwaltung, Einkaufslisten-Transfer-Button
- public/styles/meals.css: Wochengitter, Slot-Karten, Modal-Overlay, Zutaten-Zeilen,
  Transfer-Panel, Typ-Farben
- test-meals.js: 22 Tests (CRUD, Wochensortierung, Constraint, CASCADE, Integration,
  Autocomplete, Wochenberechnung)
- package.json: test:meals + Gesamt-Test-Suite erweitert
- public/index.html: meals.css eingebunden

Gesamt: 93 Tests bestanden (29 DB + 8 Dashboard + 17 Tasks + 17 Shopping + 22 Meals)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 20:28:19 +01:00
ulsklyc 2ab250cc35 feat: Phase 2 Schritt 10 — Einkaufslisten-Modul
Backend:
- GET /shopping — alle Listen mit item_total/item_checked Zähler
- POST/PUT/DELETE /shopping/:listId — Listen-CRUD
- GET /shopping/:listId/items — Artikel nach Supermarkt-Gang sortiert
  (Obst→Backwaren→Milch→Fleisch→Tiefkühl→Getränke→Haushalt→Drogerie→Sonstiges)
  Abgehakte innerhalb der Kategorie ans Ende
- POST /shopping/:listId/items — Artikel hinzufügen
- PATCH /shopping/items/:id — Artikel aktualisieren (abhaken, umbenennen)
- DELETE /shopping/items/:id — Einzelartikel löschen
- DELETE /shopping/:listId/items/checked — nur abgehakte löschen
- GET /shopping/suggestions?q= — Autocomplete aus bisherigen Einträgen

Frontend:
- Multi-Listen-Tabs (horizontal scrollbar, Artikel-Zähler im Tab)
- Quick-Add: Name + Menge + Kategorie-Dropdown in einer Zeile
- Autocomplete-Dropdown mit Tastaturnavigation (↑↓ Enter Escape)
- Optimistisches Toggle: Checkbox reagiert sofort, Rollback bei Fehler
- "Abgehakt löschen"-Button erscheint dynamisch bei checked > 0
- Listen umbenennen/löschen direkt im Header
- Kategorie-Icons (Lucide) in Gruppen-Überschriften

Tests: 17/17 bestanden (71 gesamt)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 18:10:01 +01:00
ulsklyc 433124790f feat: Phase 2 Schritt 9 — Aufgaben-Modul (CRUD + Listenansicht + Subtasks)
Backend:
- GET /tasks mit Filtern (status, priority, assigned_to, category)
- GET /tasks/:id mit Subtasks
- POST /tasks mit Tiefenlimit (max. 2 Ebenen)
- PUT /tasks/:id, PATCH /tasks/:id/status, DELETE /tasks/:id
- GET /tasks/meta/options für Dropdown-Daten
- Sortierung: Priorität → Fälligkeit, done-Tasks ans Ende

Frontend:
- Listenansicht gruppiert nach Kategorie oder Fälligkeit (umschaltbar)
- Filter-Chips: Status, Priorität, Person (horizontal scrollbar)
- Task-Card: Prioritäts-Badge, Fälligkeitsdatum, Avatar, Edit-Button
- Status-Toggle per Checkbox (open ↔ done)
- Subtask-Fortschrittsbalken + ein-/ausklappbare Subtask-Liste
- Subtask inline abhaken oder neu erstellen
- Overdue-Badge in der Navigation
- CRUD-Modal: Titel, Beschreibung, Priorität, Kategorie, Datum, Zuweisung
- Skeleton-Loading während API-Call

Tests: 17/17 bestanden (54 gesamt)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 18:02:59 +01:00
ulsklyc 6d8763bbb9 feat: Phase 2 Schritt 8 — Dashboard mit allen Widgets
- Aggregierter GET /api/v1/dashboard Endpoint (1 Request für alle Widgets)
- Widget: Begrüßung mit tageszeit-abhängigem Text + aktuellem Datum
- Widget: Dringende Aufgaben (priority high/urgent, fällig ≤ 48h, nicht done)
- Widget: Anstehende Termine (nächste 5, mit Avatar-Farbe)
- Widget: Heutiges Essen (nach Mahlzeit-Typ sortiert)
- Widget: Angepinnte Notizen (max. 3, mit Notizfarbe)
- Skeleton-Loading-States während API-Call (keine Spinner)
- FAB Speed-Dial: + Aufgabe, + Termin, + Einkauf, + Notiz
- Responsives 1/2/3-Spalten-Grid (Mobil / Tablet / Desktop)
- Dashboard-Tests: 8/8 bestanden (node:sqlite)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 14:42:08 +01:00
ulsklyc d49cbe33b3 feat: Phase 1 — Projektstruktur, DB-Schema, Auth-System
- Vollständige Verzeichnisstruktur gemäß CLAUDE.md
- Express-Server mit Helmet, Sessions, Rate Limiting, SPA-Fallback
- SQLite-Schema (Migration v1): 10 Tabellen, updated_at-Triggers, Indizes
- Versioniertes Migrations-System (schema_migrations)
- Auth-Routen: Login, Logout, /me, Admin-User-CRUD
- Frontend App-Shell: SPA-Router, API-Client, Design-System (CSS Tokens)
- PWA: Service Worker, Web App Manifest
- Setup-Script für ersten Admin-User (node setup.js)
- DB-Tests mit node:sqlite built-in: 29/29 bestanden
- Docker Compose + Dockerfile + Nginx-Beispielkonfiguration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 14:32:36 +01:00