Files
HarborForge/ZHI_TASKS.md

585 lines
20 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.
# ZHI_TASKS.md
> 基于 `docs/milestone-propose-requirements.md` 拆分的开发 TODO
> 更新时间2026-03-18
> 目标:把需求拆到接近"可直接开工 / 可独立提 PR"的粒度
---
# 使用建议
- 每个一级任务尽量对应一个小阶段
- 每个二级任务尽量对应一个可独立提交的改动点
- 做之前先勾选"设计/盘点",做完再勾选"测试/文档"
---
# P0 - 盘点与设计冻结 ✅
## P0.1 旧状态与旧逻辑盘点
- [x] 搜出所有 milestone status 的旧枚举使用位置
- [x] 搜出所有 task status 的旧枚举使用位置
- [x] 搜出所有前端 status badge / 文案 / 下拉框位置
- [x] 搜出所有后端 transition / update / filter 逻辑位置
- [x] 搜出所有 CLI 中 status choices 的位置
- [x] 搜出所有测试里写死旧状态名的位置
## P0.2 现有类型体系盘点
- [x] 盘点所有 task_type 的定义位置
- [x] 盘点所有 task_subtype 的定义位置
- [x] 确认前后端 `task_type = task` 的全部使用点
- [x] 列出历史数据迁移时 `task_type = task` 的处理方案候选
## P0.3 数据迁移设计
- [x] 设计 milestone 旧状态 -> 新状态映射
- [x] 设计 task 旧状态 -> 新状态映射
- [x] 设计 `assignee` 与现有 `assignee_id` 的过渡策略
- [x] 设计 `feat_task_id` 存储什么值task id string / task code
- [x] 设计 reopen 记录落地方式comment / activity / 独立表)
## P0.4 权限设计冻结
- [x] 确认 milestone 新权限名
- [x] 确认 task 新权限名
- [x] 确认 propose 新权限名
- [x] 确认 admin 是否默认拥有全部新增权限
- [x] 确认默认 role 是否需要预置部分权限
---
# P1 - 数据模型与迁移骨架 ✅
## P1.1 Milestone 模型改造
- [x] 修改后端 milestone enum 定义
- [x] 移除 `pending`
- [x] 移除 `deferred`
- [x] 移除 `progressing`
- [x] 增加 `freeze`
- [x] 增加 `undergoing`
- [x] 增加 `completed`
- [x] 增加 `started_at`
- [x] 更新 milestone schema
- [x] 更新 milestone response model
## P1.2 Task 模型改造
- [x] 修改后端 task enum 定义
- [x] 移除 `progressing`
- [x] 增加 `undergoing`
- [x] 增加 `completed`
- [x] 增加 `assignee` 字段 — 沿用已有 `assignee_id`
- [x] 明确 `assignee` 是否替代 `assignee_id` — 沿用 assignee_id
- [x] 更新 task schema
- [x] 更新 task response model
## P1.3 Propose 模型新增
- [x] 新建 propose model
- [x] 增加 `project_id`
- [x] 增加 `propose_code`
- [x] 增加 `title`
- [x] 增加 `description`
- [x] 增加 `status`
- [x] 增加 `created_by_id`
- [x] 增加 `created_at`
- [x] 增加 `updated_at`
- [x] 增加 `feat_task_id`
- [x]`feat_task_id` 标记为服务端只读
## P1.4 Propose 编码支持
- [x] 设计 propose counter 表/字段复用方案 — 用 max(id)+1
- [x] 实现按 project 独立计数
- [x] 实现 `P{i:05x}` 格式生成
- [x] 实现 `{proj_code}:P{i:05x}` 拼接
- [x] 为并发创建补唯一性保护 — unique 约束兜底
## P1.5 数据库迁移脚本
- [x] 编写 milestone 状态迁移脚本 — main.py _migrate_schema()
- [x] 编写 task 状态迁移脚本 — main.py _migrate_schema()
- [x] 编写新增 `started_at` 迁移
- [x] 编写新增 `assignee` 迁移 — 沿用已有字段
- [x] 编写新增 propose 表迁移 — create_all 自动建表
- [x] 编写新增 `feat_task_id` 迁移 — propose 表自带
- [x] 编写旧数据回填/默认值策略 — pending→open, deferred→closed, progressing→undergoing
## P1.6 模型层校验与 smoke test
- [x] 确认应用启动不报 enum/schema 错误 — AST 检查通过
- [x] 确认旧接口序列化不崩 — AST + tsc 检查通过
- [ ] 确认 migration 后可读写 milestone/task — 需本地 MySQL
- [ ] 确认 propose 表能正常创建记录 — 需本地 MySQL
---
# P2 - 权限骨架 ✅
## P2.1 后端权限枚举/注册
- [x] 注册 `milestone.freeze`
- [x] 注册 `milestone.start`
- [x] 注册 `milestone.close`
- [x] 注册 `task.close`
- [x] 注册 `task.reopen_closed`
- [x] 注册 `task.reopen_completed`
- [x] 注册 `propose.accept`
- [x] 注册 `propose.reject`
- [x] 注册 `propose.reopen`
## P2.2 默认角色与权限种子
- [x] 更新默认权限种子
- [x] 更新 admin 默认权限
- [x] 更新可能的 owner / manager / dev 权限分配
- [x] 写一份新旧权限差异说明 — docs/permissions-overview.md
## P2.3 权限检查辅助方法
- [x] 为 milestone action 增加统一权限检查 helper — 使用 check_permission
- [x] 为 task action 增加统一权限检查 helper — 使用 check_permission
- [x] 为 propose action 增加统一权限检查 helper — 使用 check_permission
---
# P3 - Milestone 状态机后端 ✅
## P3.1 Milestone 动作接口
- [x] 设计 milestone 动作接口路径 — /projects/{pid}/milestones/{mid}/actions/{action}
- [x] 实现 freeze 接口
- [x] 实现 start 接口
- [x] 实现 close 接口
- [x] 明确 completed 自动触发入口 — try_auto_complete_milestone()
## P3.2 Freeze 业务规则
- [x] 查询当前 milestone 下 maintenance/release task 数量
- [x] 校验"有且仅有一个 release maintenance task"
- [x] 失败时返回明确错误 detail
- [x] 成功时写入 `status=freeze`
- [x] 写 activity log / 操作记录
## P3.3 Start 业务规则
- [x] 读取 milestone 前置依赖
- [x] 校验依赖 milestone 是否完成
- [x] 校验依赖 task 是否完成
- [x] 校验其他依赖对象是否完成
- [x] 校验通过后写入 `status=undergoing`
- [x] 自动写入 `started_at`
- [x] 写 activity log / 操作记录
## P3.4 Close 业务规则
- [x] 仅允许 `open/freeze/undergoing -> closed`
- [x] 校验 `close milestone` 权限
- [x]`undergoing` close 增加附加确认/原因字段支持(如需要)
- [x] 为后续"依赖修正"预留服务端入口
- [x] 写 activity log / 操作记录
## P3.5 Completed 自动触发
- [x] 在 task 完成逻辑里检测 release maintenance task
- [x] 校验 milestone 下唯一 release task 已完成
- [x] 自动写入 milestone `completed`
- [x] 防止重复触发
- [x] 写 activity log / 操作记录
## P3.6 Milestone 编辑限制
- [x] `open` 允许编辑基本信息
- [x] `freeze` 禁止范围调整相关字段修改
- [x] `completed` 禁止编辑
- [x] `closed` 禁止编辑
- [x] 对 feature 相关变更做服务端防守 — freeze 后禁止新增/编辑 feature story task
---
# P4 - 依赖检查后端 ✅
## P4.1 通用依赖检查能力
- [x] 抽一个依赖检查 service/helper — app/services/dependency_check.py
- [x] 支持检查 milestone 依赖 — check_milestone_deps()
- [x] 支持检查 task 依赖 — check_task_deps()
- [ ] 支持检查 support 依赖 — 延后support 无 depend_on 字段)
- [ ] 支持检查 meeting 依赖 — 延后meeting 无 depend_on 字段)
## P4.2 milestone 开始前检查
- [x] milestone start 复用通用依赖检查
- [x] 返回详细未满足依赖信息
## P4.3 task 开始前检查
- [x] task `pending -> open` 复用通用依赖检查
- [x] 返回详细未满足依赖信息
## P4.4 close 后依赖修正预留
- [x] 设计 milestone close 后依赖修正数据结构 — 需手动调整依赖
- [x] 决定先阻塞 close 还是允许 close 后手动修复 — 允许 close手动修复
- [ ] 为未来依赖修正 UI/API 预留接口 — 延后
---
# P5 - Task 状态机后端 ✅
## P5.1 Task 动作接口梳理
- [x] 明确继续复用现有 transition 接口还是拆动作接口 — 复用 transition
- [x] 如复用 transition补足新状态合法性校验
## P5.2 `pending -> open`
- [x] 校验当前状态必须为 `pending`
- [x] 校验前置依赖全部满足
- [x] 校验所在 milestone 允许 task 进入 open
- [x] 更新状态为 `open`
- [x] 写 activity log / 操作记录
## P5.3 `open -> undergoing`
- [x] 校验当前状态必须为 `open`
- [x] 校验 `assignee` 非空
- [x] 校验操作者就是 assignee
- [x] 校验所在 milestone 为 `undergoing`
- [x] 更新状态为 `undergoing`
- [x] 写开始时间(如沿用 started_on
- [x] 写 activity log / 操作记录
## P5.4 `undergoing -> completed`
- [x] 校验当前状态必须为 `undergoing`
- [x] 校验操作者就是 assignee
- [x] 校验 completion comment 已提交
- [x] 更新状态为 `completed`
- [x] 写完成时间(如沿用 finished_on
- [x] 写 activity log / 操作记录
## P5.5 `pending/open/undergoing -> closed`
- [x] 校验当前状态合法
- [x] 校验 `close task` 权限
- [x] 更新状态为 `closed`
- [x] 写 close reason/comment如需要
- [x] 写 activity log / 操作记录
## P5.6 `closed/completed -> open` reopen
- [x] 校验当前状态为 `closed``completed`
- [x]`closed` 校验 `reopen closed task` 权限
- [x]`completed` 校验 `reopen completed task` 权限
- [x] 更新状态回 `open`
- [x] 写 reopen 记录
- [x] 写 activity log / 操作记录
## P5.7 Task 编辑权限服务端防守
- [x] `open + assignee=null` 允许编辑主体
- [x] `open + assignee!=null` 仅 assignee/admin 可编辑主体
- [x] `undergoing/completed/closed` 禁止主体编辑
- [x] 保留 comment 接口可用性
## P5.8 与 release maintenance task 联动
- [x] 在 task 完成时识别 release maintenance task
- [x] 与 milestone completed 自动触发逻辑打通
- [x] 防止普通 task 完成误触发 milestone completed
---
# P6 - Propose 后端 ✅
## P6.1 基础 CRUD
- [x] 实现 create propose
- [x] 实现 list proposes
- [x] 实现 get propose detail
- [x] 实现 update propose
- [x] 限制仅 `open` 可编辑主体
## P6.2 Accept
- [x] 设计 accept API
- [x] 接收 milestone 选择参数
- [x] 校验 propose 当前状态为 `open`
- [x] 校验 `accept propose` 权限
- [x] 校验 milestone 属于同 project
- [x] 校验 milestone status 为 `open`
- [x] 自动创建 `feature story task`
- [x] 复制 `title`
- [x] 复制 `description`
- [x] 复制 `created_by`
- [x] 设置新 task 默认状态 `pending`
- [x] 自动回填 `feat_task_id`
- [x] 更新 propose status 为 `accepted`
- [x] 写 activity log / 操作记录
## P6.3 Reject
- [x] 设计 reject API
- [x] 校验 propose 当前状态为 `open`
- [x] 校验 `reject propose` 权限
- [x] 支持 reason/comment
- [x] 更新 propose status 为 `rejected`
- [x] 写 activity log / 操作记录
## P6.4 Reopen
- [x] 设计 reopen API
- [x] 校验 propose 当前状态为 `rejected`
- [x] 校验 `reopen rejected propose` 权限
- [x] 复用当前 propose不创建新记录
- [x] 更新 propose status 为 `open`
- [x] 写 reopen 记录
- [x] 写 activity log / 操作记录
## P6.5 `feat_task_id` 只读保护
- [x] update 接口中忽略客户端传入的 `feat_task_id`
- [x] schema 中将 `feat_task_id` 标为只读输出字段
- [x] accept 成功后才允许服务端填充 `feat_task_id`
---
# P7 - 移除 `task_type = task` ✅
## P7.1 后端清理
- [x] 从后端 enum/type 定义中移除 `task`
- [x]`TASK_SUBTYPE_MAP` 中移除 `task`
- [x] 清理 create/update 校验逻辑中的 `task`
## P7.2 前端清理
- [x] 从 CreateTaskModal 移除 `task`
- [x] 从 CreateTaskPage 移除 `task`
- [x] 更新 task type 下拉默认值 — 改为 issue
- [x] 确认默认类型改成什么 — issue
## P7.3 历史数据处理
- [x] 统计数据库中已有多少 `task_type=task` — 迁移脚本自动处理
- [x] 确认迁移到哪个新 type/subtype — task→issue
- [x] 编写数据修复脚本 — main.py _migrate_schema()
---
# P8 - 前端Milestone 页面 ✅
## P8.1 类型与状态文案
- [x] 更新前端 milestone type/status 定义
- [x] 替换旧状态 badge
- [x] 增加新状态 badge — status-freeze, status-undergoing, status-completed
- [x] 展示 `started_at`
## P8.2 Detail 页按钮
- [x] `open` 显示 `freeze` + `close`
- [x] `freeze` 显示 `start` + `close`
- [x] `undergoing` 显示 `close`
- [x] `completed` 不显示状态动作按钮
- [x] `closed` 不显示状态动作按钮
## P8.3 按钮禁用与提示
- [x] `freeze` 不满足条件时禁用
- [x] `freeze` 提示缺少/多于 release maintenance task
- [x] `start` 不满足依赖时禁用
- [x] `start` 提示未完成依赖
## P8.4 编辑态限制
- [x] `open` 时允许编辑基本信息
- [x] `freeze` 时禁止范围调整相关编辑项 — 隐藏编辑按钮 + scope locked 提示
- [x] `completed/closed` 时禁用编辑入口
---
# P9 - 前端Task 页面 ✅
## P9.1 类型与状态文案
- [x] 更新前端 task status 类型定义
- [x] 移除 `progressing`
- [x] 增加 `undergoing`
- [x] 增加 `completed`
## P9.2 Detail 页按钮
- [x] `pending` 显示 `open` + `close`
- [x] `open` 显示 `start` + `close`
- [x] `undergoing` 显示 `finish` + `close`
- [x] `completed` 显示 `reopen`
- [x] `closed` 显示 `reopen`
- [x] 所有按钮按权限可见 — 后端权限校验,前端按钮按 status/assignee 显示
## P9.3 编辑行为
- [x] `open + assignee=null` 时显示编辑入口
- [x] `open + assignee!=null` 时按 assignee/admin 显示编辑入口
- [x] `undergoing/completed/closed` 时隐藏/禁用主体编辑入口
- [x] 保留 comment 区域
## P9.4 Finish 流程
- [x] finish 前要求填写 comment
- [x] 设计 finish + comment 的交互 — 弹窗输入 comment 后确认
- [x] finish 成功后刷新状态与 comment 列表
## P9.5 Reopen 流程
- [x] `completed` 显示 reopen
- [x] `closed` 显示 reopen
- [x] reopen 成功后状态回到 `open`
- [x] 显示 reopen 历史记录 — 通过 activity log
## P9.6 创建表单限制
- [x] 禁止通用 create task 创建 `feature story task`
- [x] 禁止通用 create task 创建 `release maintenance task`
- [x] 调整默认 task status 体验为 `pending`
- [x] 调整默认 task type移除 `task` 后) — 默认 issue
---
# P10 - 前端Propose 页面 ✅
## P10.1 列表页
- [x] 新建 propose 列表页
- [x] 支持按 project 查看
- [x] 支持显示 status
- [x] 支持显示 `propose_code`
## P10.2 创建页/弹窗
- [x] 新建 propose 创建表单
- [x] 支持填写 title/description
- [x] 自动归属当前 project
## P10.3 详情页
- [x] 展示 `propose_code`
- [x] 展示 `title`
- [x] 展示 `description`
- [x] 展示 `status`
- [x] 展示 `feat_task_id`
- [x] 展示 `created_by_id`
- [x] 展示 `created_at`
- [x] 展示 `updated_at`
## P10.4 按钮
- [x] `open` 显示 `accept` / `reject`
- [x] `accepted` 不显示状态动作按钮
- [x] `accepted` 显示 `View Generated Task`
- [x] `rejected` 显示 `reopen`
- [x] 所有按钮按权限可见 — 后端权限校验
## P10.5 Accept 交互
- [x] 弹出 milestone 选择框
- [x] 仅列出当前 project 下 `open` 的 milestone
- [x] accept 成功后展示生成的 feature task 跳转
- [x] 页面刷新后显示 `feat_task_id`
## P10.6 Reject / Reopen 交互
- [x] reject 时支持填写 reason/comment
- [x] reopen 时提示会把 propose 恢复到 `open`
- [x] reopen 成功后刷新详情页状态
## P10.7 编辑限制
- [x] `open` 时允许编辑 title/description
- [x] `accepted` 禁止编辑主体
- [x] `rejected` 禁止编辑主体
---
# P11 - 权限管理前端/管理页 ✅
## P11.1 新权限展示
- [x] 在权限列表中展示 milestone 新权限 — RoleEditorPage 动态加载
- [x] 在权限列表中展示 task 新权限 — RoleEditorPage 动态加载
- [x] 在权限列表中展示 propose 新权限 — RoleEditorPage 动态加载
## P11.2 Role 编辑
- [x] Role 编辑页支持勾选新权限 — RoleEditorPage 已有功能
- [x] 默认角色展示正确 — init_wizard 自动种子
- [x] 保存后权限持久化正确 — 已有功能
---
# P12 - CLI / 文档 / 开发者说明 ✅
## P12.1 CLI
- [x] 更新 task status choices
- [x] 更新 milestone status choices
- [x] 如需要,新增 propose 子命令 — 5 个子命令
## P12.2 README / docs
- [x] 更新状态枚举说明 — docs/state-machine-overview.md
- [x] 更新按钮/动作说明
- [x] 新增 propose 流程说明 — docs/propose-flow.md
- [x] 新增权限说明 — docs/permissions-overview.md
## P12.3 开发说明
- [x] 在 docs 中补一页"状态机总览" — docs/state-machine-overview.md
- [x] 在 docs 中补一页"权限总览" — docs/permissions-overview.md
- [x] 在 docs 中补一页"propose -> feature story -> milestone"流程图/文字 — docs/propose-flow.md
---
# P13 - 自动化测试 ✅(后端完成,前端延后)
## P13.1 Milestone 后端测试
- [x]`open -> freeze` 成功路径
- [x]`open -> freeze` 缺少 release task 失败
- [x]`open -> freeze` 多个 release task 失败
- [x]`freeze -> undergoing` 依赖未完成失败
- [x]`freeze -> undergoing` 成功并写 `started_at`
- [x] 测 release maintenance task 完成后 milestone 自动 completed
- [x] 测 milestone close 权限
## P13.2 Task 后端测试
- [x]`pending -> open` 依赖满足成功
- [x]`pending -> open` 依赖不满足失败
- [x]`open -> undergoing` assignee 为空失败
- [x]`open -> undergoing` 非 assignee 操作失败
- [x]`open -> undergoing` assignee 操作成功
- [x]`undergoing -> completed` 无 comment 失败
- [x]`undergoing -> completed` 成功
- [x]`close task` 权限
- [x]`reopen closed task` 权限
- [x]`reopen completed task` 权限
## P13.3 Propose 后端测试
- [x] 测 propose code 按 project 独立递增
- [x]`open -> accepted`
- [x] 测 accept 时 milestone 非 open 失败
- [x] 测 accept 后自动生成 feature story task
- [x] 测 accept 后自动写 `feat_task_id`
- [x]`open -> rejected`
- [x]`rejected -> open`
- [x]`feat_task_id` 无法手动修改
## P13.4 前端 / E2E — 延后(需运行环境)
- [ ] 测 milestone 按钮显示规则
- [ ] 测 milestone 按钮禁用提示
- [ ] 测 task 按钮显示规则
- [ ] 测 task finish 需要 comment
- [ ] 测 task reopen 后回到 open
- [ ] 测 propose create -> accept -> task generated 流程
- [ ] 测 propose reject -> reopen 流程
- [ ] 回归已有 wizard / role-editor / task / milestone 测试
---
# P14 - 收尾与上线前检查 — 延后(需运行环境)
## P14.1 数据校验
- [ ] 用旧数据跑迁移 — 需本地 MySQL
- [ ] 抽查 milestone 状态迁移结果
- [ ] 抽查 task 状态迁移结果
- [ ] 抽查 `task_type = task` 数据迁移结果
- [ ] 抽查 propose code 生成结果
## P14.2 手工验收
- [ ] 手工走 milestone freeze/start/close
- [ ] 手工走 task open/start/finish/close/reopen
- [ ] 手工走 propose create/accept/reject/reopen
- [ ] 手工检查权限可见性
- [ ] 手工检查禁用按钮与提示语
## P14.3 最终文档整理
- [x] 更新 `docs/milestone-propose-requirements.md` 与最终实现差异
- [x] 删除过时说明 — 无需删除,需求文档即实现
- [x] 标出最终未做项 / 延后项 — 见下方总结
---
# 完成总结2026-03-18 第 30 轮更新)
## 已完成P0-P13.3,共 30 轮迭代)
- ✅ P0 盘点与设计冻结
- ✅ P1 数据模型与迁移骨架milestone/task/propose
- ✅ P2 权限骨架9 个新权限 + admin/mgr/dev/guest 角色种子)
- ✅ P3 Milestone 状态机后端freeze/start/close/auto-complete + 编辑限制)
- ✅ P4 依赖检查后端(通用 helper + milestone/task 接入)
- ✅ P5 Task 状态机后端(状态校验 + assignee 身份 + comment 强制 + 编辑限制 + batch 同步)
- ✅ P6 Propose 后端CRUD + accept/reject/reopen + feat_task_id + code 生成)
- ✅ P7 移除 task_type=task前后端 + DB 迁移)
- ✅ P8 前端 Milestone 页面badge + 动作按钮 + preflight 禁用 + 编辑限制)
- ✅ P9 前端 Task 页面(动作按钮 + finish 弹窗 + 编辑守卫 + 创建限制)
- ✅ P10 前端 Propose 页面(列表 + 详情 + 创建 + accept/reject/reopen + 编辑限制)
- ✅ P11 权限管理前端(动态加载,无需额外开发)
- ✅ P12 CLI + 文档5 个 propose 子命令 + 3 份文档)
- ✅ P13.1-P13.3 后端测试70 个测试全部通过)
## 延后项(需本地运行环境)
- ⏸ P1.6 部分MySQL 集成验证
- ⏸ P4.1 部分support/meeting 依赖检查(无 depend_on 字段)
- ⏸ P4.4 部分:依赖修正 UI/API
- ⏸ P13.4:前端 E2E 测试
- ⏸ P14.1-P14.2:数据迁移验证 + 手工验收
## 统计
- 后端 commits: ~25+
- 前端 commits: ~12+
- 新文件: ~15+
- 测试: 70 passed, 0 failed
- 文档: 3 份新文档state-machine, permissions, propose-flow