# 版本模块规则引擎与任务类型设计 ## 背景 版本详情里的调研、产品方案、UI 设计、开发任务、测试用例已经形成一条执行链路,但有几处规则还散在 UI 组件里: - 开发任务的任务类型太粗,测试用例还没有任务类型。 - AI 拆解只输出 `role`,不能稳定落到当前系统的任务类型字典。 - 计划任务可以通过右上角勾选直接完成,绕过子任务和成果提交。 - 关联需求的候选来源不够明确,容易误用全量需求池。 - 调研、产品方案、UI 设计的关联需求选择缺少全选能力。 这次设计的目标是把这些规则收敛到字典、选择器和工作流引擎里,而不是继续在页面组件里散写条件。 ## 目标 1. 任务类型能支撑更细的开发与测试范围。 2. DevTask 和 TestCase 共用同一套任务类型字典。 3. AI 拆解必须输出任务类型,并能稳定映射到系统字典。 4. VersionPlan 的完成条件由统一规则函数判断。 5. 所有关联需求入口只从当前版本所属项目下的已采纳需求中选择,不从全量需求池选择。 6. 调研、产品方案、UI 设计的关联需求选择支持全选。 7. 项目文档明确约束:跨模块联动、状态流转、完成条件、AI 契约必须优先考虑引擎、状态机或统一规则函数。 ## 非目标 - 不做本地数据导入导出。 - 不在这一步把 `app_data` 全量拆成关系表。 - 不让 AI 自动分配负责人。 - 不让 AI 直接写入正式 DevTask/TestCase;仍然只写入草案。 ## 方案概览 新增或调整三个规则层: 1. `task-category.ts`:任务类型字典扩展为开发、测试、实施、其他,并增加稳定语义码。 2. `requirement-selector.ts`:统一筛选当前项目下可用于关联的需求。 3. `version-plan-workflow.ts`:统一计算计划进度、是否能提交成果、是否能完成、缺少什么条件。 页面组件只负责展示和触发动作,不直接决定业务规则。 ## 任务类型字典 `TaskCategory` 继续作为开发任务和测试用例的共享字典,但增加一个稳定字段: ```ts interface TaskCategory { id: string; // 存储主键,仍用于 DevTask.categoryId / TestCase.categoryId code: string; // 稳定语义码,给 AI 和映射逻辑使用 name: string; // 展示名称,可被管理员调整 group: 'development' | 'testing' | 'implementation' | 'other'; color?: string; sortOrder: number; isSystem: boolean; } ``` 推荐预置分类示例: - 开发:前端页面、前端交互、后端接口、后端业务逻辑、数据库/数据结构、权限/流程、第三方集成、接口联调 - 测试:功能测试、接口测试、异常场景、兼容性测试、回归测试、数据校验 - 实施:数据处理、实施支持、配置部署 - 其他:文档、协调、待确认 `id` 用于系统存储,`code` 用于 AI 输出和迁移兼容。管理员可以改名称,但不建议随意修改系统预置 `code`。 ## 测试用例任务类型 `TestCase` 增加 `categoryId`: ```ts interface TestCase { categoryId: string; } ``` 影响范围: - `TestCaseCreateModal` 增加任务类型必填项。 - `TestCaseRow` 和 `TestCaseDetailDrawer` 展示类型标签。 - `useTestCaseStore.fetchTestCases` 对旧数据做兼容补齐,默认映射到测试分组的第一个系统类型。 - AI 草案写入 TestCase 时也要映射 `categoryCode -> categoryId`。 ## 关联需求选择规则 所有关联需求入口统一使用同一套候选规则: ```ts requirements.filter((r) => r.projectId === version.projectId && r.status === 'adopted' ) ``` 含义: - 候选来自当前版本所属项目下的需求,不从产品级全量需求池直接取。 - 只有已采纳需求可被新选择。 - 如果历史计划已经关联了某条需求,但该需求后来不再满足候选条件,编辑时保留旧关联并标记为“历史关联”,避免悄悄丢数据。 - 版本需求 Tab、调研计划、产品方案、UI 设计、开发任务和测试用例中的需求选择都复用该规则函数。 调研、产品方案、UI 设计的关联需求控件增加: - 全选当前候选。 - 清空选择。 - 已选数量 / 候选数量提示。 - 候选为空时说明需要先在项目下采纳需求。 ## VersionPlan 工作流引擎 新增 `apps/web/lib/version-plan-workflow.ts`,作为计划完成规则的唯一入口。 建议导出: ```ts interface PlanCompletionState { checklistTotal: number; checklistCompleted: number; requirementTotal: number; requirementCompleted: number; hasResult: boolean; canSubmitResult: boolean; canComplete: boolean; missingReasons: string[]; } function getPlanCompletionState(plan: VersionPlan): PlanCompletionState; function canTogglePlanChecklist(plan: VersionPlan, now?: Date): boolean; function canEditPlanRequirementCoverage(plan: VersionPlan, now?: Date): boolean; ``` 完成规则: - 调研、产品方案、UI 设计都使用 `tasks` 作为子任务清单。 - 子任务必须全部勾选完成。 - 完成时必须提交成果,成果可以是链接或文件。 - 产品方案和 UI 设计如果有关联需求覆盖清单,也必须全部勾选覆盖完成。 - 右上角“直接完成”的勾选按钮取消。 - `PlanTab` 和 `PlanDetailDrawer` 都只调用工作流引擎,不再各自写完成条件。 状态写入仍保持: - `pending -> in_progress -> completed` - `actualStartAt` 在开始时写入。 - `completedAt` 只能通过提交成果完成时写入。 ## AI 拆解契约 AI 输出不直接返回数据库 `categoryId`,而是返回稳定语义码: ```ts interface AgentDevTaskDraft { title: string; description?: string; categoryCode: string; priority: 'P0' | 'P1' | 'P2' | 'P3'; estimateHours: number; references: AgentReference[]; } interface AgentTestCaseDraft { title: string; description: string; categoryCode: string; priority: 'P0' | 'P1' | 'P2' | 'P3'; references: AgentReference[]; } ``` 映射规则: 1. 优先按 `TaskCategory.code` 匹配。 2. 匹配不到时按名称做宽松匹配。 3. 仍匹配不到时,开发任务落到开发分组默认类型,测试用例落到测试分组默认类型。 4. 映射失败不阻断 AI 报告展示,但确认写入前必须能得到 `categoryId`。 `prompts/decompose.ts` 的 tool schema 要求 devTaskDrafts 和 testCaseDrafts 都必须带 `categoryCode`。 ## UI 行为 - 计划卡片右上角不再显示直接完成的勾选按钮。 - 完成入口改为“提交成果”,按钮在条件不足时禁用并展示缺失原因。 - 完成弹窗保留链接/文件两种结果类型。 - 调研、产品方案、UI 设计新建/编辑时都展示关联需求选择,并支持全选。 - 测试用例新建弹窗增加任务类型选择。 - AI 草案确认弹窗展示每条任务/用例的任务类型。 ## 兼容与迁移 当前业务数据仍存于 PostgreSQL `app_data` JSONB。 - 新增字段时在 store fetch 阶段做轻量兼容补齐。 - 旧 TestCase 没有 `categoryId` 时补齐默认测试类型。 - 旧 TaskCategory 没有 `code` 时按系统预置映射补齐;自定义类型生成稳定 code。 - 不恢复业务 localStorage 缓存。 ## 验证计划 实现时至少覆盖: - `version-plan-workflow` 单元测试: - 子任务未完成不能完成。 - 未提交成果不能完成。 - 子任务完成 + 成果存在才可完成。 - 产品方案/UI 设计有关联需求覆盖时,未覆盖完不能完成。 - 任务类型映射测试: - `categoryCode` 能映射系统类型。 - 未知 `categoryCode` 有合理 fallback。 - TestCase 旧数据能补齐类型。 - AI schema 测试: - devTaskDrafts 和 testCaseDrafts 都要求 `categoryCode`。 - 手工 UI 验证: - 调研/产品/UI 关联需求全选可用。 - 候选需求只来自当前项目已采纳需求。 - 顶部直接完成按钮消失。 - 测试用例创建必须选择任务类型。 ## 后续实现顺序 1. 写规则引擎和选择器测试。 2. 实现任务类型字典扩展和旧数据兼容。 3. 给 TestCase 增加 `categoryId`。 4. 接入 VersionPlan 工作流引擎。 5. 接入需求选择器和全选 UI。 6. 升级 AI schema、共享类型和草案写入映射。 7. 跑类型检查和核心测试。