Files
2026-09-28 22:23:45 +02:00

8.3 KiB

phase, plan, quick_id, status, subsystem, tags, requires, provides, affects, tech-stack, key-files, decisions, metrics, estimate, actuals, plan_head_before, plan_head_after
phase plan quick_id status subsystem tags requires provides affects tech-stack key-files decisions metrics estimate actuals plan_head_before plan_head_after
quick-260928-ujj 01 260928-ujj complete web, api, shared, docs
design-mosaik
dashboard-background
prisma-migration
changelog
1.5.0
design/mosaik (76d17fe)
Design Mosaik auf main (Merge 9fa0a3f)
User.dashboardBackground (JSONB) + PATCH /users/me/dashboard-background
parseDashboardBackground / DASHBOARD_BACKGROUND_PRESET_IDS in @tessera/shared
CHANGELOG "Unveröffentlicht" mit Neu/Geändert/Behoben fuer 1.5.0
apps/web (115 Dateien aus dem Merge)
apps/api user/auth
added patterns
Gemeinsame Pruefregel in @tessera/shared, angewendet beim Schreiben (Controller) und Lesen (getMe)
Hook liest Benutzerwahl aus dem Auth-Store und speichert optimistisch ueber Server-Aktion mit Ruecksetzen
created modified
apps/api/prisma/migrations/20260928120000_user_dashboard_background/migration.sql
apps/web/src/components/dashboard/dashboard-background.test.tsx
packages/shared/src/index.ts
apps/api/prisma/schema.prisma
apps/api/src/auth/auth.service.ts
apps/api/src/auth/auth.service.spec.ts
apps/api/src/user/user.controller.ts
apps/api/src/user/user.controller.spec.ts
apps/web/src/lib/auth-actions.ts
apps/web/src/lib/stores/auth-store.ts
apps/web/src/components/layout/header.tsx
apps/web/src/components/layout/header.test.tsx
apps/web/src/lib/dashboard-background.ts
apps/web/src/lib/dashboard-background.test.ts
apps/web/src/components/dashboard/dashboard-background.tsx
apps/web/src/app/(portal)/page.tsx
apps/web/src/messages/de.json
apps/web/src/messages/en.json
docs/mandantentrennung-zugriffsklassifikation.md
docs/anleitung-anwender.md
docs/anleitung-entwicklung.md
CHANGELOG.md
Dashboard-Hintergrund als JSONB-Spalte User.dashboardBackground; null = nie gewaehlt, { kind: 'none' } = bewusst kein Hintergrund
parseDashboardBackground in @tessera/shared ist die einzige Pruefregel (Allowlist kind/Preset, imageId nur UUID) fuer API-Schreiben, API-Lesen und Web-Altdatenuebernahme
Alter localStorage-Schluessel wird immer einmal gelesen und entfernt, uebernommen nur bei Server-Wert null
Biome: nur vom Merge neu eingebrachte Befunde behoben; vorbestehende Format-/Importbefunde (158 an der Basis) bleiben ausser Umfang
duration completed
17min 2026-09-28
tokens tasks
95000 3
tokens tasks commits
95700 3 17
a8a910fd29 cb45d2663a

Quick 260928-ujj Plan 01: Design Mosaik uebernehmen und fuer 1.5.0 vorbereiten — Summary

Design „Mosaik“ per --no-ff-Merge (zweiter Elternteil 76d17fe) auf main übernommen. Der Dashboard-Hintergrund wird jetzt pro Benutzer in User.dashboardBackground (JSONB) gespeichert: PATCH /users/me/dashboard-background prüft mit dem gemeinsamen parseDashboardBackground, und der Wert kommt zusammen mit accentColor über getMe zurück. Die alte Wahl aus dem localStorage wird einmal übernommen. CHANGELOG und beide Anleitungen sind für 1.5.0 vorbereitet.

Commits

Task Commit Beschreibung
1 9fa0a3f feat(260928-ujj): Design Mosaik uebernehmen (Merge, Eltern a8a910f + 76d17fe; bringt 12 Commits aus design/mosaik mit)
2 (RED) 76f6d87 test(260928-ujj): rote Tests fuer Dashboard-Hintergrund in der Datenbank
2 (GREEN) 0aaa152 feat(260928-ujj): Dashboard-Hintergrund pro Benutzer in der Datenbank
3 (Biome) 69d1730 fix(260928-ujj): Biome-Formatierung der mit Design Mosaik eingebrachten Dateien
3 cb45d26 docs(260928-ujj): CHANGELOG und Anleitungen fuer Design Mosaik

commits: 17 wurde gemessen mit git rev-list --count a8a910f..HEAD. Die Zahl enthält die 12 Commits aus design/mosaik, die der Merge mitbringt. Auf der ersten Elternlinie stehen 5 eigene Commits.

