功能实现细节¶
本文件是技术设计到代码的“施工图”。每个用户故事一节,开发 Agent 以此为准。 与
user-story-details.md的区别:那份偏业务/验收,本文件偏技术落地(模块、文件、事务、测试)。每个故事使用显式 HTML 锚点,保证 CSV 的
api_ref/ 实现文档引用可跳转:
US-004 创建任务¶
1. 涉及模块¶
backend/internal/usecase/taskbackend/internal/adapter/http/task_handler.gobackend/internal/adapter/postgres/repo/task_repo.gofrontend/src/views/ProjectBoardView.vuefrontend/src/components/task/CreateTaskModal.vue
2. 数据表¶
- 读:
projects,project_members,users - 写:
tasks,audit_logs,outbox - 关键约束:
tasks.project_id外键tasks.title长度 1-100tasks.priority枚举tasks.status枚举tasks.version乐观锁
3. API¶
POST /api/v1/tasks- Operation:
createTask - 请求/响应:见
openapi.yaml#/paths/~1tasks/post - 幂等:
Idempotency-Key,24 小时 - 认证:Bearer token
4. 业务逻辑¶
- 校验
project_id存在且未归档。 - 校验当前用户是项目成员。
- 校验
assignee_id是项目成员。 - 校验
due_date不早于今天(按用户时区)。 - 补齐默认值:
priority=medium、status=todo。 - 插入
tasks。 - 写
audit_logs(task.created)。 - 写
outbox(task.created事件)。 - 返回
TaskResponse。
5. 事务边界¶
- 步骤 6-8 在同一个数据库事务内。
- 通知发送在事务外,由 worker 消费
outbox。 - 事务失败时,任务、审计、事件全部回滚。
6. 错误码¶
| 场景 | HTTP | 错误码 |
|---|---|---|
| 标题为空/超长 | 400 | VALIDATION_ERROR |
| 项目不存在 | 404 | PROJECT_NOT_FOUND |
| 非项目成员 | 403 | FORBIDDEN |
| 项目已归档 | 409 | PROJECT_ARCHIVED |
| 负责人不在项目 | 400 | ASSIGNEE_NOT_IN_PROJECT |
| 重复幂等键 | 200/201 | 返回首次结果 |
7. 并发与幂等¶
- 幂等键作用域:用户 + 路由。
- 幂等记录保留 24 小时。
- 任务编号使用数据库序列,避免并发重复。
version用于更新,不用于创建。- 并发创建同名任务允许,不做唯一约束。
8. 后端实现要点¶
- Handler:解析 JSON、校验 DTO、获取 user/tenant、调用 usecase。
- Usecase:业务规则、权限、事务编排。
- Repo:参数化 SQL、插入、查询、审计、outbox。
- 错误:统一
domain.AppError,handler 集中映射。 - 日志:
request_id,user_id,tenant_id,project_id,task_id,duration_ms。 - 指标:
task_created_total{project_id}。
9. 前端实现要点¶
- 页面:项目看板 → “新建任务”弹窗。
- 字段:标题、描述、负责人、截止日期、优先级。
- 状态:
- 提交中:按钮 loading,禁止重复提交。
- 成功:关闭弹窗、乐观插入卡片、toast。
- 失败:保留输入、字段错误、表单级错误。
- 校验:与后端规则一致(Zod/表单校验)。
- 交互:Esc 关闭、点击遮罩关闭(未提交时)、焦点锁定。
- 可访问性:label、aria-describedby、focus ring。
10. 测试¶
10.1 单元测试¶
- 空标题、超长标题、非法 priority。
- 非项目成员 → 403。
- 负责人不在项目 → 400。
- 项目归档 → 409。
- 成功创建 → 返回正确字段。
- 默认值生效。
- 幂等重复请求 → 返回首次结果。
10.2 集成测试¶
- 插入任务 + 审计 + outbox 同事务。
- 事务回滚(模拟审计失败)。
- 唯一约束/外键。
- 并发创建。
10.3 API 测试¶
- 201 响应结构。
- 400/403/404/409 错误格式。
- 认证缺失 → 401。
10.4 E2E¶
- 正常创建。
- 空标题。
- 无权限。
- 日期非法。
- 刷新后持久化。
11. 文件所有权¶
可修改:
backend/internal/usecase/task/**backend/internal/adapter/http/task_handler.gobackend/internal/adapter/postgres/repo/task_repo.go- 对应
_test.go frontend/src/components/task/CreateTaskModal.vuefrontend/src/views/ProjectBoardView.vue- 对应前端测试
禁止修改:
backend/internal/adapter/http/router.gobackend/cmd/api/main.gobackend/migrations/**backend/api/openapi.yaml- 其他 Agent 的模块
12. 依赖与顺序¶
- 依赖:US-002(项目)、US-003(成员)。
- 被依赖:US-005(看板)。
- 合并顺序:US-002 → US-003 → US-004 → US-005。
13. 可观测性¶
- 日志字段:
request_id,user_id,tenant_id,project_id,task_id,duration_ms。 - 指标:
task_created_total、task_create_duration_seconds。 - 审计:
action=task.created,resource=task:<id>。 - 告警:创建失败率 > 1%(5 分钟)。
14. 完成定义¶
- 代码编译/类型检查通过
- 单元测试全绿
- 集成测试全绿
- E2E 通过
- 实现报告已生成
- CSV 状态更新为
qa_pass - 代码审查无 P0/P1
US-xxx <标题>¶
1. 涉及模块¶
<backend module><frontend component>
2. 数据表¶
- 读:
<tables> - 写:
<tables> - 关键约束:
<...>
3. API¶
<METHOD> <path>- Operation:
<operationId> - 幂等:
<...> - 认证:
<...>
4. 业务逻辑¶
<...><...>
5. 事务边界¶
<...>
6. 错误码¶
| 场景 | HTTP | 错误码 |
|---|---|---|
<...> |
<...> |
<...> |
7. 并发与幂等¶
<...>
8. 后端实现要点¶
<...>
9. 前端实现要点¶
<...>
10. 测试¶
- 单元:
<...> - 集成:
<...> - API:
<...> - E2E:
<...>
11. 文件所有权¶
可修改:
<path>
禁止修改:
<path>
12. 依赖与顺序¶
- 依赖:
<story_id> - 被依赖:
<story_id> - 合并顺序:
<...>
13. 可观测性¶
- 日志:
<...> - 指标:
<...> - 审计:
<...>
14. 完成定义¶
- 编译/类型检查
- 单元测试
- 集成测试
- E2E
- 实现报告
- CSV 状态
- 代码审查