Commit Graph

49 Commits

Author SHA1 Message Date
Ulas 446b9b1388 feat(budget): configurable currency in settings (#20)
Add household-wide currency preference for the budget section.
Users can select from 13 currencies (EUR, USD, GBP, SEK, NOK, DKK,
CHF, PLN, CZK, HUF, JPY, AUD, CAD) in Settings → Budget.

- preferences API (GET/PUT) now includes currency field
- budget page loads currency from preferences on render
- formatAmount() uses locale-aware Intl.NumberFormat with chosen currency
- settings page gains a Budget section with a currency select
- all three locales (de, en, it) updated with new i18n keys
2026-04-05 11:55:38 +02:00
Ulas 212a8bdb0a fix(dashboard): filter todayMeals by visible_meal_types preference (#14)
The dashboard meal widget was showing all meal types regardless of the
household meal visibility settings configured in Settings > Meal Plan.

Root cause: the todayMeals SQL query in dashboard.js did not read
visible_meal_types from sync_config. The Meals page applied this filter
client-side, but the dashboard API returned unfiltered data.

Fix: read visible_meal_types from sync_config before the query and inject
the active types as IN (?) placeholders. Falls back to all four types when
no preference is stored.
2026-04-05 03:12:01 +02:00
Ulas 0940afc170 chore(release): v0.11.0
Bump version and update CHANGELOG for release v0.11.0.
2026-04-05 03:09:06 +02:00
Ulas 08159ec8b4 feat(meals): customizable meal type visibility in Settings (#14)
Users can now toggle which meal types (breakfast, lunch, dinner, snack)
are displayed in the meal planner via a new Settings section. Preference
is stored household-wide in sync_config and applied as a filter on the
meals page. Includes preferences API, i18n (DE/EN/IT), and Settings UI.
2026-04-04 22:51:57 +02:00
Ulas 0421b540cd feat(tasks): persist view mode and support ?view=kanban URL parameter
View mode (list/kanban) is now saved to localStorage and restored on
page load. URL parameter ?view=kanban takes precedence, enabling tablet
kiosk setups to default to Kanban view. Toggle buttons reflect the
active view correctly on initial render.

Closes #17
2026-04-04 22:34:29 +02:00
Ulas 2c36fa0307 feat(tasks): add optional "none" priority level for tasks without urgency
New tasks default to "none" priority instead of "medium". Tasks with no
priority hide the badge in list and dashboard views, reducing visual noise
for routine items. Includes DB migration v4 and i18n keys (de, en, it).

Closes #15
2026-04-04 22:13:51 +02:00
Ulas 2508473265 fix(pwa): fix UI overlap, scroll bleed and wrong nav height on iOS
Three root causes fixed:

1. Double safe-area padding: pwa.css set padding-top/bottom on body
   globally, but page containers already account for safe-area-inset
   in their height calculations. Removed body vertical padding (kept
   only in standalone media query for padding-top).

2. Wrong nav token: all page containers used --nav-height-mobile (56px)
   instead of --nav-bottom-height (68px = 56px scroll + 12px dots),
   causing 12px of content to render behind the bottom nav.

3. Scroll bleed: fixed-height page containers lacked overflow:hidden,
   allowing scroll events to propagate to the body. Added
   overscroll-behavior-y:contain on app-content globally.

Fixes #16
2026-04-04 22:02:19 +02:00
Ulas 7eb06ed905 fix(modal): replace native prompt() with custom modal dialogs
Native browser prompt() is unreliable on mobile browsers and PWAs,
often requiring multiple clicks to close. Replace all prompt() calls
with custom promptModal() and selectModal() functions that use the
existing modal system with proper focus management and animations.

Affected pages: shopping (create/rename list), tasks (add subtask),
meals (choose shopping list).

Fixes #12
2026-04-04 21:31:50 +02:00
Ulas c93be9049c feat(dashboard): add shopping list widget
Show shopping lists with open items directly on the dashboard.
Each list displays a progress bar, the first few unchecked items,
and a "+N more" overflow indicator. Widget only appears when there
are lists with open items.

Backend: new shoppingLists query in /api/v1/dashboard (up to 3 lists,
6 open items each). Frontend: renderShoppingLists() widget following
existing widget pattern. CSS: compact list/progress/item styles.
i18n: shoppingMore key added to de/en/it.

Requested in discussion #9
2026-04-04 14:30:31 +02:00
Ulas 47b34c4829 fix(modal): add fallback timer for mobile close animation
On mobile, closeModal() relies on the CSS animationend event to call
_doClose(). When the animation does not fire (prefers-reduced-motion,
tab switch, browser quirk), the modal stays stuck and the user cannot
dismiss it. A 300ms fallback timer now guarantees cleanup runs.

Reported in discussion #9
2026-04-04 14:16:00 +02:00
Ulas 597c2602aa fix(i18n): translate category names in tasks and budget displays
Category group headers in tasks and bar chart labels / transaction meta
in budget were showing raw German database keys instead of going through
CATEGORY_LABELS() i18n mapping.

Closes #11
2026-04-04 14:08:41 +02:00
Ulas 6454c1fc9f chore: bump version to v0.7.5 and update changelog 2026-04-04 07:27:42 +02:00
Ulas 1c7b77401d chore: bump version to v0.7.4 and update changelog 2026-04-04 06:51:38 +02:00
Ulas 364d029950 fix(ux): prevent iOS auto-zoom on inputs + lazy-load page CSS
Increase font-size to 16px on mobile for shopping quick-add inputs,
notes search, and contacts search. Desktop breakpoint restores compact
sizes. Move 9 page-specific stylesheets from index.html to on-demand
loading in router.js, reducing initial CSS payload.
2026-04-04 06:39:45 +02:00
Ulas 70c1291ae7 fix(a11y): skip-link target, priority labels, greeting tokens
- Rename #page-content to #main-content so skip-to-content link
  targets the semantic <main> landmark
- Add sr-only priority labels to dashboard task items for screen
  readers (WCAG 1.4.1 color-not-only)
- Replace hardcoded hex in greeting gradient with accent tokens
  so dark mode themes the banner correctly
- Replace hardcoded gap: 2px with --space-0h token
- Bump version to 0.7.2
2026-04-04 06:31:21 +02:00
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 9b21a72d40 chore: release v0.7.0 - audit remediation
Bump version to 0.7.0 and add CHANGELOG entry covering all
audit findings: bcrypt upgrade, ESM migration, session secret
hardening, structured logging, documentation translations,
and repository cleanup.
2026-04-04 01:22:39 +02:00
Ulas b139eea623 refactor(esm): migrate server and tests from CommonJS to ESM
Convert all server/, test, and setup files from require()/module.exports
to import/export syntax. Activate ESM globally via "type": "module" in
package.json and load dotenv via --import dotenv/config in npm scripts.
2026-04-03 23:11:20 +02:00
Ulas ae8fbdd465 fix(deps): upgrade bcrypt 5.1.1->6.0.0 and patch path-to-regexp ReDoS
Resolves all 5 npm audit vulnerabilities (4 high in tar via
node-pre-gyp, 1 high path-to-regexp ReDoS). bcrypt 6 replaces
node-pre-gyp with prebuildify, removing 46 transitive packages.
2026-04-03 21:58:28 +02:00
Ulas 614a496256 docs: translate package.json description and .env.example to English
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 21:54:31 +02:00
Ulas 3d2604bab9 fix(security): address critical and high findings from security audit
Fix stored XSS in tasks (titles/subtasks) and settings (member list)
by applying escHtml(). Harden trust proxy to loopback default, add
OAuth state parameter for Google Calendar CSRF protection, sanitize
CSV export against formula injection, invalidate sessions on user
deletion, restrict usernames to alphanumeric chars, and require admin
role for calendar sync triggers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 17:28:36 +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 b1ee4439be feat(i18n): add Italian localization
Add complete Italian translation (497 keys) based on PR #7 by
@albanobattistella. Fixed filename from "it. json" to "it.json" and
registered Italian in SUPPORTED_LOCALES and the locale picker component.

Co-Authored-By: albanobattistella <34811668+albanobattistella@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 15:35:08 +02:00
Ulas 678c896862 fix(calendar): expand recurring multi-day events and support YEARLY frequency
Root causes:
1. parseRRule did not strip the "RRULE:" prefix stored by the ICS parser,
   causing all recurrence rules from CalDAV sync to silently fail parsing
2. YEARLY frequency (used by birthday events) was not supported
3. expandRecurringEvents filtered instances only by start date, missing
   multi-day events that start before the view window but span into it
4. All-day recurring instances got datetime end values instead of date-only

Fixes #5 (follow-up from @tschig)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 12:47:18 +02:00
Ulas eafe2b964d fix(sync): resolve iCloud Calendar sync FOREIGN KEY crash and sync all calendars
The Apple Calendar sync hardcoded created_by=1 which fails when no user
with ID 1 exists, causing every single event import to fail silently.
Now dynamically resolves the first available user. Also syncs all
calendars instead of only the first one, adds the missing cfgDel helper,
and gracefully skips unreachable calendars.

Fixes #4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 12:10:58 +02:00
Ulas cd963540cf fix(db): quote SQLCipher PRAGMA hex key to fix fresh install crash
The hex-encoded encryption key (x'...') is not valid as a bare PRAGMA
value in better-sqlite3. Wrapping it in double quotes produces valid
SQLCipher PRAGMA syntax.

Fixes #3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 11:43:46 +02:00
Ulas 5cb71bb424 fix: align Node.js version to >=22 across Dockerfile and package.json
Dockerfile used node:20-slim but the project requires Node >=22
(--experimental-sqlite in tests, CI matrix). package.json had a
duplicate engines block where the second (>=20.0.0) silently
overwrote the correct first one (>=22.0.0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:16:49 +02:00
Ulas 91c2e0ad98 fix: address CodeQL security findings (v0.5.2)
- Rate-limit SPA fallback route (missing rate limiting on fs access)
- Add csrfMiddleware to all state-changing auth routes (logout, create
  user, change password, delete user) — previously bypassed global CSRF
  middleware due to router registration order
- Fix incomplete vCard escaping: escape backslashes before other special
  characters to prevent injection via contact fields
- Restrict CI GITHUB_TOKEN to contents: read (least privilege)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 18:30:03 +02:00
Ulas b9b81a461e chore: release v0.5.1 — update CHANGELOG and package version
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 12:00:37 +02:00
Ulas b2fbd11287 fix: add social-preview.png, correct test count, add engines field
- Add social-preview.png to version control (referenced in README but untracked)
- Update README: test count 146+ → 162 across 9 suites
- Add engines.node >=22.0.0 to package.json (required for --experimental-sqlite)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 11:41:34 +02:00
Ulas c66018ff49 chore: release v0.5.0 — update CHANGELOG, SPEC, and package version 2026-03-31 23:38:38 +02:00
Ulas ce38f7041b fix: add browser path loader for Node.js tests, update test:modal-utils script 2026-03-31 23:34:43 +02:00
Ulas 0defc3c589 chore: release v0.3.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:29:58 +02:00
Ulas 675a0ff2b7 chore: bump to v0.2.1, finalize CHANGELOG
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:37:09 +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 656c1290dc chore: bump to v0.2.0, finalize CHANGELOG, update SPEC with UX patterns 2026-03-30 21:59:51 +02:00
Ulas b2327375b8 fix: remove unnecessary --experimental-vm-modules flag from test:ux-utils 2026-03-30 17:16:20 +02:00
Ulas f4eb567219 feat: add stagger() and vibrate() UX utilities with tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:14:15 +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 eff3e4bfb2 docs: README komplett überarbeitet — professioneller, anfängerfreundlicher, visuell ansprechender
- Einladender Hero-Bereich mit klarem Value Proposition
- Vergleichstabelle Cloud vs. Selfhosted
- Ausführliche Schritt-für-Schritt-Installationsanleitung mit Erklärungen für Einsteiger
- Expandierbare Details-Blöcke für zusätzliche Hilfe
- FAQ-Sektion für häufige Fragen
- Sicherheitsübersicht als übersichtliche Tabelle
- Bessere visuelle Struktur mit mehr Whitespace und klarerer Hierarchie
- package.json Beschreibung verbessert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 00:46:46 +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 0dac77773a security: MIT-Lizenz, .gitignore härten, Fail-Fast für SESSION_SECRET
- LICENSE: MIT-Lizenz (bereits vorhanden, korrekt)
- package.json: "license": "MIT" ergänzt
- README.md: Lizenz-Badge auf MIT aktualisiert, Lizenz-Sektion angepasst
- .gitignore: .claude/ und *.txt hinzugefügt (verhindert versehentliches
  Committen von Claude Code Einstellungen und Token-Textdateien)
- server/auth.js: Fail-Fast in Produktion wenn SESSION_SECRET fehlt;
  Fallback-String auf 'dev-only-secret-not-for-production' umbenannt
  (klarere Intention, kein bekannter Produktions-Wert im Public Repo)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 23:01:08 +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