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
This commit is contained in:
@@ -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 |
|
||||||
Reference in New Issue
Block a user