import type { DevTask, DevTaskStatus } from './dev-task'; import { canStartDevTask, canTransition } from './dev-task'; export interface DevTaskWorkflowResult { ok: boolean; patch?: Partial; message?: string; } export interface DevTaskTransitionOptions { now?: Date; delayReason?: string; } export function normalizeDevTaskOnCreate(task: DevTask): DevTask { return { ...task, status: 'todo', actualStartAt: undefined, actualEndAt: undefined, }; } export function applyDevTaskTransition( task: DevTask, to: DevTaskStatus, options: DevTaskTransitionOptions = {}, ): DevTaskWorkflowResult { if (!canTransition(task.status, to)) { return { ok: false, message: `不允许从「${task.status}」流转到「${to}」` }; } if (to === 'submitted' && task.isBlocked) { return { ok: false, message: '任务仍处于阻塞中,请先解除阻塞后再提测' }; } const nowIso = (options.now ?? new Date()).toISOString(); if (to === 'in_progress' && !canStartDevTask(task)) { return { ok: false, message: '开始开发前需要先领取并填写预计开始和预计截止时间' }; } const patch: Partial = { status: to, aiDraft: false, }; if (to === 'in_progress' && !task.actualStartAt) { patch.actualStartAt = nowIso; if (options.delayReason?.trim()) patch.delayReason = options.delayReason.trim(); } if (to === 'submitted') { patch.actualEndAt = nowIso; } return { ok: true, patch }; }