跳转至

11 完整实战:从 0 到 1 做一个任务系统

本章用一个虚构但完整的项目 TeamTask,把前面十章串起来。你可以照着做一遍,但不要照抄所有细节——重点看 每个阶段产出什么、门禁怎么过、Agent 怎么分工。


0. 项目背景

  • 客户:20 人的咨询团队
  • 现状:用 Excel + 微信群管理任务
  • 痛点:负责人不清、截止日期遗忘、反馈散落
  • 目标:3 周内上线一个 MVP
  • 约束:预算有限、团队用邮箱登录、部署 AWS、Windows + WSL 开发
  • 成功指标:团队 80% 的任务在系统内创建;周会不再逐条对 Excel

角色

角色 谁
产品负责人 你(人)
需求/设计/开发/测试 AI Agent 团队
最终验收 你 + 团队代表

1. Day 1:需求调研

1.1 原始记录

docs/00-discovery/raw-notes.md:

# 原始需求记录

日期:2026-10-26
记录人:产品负责人

## 背景
20 人咨询团队,目前用 Excel 管理项目任务。问题:
- 任务负责人不清楚
- 截止日期被忘记
- 客户反馈散落在微信
- 每周例会要花 1 小时对进度

## 想要
- 创建项目
- 邀请成员
- 创建任务,指定负责人/截止日期/优先级
- 看板查看进度
- 评论和提醒

## 约束
- 3 周上线
- 邮箱登录(先不做企业微信)
- AWS 部署
- 先做 Web,不做移动端

## 不确定
- 权限要几层?
- 要不要审计日志?
- 要不要附件?

1.2 AI 访谈

给 AI 的提示词(见 01 需求调研),AI 提出 10 个问题,你回答其中关键的 6 个:

# 访谈回答

Q1 用户角色?
A:管理员(创建项目、邀请成员)、成员(创建/编辑任务)、访客(只读)。

Q2 权限边界?
A:成员只能看到自己所属的项目;管理员可以管理成员;访客只读。

Q3 任务状态?
A:待办、进行中、已完成。允许回退,但记录审计。

Q4 删除?
A:软删除,管理员可恢复,普通成员不可删除。

Q5 通知?
A:MVP 只做站内通知,不做邮件/微信。

Q6 审计?
A:需要,记录创建/修改/删除/状态变更。

Q7 数据量?
A:20 人,约 50 个项目,1 万任务/年。

Q8 时区?
A:中国时区,但服务端存 UTC。

Q9 上线环境?
A:AWS,单区域,先单实例。

Q10 预算/时间?
A:3 周,1 人 + AI。

1.3 生成 spec(节选)

docs/00-discovery/spec.md:

# 功能规格说明书:TeamTask

## 1. 背景与问题
咨询团队用 Excel 管理任务,导致责任不清、进度不可见、反馈散落。

## 2. 目标
- 3 周内上线 Web MVP
- 团队能在系统内创建项目、邀请成员、管理任务
- 周会可以直接看看板,不再逐条对 Excel

## 3. 非目标
- 不做移动端 App
- 不做企业微信/微信登录
- 不做支付/计费
- 不做附件上传(v2)
- 不做复杂报表(v2)

## 4. 用户与角色
| 角色 | 权限 |
|---|---|
| 管理员 | 创建项目、邀请/移除成员、管理项目设置 |
| 成员 | 查看所属项目、创建/编辑任务、评论 |
| 访客 | 只读 |

## 5. 功能需求
### FR-001 登录
...
### FR-002 创建项目
...
### FR-003 邀请成员
...
### FR-004 创建任务
...
### FR-005 任务看板
...

## 6. 非功能需求
- P95 API 延迟 < 500ms(50 并发)
- 月度可用性 ≥ 99.5%
- 所有写操作有审计日志
- 日志不含密码/令牌
- 支持 Chrome/Safari/Edge 最近两个版本

## 7. 数据实体
users, projects, project_members, tasks, comments, audit_logs

## 8. 权限模型
- 项目级角色:admin/member/viewer
- 对象级校验:所有任务操作必须校验项目成员身份
- 非成员一律 403

