fix(dashboard): scope localStorage key by userId to prevent cross-user layout bleed (#27)

New users on a shared device were picking up a previous user's stale
(potentially empty) dashboard layout from localStorage because the key
"capakraken_dashboard_v1" was not user-scoped.

- useDashboardLayout: key is now capakraken_dashboard_v1_{userId};
  userId is resolved via trpc.user.me before touching localStorage
- Initial state falls back to createDefaultDashboardLayout() until
  userId resolves, then hydrates from the user-scoped key
- DB layout still wins over localStorage when it has data (unchanged)
- E2E test suite covers: new-user flow, modal widget list, add widget
  persists after reload, cross-user localStorage isolation
- plan.md: added ticket #27 implementation plan

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-04-01 22:44:41 +02:00
parent d3bfa8ca98
commit 745be7ee8b
3 changed files with 360 additions and 11 deletions
+40 -1
View File
@@ -1,7 +1,46 @@
# CapaKraken — Umsetzungsplan
Gitea-Repo: `https://gitea.hartmut-noerenberg.com/Hartmut/plANARCHY`
Stand: 2026-04-01 | Issues: #19#26
Stand: 2026-04-01 | Issues: #19#27
---
## Plan: Ticket #27 — Dashboard Widget Bug (new users see empty modal)
### Anforderungsanalyse
Neue Nutzer können keine Widgets zum Dashboard hinzufügen. Root cause: `localStorage`-Key
`"capakraken_dashboard_v1"` ist **nicht user-scoped**. Wenn User A sich ausloggt und User B
auf demselben Gerät anmeldet, liest `useDashboardLayout` das Layout von User A aus
`localStorage`. Hat User A ein leeres Dashboard gespeichert, sieht User B 0 Widgets —
und nach Klick auf "Add Widget" im Modal erscheint der neue Widget **nicht** (da der
Hydrationszustand nicht sauber initialisiert wird).
**Fix:** localStorage-Key auf `capakraken_dashboard_v1_{userId}` umstellen. Vor dem Zugriff
auf `localStorage` wartet der Hook auf `trpc.user.me`, um die User-ID zu kennen.
### Betroffene Pakete & Dateien
| Paket | Datei | Art |
|-------|-------|-----|
| `apps/web` | `src/hooks/useDashboardLayout.ts` | edit — user-scoped storage key |
| `apps/web` | `e2e/dev-system/dashboard-widgets.spec.ts` | create — E2E tests |
### Task-Liste
- [x] **T-1:** `useDashboardLayout` auf user-scoped localStorage umstellen → `useDashboardLayout.ts`
- [x] **T-2:** E2E-Test für den kompletten Widget-Flow (new user, add, persist, reload) → `dashboard-widgets.spec.ts`
- [ ] **T-3:** `pnpm --filter @capakraken/web exec tsc --noEmit` — keine neuen TS-Fehler
- [ ] **T-4:** E2E-Tests gegen laufenden Dev-Server ausführen (manuell oder CI)
- [ ] **T-5:** Commit + Ticket #27 auf Gitea kommentieren + `in-review` setzen
### Akzeptanzkriterien
- [ ] Neuer Admin-User sieht nach Login das Default-Dashboard (stat-cards)
- [ ] Modal zeigt alle 11 Widgets an
- [ ] Gewählter Widget erscheint sofort auf dem Dashboard
- [ ] Nach Page-Reload ist der Widget weiterhin sichtbar
- [ ] Cross-User-Bleed: User B erbt nicht das Layout von User A
---