Files
ftb-project-management/docs/specs/2026-06-11-dev-task-module-design.md
Script Generator a560634091 feat(dev-task): 开发任务模块 V1 完整实现
- 核心库:dev-task.ts(类型+状态机+进度计算)、task-worklog.ts(工时)、task-category.ts(字典)、work-item.ts(聚合契约)
- Store:useDevTaskStore(CRUD+状态流转)、useTaskWorklogStore(工时记录)、useTaskCategoryStore(字典管理)
- UI组件:DevTaskTab、DevTaskCreateModal、DevTaskDetailDrawer、DevTaskRow、WorklogPanel、StatusBadge、CategoryChip
- 集成:版本详情页"开发任务"Tab、"与我相关"工作台开发任务分组、任务类型管理页
- 设计文档:spec + 实施计划

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-11 18:02:07 +08:00

358 lines
11 KiB
Markdown
Raw Permalink 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.

---
title: 开发任务模块DevTask设计规格
date: 2026-06-11
module: dev-task
status: approved
---
# 开发任务模块DevTask— 设计规格
## 1. 定位与层级
DevTask 是"执行层"实体,归属于版本下某条需求,代表一个可分配、可追踪工时的开发工作项。
```
Version版本
├── VersionPlan计划层调研/产品/UI← 已有
├── DevTask执行层开发任务← 本文档
│ └── 归属于 Requirement需求
│ └── TaskWorklog工时记录
└── TestCase / Bug后续
```
### 归属关系
- DevTask **必须**归属于一条需求(`requirementId` 必填)
- `versionId` 从需求推导,不冗余存储
- 通过 `Requirement → Version` 链路追溯到版本和产品
## 2. 数据模型
### 2.1 DevTask开发任务
```typescript
interface DevTask {
id: string;
taskNo: string; // 自动生成DEV-001、DEV-002...
requirementId: string; // 所属需求(必填)
title: string;
description?: string;
categoryId: string; // 任务类型(字典表 TaskCategory
assigneeId: string; // 负责人
reviewerId?: string; // 验收人预留V1 可选不填)
priority: 'P0' | 'P1' | 'P2' | 'P3'; // 默认继承需求优先级,允许覆盖
estimateHours: number; // 预计工时(小时)
actualHours: number; // 实际工时(只读,= Σ TaskWorklog.hours
startDate?: string; // 开始日期 YYYY-MM-DD
dueDate?: string; // 截止日期 YYYY-MM-DD
completedAt?: string; // 完成日期 YYYY-MM-DD
status: DevTaskStatus;
isBlocked: boolean; // 阻塞标记(正交于 status
blockReason?: string; // 阻塞原因
blockedById?: string; // 造成阻塞的任务 ID可选
predecessorIds?: string[]; // 前置任务 ID 列表
riskLevel?: 'low' | 'medium' | 'high'; // 系统计算字段,不可手动编辑
createdBy: string;
createdAt: string;
updatedAt: string;
}
type DevTaskStatus = 'todo' | 'in_progress' | 'testing' | 'submitted' | 'done';
```
### 2.2 TaskWorklog工时记录
```typescript
interface TaskWorklog {
id: string;
taskId: string; // 所属 DevTask
userId: string; // 登记人
date: string; // YYYY-MM-DD
hours: number; // 当日投入小时数
workContent: string; // 工作内容(必填,为日报系统提供数据源)
createdAt: string;
}
```
- DevTask.actualHours = 该任务下所有 TaskWorklog.hours 的累加
- actualHours 字段只读,不允许直接编辑
- workContent 必填,格式示例:"完成排班页面基础布局"、"对接排班接口"
- V2 与加班记录、日报模块打通,统一为"工时记录中心"
- 日报可直接聚合当日 workContent 生成:`排班页面布局4h+ 接口联调2h= 6h`
### 2.3 TaskCategory任务类型字典
```typescript
interface TaskCategory {
id: string;
name: string; // 显示名称
group: 'development' | 'testing' | 'implementation' | 'other'; // 分组,用于报表统计
color?: string; // 图表配色
sortOrder: number; // 排列顺序
isSystem: boolean; // 系统预置不可删除
}
```
系统预置值:
| 名称 | 分组 | 说明 |
|------|------|------|
| 前端开发 | development | Web/移动端页面 |
| 后端开发 | development | API/服务层 |
| 数据库设计 | development | 表结构/迁移 |
| 接口联调 | development | 前后端对接 |
| 测试验证 | testing | 测试执行 |
| 缺陷修复 | testing | Bug 修复 |
| 数据处理 | implementation | ETL/数据清洗 |
| 实施支持 | implementation | 部署/实施 |
管理员可在"系统管理"中增删自定义类型。
## 3. 状态机
```
todo → in_progress → testing → submitted → done
↑ │ │
└─────────┘ │
↑ │
└────────────────────┘
```
| 状态 | 含义 | 推导进度 |
|------|------|---------|
| todo | 待开发 | 0% |
| in_progress | 开发中 | 50% |
| testing | 自测 | 80% |
| submitted | 提测 | 90% |
| done | 已完成 | 100% |
### 状态流转规则
正向流转:
- todo → in_progress → testing → submitted → done
允许回退(有限):
- testing → in_progress自测发现需要返工
- submitted → in_progress测试打回
禁止回退:
- done → 任何状态(完成是终态,返工走新任务或 Bug
- todo → 非 in_progress不能跳级
回退时记录操作日志(操作人、时间、原因)。
## 4. 阻塞设计(正交标记)
阻塞不是状态枚举值,而是叠加在任何状态之上的标记:
| 字段 | 类型 | 说明 |
|------|------|------|
| isBlocked | boolean | 是否被阻塞 |
| blockReason | string? | 阻塞原因描述 |
| blockedById | string? | 造成阻塞的任务 ID |
示例场景:
- `status=in_progress + isBlocked=true`:开发中但等后端接口
- `status=testing + isBlocked=true`:自测发现问题等需求确认
- `status=todo + isBlocked=true`:依赖的前置任务未完成
工作台筛选 `isBlocked=true` 可一键拉出所有阻塞项。
## 5. 进度计算规则
### 5.1 单任务进度
由 status 推导(见状态机表),不设人工填写的百分比字段。
### 5.2 需求级开发进度
```
需求开发进度 = Σ(任务.estimateHours × 任务状态推导进度) / Σ(任务.estimateHours)
```
示例:
| 任务 | 预计工时 | 状态 | 推导进度 | 加权 |
|------|---------|------|---------|------|
| 排班界面 | 16h | done | 100% | 16 |
| 排班规则组件 | 8h | in_progress | 50% | 4 |
| 排班算法接口 | 24h | todo | 0% | 0 |
需求进度 = (16 + 4 + 0) / (16 + 8 + 24) = 20 / 48 = **41.7%**
### 5.3 版本开发进度
```
版本开发进度 = Σ(版本下所有 DevTask.estimateHours × 状态推导进度) / Σ(estimateHours)
```
### 5.4 工时投入展示(辅助指标,不参与进度)
```
工时投入比 = Σ actualHours / Σ estimateHours
```
展示为:`已投入 32h / 预计 56h (57%)`
用途:工时偏差分析、健康度评估、加班趋势关联。
## 6. 工时展示规则
存储单位始终为**小时(h)**。展示时自动转换:
| 值 | 展示 |
|---|---|
| 4h | 4h |
| 8h | 8h1人天 |
| 16h | 16h2人天 |
| 24h | 24h3人天 |
转换规则:`1人天 = 8h`,仅当 ≥ 8h 时附带人天标注。
## 7. 优先级继承
```
Requirement.priority = P1
↓ 创建任务时默认继承
DevTask.priority = P1可覆盖为 P0/P2/P3
```
UI 行为:创建任务弹窗中,优先级字段预填为需求优先级,允许手动修改。
## 8. 前置任务(依赖)
| 字段 | 说明 |
|------|------|
| predecessorIds | string[],前置任务 ID 列表 |
V1 功能范围:
- 创建/编辑时可选择同版本内的其他 DevTask 作为前置
- 详情页展示前置任务列表,可跳转
- 前置任务未完成时,系统不阻止本任务开始(仅展示提示)
V2 扩展:
- 甘特图依赖线
- 关键路径计算
- 自动阻塞提醒
## 9. 风险等级(系统自动计算,不可手动编辑)
V1 预留 `riskLevel` 字段由系统自动计算UI 上不提供手动编辑入口。
V2 自动规则:
| 条件 | 风险等级 |
|------|---------|
| actualHours > estimateHours × 1.5 | high |
| today > dueDate 且 status ≠ done | high |
| isBlocked 持续超过 2 天 | high |
| actualHours > estimateHours × 1.2 | medium |
| today > dueDate - 3天 | medium |
| 其他 | low |
风险逐层汇总:任务 → 需求 → 版本 → 项目,与已有 `version.riskLevel` 计算保持一致。
设计原则:风险等级反映客观数据,不允许人为干预(避免"明明很危险但负责人填低风险")。
## 10. "与我相关"统一聚合层
### 10.1 统一工作项模型(锁定契约)
所有可分配实体必须遵守以下统一语义,新增实体类型时不得打破此契约:
```typescript
type WorkItem = {
entityType: 'plan' | 'devTask' | 'testCase' | 'bug';
entityId: string;
title: string;
status: string;
isBlocked?: boolean;
assigneeId: string; // 必须:负责人
reviewerId?: string; // 可选:验收人
versionId: string; // 必须:从各实体推导
versionName?: string;
priority?: string; // 必须:优先级
dueDate?: string; // 必须:截止日期
categoryLabel?: string; // 任务类型名称
};
```
未来新增实体(发布任务、实施任务、运维任务等)只需实现此接口,即可自动接入工作台,无需修改聚合逻辑。
### 10.2 工作台分组
左侧导航扩展:
| 分组 | 数据来源 | 状态 |
|------|---------|------|
| 全部待办 | 所有 entityType | — |
| 调研 | VersionPlan(type=research) | 已有 |
| 产品方案 | VersionPlan(type=product) | 已有 |
| UI设计 | VersionPlan(type=ui) | 已有 |
| 开发任务 | DevTask | 本次新增 |
| 测试/Bug | TestCase + Bug | 后续 |
### 10.3 右侧状态视图
按状态分列展示:
- 待处理todo / pending
- 进行中in_progress
- 阻塞isBlocked = true跨所有状态
- 待验收testing / submitted
### 10.4 联动规则
- 创建 DevTask 并指定 assigneeId → 自动出现在该成员"与我相关"
- 变更 assigneeId → 从原负责人工作台移除,加入新负责人工作台
- 状态变更 → 自动在工作台内移动列
## 11. 与加班模块的关系
已有加班记录存储小时数。未来数据链路:
```
TaskWorklog任务工时
↓ 当日工时 > 8h 部分
OvertimeRecord加班记录
↓ 按月汇总
加班统计仪表盘
```
V1 两个模块独立运行。V2 建立工时 → 加班自动关联。
## 12. 涉及新增文件(预估)
| 路径 | 说明 |
|------|------|
| `apps/web/lib/dev-task.ts` | DevTask 类型定义 + 进度计算函数 |
| `apps/web/lib/task-worklog.ts` | TaskWorklog 类型 + 聚合函数 |
| `apps/web/lib/task-category.ts` | TaskCategory 类型 + 预置数据 |
| `apps/web/stores/useDevTaskStore.ts` | DevTask 状态管理localStorage V1 |
| `apps/web/stores/useTaskWorklogStore.ts` | 工时记录状态管理 |
| `apps/web/components/dev-task/` | DevTask 相关组件目录 |
| `apps/web/app/versions/[id]/` | 版本详情页 DevTask Tab |
## 13. 不在本次范围
- 甘特图依赖线渲染
- 风险等级自动计算
- 工时 → 加班自动关联
- 测试用例 / Bug 模块
- 后端 API 实现V1 全部 localStorage