## 9. 错误与异常
- 统一错误码
- 所有错误带 request_id
- 网络失败可重试
- 并发更新用乐观锁

## 10. 范围之外
- 移动端、附件、报表、企业微信、支付

1.4 用户故事(节选)

docs/00-discovery/user-story.csv:

story_id,module,title,as_a,i_want,so_that,priority,status,owner,branch,spec_ref,details_ref,api_ref,db_tables,feature_report,e2e_manifest,unit_test_status,integ_test_status,dev_url,staging_url,prod_url,dev_deploy_status,staging_deploy_status,prod_deploy_status,estimate_sp,actual_sp,dependencies,last_updated,notes
US-001,认证,用户登录,注册用户,用邮箱和密码登录,我能安全地进入系统,P0,ready,backend-agent-1,feat/US-001-login,spec.md#fr-001,user-story-details.md#us-001,openapi.yaml#/paths/~1auth~1login/post,"users;audit_logs",docs/03-dev/reports/US-001-用户登录.md,docs/04-qa/manifests/US-001.json,pending,pending,http://localhost:5173,https://staging.example.com,https://app.example.com,not_deployed,not_deployed,not_deployed,3,,,2026-10-26T10:00:00+08:00,
US-002,项目,创建项目,团队管理员,创建一个新项目,我能组织团队工作,P0,ready,backend-agent-2,feat/US-002-create-project,spec.md#fr-002,user-story-details.md#us-002,openapi.yaml#/paths/~1projects/post,"projects;project_members;audit_logs",docs/03-dev/reports/US-002-创建项目.md,docs/04-qa/manifests/US-002.json,pending,pending,http://localhost:5173,https://staging.example.com,https://app.example.com,not_deployed,not_deployed,not_deployed,3,,US-001,2026-10-26T10:00:00+08:00,
US-003,项目,邀请成员,项目管理员,邀请团队成员加入项目,成员能协作,P0,ready,backend-agent-2,feat/US-003-invite-member,spec.md#fr-003,user-story-details.md#us-003,openapi.yaml#/paths/~1projects~1{id}~1members/post,"project_members;invitations;audit_logs",docs/03-dev/reports/US-003-邀请成员.md,docs/04-qa/manifests/US-003.json,pending,pending,http://localhost:5173,https://staging.example.com,https://app.example.com,not_deployed,not_deployed,not_deployed,3,,US-002,2026-10-26T10:00:00+08:00,
US-004,任务,创建任务,项目成员,创建带负责人和截止日期的任务,我能把工作分配清楚,P0,ready,backend-agent-3,feat/US-004-create-task,spec.md#fr-004,user-story-details.md#us-004,openapi.yaml#/paths/~1tasks/post,"tasks;audit_logs",docs/03-dev/reports/US-004-创建任务.md,docs/04-qa/manifests/US-004.json,pending,pending,http://localhost:5173,https://staging.example.com,https://app.example.com,not_deployed,not_deployed,not_deployed,5,,"US-002;US-003",2026-10-26T10:00:00+08:00,
US-005,任务,任务看板,项目成员,在看板上拖动任务改变状态,我能直观管理进度,P1,ready,frontend-agent-1,feat/US-005-kanban,spec.md#fr-005,user-story-details.md#us-005,openapi.yaml#/paths/~1tasks~1{id}~1status/patch,"tasks",docs/03-dev/reports/US-005-任务看板.md,docs/04-qa/manifests/US-005.json,pending,pending,http://localhost:5173,https://staging.example.com,https://app.example.com,not_deployed,not_deployed,not_deployed,5,,US-004,2026-10-26T10:00:00+08:00,

1.5 排期

docs/00-discovery/schedule.md:

# 排期

## 里程碑
| 里程碑 | 日期 | 交付物 | 门禁 |
|---|---|---|---|
| M1 需求冻结 | 10-27 | spec + stories + 排期 | G1 |
| M2 设计冻结 | 10-29 | Figma + ui-spec | G2 |
| M3 视觉验收 | 10-31 | HTML 原型 | G3 |
| M4 契约冻结 | 11-01 | OpenAPI + schema + tech-design | G4 |
| M5 功能完成 | 11-08 | 代码 + 测试 | G5 |
| M6 验收通过 | 11-11 | Word 报告 + 人工走查 | G6 |
| M7 上线 | 11-13 | 生产部署 + 冒烟 | G7 |
| M8 线上验证 | 11-14 | 线上 Word 报告 | 发布验收 |

