| title |
status |
audience |
language |
last_updated |
| ProductDialog Profiel |
active |
|
nl |
2026-05-04 |
ProductDialog Profiel
Volgt docs/patterns/dialog.md. Dit document beschrijft alleen de afwijkingen en entity-specifieke keuzes.
Velden
| Veld |
Type |
Mode |
Validatie |
name |
string |
both |
min 1, max 200 |
code |
string? |
both |
max 20, alleen [a-zA-Z0-9._-]; uniek per gebruiker |
description |
string? |
both |
max 4000, markdown vrij |
repo_url |
string? | null |
both |
https URL, moet beginnen met https://github.com/ |
definition_of_done |
string? |
both |
max 4000, vrije tekst |
auto_pr |
boolean |
both |
default false |
URL- of state-pattern
- Gekozen: state-based (§11.2)
- Reden: dialog leeft binnen één parent-component (
ProductList op /dashboard en de product-actions-bar op /products/[id]); deep-linking is niet vereist
- Open-state komt uit
ProductList (lijst-context) of EditProductButton (single-item context)
Status-veld
N.v.t. — Product heeft geen status-enum. archived is een boolean buiten dit dialog (eigen archive-flow).
Server actions
createProductAction(data) in actions/products.ts — context-arg via revalidatePath('/products') + revalidatePath('/dashboard')
updateProductAction(id, data) in actions/products.ts — context-arg via revalidatePath('/products/${id}') + revalidatePath('/dashboard') + pg_notify('product_updated')
- Beide hebben
session.userId-check, session.isDemo-check (laag 2 demo-policy) en productAccessFilter voor update
- Resultaat-shape:
{ success: true, productId? } of { error: string, code?: 422|403, fieldErrors?: Record<string, string[]> }
Foutcodes
| Code |
Wanneer |
UI |
| 422 |
zod-validatie of code-uniqueness |
fieldErrors → form.setError, geen toast, focus naar eerste error-veld |
| 403 |
niet ingelogd, demo-modus, of geen toegang tot product |
toast met message |
| 500 |
onverwacht |
huidige behandeling: error wordt door React opgevangen — laat de form open |
Speciale gedragingen
- Custom switch voor
auto_pr: native <button role="switch"> met MD3-kleur-tokens (geen aparte primitive in v1; zou gepromoot moeten worden naar components/shared/switch.tsx zodra elders nodig).
- Code-uniqueness server-side: bij conflict wordt
fieldErrors.code gezet; veld krijgt rode rand.
useProductsStore updates: na succesvolle save wordt de in-memory store synchroon bijgewerkt zodat de productlijst onmiddellijk reageert (lokaal-first).
Bewust NIET in v1
- Verwijderen vanuit deze dialog (loopt via
archiveProductAction op een andere knop)
- Bulk edit
- Members beheren (eigen scherm op
/products/[id]/settings)