Story 5 van PBI "Alle dialogen conform docs/patterns/dialog.md". - lib/schemas/sprint.ts — gedeelde zod-schemas (create/dates/goal) - actions/sprints.ts — code+fieldErrors voor 422; code: 403 voor auth/demo errors - StartSprintButton dialog: useDirtyCloseGuard, useDialogSubmitShortcut, entityDialog* layout-classes; DemoTooltip op trigger; veld-niveau errors via fieldErrors - SprintHeader's date- en complete-dialogen: zelfde behandeling; date- dialog krijgt dirty-guard, complete-dialog krijgt DemoTooltip op bevestigen - docs/specs/dialogs/sprint.md — entity-profile dat alle drie de modes documenteert; consolidatie naar één SprintDialog component bewust uitgesteld - Sprint-dates tests aangepast aan nieuwe action-shape Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.2 KiB
3.2 KiB
| title | status | audience | language | last_updated | ||
|---|---|---|---|---|---|---|
| Sprint Dialogs Profiel | active |
|
nl | 2026-05-04 |
Sprint Dialogs Profiel
Volgt
docs/patterns/dialog.md. Dit document beschrijft alleen de Sprint-specifieke afwijkingen en keuzes.
Sprint heeft drie dialog-flows verspreid over twee componenten:
| Flow | Locatie | Mode |
|---|---|---|
| Sprint starten | components/sprint/start-sprint-button.tsx |
create |
| Datums bewerken | components/sprint/sprint-header.tsx (inline) |
edit |
| Sprint afronden | components/sprint/sprint-header.tsx (inline) |
actie-bevestiging |
Daarnaast bestaat een inline edit-form voor de Sprint Goal in sprint-header.tsx — dat is geen dialog (geen modale overlay) maar een toggleable form-row.
Velden
Create / Edit dates
| Veld | Type | Validatie |
|---|---|---|
sprint_goal |
string (alleen create) | min 1, max 500 |
start_date |
date | null | optioneel; end_date >= start_date |
end_date |
date | null | optioneel; end_date >= start_date |
Complete sprint
Geen form-velden. Per story-rij in de sprint kiest de gebruiker 'DONE' of 'OPEN' (default 'OPEN'). De decisions-map wordt direct aan completeSprintAction doorgegeven.
URL- of state-pattern
- Gekozen: state-based (§11.2)
- Reden: alle dialogen zijn local-state in hun parent-component (button of header). Sprint heeft geen deep-link-bare detail-pagina voor zijn dialogen.
Server actions
createSprintAction(_prev, fd)—actions/sprints.ts— revalidate/products/${productId}updateSprintDatesAction(_prev, fd)— idem — revalidate/products/${productId}/sprintupdateSprintGoalAction(_prev, fd)— idem — revalidate/products/${productId}/sprintcompleteSprintAction(sprintId, decisions)— niet form-based; directe argumenten- Alle hebben
session.userId-check,session.isDemo-check (laag 2 demo-policy) enproductAccessFilter/getAccessibleProductvoor scope - Resultaat-shape:
{ success: true, ... }of{ error: string, code?: 422|403, fieldErrors?: Record<string, string[]> }
Foutcodes
| Code | Wanneer | UI |
|---|---|---|
| 422 | zod-validatie of date-order constraint | fieldErrors onder de velden, geen toast |
| 403 | niet ingelogd, demo-modus, of geen toegang | toast met message |
Schema
lib/schemas/sprint.ts exporteert:
createSprintSchema— productId, sprint_goal, start_date, end_dateupdateSprintDatesSchema— id, start_date, end_dateupdateSprintGoalSchema— id, sprint_goalvalidateDateOrder— refinement gebruikt door beide date-schemas
Alle drie de actions importeren hier; geen inline schemas meer.
Bewust NIET in v1
- ❌ Eén consolideerde
SprintDialog-component metmode: 'create' | 'edit-dates' | 'complete'— overwogen tijdens story 5 maar niet uitgevoerd; de dialogen leven natuurlijker in hun parent-component (button / header) en worden niet hergebruikt elders. Indien een vierde sprint-dialog ontstaat, hernieuw deze afweging. - ❌ Bewerken van de Sprint Goal vanuit deze dialogen — gebeurt via een inline-form in
sprint-header.tsx(toggleable, geen modal) - ❌ Sprint-templates / kopiëren van vorige sprint