Commit Graph

40 Commits

Author SHA1 Message Date
Ulas 4fe4f6cb38 feat: BL-07–BL-10 — notes search, weather refresh, vCard import/export, PWA offline page
- Notes: client-side full-text search bar (filters title + content)
- Dashboard: weather refresh button + 30-min auto-refresh interval
- Contacts: vCard 3.0 export per contact (GET /:id/vcard); vCard import
  via file input with client-side parser (FN, TEL, EMAIL, ADR, NOTE, CATEGORIES)
- PWA: /offline.html served when network unavailable; cached in app-shell (sw v20)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:35:03 +02:00
Ulas d866d32336 feat: Apple CalDAV credentials form + connect/disconnect UI (BL-04)
Admin can now enter CalDAV URL, Apple-ID and app-specific password
directly in Settings; credentials are tested live before saving and
stored in sync_config (take precedence over .env); disconnect clears
DB-stored credentials without server restart. Auto-sync interval
(15 min, configurable via SYNC_INTERVAL_MINUTES) was already in place.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:27:07 +02:00
Ulas 6fd209ba5e feat: meals drag & drop between slots and days (BL-03)
Pointer Events-based drag & drop (touch + mouse compatible):
- Ghost element follows pointer; drops on empty slots move the meal,
  drops on occupied slots swap both meals via concurrent PUT requests
- prefers-reduced-motion: no ghost animation, interaction still works
- Suppress-click guard prevents accidental edit modal after drag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:23:39 +02:00
Ulas 6a860f2c13 feat(calendar): expand recurring events in GET /calendar and /upcoming
expandRecurringEvents() iterates from the event's original start date,
generating all occurrences within the requested window using the existing
nextOccurrence() service (max 1000 iterations). The SQL query is extended
to also fetch recurring events that started before the window. Event
duration is preserved across instances. Virtual instances carry
is_recurring_instance=1 and are shown with a repeat icon in the agenda
view. /upcoming expands across a 90-day forward window.

Closes BL-01.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:17:39 +02:00
Ulas 82e5b2cd85 feat(budget): auto-generate recurring entry instances per month
Adds schema migration v3 (recurrence_parent_id column + budget_recurrence_skipped
table). On every GET /api/v1/budget, the server checks all recurring originals
(is_recurring=1, no parent) and creates missing instances for the requested month
using the same day-of-month (clamped to the last day). Deleted instances are
recorded in budget_recurrence_skipped so they are not recreated on the next visit.
Generated instances are shown with a ↩ indicator in the transaction list.

Closes BL-05.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:13:37 +02:00
Ulas 26d3d12a22 feat(budget): add month-over-month comparison to summary cards
Each summary card (Einnahmen, Ausgaben, Saldo) now shows a trend line
comparing the current month to the previous one. The previous month's
summary is fetched in parallel via the existing /budget/summary endpoint,
so there is no extra round-trip latency. Positive deltas render in green
(▲), negative in red (▼), unchanged in neutral grey (—).

Closes BL-02.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:54:04 +02:00
Ulas 3e25339c86 fix: resolve event-listener leaks and CSS gaps found in code quality audit
- notes.js (Critical): move grid click listener from renderGrid() to
  render() — was re-registered on every save/pin/delete, causing
  multiple API calls per user action after several interactions
- dashboard.js (Major): introduce AbortController (_fabController) so
  the anonymous document click listener from initFab() is cancelled on
  each new render() cycle; also remove the redundant initFab() call on
  the skeleton render
- layout.css (Major): extend .label selector to include .form-label,
  covering usage in notes.js and settings.js without a mass-rename
- test-modal-utils.js (Major): 12 unit tests for wireBlurValidation,
  btnSuccess, btnError; registered as test:modal-utils in package.json
- notes.js (Minor): add btnError() shake feedback to save error handler
- calendar.js (Minor): add popup.isConnected guard to closePopup so
  the listener self-removes correctly after navigation without a click

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:26:49 +02:00
Ulas 0ac2769fac feat: blur-triggered inline validation and submit button feedback
Task 13: wireBlurValidation() activates error/valid state on required
fields after blur. Task 14: btnSuccess() shows a checkmark for 700ms
then closes the modal; btnError() triggers a shake animation on failure.
Both wired into the tasks form submit handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 21:22:36 +02:00
Ulas b9ec36611d feat: consistent vibration feedback via vibrate() utility across modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 21:18:44 +02:00
Ulas 0eab480a0e style: unify all empty states to shared .empty-state class across all modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:25:13 +02:00
Ulas eb0ac95e1d fix: scope stagger selector to #budget-list in budget.js 2026-03-30 17:21:53 +02:00
Ulas bc6e759b79 feat: staggered fade-in for list items across all modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:19:33 +02:00
Ulas cb8b108d3c fix: Notizen-Toolbar erweitert + Essen-Widget 2×2-Grid auf Desktop
Pinnwand: Pflichtfeld-Stern entfernt, Markdown-Hinweis ergänzt,
Formatierungs-Toolbar um Unterstreichen, Durchgestrichen, Überschrift,
nummerierte Liste, Checkliste, Link, Code, Zitat und Trennlinie erweitert.
Dashboard: Essen-Widget nutzt ab Desktop 2×2-Layout statt 4×1 für
bessere Lesbarkeit der Mahlzeiten-Labels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 15:31:50 +01:00
Ulas 2f0b0c05ec feat: Notizen — automatische Textkontrastfarbe + Formatierungs-Toolbar
Kontrastproblem: Titel, Inhalt und Footer-Elemente der Notizkarten
überschrieben die Inline-Textfarbe mit festen Token-Werten. Jetzt
erben alle Elemente die adaptiv berechnete Farbe (dunkel auf hellen
Karten, hell auf dunklen).