## 关键路径
US-001 → US-002 → US-003 → US-004 → US-005 → 联调 → E2E → 部署

## 缓冲
- 技术风险:20%
- 评审返工:20%
- 环境/权限:10%

1.6 G1 门禁

产品负责人确认:

## 范围确认
- 确认人:产品负责人
- 日期:2026-10-27
- 结论:P0/P1 范围接受;移动端、附件、企业微信推迟到 v2
- 备注:先保证 3 周上线,功能可少但必须稳定

2. Day 2-3:UI 设计

2.1 页面清单

页面 ID 名称 路由 故事 状态
P-001 登录 /login US-001 默认/提交中/错误/锁定
P-002 项目列表 /projects US-002 默认/加载/空/错误
P-003 项目看板 /projects/:id US-004, US-005 默认/加载/空/错误/无权限
P-004 成员管理 /projects/:id/members US-003 默认/加载/空/错误

2.2 设计 token

docs/02-ui/design-tokens.json(节选):

{
  "color": {
    "brand-600": "#2563eb",
    "neutral-0": "#ffffff",
    "neutral-50": "#f8fafc",
    "neutral-900": "#0f172a",
    "danger-500": "#ef4444"
  },
  "font": {
    "family-sans": "Inter, 'Noto Sans SC', system-ui, sans-serif",
    "size-sm": "14px",
    "size-md": "16px",
    "size-xl": "24px"
  },
  "space": { "2": "8px", "3": "12px", "4": "16px", "6": "24px" },
  "radius": { "md": "10px", "lg": "16px" }
}

2.3 设计稿

  • Figma 文件:TeamTask MVP
  • 页面:P-001 ~ P-004
  • 每个页面包含:默认、加载、空、错误、无权限
  • 组件:Button、Input、Select、Modal、Badge、Avatar、EmptyState、Skeleton、TaskCard、KanbanColumn

2.4 ui-spec.md(节选)

### P-003 项目看板
- 三列:待办/进行中/已完成
- 列宽 320px,间距 16px
- 任务卡片:标题、负责人头像、截止日期、优先级 Badge
- 逾期:日期红色 + “已逾期”
- 空状态:EmptyState + 新建任务
- 加载:3 张骨架卡片
- 错误:ErrorState + 重试
- 无权限:NoPermissionState
- 拖拽:乐观更新,失败回滚 + toast
- 移动端:单列 + 横向切换

2.5 G2 门禁

评审记录:

## 设计评审
- 结论:有条件通过
- 问题:
  - D-001:移动端三列挤压 → 改单列
  - D-002:错误提示只靠红色 → 加图标
  - D-003:邀请弹窗缺“成员已存在”状态 → 补充
- 修复后通过

3. Day 4-5:前端原型

3.1 静态原型

  • frontend/prototype/login.html
  • frontend/prototype/projects.html
  • frontend/prototype/project-board.html
  • 共用 styles/tokens.css

3.2 视觉验收

用 Chrome MCP:

打开 project-board.html,分别以 1440x900、1024x768、390x844 截图,
保存到 docs/02-ui/screens/。
用 chrome_javascript 检查:
- 是否有横向滚动条
- 主内容宽度、列宽、间距
- 按钮 focus 样式
输出偏差列表。

人确认:

## G3 视觉验收
- 结论:通过
- 备注:卡片阴影略重,已调整为 sm;移动端改为单列

4. Day 6:技术设计

4.1 技术栈

  • 前端:Vue 3 + TypeScript + Vite + Pinia
  • 后端:Go 1.23 + chi + pgx + sqlc
  • 数据库:PostgreSQL 16
  • 部署:Docker + AWS ECS Fargate + RDS + S3/CloudFront

4.2 API 契约(节选)

