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

5.9 KiB
Raw Blame History

关键设计决策记录

每条决策都包含为什么这么做,避免后续模型重新讨论或推翻。

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 状态。

决策:去掉 donesubmitted 是终态。测试通过/失败产生 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 强行套流程浪费时间。