Files
schalli 5e8b2c2c39 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
2026-07-01 10:01:15 +02:00

6.0 KiB
Raw Permalink Blame History


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