feat(ai): 优化拆解重跑与结果展示
This commit is contained in:
@@ -29,6 +29,11 @@
|
||||
- ❓ 注释含糊无法转化
|
||||
- 对账报告先呈现给用户,用户审核后才执行写入
|
||||
|
||||
4. **AI 预估不等于执行人预估**
|
||||
- AI 只能输出 `aiEstimateHours`
|
||||
- `estimateHours` 留给负责人/执行人确认后填写
|
||||
- AI 不输出预计开始/截止时间,排期由负责人后续维护
|
||||
|
||||
4. **历史版本不强制存储**
|
||||
- 系统不要求历史原型 URL 作为基准
|
||||
- 拆偏问题靠"对账报告"暴露给用户,由人工补救
|
||||
@@ -45,7 +50,7 @@
|
||||
- 当前版本关联需求列表(已被加进 Version 的 Requirement[])
|
||||
- 版本成员清单(带角色:前端/后端/UI/测试)
|
||||
|
||||
**调用入口**:版本详情页 → 产品方案 Tab → 计划状态 = completed 后,按钮「AI 拆解任务和用例」
|
||||
**调用入口**:版本详情页 → 产品方案 Tab → 计划状态 = completed 后,按钮「AI 拆解开发任务」或「AI 拆解测试用例」
|
||||
|
||||
**触发条件**:
|
||||
- 当前版本至少有 1 条 type=product 的 VersionPlan 处于 `completed` 且 resultUrl 非空(提交了原型)
|
||||
@@ -53,12 +58,16 @@
|
||||
|
||||
**输出**:
|
||||
- 对账报告(结构化文本,含"完美对应/单边/含糊"三段)
|
||||
- DevTask 草案数组(每条带 `aiDraft: true` + `references[]`)
|
||||
- TestCase 草案数组(每条带 `aiDraft: true` + `references[]`)
|
||||
- DevTask 草案数组(每条带 `aiDraft: true` + `references[]` + `aiEstimateHours`)
|
||||
- TestCase 草案数组(每条带 `aiDraft: true` + `references[]` + `aiEstimateHours`)
|
||||
- `target = dev_tasks` 时 `testCaseDrafts` 必须为空数组;`target = test_cases` 时 `devTaskDrafts` 必须为空数组
|
||||
|
||||
**写入**:
|
||||
- 用户确认后,调用 `useDevTaskStore.createTask` 和 `useTestCaseStore.createTestCase`
|
||||
- 打开采纳弹窗前,前端先过滤当前版本已采纳过的重复 DevTask/TestCase 草案
|
||||
- 写入字段中 `aiDraft: true`、`aiDraftAt: ISO时间戳`
|
||||
- 写入 `aiEstimateHours`,不写入执行人预估 `estimateHours`
|
||||
- DevTask 草案不写预计开始/截止时间,负责人后续排期时再填写
|
||||
|
||||
**权限**:
|
||||
- 读:Version, Requirement, VersionPlan, Member
|
||||
@@ -172,6 +181,7 @@ interface Reference {
|
||||
aiDraft?: boolean;
|
||||
aiDraftAt?: string; // ISO 时间戳
|
||||
references?: Reference[];
|
||||
aiEstimateHours?: number; // AI 预估耗时,单位小时
|
||||
```
|
||||
|
||||
### Agent 输入预期
|
||||
@@ -182,6 +192,7 @@ interface DecomposeInput {
|
||||
prototypeUrl: string; // 从产品方案 completed 计划的 resultUrl 派生
|
||||
requirements: Requirement[]; // 当前版本所属项目下已采纳、可用于本次拆解的需求
|
||||
members: VersionMember[]; // 该版本参与人员(带角色)
|
||||
target?: 'all' | 'dev_tasks' | 'test_cases';
|
||||
}
|
||||
```
|
||||
|
||||
@@ -197,12 +208,12 @@ interface DecomposeOutput {
|
||||
noteOnly: string[]; // 原型注释 ID 列表
|
||||
ambiguous: Array<{ noteId: string; reason: string }>;
|
||||
};
|
||||
devTaskDrafts: Array<Omit<DevTask, 'id' | 'taskNo' | 'createdAt' | 'updatedAt' | 'isBlocked' | 'categoryId'> & { categoryCode: string; aiDraft: true; aiDraftAt: string; references: Reference[] }>;
|
||||
testCaseDrafts: Array<Omit<TestCase, 'id' | 'caseNo' | 'createdAt' | 'updatedAt' | 'status' | 'categoryId'> & { categoryCode: string; aiDraft: true; aiDraftAt: string; references: Reference[] }>;
|
||||
devTaskDrafts: Array<{ title: string; description?: string; categoryCode: string; priority: Priority; aiEstimateHours: number; references: Reference[] }>;
|
||||
testCaseDrafts: Array<{ title: string; description: string; categoryCode: string; priority: Priority; aiEstimateHours: number; references: Reference[] }>;
|
||||
}
|
||||
```
|
||||
|
||||
要求:AI 不输出数据库 `categoryId`,只输出稳定 `categoryCode`。前端确认写入时按 `TaskCategory.code` 映射成 `categoryId`;映射失败时使用对应分组的默认类型兜底。
|
||||
要求:AI 不输出数据库 `categoryId`,只输出稳定 `categoryCode`。前端确认写入时按 `TaskCategory.code` 映射成 `categoryId`;映射失败时使用对应分组的默认类型兜底。AI 不输出 `estimateHours`、预计开始或预计截止。
|
||||
|
||||
## 视觉规范
|
||||
|
||||
|
||||
@@ -150,9 +150,11 @@ V2 接入后端后改为基于 `ProjectMember` 表的 RBAC(Owner/Admin/Member/
|
||||
| DevTask | references | Reference[]? | 引用来源(需求/原型批注) |
|
||||
| DevTask | aiDraft | boolean? | AI 草案标记 |
|
||||
| DevTask | aiDraftAt | string? | AI 生成时间戳 |
|
||||
| DevTask | aiEstimateHours | number? | AI 预估耗时;执行人预估仍写 estimateHours |
|
||||
| TestCase | references | Reference[]? | 同上 |
|
||||
| TestCase | aiDraft | boolean? | 同上 |
|
||||
| TestCase | aiDraftAt | string? | 同上 |
|
||||
| TestCase | aiEstimateHours | number? | AI 预估耗时;执行人预估仍写 estimateHours |
|
||||
|
||||
## 版本模块规则层(V2.2 设计约束)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- `testing` → 80%
|
||||
- `submitted` → 100%
|
||||
|
||||
**理由**:客观、不允许造假。需求级/版本级进度 = `Σ(estimateHours × 状态推导%) / Σ(estimateHours)`。
|
||||
**理由**:客观、不允许造假。需求级/版本级进度 = `Σ(估算耗时 × 状态推导%) / Σ(估算耗时)`。估算耗时优先取执行人填写的 `estimateHours`,没有时才用 AI 草案的 `aiEstimateHours` 兜底。
|
||||
|
||||
## 2. 实际工时 — 由开始/完成时间戳计算
|
||||
|
||||
@@ -269,3 +269,34 @@
|
||||
- 需求候选来源属于领域边界;统一 selector 能避免从需求池、项目需求、版本需求之间误取数据。
|
||||
- AI 不应该猜数据库 id;稳定语义码能兼容管理员调整展示名称,也方便后续扩展更多模型。
|
||||
- 测试用例带任务类型后,才能知道测试覆盖范围,AI 拆解和人工创建的数据形状也一致。
|
||||
|
||||
## 24. AI 预估和执行人预估分离
|
||||
|
||||
**问题**:AI 拆解写入 `estimateHours` 会让系统误以为负责人已经确认了工时和排期;同时 AI 会根据原型自动反推预计开始/截止,造成“计划已填”的错觉。
|
||||
|
||||
**决策**:
|
||||
- AI 输出字段统一改为 `aiEstimateHours`,不再输出/写入 `estimateHours`。
|
||||
- `estimateHours` 只表示执行人或负责人确认后的执行预估。
|
||||
- 进度和统计口径优先使用 `estimateHours`;缺失时使用 `aiEstimateHours` 兜底;两者都没有时才从计划时间推导或按无估时处理。
|
||||
- AI 采纳开发任务时不写预计开始/截止时间,由负责人后续填写计划排期。
|
||||
- AI 重新拆解入口拆成“重新拆解开发任务”和“重新拆解测试用例”,请求通过 `target` 控制本次只生成哪类草案。
|
||||
- AI 估时允许小于 0.5h,汇总时保留小数精度;实际耗时仍按状态时间戳计算并保持 0.5h 口径。
|
||||
|
||||
**理由**:
|
||||
- AI 给的是建议,不是负责人承诺。
|
||||
- 排期属于执行人计划,不能由拆解 Agent 代填。
|
||||
- 独立重拆能避免修改开发任务时顺手覆盖测试用例,降低误采纳风险。
|
||||
|
||||
## 25. AI 重新拆解先过滤已采纳重复草案
|
||||
|
||||
**问题**:第一次 AI 拆解的 DevTask/TestCase 已经被采纳后,用户再次重新拆解时,模型可能再次输出同一批草案。若直接展示给用户采纳,会造成开发任务和测试用例重复。
|
||||
|
||||
**决策**:
|
||||
- AI 返回结果后,前端在打开采纳弹窗前先做确定性去重。
|
||||
- 开发任务比对范围是当前版本已关联需求下的现有 DevTask;测试用例比对范围是当前版本下的现有 TestCase。
|
||||
- 重复判定使用:任务类型 code + 标题规范化 + 引用来源(需求 / 原型批注)一致。
|
||||
- 重复草案不进入采纳列表,只在弹窗提示已过滤数量。
|
||||
|
||||
**理由**:
|
||||
- 去重不能只依赖模型提示,必须有系统规则兜底。
|
||||
- 标题也参与签名,避免同一需求/QY 下不同真实工作项被误过滤。
|
||||
|
||||
@@ -135,21 +135,22 @@ Workspace 页面(树筛选 + tab 筛选 + 已完成开关)
|
||||
↓
|
||||
4. 从当前项目已采纳需求中关联需求到本版本
|
||||
↓
|
||||
5. 点击「AI 拆解任务和用例」按钮(位于产品方案 Tab)
|
||||
5. 点击「AI 拆解开发任务」或「AI 拆解测试用例」按钮(位于产品方案 Tab)
|
||||
↓
|
||||
6. Agent 从 product 类型的 completed 计划取 resultUrl 作为原型,
|
||||
抓取原型 + 关联需求 + 版本成员,输出对账报告 + 任务/用例草案
|
||||
↓
|
||||
7. 用户审核对账报告
|
||||
├─ 系统先自动过滤已采纳过的重复 DevTask/TestCase 草案
|
||||
├─ 报告全 ✅:直接确认写入
|
||||
├─ 报告有 ⚠️/❓:选择性放弃部分草案 / 补充信息后重跑
|
||||
└─ 报告全 ❓:放弃 AI 拆解,人工创建
|
||||
↓
|
||||
8. 确认后,DevTask / TestCase 草案写入对应 Tab,标记 aiDraft: true
|
||||
8. 确认后,DevTask / TestCase 草案写入对应 Tab,标记 aiDraft: true,并写入 aiEstimateHours
|
||||
↓
|
||||
9. 团队成员在 DevTask Tab 看到紫色边的 AI 草案任务
|
||||
↓
|
||||
10. 任意成员编辑任务(改标题/描述/负责人/优先级/时间/分类),保存后 aiDraft 自动清除
|
||||
10. 任意成员编辑任务(改标题/描述/负责人/优先级/时间/分类/执行预估),保存后 aiDraft 自动清除
|
||||
(changeStatus / setBlocked 等用户主动操作也会清除)
|
||||
```
|
||||
|
||||
@@ -179,6 +180,11 @@ Workspace 页面(树筛选 + tab 筛选 + 已完成开关)
|
||||
- 多个组件共用的候选筛选规则进 selector/helper。
|
||||
- AI 输入输出字段先更新 `agent-spec.md` 和 shared type,再改 prompt/schema。
|
||||
|
||||
AI 估时约束:
|
||||
- `aiEstimateHours` 是 AI 建议工时,只能由 AI 拆解写入。
|
||||
- `estimateHours` 是执行人预估,只能由人工创建/编辑或负责人确认排期时写入。
|
||||
- 统计进度优先取 `estimateHours`,没有时取 `aiEstimateHours`,避免 AI 草案在未确认前失去统计权重。
|
||||
|
||||
版本模块新增规则:
|
||||
|
||||
- `version-plan-workflow.ts` 是调研/产品方案/UI 设计完成条件的唯一入口。
|
||||
|
||||
Reference in New Issue
Block a user