Formatierungs-Toolbar: Fett, Kursiv und Liste als Buttons über dem
Textfeld im Editor. Fügt Markdown-Syntax ein, unterstützt Selektion
und Tastaturkürzel (Strg+B, Strg+I). Markdown-Rendering bleibt
unverändert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 09:05:28 +01:00
Ulas cacec64777 fix: Dashboard-Widgets zeigen jetzt alle offenen Aufgaben und neueste Notizen
Aufgaben-Widget zeigte nur high/urgent Tasks mit Fälligkeit ≤48h,
Pinnwand-Widget nur explizit gepinnte Notizen. Neue Einträge waren
dadurch im Dashboard unsichtbar.

- Aufgaben: alle offenen Tasks (sortiert nach Priorität), Limit 5
- Notizen: neueste 3 (gepinnte zuerst, dann nach Aktualisierung)
- Greeting-Chip zählt weiterhin nur high/urgent Tasks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 23:30:00 +01:00
Ulas d69c5a0413 feat: Wetter-Widget responsive über volle Breite im Desktop-Dashboard
Auf Desktop wird das Wetter-Widget über allen anderen Widgets platziert
mit horizontalem Layout (aktuelles Wetter links, Vorhersage rechts).
Vorhersagezeitraum skaliert mit Bildschirmbreite: 3 Tage (Mobil),
4 Tage (Tablet), 5 Tage (Desktop/Wide).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 15:20:55 +01:00
ulsklyc e4760473a7 fix: Login-Seite zentriert + Hero-Bereich mit Tagline über dem Formular
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 14:29:31 +01:00
ulsklyc d5a0e701b0 a11y: aria-hidden auf allen Icons + aria-label auf icon-only Buttons (Redesign Phase F)
- Alle data-lucide Icons: aria-hidden="true" (dekorativ)
- Icon-only Buttons/Links: title→aria-label (Screenreader-zugänglich)
- Betrifft: modal.js, contacts, meals, budget, calendar, notes, tasks,
  shopping, dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:48:23 +01:00
ulsklyc 3e63a7086d a11y: add h1 headings to all pages (Redesign Phase B)
Every page now has exactly one <h1> per spec §2.3.
Six pages use sr-only <h1>; notes uses visible <h1> in toolbar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:30:29 +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 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 c8c39930b5 feat: FAB auch auf der Einkaufsseite hinzufügen
- Blauer Plus-FAB unten rechts auf Mobile
- Fokussiert das Quick-Add-Eingabefeld und scrollt es ins Sichtfeld
- Erstellt eine neue Liste, wenn noch keine vorhanden ist
- Service Worker Cache v14

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:23:15 +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 2e3e67baeb fix: Error Handling in Backend und Frontend verbessern (Phase 5, Schritt 31)
- Backend: JSON-Parse-Error + Payload-Too-Large Middleware in index.js
- Backend: Dashboard äußerer try/catch für db.get()-Fehler
- Backend: contacts/meta Route mit try/catch
- Frontend: try/catch + Toast-Fallback in loadMonth (budget), loadRange (calendar),
  loadWeek (meals), loadLists/switchList (shopping), initiales Laden (notes)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 00:35:16 +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 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 7244fc95f1 fix: Session-Store, DOM-Timing und API-Pfad-Fehler beheben
- connect-sqlite3 durch eigenen BetterSQLiteStore ersetzt (sessions-Tabelle
  in der bestehenden DB, keine native Kompilierung nötig)
- db.init() vor require('./auth') gezogen damit BetterSQLiteStore-Konstruktor
  db.get() erfolgreich aufrufen kann
- router.js: App-Shell und pageWrapper vor module.render() in DOM einfügen
  damit document.getElementById() in Seiten-Modulen funktioniert
- Seiten-Module (meals, notes, contacts, calendar, budget): _container-Referenz
  eingeführt, alle document.getElementById() auf _container.querySelector() bzw.
  document.querySelector() für body-Elemente umgestellt
- login.js: User-Objekt nach erfolgreichem Login an navigate() übergeben
  damit auth.me()-Roundtrip entfällt
- calendar.js: /users → /auth/users korrigiert (404-Fix)
- SW-Cache v8 (erzwingt Reload aller gecachten Seiten-Module)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 11:49:10 +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