Files
ftb-project-management/docs/decisions.md
Script Generator 6d2f6d8b9f docs+fix: 4份核心文档 + 项目模块版本记录数据全联动
文档:
- architecture.md - 整体架构、心智模型、关键设计原则
- decisions.md - 16条关键决策记录(含为什么)
- workflow.md - 工作流程和协作偏好
- roadmap.md - V1/V2/V3 路线图和已完成清单

修复项目详情版本记录:
1. 状态胶囊数据联动(开发中分支也补传 stageProgress)
2. 日期数据联动:
   - 实际开始 = 取所有阶段最早 actualStartAt/startDate/startedAt
   - 实际截止 = 取所有阶段最晚 completedAt/closedAt
   - 数据完全和版本详情一致

VersionCard 的 versionData useMemo 增加 actualStart/actualEnd 派生字段,
两种状态分支(developing/released)都使用派生值,不再用静态 version.startDate

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-16 12:40:10 +08:00

158 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 关键设计决策记录
每条决策都包含**为什么这么做**,避免后续模型重新讨论或推翻。
## 1. 进度计算 — 由状态推导,不要手填百分比
**问题**Jira/TAPD 等系统让开发手填进度20%/35%/50%),数据完全主观,不可靠。
**决策**DevTask 进度由 `status` 推导:
- `todo` → 0%
- `in_progress` → 50%
- `testing` → 80%
- `submitted` → 100%
**理由**:客观、不允许造假。需求级/版本级进度 = `Σ(estimateHours × 状态推导%) / Σ(estimateHours)`
## 2. 实际工时 — 由开始/完成时间戳计算
**问题**:让人手填工时太粗糙(一天 8h 真的全部花在这个任务吗?)。
**决策**:精确到 0.5h 的时间差计算
```
实际工时 = (completedAt - startDate) / 3600000精确到 0.5h
```
**理由**:状态流转时自动记录精确时间戳,工时直接派生。
## 3. DevTask "已提测" = 终态
**问题**:原本有 `submitted → done`,但开发提测之后就交付完成了,后续测试结果不应该回过来改 DevTask 状态。
**决策**:去掉 `done``submitted` 是终态。测试通过/失败产生 Bug不影响 DevTask。
**理由**DevTask 的责任是"开发到提测",验收是 TestCase 的职责。
## 4. 调研/产品/UI — 自动开始 + 手动提前开始
**问题**:到了计划开始日期,状态还是 pending 不合理。
**决策**
- 当前时间 ≥ `startTime` 时自动视为 in_progress
- 用户可在计划日期前手动点"开始"
- 自动开始时记录 `actualStartAt`(精确到分钟)
**理由**:减少冗余操作但保留灵活性。
## 5. TestCase 主归属版本,需求是可选标签
**问题**:早期把测试用例挂在需求上,但同一需求跨版本迭代时用例难以管理。
**决策**
- TestCase.versionId 必填(执行归属)
- TestCase.requirementId 可选(语义标签)
- 测试人员从"我的测试用例"看到的就是当前版本的用例
**理由**:测试是按版本执行的,不是按需求;但需求作为思考维度仍然有用。
## 6. Bug 直接挂版本
**问题**:早期通过 `Bug → TestCase → Requirement → Version` 四级反查,太绕。
**决策**Bug 增加 `versionId` 字段,直接挂版本。`testCaseId` 保留作为来源追溯。
**理由**:判断"能不能发布"的唯一维度是版本,必须 O(1) 查询。
## 7. 跨模块通信 — 引擎层,不是事件总线
**问题**模块多了A store 改动影响 B 的派生数据,散落各处难维护。
**决策**:建立**纯函数引擎**
- `linkage-engine.ts`:从 DevTask 状态派生需求"实际进度"
- `workspace-engine.ts`:聚合所有 store 数据为统一 WorkItem
**理由**:事件总线过度设计,纯函数派生更可预测。新增模块只需在引擎中添加聚合逻辑。
## 8. 时间字段统一 ISO 时间戳到分钟
**问题**:日期(`YYYY-MM-DD`) vs 时间戳混用UI 展示不一致。
**决策**:所有"实际开始/完成"用 `new Date().toISOString()`,展示统一 `slice(0, 16).replace('T', ' ')`
**理由**:时间戳到分钟够精确,不像秒/毫秒那么噪。
## 9. 任务类型字典化 + 分组
**问题**:早期 enum 写死类型(前端/后端/大数据/其他),新增类型需改代码。
**决策**:建 TaskCategory 字典表 + groupdevelopment/implementation/other管理员可增删。
**理由**:业务变化快,配置 > 写死。group 方便统计(开发工时 vs 实施工时)。
## 10. 阻塞正交标记,不是状态值
**问题**`status: blocked` 会丢信息——`开发中+阻塞``自测+阻塞`
**决策**
- `status: todo|in_progress|testing|submitted`
- `isBlocked: boolean` + `blockReason: string` + `blockedById: string`
**理由**:阻塞和状态正交。工作台筛选 `isBlocked=true` 一键拉出所有阻塞项,跨状态。
## 11. 加班原因可选,且去掉"其他"
**问题**:可选"其他"会让人逃避思考具体原因。
**决策**:变更原因/加班原因严格定义有限选项,**没有"其他"**。
**理由**:强制具体化,统计才有意义。
## 12. 项目维度 vs 个人维度耗时分开计算
**问题**:多个开发并行做任务,简单加总会重复计算时间。
**决策**
- **个人耗时**:每个任务独立累加(`Σ(end - start)`
- **项目维度阶段耗时**`min(start)``max(end)` 日历跨度(不重复)
**理由**:两个维度回答不同问题——"谁花了多少时间" vs "这个阶段拖了多久"。
## 13. 删除版本时清理孤儿数据
**问题**:删版本只删 version 实体,留下 PlanTask/DevTask/TestCase/Bug 变成孤儿数据。
**决策**:删除版本时级联清理:
1. 释放需求 versionId回需求池
2. 删除 PlanTask
3. 删除 DevTask通过需求 ID
4. 删除 TestCase
5. 删除 Bug
**理由**localStorage 没外键约束,必须手动级联。
## 14. 工作台数据点击 → 侧边详情 + 可操作
**问题**:早期工作台只显示信息,操作要跳转到版本详情。
**决策**:点击卡片打开 Drawer复用版本详情用的同一组件可在 Drawer 内完成状态流转、转交、提 Bug 等。
**理由**减少跳转工作台一站式处理。Drawer 顶部显示"产品/项目/版本"上下文,不会迷失。
## 15. UI 阴影统一 shadow-2xl
**问题**:各 Drawer 阴影不一致(有些 `shadow-lg` 有些 `shadow-2xl`)。
**决策**:全局 Drawer 用 `shadow-2xl`
**理由**:视觉权重明显,且一致。
## 16. 不进入 Brainstorm 模式的判定
**约定**:以下情况直接修复,**不强制走 brainstorming 流程**
1. Bug fix明确 bug方案直接
2. 已批准方案的 in-progress 延续
3. 用户已通过 AskUserQuestion 选择了方案
4. 简单文案/样式调整
**理由**brainstorming 适合新功能设计bug fix 强行套流程浪费时间。