diff --git a/src/lib/pipeline/stage-machine.ts b/src/lib/pipeline/stage-machine.ts index f9b40b0..635cca2 100644 --- a/src/lib/pipeline/stage-machine.ts +++ b/src/lib/pipeline/stage-machine.ts @@ -2,16 +2,26 @@ import type { StageStatus } from "@/generated/prisma/client"; /** * Valid stage status transitions. + * + * NONE-approval stages take the IN_PROGRESS → APPROVED shortcut ("Mark + * Complete"). FORMAL/SIMPLE-approval stages route through IN_REVIEW + * first (the StageReviewPanel's Submit-for-Review → Approve flow). + * Both paths are allowed at the state-machine level; UI gating decides + * which one is exposed. + * + * CHANGES_REQUESTED → APPROVED and IN_PROGRESS → SKIPPED are quality- + * of-life shortcuts producers asked for so they don't have to bounce + * through an extra status to close out simple work. */ const TRANSITIONS: Record = { - BLOCKED: ["NOT_STARTED", "SKIPPED"], + BLOCKED: ["NOT_STARTED", "IN_PROGRESS", "SKIPPED"], NOT_STARTED: ["IN_PROGRESS", "SKIPPED"], - IN_PROGRESS: ["IN_REVIEW"], - IN_REVIEW: ["APPROVED", "CHANGES_REQUESTED"], - CHANGES_REQUESTED: ["IN_PROGRESS"], + IN_PROGRESS: ["IN_REVIEW", "APPROVED", "CHANGES_REQUESTED", "SKIPPED"], + IN_REVIEW: ["APPROVED", "CHANGES_REQUESTED", "IN_PROGRESS"], + CHANGES_REQUESTED: ["IN_PROGRESS", "APPROVED"], APPROVED: ["DELIVERED", "IN_PROGRESS"], // reopen if client sends updated files - DELIVERED: ["IN_PROGRESS"], // reopen for rework - SKIPPED: ["NOT_STARTED"], // unskip if stage becomes needed + DELIVERED: ["IN_PROGRESS", "APPROVED"], // reopen for rework + SKIPPED: ["NOT_STARTED", "IN_PROGRESS"], // unskip if stage becomes needed }; export function canTransition(