From bae0d478eacbd42250f9a40209fb3108277e4a0d Mon Sep 17 00:00:00 2001 From: Janpeter Visser Date: Sat, 2 May 2026 17:45:37 +0200 Subject: [PATCH] docs: add story-with-ui-component pattern + CLAUDE.md reference (#51) Documents the mandatory 3-task pattern (Helper / Component / Integration) for stories introducing UI components. Cites the 2026-05-02 Velocity story as the anti-pattern and the Foundation Sprint Health story as the blueprint. Co-authored-by: Claude Sonnet 4.6 --- CLAUDE.md | 1 + docs/patterns/story-with-ui-component.md | 64 ++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 docs/patterns/story-with-ui-component.md diff --git a/CLAUDE.md b/CLAUDE.md index 010083b..621104c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -112,6 +112,7 @@ Lees het relevante patroon vóór je begint. Nooit uit het hoofd schrijven. | QR-pairing (unauth-SSE + pre-auth cookie) | `docs/patterns/qr-login.md` | | Bidirectionele async-comms MCP-agent ↔ user | `docs/patterns/claude-question-channel.md` | | **Entity Dialog (verplicht voor élke create/edit/detail-dialog)** | `docs/patterns/dialog.md` — bron-of-truth; per entiteit één profile-doc (bv. `docs/scrum4me-task-dialog.md`) | +| **Story met UI-component (verplicht 3-task-patroon: Helper / Component / Integration)** | `docs/patterns/story-with-ui-component.md` — elke story met een `*-component.tsx` vereist een afsluitende Integration-task die de component in `page.tsx` wirt | | Status-enum mapping (DB ↔ API) | `lib/task-status.ts` | | Client/server module-boundary | `*-server.ts` bevat DB-calls of node-only deps; `*.ts` is pure (client-safe). Nooit `import { ... } from '@/lib/foo-server'` in een client-component, anders krijg je `Module not found: 'dns'`/`'pg'`-style runtime fouten | diff --git a/docs/patterns/story-with-ui-component.md b/docs/patterns/story-with-ui-component.md new file mode 100644 index 0000000..ea0ad82 --- /dev/null +++ b/docs/patterns/story-with-ui-component.md @@ -0,0 +1,64 @@ +# Patroon: Story met UI-component + +## Probleemstelling + +Zonder een afsluitende Integration-task leverden agent-batches helpers en components die nooit in de UI verschenen. De Velocity-story (`cmomu4xpq001obortc9enpvfa`) van 2 mei 2026 is het concrete incident: Helper (`getVelocity`) en Component (`VelocityChart`) werden gebouwd en getest, maar zonder Integration-task bleef de `/insights`-pagina leeg. + +## Verplicht patroon + +Elke story die een `*-component.tsx` introduceert **moet** minimaal drie tasks bevatten: + +| # | Type | Doel | Bestand | +|---|---|---|---| +| 1 | **Helper** | Data-aggregatie of business-logic | `lib//.ts` | +| 2 | **Component** | Presentational layer | `app/.../.tsx` | +| 3 | **Integration** | Wire component in page + verify renders | `app/...//page.tsx` | + +De Integration-task heeft `verify_required: ALIGNED` — de agent-verify moet de page.tsx in de diff terugzien voordat de job als `done` wordt geaccepteerd. + +## Blueprint: Foundation Sprint Health-story + +De story `cmomu0txi0016borthlautjjp` ("Foundation: route, recharts, sprint-dates migration, chart-colors helper") volgt dit patroon correct: + +- **Tasks 1–3** — Helper-tasks (sprint-dates migration, chart-colors, route scaffolding) +- **Task 4** — "Sprint-info-strip + integratie in /insights page" — sluit de loop: component wordt in `page.tsx` geïmporteerd en gerenderd + +Gebruik deze story als blueprint bij het aanmaken van nieuwe PBI's met UI-componenten. + +## Anti-patroon + +De Velocity-story had alleen Helper + Component. De Integration-task ontbrak: + +``` +✅ cmomu54pw001pbortedjhg2l8 Helper: getVelocity +✅ cmomu5bht001qbortlcq15arc Component: VelocityChart +❌ (ontbreekt) Integration: wire VelocityChart into /insights page +``` + +Resultaat: de component bestaat en compileert, maar is nergens te zien. + +## Reviewchecklist bij PBI-creatie + +Voordat een PBI met UI-features naar de backlog gaat: + +- [ ] Elke story die een `*-component.tsx` introduceert heeft een Integration-task +- [ ] Integration-task raakt minimaal `app/(app)//page.tsx` +- [ ] Integration-task heeft `verify_required: ALIGNED` (of een equivalent verify-gate) +- [ ] Integration-task title volgt het formaat: `Integration: wire into ` + +## Template (kopieer bij elke nieuwe UI-story) + +``` +Task 1 — Helper: + Bestand: lib//.ts + Tests: minimaal 3 scenario's + +Task 2 — Component: + Bestand: app/(app)//components/.tsx + Tests: TypeScript + render-smoke + +Task 3 — Integration: wire into / page + Bestanden: app/(app)//page.tsx + verify_required: ALIGNED + Done when: component verschijnt in de browser zonder empty-state op dev-data +```