Story 3 van PBI "Alle dialogen conform docs/patterns/dialog.md". - lib/schemas/pbi.ts — gedeeld zod-schema (createPbiSchema/updatePbiSchema) - actions/pbis.ts — returnen nu code+fieldErrors (422) en code: 403 voor auth/demo errors - PbiDialog adopt useDirtyCloseGuard, useDialogSubmitShortcut, entityDialog* layout-classes; submit-knop + Annuleren in DemoTooltip - isDemo-prop toegevoegd, pbi-list geeft 'm door - docs/specs/dialogs/pbi.md — "Bekende gaps" weggewerkt; alleen bewuste uitsluitingen blijven Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
26 lines
857 B
TypeScript
26 lines
857 B
TypeScript
import { z } from 'zod'
|
|
import { MAX_CODE_LENGTH } from '@/lib/code'
|
|
|
|
const codeField = z.string().max(MAX_CODE_LENGTH).optional()
|
|
const statusField = z.enum(['ready', 'blocked', 'done']).optional()
|
|
|
|
export const createPbiSchema = z.object({
|
|
productId: z.string(),
|
|
code: codeField,
|
|
title: z.string().min(1, 'Titel is verplicht').max(200),
|
|
description: z.string().max(2000).optional(),
|
|
priority: z.coerce.number().int().min(1).max(4),
|
|
status: statusField,
|
|
})
|
|
|
|
export const updatePbiSchema = z.object({
|
|
id: z.string(),
|
|
code: codeField,
|
|
title: z.string().min(1, 'Titel is verplicht').max(200),
|
|
description: z.string().max(2000).optional(),
|
|
priority: z.coerce.number().int().min(1).max(4),
|
|
status: statusField,
|
|
})
|
|
|
|
export type CreatePbiInput = z.infer<typeof createPbiSchema>
|
|
export type UpdatePbiInput = z.infer<typeof updatePbiSchema>
|