---
title: "Sprint Dialogs Profiel"
status: active
audience: [ai-agent, contributor]
language: nl
last_updated: 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}/sprint`
- `updateSprintGoalAction(_prev, fd)` — idem — revalidate `/products/${productId}/sprint`
- `completeSprintAction(sprintId, decisions)` — niet form-based; directe argumenten
- Alle hebben `session.userId`-check, `session.isDemo`-check (laag 2 demo-policy) en `productAccessFilter`/`getAccessibleProduct` voor 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_date
- `updateSprintDatesSchema` — id, start_date, end_date
- `updateSprintGoalSchema` — id, sprint_goal
- `validateDateOrder` — 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** met `mode: '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
