// Bidirectionele case-mapper voor IdeaStatus + transitie-guard helper. // DB houdt UPPER_SNAKE; API exposeert lowercase. // Patroon volgt lib/task-status.ts. import type { IdeaStatus } from '@prisma/client' const IDEA_DB_TO_API = { DRAFT: 'draft', GRILLING: 'grilling', GRILL_FAILED: 'grill_failed', GRILLED: 'grilled', PLANNING: 'planning', PLAN_FAILED: 'plan_failed', PLAN_READY: 'plan_ready', PLANNED: 'planned', } as const satisfies Record const IDEA_API_TO_DB: Record = { draft: 'DRAFT', grilling: 'GRILLING', grill_failed: 'GRILL_FAILED', grilled: 'GRILLED', planning: 'PLANNING', plan_failed: 'PLAN_FAILED', plan_ready: 'PLAN_READY', planned: 'PLANNED', } export type IdeaStatusApi = (typeof IDEA_DB_TO_API)[IdeaStatus] export function ideaStatusToApi(s: IdeaStatus): IdeaStatusApi { return IDEA_DB_TO_API[s] } export function ideaStatusFromApi(s: string): IdeaStatus | null { return IDEA_API_TO_DB[s.toLowerCase()] ?? null } export const IDEA_STATUS_API_VALUES = Object.values(IDEA_DB_TO_API) // --------------------------------------------------------------------------- // State-machine transition table (zie docs/plans/M12-ideas.md state-machine). // Server-actions gebruiken canTransition(from, to) als guard vóór mutatie. // // Asymmetrisch: trek vanuit DRAFT alleen naar GRILLING; vanuit GRILLED kan // re-grill (→ GRILLING) of make-plan (→ PLANNING) gebeuren. PLANNED is een // terminal state; verlaat alleen via expliciete relink (PBI verwijderd → PLAN_READY). const ALLOWED_TRANSITIONS: Record> = { DRAFT: ['GRILLING'], GRILLING: ['GRILLED', 'GRILL_FAILED'], GRILL_FAILED: ['GRILLING', 'DRAFT'], GRILLED: ['GRILLING', 'PLANNING'], PLANNING: ['PLAN_READY', 'PLAN_FAILED'], PLAN_FAILED: ['PLANNING', 'GRILLED'], PLAN_READY: ['PLANNING', 'PLANNED', 'GRILLING'], // GRILLING via startGrillJobAction (re-grill) PLANNED: ['PLAN_READY', 'GRILLING'], // PLAN_READY via relinkIdeaPlanAction; GRILLING via startGrillJobAction } export function canTransition(from: IdeaStatus, to: IdeaStatus): boolean { return ALLOWED_TRANSITIONS[from].includes(to) } // Statussen waarin een idee bewerkbaar is (form-input, niet md-velden). const EDITABLE_STATUSES: ReadonlyArray = [ 'DRAFT', 'GRILL_FAILED', 'GRILLED', 'PLAN_FAILED', 'PLAN_READY', ] export function isIdeaEditable(s: IdeaStatus): boolean { return EDITABLE_STATUSES.includes(s) } // Statussen waarin grill_md bewerkbaar is (handmatige finetuning). export function isGrillMdEditable(s: IdeaStatus): boolean { return s === 'GRILLED' || s === 'PLAN_READY' } // Statussen waarin plan_md bewerkbaar is. export function isPlanMdEditable(s: IdeaStatus): boolean { return s === 'PLAN_READY' }