From 5e8b2c2c398a8d8ee840bfa0c3ea395b50e73aa8 Mon Sep 17 00:00:00 2001 From: Schalli Date: Wed, 1 Jul 2026 10:01:15 +0200 Subject: [PATCH] docs(08-01): complete widget registry foundation + Calculator plan summary - 3/3 tasks executed (RED/GREEN/verify) - 16 tests added and passing (67 total web suite) - SUMMARY.md created with self-check PASSED --- .../08-01-SUMMARY.md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 .planning/phases/08-dashboard-widgets-vollimplementierung/08-01-SUMMARY.md diff --git a/.planning/phases/08-dashboard-widgets-vollimplementierung/08-01-SUMMARY.md b/.planning/phases/08-dashboard-widgets-vollimplementierung/08-01-SUMMARY.md new file mode 100644 index 0000000..794be9a --- /dev/null +++ b/.planning/phases/08-dashboard-widgets-vollimplementierung/08-01-SUMMARY.md @@ -0,0 +1,119 @@ +--- +phase: 08-dashboard-widgets-vollimplementierung +plan: "01" +subsystem: dashboard-widgets +tags: [calculator, widget-registry, tdd, dashboard, i18n, validation] +status: complete + +dependency_graph: + requires: [] + provides: + - WidgetType union with calculator/favorites/link/stopwatch + - WIDGET_CONSTRAINTS for all 8 widget types (DASH-11) + - wireCalculatorWidget / wireFavoritesWidget / wireLinkWidget / wireStopwatchWidget + - CalculatorWidget component (fully functional) + affects: + - apps/web/src/components/dashboard/widget-registry.tsx + - apps/web/src/components/dashboard/widget-catalog-modal.tsx + - apps/web/src/app/(portal)/page.tsx + - apps/api/src/dashboard/dto/create-widget.dto.ts + +tech_stack: + added: [] + patterns: + - TDD Red/Green cycle for widget + registry tests + - Arithmetic logic ported from personal-dashboard (parseDisplay/formatNumber/calculate) + - Tailwind-only styling (no CSS modules) + - wireXWidget() lazy-loading pattern extended to 4 new widget types + - @IsIn() allow-list in DTO updated (T-08-01 threat mitigated) + +key_files: + created: + - apps/web/src/components/dashboard/widgets/calculator-widget.tsx + - apps/web/src/components/dashboard/widgets/calculator-widget.test.tsx + - apps/web/src/components/dashboard/widget-registry.test.tsx + modified: + - apps/web/src/components/dashboard/widget-registry.tsx + - apps/web/src/components/dashboard/widget-catalog-modal.tsx + - apps/web/src/app/(portal)/page.tsx + - apps/web/src/messages/de.json + - apps/web/src/messages/en.json + - apps/api/src/dashboard/dto/create-widget.dto.ts + +decisions: + - "Grid constraints defined per-widget (D-01): calculator minW:2 minH:4 defaultW:3 defaultH:5; favorites minW:2 minH:3 defaultW:3 defaultH:5; link minW:2 minH:2 defaultW:2 defaultH:2; stopwatch minW:2 minH:2 defaultW:3 defaultH:3" + - "Calculator keyboard handler uses stopPropagation() in all handled branches (T-08-02 / Pitfall 1)" + - "Pre-existing API TypeScript errors (avatarPath) out of scope — not introduced by this plan" + +metrics: + duration: "~10 minutes" + completed: "2026-07-01" + tasks_completed: 3 + tests_added: 16 + files_created: 3 + files_modified: 7 +--- + +# Phase 08 Plan 01: Widget Registry Foundation + Calculator Summary + +Widget-Registry-Grundlage fuer alle Phase-8-Typen (DASH-11) und voll funktionsfaehiger Calculator-Widget (DASH-08) via TDD Red/Green-Zyklus. + +## What Was Built + +- **Calculator Widget** (`calculator-widget.tsx`): Vollstaendige Implementierung portiert aus personal-dashboard. Grundrechenarten (+, −, ×, ÷), Tastatureingabe, Dezimalkomma, Division-durch-Null-Schutz ("Fehler"), Memory-Funktionen (MC/MR/M+/M−/MS). `stopPropagation()` in jedem Keyboard-Handler-Branch verhindert react-grid-layout-Interferenz. +- **Widget Registry Foundation**: `WidgetType`-Union auf 8 Typen erweitert. `WIDGET_CONSTRAINTS` mit einheitlicher Feldstruktur (minW/minH/defaultW/defaultH) fuer alle 8 Typen. Vier neue SVG-Icons, vier neue WIDGET_REGISTRY-Eintraege, vier neue `wireXWidget()`-Funktionen fuer spaetere Plaene. +- **Catalog Modal**: `WIDGET_TYPES`-Array auf alle 8 Typen erweitert — neue Widgets erscheinen im Dashboard-Katalog. +- **API DTO**: `@IsIn()`-Allowlist auf alle 8 WidgetTypes erweitert — POST `/dashboard/widgets` akzeptiert neue Typen ohne 400-Fehler. +- **i18n**: Schluesselsatz fuer calculator/favorites/link/stopwatch in `de.json` und `en.json` ergaenzt. + +## Tasks + +| Task | Description | Status | Commit | +|------|-------------|--------|--------| +| 1 | RED: Failing tests fuer Calculator und Registry-Constraints | Complete | b751ae7 | +| 2 | GREEN: Registry-Foundation + Calculator-Implementierung | Complete | 63ec93b | +| 3 | Full Suite + TypeCheck-Gate | Complete | — (no changes needed) | + +## Test Results + +- **calculator-widget.test.tsx**: 6 Tests — initiales Display "0", 7+3=10, 8×2=16, Division-durch-Null=Fehler, Keyboard 5*6Enter=30, Dezimalkomma 1,5+1,5=3 +- **widget-registry.test.tsx**: 10 Tests — alle 8 WidgetTypes haben 4 numerische Constraint-Felder +- **Full Web Suite**: 67/67 Tests bestehen +- **Web TypeScript**: sauber (0 Fehler) +- **API TypeScript**: 6 Pre-existing-Fehler (avatarPath — nicht durch diesen Plan verursacht) + +## Deviations from Plan + +### Pre-Existing Issue (out of scope) + +**API TypeScript-Fehler (avatarPath):** `src/auth/auth.service.ts` und `src/user/user.controller.ts` referenzieren `avatarPath` das noch nicht im Prisma-Client generiert wurde (Quick Plan 260630-gbh fugte Avatar-Feature hinzu, aber `prisma generate` wurde nach `db push` nicht in den Commit aufgenommen). Diese 6 Fehler existieren identisch im Main-Branch und wurden durch Plan 01 nicht eingefuehrt. Scope: DEFERRED. + +### Node Modules (worktree setup) + +Symlinks von `apps/web/node_modules` und `apps/api/node_modules` im Worktree auf Main-Repo-node_modules wurden erstellt um Tests lauffaehig zu machen. Die Symlinks sind in `.gitignore` (`node_modules/`) und werden nicht committed. + +### Test-Ausführungsbefehl (auto-fix) + +Der Plan spezifiziert `pnpm --filter @tessera/web test --run` — dieser Befehl existiert im Worktree nicht (`node_modules` fehlen initial). Fix: Symlinks erstellt, dann direkt `node_modules/.bin/vitest run` aufgerufen. Gleiches Ergebnis. + +### "Gleich"-Button ariaLabel + +Der `=`-Button hat `ariaLabel={`Gleich ${getOperatorLabel(pendingOperator)}`}`. Die Tests nutzen `getByRole('button', { name: /gleich/i })` (case-insensitive regex) statt des genauen Labels, was mit dem dynamischen Label kompatibel ist. + +## Known Stubs + +Keine Stubs. Calculator-Widget ist vollstaendig implementiert. Die Placeholder-Komponente fuer favorites/link/stopwatch in WIDGET_REGISTRY ist bewusst — diese Widgets werden in Plaenen 02-04 implementiert. + +## Threat Surface Scan + +Keine neuen Sicherheitsoberflaechen eingefuehrt. T-08-01 (Tampering via widgetType) und T-08-02 (DoS via Keyboard-Events) wurden gemaess Threat Model mitigiert. + +## Self-Check: PASSED + +| Item | Status | +|------|--------| +| calculator-widget.tsx | FOUND | +| calculator-widget.test.tsx | FOUND | +| widget-registry.test.tsx | FOUND | +| Commit b751ae7 (RED) | FOUND | +| Commit 63ec93b (GREEN) | FOUND |