* fix(ideas): respecteer YAML-volgorde bij plan-materialize Tasks erven nu story-priority i.p.v. eigen task.priority bij materializeIdeaPlanAction. Worker sorteert op `priority ASC, sort_order ASC`; gemixte task-priorities binnen één story zouden anders de YAML-volgorde verstoren (e.g. tasks met priority 1/1/1/2/1/2 → worker-volgorde 1,2,3,5,4,6 i.p.v. 1,2,3,4,5,6). - actions/ideas.ts: priority = s.priority bij task-create - lib/schemas/idea.ts: task.priority optional (geaccepteerd, genegeerd) - lib/idea-prompts/make-plan.md: documenteer dat task.priority genegeerd wordt - __tests__/lib/idea-schemas.test.ts: test dat omitted task.priority slaagt Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(make-plan): documenteer backtick-format voor implementation_plan-paden verify_task_against_plan extraheert paden uit implementation_plan via twee regex-patronen (backticks + bullet). Paden inline in genummerde tekst-stappen worden niet herkend → planPaths.length=0 → bij diff >50 regels DIVERGENT. Voeg sectie "Bestandspaden in implementation_plan — verplicht format" toe die uitlegt welke formats werken (backticks, bullets) en welke niet (inline). Plus verband met verify_required-keuze: default ALIGNED_OR_PARTIAL behouden voor ADR-stubs en multi-file edits. Voorkomt herhaling van T-963 cancelled_by_self-symptoom waar implementatie slaagde maar verifier DIVERGENT teruggaf. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
// Velden die de gebruiker invult bij create/edit. Status wordt door
|
|
// server-actions gezet (niet door client-input).
|
|
export const ideaCreateSchema = z.object({
|
|
title: z.string().trim().min(1, 'Titel is verplicht').max(200, 'Maximaal 200 tekens'),
|
|
description: z.string().max(4000, 'Maximaal 4000 tekens').optional().nullable(),
|
|
product_id: z.string().cuid('Ongeldig product').optional().nullable(),
|
|
})
|
|
|
|
export const ideaUpdateSchema = ideaCreateSchema.partial()
|
|
|
|
export type IdeaCreateInput = z.infer<typeof ideaCreateSchema>
|
|
export type IdeaUpdateInput = z.infer<typeof ideaUpdateSchema>
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// plan_md frontmatter — strict format dat door make-plan-job geproduceerd
|
|
// wordt en door materializeIdeaPlanAction wordt geparseerd. Zie
|
|
// docs/plans/M12-ideas.md "Plan-md formaat A".
|
|
|
|
const verifyRequiredEnum = z.enum(['ALIGNED', 'ALIGNED_OR_PARTIAL', 'ANY'])
|
|
|
|
// Task-level priority is geaccepteerd in het schema voor backward-compat,
|
|
// maar wordt door `materializeIdeaPlanAction` genegeerd ten faveure van
|
|
// story-priority. Reden: worker sorteert op `priority ASC, sort_order ASC`
|
|
// — gemixte task-priorities binnen één story zouden de YAML-volgorde
|
|
// verstoren. Auteurs hoeven het veld dus niet meer in te vullen.
|
|
const planTaskSchema = z.object({
|
|
title: z.string().min(1).max(200),
|
|
description: z.string().max(4000).optional(),
|
|
implementation_plan: z.string().max(8000).optional(),
|
|
priority: z.number().int().min(1).max(4).optional(),
|
|
verify_required: verifyRequiredEnum.optional(),
|
|
verify_only: z.boolean().optional(),
|
|
})
|
|
|
|
const planStorySchema = z.object({
|
|
title: z.string().min(1).max(200),
|
|
description: z.string().max(4000).optional(),
|
|
acceptance_criteria: z.string().max(4000).optional(),
|
|
priority: z.number().int().min(1).max(4),
|
|
tasks: z.array(planTaskSchema).min(1, 'Story moet minimaal 1 taak hebben'),
|
|
})
|
|
|
|
const planPbiSchema = z.object({
|
|
title: z.string().min(1).max(200),
|
|
description: z.string().max(4000).optional(),
|
|
priority: z.number().int().min(1).max(4),
|
|
})
|
|
|
|
export const ideaPlanMdFrontmatterSchema = z.object({
|
|
pbi: planPbiSchema,
|
|
stories: z.array(planStorySchema).min(1, 'Plan moet minimaal 1 story bevatten'),
|
|
})
|
|
|
|
export type IdeaPlanFrontmatter = z.infer<typeof ideaPlanMdFrontmatterSchema>
|
|
export type IdeaPlanStory = z.infer<typeof planStorySchema>
|
|
export type IdeaPlanTask = z.infer<typeof planTaskSchema>
|