import type { Permission } from '@/lib/auth/permissions' /** * Lebenszyklus einer Akte, siehe docs/05-akten-und-vorlagen.md. * * DRAFT ──► OPEN ──► REVIEW ──► CLOSED ──► ARCHIVED * │ ▲ │ * ▼ │ └──► OPEN (Rückgabe zur Nachbesserung) * DORMANT * * SEALED ist aus jedem Zustand erreichbar und nur mit Recht 'admin' oder * Stufe 5 lesbar. */ export type CaseStatusName = | 'DRAFT' | 'OPEN' | 'DORMANT' | 'REVIEW' | 'CLOSED' | 'ARCHIVED' | 'SEALED' export type Transition = { from: CaseStatusName to: CaseStatusName permission: Permission /** Verlangt eine Begründung, die als Vermerk im Verlauf landet. */ requiresReason?: boolean /** Verlangt, dass alle `requiredToClose`-Felder gefüllt sind. */ requiresCompleteSections?: boolean } export const TRANSITIONS: readonly Transition[] = [ { from: 'DRAFT', to: 'OPEN', permission: 'case.edit' }, { from: 'OPEN', to: 'DORMANT', permission: 'case.edit' }, { from: 'DORMANT', to: 'OPEN', permission: 'case.edit' }, { from: 'OPEN', to: 'REVIEW', permission: 'case.edit' }, { from: 'REVIEW', to: 'OPEN', permission: 'case.edit' }, { from: 'REVIEW', to: 'CLOSED', permission: 'case.close', requiresCompleteSections: true }, { from: 'CLOSED', to: 'OPEN', permission: 'case.reopen', requiresReason: true }, { from: 'CLOSED', to: 'ARCHIVED', permission: 'case.close' }, ] /** SEALED erreicht man aus jedem Zustand, aber nur mit dem Recht 'admin'. */ export const SEAL_PERMISSION: Permission = 'admin' export function findTransition( from: CaseStatusName, to: CaseStatusName, ): Transition | undefined { if (to === 'SEALED' && from !== 'SEALED') { return { from, to, permission: SEAL_PERMISSION, requiresReason: true } } return TRANSITIONS.find((t) => t.from === from && t.to === to) } export function allowedTargets(from: CaseStatusName): CaseStatusName[] { const targets = TRANSITIONS.filter((t) => t.from === from).map((t) => t.to) if (from !== 'SEALED') targets.push('SEALED') return targets }