docs/01-design/api/openapi.yaml:

paths:
  /tasks:
    post:
      operationId: createTask
      summary: 创建任务
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTaskRequest'
      responses:
        '201':
          description: 创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskResponse'
        '400':
          description: 参数错误
        '403':
          description: 无权限
        '409':
          description: 项目已归档

4.3 数据库(节选)

CREATE TABLE tasks (
    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id  UUID NOT NULL REFERENCES projects(id),
    title       TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 100),
    description TEXT,
    assignee_id UUID REFERENCES users(id),
    due_date    DATE,
    priority    TEXT NOT NULL DEFAULT 'medium',
    status      TEXT NOT NULL DEFAULT 'todo',
    version     INTEGER NOT NULL DEFAULT 0,
    created_by  UUID NOT NULL REFERENCES users(id),
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    deleted_at  TIMESTAMPTZ
);

CREATE INDEX idx_tasks_project_status_due
    ON tasks (project_id, status, due_date)
    WHERE deleted_at IS NULL;

4.4 实现细节(US-004 节选)

## US-004 创建任务

### 业务逻辑
1. 校验 project_id 存在且未归档。
2. 校验当前用户是项目成员。
3. 校验 assignee_id 是项目成员。
4. 校验 due_date 不早于今天。
5. 插入 tasks。
6. 写 audit_logs。
7. 写 outbox(任务创建事件)。
8. 返回 TaskResponse。

### 事务
- 步骤 5-7 在同一事务。
- 通知在事务外,由 worker 消费 outbox。

### 错误码
| 场景 | 状态码 | 错误码 |
|---|---|---|
| 标题为空 | 400 | VALIDATION_ERROR |
| 项目不存在 | 404 | PROJECT_NOT_FOUND |
| 非项目成员 | 403 | FORBIDDEN |
| 项目已归档 | 409 | PROJECT_ARCHIVED |
| 负责人不在项目 | 400 | ASSIGNEE_NOT_IN_PROJECT |

4.5 文件所有权(节选)

