架构:新建 lib/linkage-engine.ts 联动引擎 - deriveReqDevStatus(): 从 devTasks 推导需求开发状态 - canEditRequirement(): 开发中的需求不可编辑 - checkVersionChangeRisk(): 版本变更风险检查 - 所有跨模块推导逻辑集中在此文件 功能改动: 1. 导航改名"需求"→"需求池" 2. 新建需求:所属产品/项目必填,移除产品负责人字段 3. 需求表格新增"开发状态"列: 未排期/待开发/开发中/已完成(从 devTasks 实时推导) 4. 开发中的需求:编辑按钮禁用 5. 需求设 versionId → 版本详情关联需求天然兼容 (版本详情通过 filter(r.versionId === versionId) 读取) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
1.9 KiB
TypeScript
53 lines
1.9 KiB
TypeScript
import type { DevTask, DevTaskStatus } from './dev-task';
|
|
|
|
export type ReqDevStatus = 'unscheduled' | 'todo' | 'developing' | 'completed';
|
|
|
|
export const REQ_DEV_STATUS_LABEL: Record<ReqDevStatus, string> = {
|
|
unscheduled: '未排期',
|
|
todo: '待开发',
|
|
developing: '开发中',
|
|
completed: '已完成',
|
|
};
|
|
|
|
export const REQ_DEV_STATUS_COLOR: Record<ReqDevStatus, string> = {
|
|
unscheduled: 'bg-zinc-100 text-zinc-500',
|
|
todo: 'bg-amber-50 text-amber-600',
|
|
developing: 'bg-blue-50 text-blue-600',
|
|
completed: 'bg-emerald-50 text-emerald-600',
|
|
};
|
|
|
|
/**
|
|
* 推导需求的开发状态
|
|
* 规则:根据关联的 devTasks 状态聚合推导
|
|
*/
|
|
export function deriveReqDevStatus(reqId: string, devTasks: DevTask[]): ReqDevStatus {
|
|
const tasks = devTasks.filter((t) => t.requirementId === reqId);
|
|
if (tasks.length === 0) return 'unscheduled';
|
|
if (tasks.every((t) => t.status === 'submitted')) return 'completed';
|
|
if (tasks.some((t) => t.status === 'in_progress' || t.status === 'testing')) return 'developing';
|
|
return 'todo';
|
|
}
|
|
|
|
/**
|
|
* 需求是否可编辑
|
|
* 规则:开发中(有 in_progress 或 testing 的任务)不可编辑
|
|
*/
|
|
export function canEditRequirement(reqId: string, devTasks: DevTask[]): boolean {
|
|
const status = deriveReqDevStatus(reqId, devTasks);
|
|
return status !== 'developing';
|
|
}
|
|
|
|
/**
|
|
* 需求设置 versionId 的副作用检查
|
|
* 当需求已有关联的开发任务时,换版本是高风险操作
|
|
*/
|
|
export function checkVersionChangeRisk(reqId: string, devTasks: DevTask[]): { safe: boolean; reason?: string } {
|
|
const tasks = devTasks.filter((t) => t.requirementId === reqId);
|
|
if (tasks.length === 0) return { safe: true };
|
|
const activeTasks = tasks.filter((t) => t.status !== 'submitted');
|
|
if (activeTasks.length > 0) {
|
|
return { safe: false, reason: `该需求有 ${activeTasks.length} 个未完成的开发任务,变更版本可能导致数据不一致` };
|
|
}
|
|
return { safe: true };
|
|
}
|