Ulas
6bc4c46f03
fix(security): eliminate XSS vectors and restore zoom accessibility
...
- Extract shared esc() utility (public/utils/html.js) replacing 8
duplicate escHtml() functions across all page modules
- Apply HTML escaping to all user-controlled data in innerHTML
templates: titles, names, locations, descriptions, colors, notes
content, weather data, autocomplete suggestions
- Remove user-scalable=no and maximum-scale=1 from viewport meta
tag, restoring pinch-to-zoom for WCAG 1.4.4 compliance
- Bump version to 0.7.1
2026-04-04 06:25:28 +02:00
Ulas
1122bd269b
style: replace em dashes with hyphens throughout codebase
...
Replace all — with - in all source files (JS, CSS, HTML, JSON,
Markdown) for consistency and readability.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-04-03 17:04:39 +02:00
Ulas
41e88e0acf
Add PWA native feel: manifest, meta tags, install prompt, SW optimization, dynamic theme-color
...
Configure manifest.json with scope, maskable icons, and categories. Add iOS/Android
meta tags for standalone behavior. Create pwa.css for native touch/scroll handling
and safe area insets. Add oikos-install-prompt Web Component with Chrome install
flow and iOS guidance. Optimize service worker with network-first navigation and
expanded precache (v19). Add dynamic theme-color per route and modal overlay dimming
in standalone mode. Generate placeholder icons via sharp script.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-29 15:35:01 +02: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
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
03585662fb
fix: Lucide Icons lokal ausliefern statt CDN
...
- lucide.min.js v0.469.0 lokal gecacht (kein unpkg-Request mehr)
- Source-Map-Referenz aus Bundle entfernt (behebt NetworkError in DevTools)
- unpkg.com aus CSP entfernt (nicht mehr benötigt)
- preconnect zu unpkg.com aus index.html entfernt
- lucide.min.js zum SW-App-Shell-Cache hinzugefügt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-25 09:42:05 +01:00
ulsklyc
b08ba42b89
fix: CSP-Verletzung durch Inline-Script (SW-Registrierung)
...
Das Inline-Script in index.html für die Service-Worker-Registrierung
wurde von der Content-Security-Policy blockiert (kein 'unsafe-inline'
in script-src). Ausgelagert nach /sw-register.js ('self' erlaubt).
Außerdem: rel="preload" → rel="modulepreload" für ES-Module (korrekte
Browser-Semantik, behebt die Preload-Warnungen in der Console).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-25 09:36:10 +01:00
ulsklyc
04249e0033
feat: PWA-Icons + Favicon — modernes SVG-basiertes Haus-Icon
...
Design: Geometrisches Haus-Motiv auf diagonal-blauem Gradient (#3B9FFF →
#0A7AFF → #1847C8), Glasmorphismus-Schimmer, subtiler Drop-Shadow.
Fenster und Tür als transparente Cutouts (Gradient scheint durch).
Schornstein als architektonisches Detail. Erstellt mit SVG + librsvg.
Dateien:
- public/icons/icon-192.png (13 KB, maskable)
- public/icons/icon-512.png (46 KB, maskable)
- public/icons/apple-touch-icon.png (12 KB, 180×180)
- public/icons/favicon-32.png (1.4 KB)
- public/favicon.ico (5.4 KB, 16+32 multi-size)
- public/index.html: apple-touch-icon + favicon-Links ergänzt
- public/manifest.json: apple-touch-icon (180×180) im icons-Array
- public/sw.js: Cache-Version auf v4 erhöht, neue Icons vorab gecacht
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-24 23:25:47 +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
81d4000ee1
perf: Schritt 32 — Lazy Loading & Caching-Strategie
...
Cache-Control (server/index.js):
- Bilder/Fonts: public, max-age=2592000, immutable (30 Tage)
- HTML/JS/CSS/JSON: no-cache, must-revalidate (ETag-Revalidierung)
→ Deployment-Updates greifen sofort, unveränderte Dateien = 304 ohne Transfer
- API: no-store (kein Browser-Caching von Nutzerdaten)
Service Worker (public/sw.js → v3):
- Drei getrennte Caches: shell-v3, pages-v3, assets-v3
- App-Shell + alle Seiten-Module beim Install vorab gecacht
- Stale-While-Revalidate für App-Shell + Seiten-JS:
sofortiger Render aus Cache, Hintergrund-Update ohne Blockierung
- Cache-First für Bilder/Fonts (seltene Änderungen)
- postMessage({ type: 'SW_UPDATED' }) bei Aktivierung neuer Version
Modul-Cache + Update-Toast (public/router.js):
- moduleCache Map: dynamische imports werden einmalig gespeichert,
wiederholte Navigation braucht keinen Import-Lookup mehr
- SW_UPDATED-Handler: leert moduleCache + zeigt Update-Toast (8s)
Preconnect + Preload (public/index.html):
- <link rel="preconnect" href="https://unpkg.com ">
- <link rel="dns-prefetch" href="https://openweathermap.org ">
- <link rel="preload" href="/api.js" as="script">
- <link rel="preload" href="/router.js" as="script">
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-03-24 22:06:17 +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