## 架构 Agent
- backend/cmd/api/main.go
- backend/internal/adapter/http/router.go
- backend/api/openapi.yaml
- backend/migrations/**

## 后端 Agent 3(US-004/US-005)
- backend/internal/usecase/task/**
- backend/internal/adapter/http/task_handler.go
- backend/internal/adapter/postgres/repo/task_repo.go

## 前端 Agent 1(US-005)
- frontend/src/views/ProjectBoardView.vue
- frontend/src/components/task/**

4.6 G4 契约冻结

## 契约冻结
- 版本:v1.0.0
- 确认人:产品负责人 + 架构 Agent
- 检查:
  - 5 个故事都有 API
  - OpenAPI lint 通过
  - schema 评审通过
  - 文件所有权无冲突
  - CLAUDE.md 已更新
- 结论:冻结,进入并行开发

5. Day 7-12:多 Agent 编码

5.1 并行批次

第 1 批(串行):
  架构 Agent:main/router/config/migrations
  后端 Agent 1:US-001 登录
  后端 Agent 2:US-002 创建项目

第 2 批(并行):
  后端 Agent 2:US-003 邀请成员
  后端 Agent 3:US-004 创建任务
  前端 Agent 1:US-001 登录页 + US-002 项目列表

第 3 批:
  后端 Agent 3:US-005 状态更新
  前端 Agent 1:US-005 看板
  测试 Agent:US-001/002/004 E2E

5.2 worktree

cd ~/projects/teamtask
git checkout main && git pull

git worktree add ../teamtask-worktrees/US-001 -b feat/US-001-login main
git worktree add ../teamtask-worktrees/US-002 -b feat/US-002-create-project main
git worktree add ../teamtask-worktrees/US-004 -b feat/US-004-create-task main
git worktree add ../teamtask-worktrees/US-005-ui -b feat/US-005-kanban main

5.3 US-004 后端 Agent 任务书(节选)

# Agent 任务书:US-004 创建任务

## 目标
实现 POST /api/v1/tasks,满足 AC-1 ~ AC-4,单测/集成测试全绿。

## 文件所有权
可改:
- backend/internal/usecase/task/**
- backend/internal/adapter/http/task_handler.go
- backend/internal/adapter/postgres/repo/task_repo.go
- 对应 _test.go
禁止改:
- router.go / main.go / migrations / openapi.yaml

## 契约
- OpenAPI createTask
- 错误码见 feature-implementation.md#us-004
- Idempotency-Key 24h
- 事务:tasks + audit_logs

## 测试
- 空标题、超长标题、非法 priority
- 非项目成员 403
- 负责人不在项目 400
- 项目归档 409
- 成功创建 + 审计
- 幂等重复请求

## 完成
- go test -race ./...
- go vet ./...
- 生成报告
- 更新 CSV status=integ_done
- 提交 feat/US-004-create-task

5.4 Agent 执行记录(节选)

[Agent] 读取 CLAUDE.md / OpenAPI / schema / feature-implementation
[Agent] 实现计划:
  1. 定义 CreateTaskInput 和校验
  2. 写 failing test: TestCreateTask_EmptyTitle
  3. 实现 usecase
  4. 实现 repo + 事务
  5. 实现 handler
  6. 集成测试
  7. 报告
[Test] TestCreateTask_EmptyTitle FAILED (expected)
[Test] TestCreateTask_EmptyTitle PASSED
[Test] go test -race ./internal/... PASSED
[Agent] 生成 docs/03-dev/reports/US-004-创建任务.md
[Agent] 更新 CSV: US-004 -> integ_done
[Agent] git commit -m "feat(task): add create task endpoint"

5.5 功能报告(节选)

# US-004 创建任务 - 实现报告

## 改动文件
- internal/usecase/task/create.go
- internal/usecase/task/create_test.go
- internal/adapter/http/task_handler.go
- internal/adapter/postgres/repo/task_repo.go
- internal/adapter/postgres/repo/task_repo_test.go

## 测试结果
- 单元测试:12 passed
- 集成测试:5 passed
- race:通过
- lint:通过

## 验收标准
| AC | 测试 | 结果 |
|---|---|---|
| AC-1 正常创建 | TestCreateTask_Success | pass |
| AC-2 空标题 | TestCreateTask_EmptyTitle | pass |
| AC-3 无权限 | TestCreateTask_Forbidden | pass |
| AC-4 日期非法 | TestCreateTask_InvalidDueDate | pass |

## 已知限制
- 通知由 outbox worker 处理,worker 在 US-006 实现

5.6 合并

cd ~/projects/teamtask
git checkout -b integration
git merge --no-ff feat/US-001-login
git merge --no-ff feat/US-002-create-project
git merge --no-ff feat/US-003-invite-member
git merge --no-ff feat/US-004-create-task
git merge --no-ff feat/US-005-kanban
make test
make lint

冲突:router.go 出现两次路由新增。架构 Agent 统一解决,重跑全量测试。


6. Day 13-14:质量保证

6.1 单元/集成

make test
# go test -race ./... 12 packages ok
# integration tests 5 packages ok

6.2 E2E

启动:

docker compose -f docker-compose.dev.yml up -d
make dev
./scripts/start-chrome-debug.sh

测试 US-004:

[Step 1] navigate /login -> pass, screenshot step-01
[Step 2] fill email/password -> pass, screenshot step-02
[Step 3] click login -> pass, URL /projects, screenshot step-03
[Step 4] click project -> pass, board visible, screenshot step-04
[Step 5] click new task -> pass, modal visible, screenshot step-05
[Step 6] submit empty title -> pass, error shown, screenshot step-06
[Step 7] fill valid data -> pass, 201, screenshot step-07
[Step 8] assert card visible -> pass, screenshot step-08
[Step 9] refresh -> pass, card persists, screenshot step-09
[Step 10] cleanup test data -> pass, screenshot step-10

每一步截图只保存到磁盘(storeBase64: false),不回读模型;Word 报告会把它们按步骤嵌入。

6.3 发现 bug

BUG-004-01:提交时偶发 500。

  • 根因:前端未传 priority,后端默认值在校验之后才生效。
  • 修复:后端在 usecase 层补默认值;前端加必填校验。
  • 回归测试:TestCreateTask_DefaultPriority。
  • 重新跑 E2E 通过。

6.4 Word 报告

python3 scripts/build_test_report.py \
  --manifest docs/04-qa/manifests/US-004.json \
  --qa-root docs/04-qa \
  --out docs/04-qa/e2e-report-dev-20261110.docx

人工走查:

## G6 验收
- 人:产品负责人
- 结论:通过
- 备注:看板拖拽在移动端需要横向切换,v2 优化
- 签字:________

7. Day 15-16:部署

7.1 CI

lint ✅
unit ✅
integration ✅
build ✅
security scan ✅
push ECR ✅
deploy dev ✅
smoke dev ✅

7.2 部署生产

export AWS_PROFILE=teamtask-prod
aws sts get-caller-identity

# 前端
cd frontend && npm ci && npm run build
aws s3 sync dist/ s3://teamtask-prod-frontend/ --delete
aws cloudfront create-invalidation --distribution-id "$DIST_ID" --paths "/*"

# 后端
aws ecs update-service \
  --cluster teamtask-prod \
  --service teamtask-api \
  --task-definition teamtask-api:<revision> \
  --region ap-northeast-1

aws ecs wait services-stable \
  --cluster teamtask-prod \
  --services teamtask-api \
  --region ap-northeast-1

7.3 冒烟

curl -fsS https://api.example.com/healthz
curl -fsS https://api.example.com/readyz
curl -fsS -o /dev/null -w "%{http_code}\n" https://app.example.com

8. Day 17:线上验证

8.1 E2E

用测试账号 e2e-prod@example.com,测试租户 e2e-prod-tenant,数据前缀 e2e-20261114-US004-。

[Step 1] login -> pass
[Step 2] open test project -> pass
[Step 3] create task -> 201, pass
[Step 4] empty title -> validation error, pass
[Step 5] no-permission user -> 403, pass
[Step 6] refresh -> data persists, pass
[Step 7] cleanup -> pass
[Console] 0 errors
[Network] 0 5xx
[P95] create task 180ms

8.2 Word 报告

python3 scripts/build_test_report.py \
  --manifest docs/04-qa/manifests/US-004-prod.json \
  --qa-root docs/04-qa \
  --out docs/04-qa/e2e-report-prod-20261114.docx

8.3 签字

## 生产验收
- 版本:v1.0.0 (abc1234)
- 环境:prod
- 结论:通过
- 监控:错误率 0.02%,P95 220ms
- 签字:________

9. Day 18:复盘

9.1 数据

指标 结果
计划故事 5
完成故事 5
需求返工 1(邀请成员权限)
上线后 P0/P1 0
门禁一次通过率 60%
单元测试覆盖率 72%
E2E 覆盖 P0/P1 100%
人工走查时间 2 小时

9.2 做得好

  • 契约冻结后并行开发,冲突少;
  • Chrome MCP + Word 报告让人工走查效率高;
  • 编译器和测试抓到大部分低级错误;
  • 每个故事独立报告,定位问题快。

9.3 待改进

  • 邀请成员的权限规则在需求阶段没写清,导致返工;
  • 前端 Agent 一开始没处理“无权限”状态,E2E 才发现;
  • 生产测试账号的 2FA 花了半天配置;
  • Word 报告截图太多,文件 28MB,需要压缩。

9.4 行动项

  • 需求模板增加“权限矩阵”必填项
  • 前端 DoD 增加“五种状态”检查
  • 提前准备生产测试账号/2FA
  • 报告截图压缩到 1280px 宽
  • 把本次的 Agent 任务书沉淀到 .claude/agents/

10. 你可以从这个实战里复用什么

  • docs/ 目录结构;
  • CSV 列定义和状态机;
  • 用户故事模板;
  • OpenAPI + schema + feature-implementation 三件套;
  • 文件所有权 + worktree 并行;
  • Agent 任务书;
  • 功能报告模板;
  • E2E manifest + Word 报告脚本;
  • 发布/回滚检查清单。

下一章:12 常见问题与反模式 —— 把踩过的坑提前列出来。