Verifikation

  • git merge-base --is-ancestor 76d17fe HEAD: erfolgreich. RESIZE_AXIS_FALLBACK steht in dashboard-grid.tsx.
  • Web-Tests (vitest 4.1.9): 97 Dateien, 952 Tests grün. Direkt nach dem Merge waren es 96 Dateien und 940 Tests.
  • API-Tests (vitest 3.2.6): 85 Dateien, 1462 Tests grün, einschließlich rls-access-inventory.spec.ts.
  • tsc: shared, api und web sind sauber.
  • Builds: pnpm --filter api build und pnpm --filter web build sind erfolgreich.
  • Biome bringt keine neuen Fehler. In den seit 3fc33e3 geänderten ts/tsx-Dateien standen an der Basis 158 Fehler, jetzt sind es 156. Alle verbleibenden Befunde bestanden schon vorher (84 format, 72 organizeImports in 93 Dateien).
  • Die Migration ist lokal eingespielt (prisma migrate deploy gegen 172.19.0.2). Die Spalte dashboardBackground hat den Typ jsonb.
  • Lokaler Stack neu gebaut mit docker compose up -d --build api web. Die API meldet die Route Mapped {/users/me/dashboard-background, PATCH}. Ein Aufruf ohne Anmeldung ergibt 401.
  • Nichts gepusht, kein Tag gesetzt, den live-Zweig nicht angefasst. .planning/HANDOFF.json ist weiter nur eine lokale Änderung und wurde nicht gestaged.

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] Das Biome-Gate des Plans kann auf den geänderten Dateien nicht fehlerfrei werden

  • Found during: Task 2 und Task 3
  • Issue: Die Verify-Zeile biome check $(git diff --name-only --diff-filter=AM 3fc33e3 HEAD ...) endet mit Exit 1. Die 93 betroffenen Dateien hatten schon an der Basis 3fc33e3 zusammen 158 Format- und Importbefunde.
  • Fix: Ich habe nur die Befunde behoben, die der Merge neu eingebracht hat (12 Dateien, nur Formatierung und Importreihenfolge, eigener Commit 69d1730), dazu alle Befunde in den von mir geschriebenen Zeilen und neuen Dateien. Den Rest ganzer Dateien habe ich nicht umformatiert. Die Vorgabe des Auftraggebers („no new errors“) ist erfüllt: 158 → 156.
  • Commit: 69d1730

2. [Rule 2 - Missing critical] Der alte localStorage-Schlüssel wird auch bei gesetztem Server-Wert aufgeräumt

  • Found during: Task 2
  • Issue: Nach Plan hätte bei gesetztem Server-Wert keine Übernahme stattgefunden, der alte Schlüssel wäre dann aber für immer liegen geblieben.
  • Fix: takeLegacyDashboardBackground wird je Benutzer einmal aufgerufen und entfernt den Schlüssel immer. Übernommen wird die alte Wahl nur, wenn der Server-Wert null ist. Ein Test deckt das ab.

3. [Rule 1 - Doc] Die Anwender-Anleitung war schon vor dem Merge an drei Stellen veraltet

  • Die Seitenleiste zeigte bereits vorher keine Sprachumschaltung und keine Name/Rolle-Zeile mehr. Die Reiter standen seit 1.4.0 in der Kopfzeile. Der Stift-Schalter ist mit Mosaik zu „Bearbeiten“/„Fertig“ oben rechts geworden. Diese Stellen habe ich beim Nachziehen gegen den gemergten Code korrigiert.

Nicht ausgeführt

  • Browser-Prüfung per Playwright MCP (Hintergrund wählen, neu laden, zweiter Browserkontext): In dieser Ausführungsumgebung gab es kein Playwright-MCP-Werkzeug. Ersatzweise habe ich den lokalen Stack neu gebaut und geprüft, dass die Route gemappt ist, ohne Anmeldung 401 liefert und die Spalte in der DB existiert. Die Prüfung über zwei Geräte im Browser steht noch aus.

Hinweise

  • Eine Übernahme der alten Wahl, die fehlschlägt (z. B. wegen eines API-Ausfalls genau in dem Moment), geht verloren, weil der Schlüssel schon beim Lesen entfernt wird. Der Benutzer wählt dann einfach neu. Das ist bewusst so, damit die Übernahme garantiert nur einmal passiert.
  • Alte Prototyp-Werte mit einer Bildkennung, die keine UUID ist, werden nicht übernommen. Echte Bilderrahmen-Kennungen sind immer UUIDs.
  • Das Web liest @tessera/shared jetzt auch in dashboard-background.ts zur Laufzeit. parseDashboardBackground enthält nur löschbare Syntax (Regel aus dem Warnkommentar über WIDGET_TYPES).

Threat Flags

Keine über das Threat-Register hinaus. T-ujj-01 und T-ujj-02 sind wie geplant umgesetzt: Allowlist und UUID-Prüfung beim Schreiben und Lesen, forTenant mit where id = currentUser.id, kein Kennungsparameter.

Self-Check: PASSED

  • FOUND: apps/api/prisma/migrations/20260928120000_user_dashboard_background/migration.sql
  • FOUND: apps/web/src/components/dashboard/dashboard-background.test.tsx
  • FOUND commits: 9fa0a3f, 76f6d87, 0aaa152, 69d1730, cb45d26