Skip to content
Published at:

第 21 章:场景二:从零搭建新功能

在第 20 章中,我们用 Claude Code 理解了一个陌生项目——那是"读代码"的场景。但在日常开发中,最常见的场景是**"写代码"**:接到一个需求,从零开始搭建一个新功能模块。

本章以一个真实的 Web 应用为背景,带你完整走一遍用 Claude Code 从零搭建新功能的全流程。我们将为项目新增"用户认证"模块——涵盖注册、登录、密码重置和 JWT 鉴权。技术栈为 React + Express + PostgreSQL,但本章的核心不是这些具体技术,而是使用 Claude Code 进行新功能开发的工作流——这个工作流适应任何技术栈、任何类型的新功能。

本章目标:掌握用 Claude Code 从零开发新功能的完整流程——需求分析→架构设计→编码实现→测试验证→提交文档。学会 Plan mode 先设计再动手、逐文件审查变更、即时测试验证等关键工作习惯。

21.1 场景描述

假设你在维护一个任务管理 Web 应用(类似 Todoist 的简化版),目前用户数据存储在 localStorage 中——没有后端、没有数据库、没有多设备同步。产品经理要求你为它添加用户认证系统,支持:

  • 注册:邮箱 + 密码注册,密码加密存储
  • 登录:返回 JWT token,前端存储 token 用于后续请求
  • 密码重置:通过邮箱发送重置链接
  • 受保护路由:未登录用户重定向到登录页
  • Token 刷新:access token 过期后使用 refresh token 续期

技术方案已确定:后端新增 Express API 服务,PostgreSQL 存储用户数据,前端 React 添加登录/注册页面和路由守卫。

面对这个需求,传统的做法是:自己设计数据库表 → 手写 SQL → 写路由 → 写中间件 → 写前端页面 → 手动测试 → 修 Bug → 写 commit。这个过程即使对熟练的开发者来说也需要半天到一天。

现在,让我们看看用 Claude Code 怎么做

21.2 Step 1: 需求分析

拿到需求后的第一反应不应该是"开始写代码",而是先让 Claude Code 帮你分析,确保你和 AI 对需求的理解一致。这一步看似"浪费时间",实际上是最省时间的——它能帮你发现需求中的模糊点和遗漏点,避免后续返工。

21.2.1 初始需求输入

首先向 Claude Code 描述你的需求。关键不是描述得"简洁",而是描述得完整——把所有已知信息一次性给出去。

我要为现有的任务管理应用添加用户认证功能。目前应用是纯前端的(React + localStorage),需要改造成前后端分离架构。请帮我分析需要哪些模块。

现有情况:
- 前端:React 18,使用 React Router v6 做路由
- 后端:需要新搭建 Express API 服务
- 数据库:PostgreSQL(团队已部署)
- 认证方式:JWT(access token + refresh token)

功能需求:
1. 邮箱注册(需要邮箱验证吗?)
2. 邮箱 + 密码登录
3. 密码重置(通过邮箱发送重置链接)
4. 登录后访问受保护页面,未登录重定向
5. Token 过期后自动刷新

请先不要写代码,帮我分析:
- 需要哪些数据模型?
- 需要哪些 API 路由?
- 需要哪些前端组件和页面?
- 有哪些安全注意事项?
- 有哪些我没有明确但你应该提醒我的点?

最后一个问题是关键。你不可能在第一次描述需求时就考虑周全——让 Claude Code 帮你补充。它会从安全、用户体验、边界条件等角度提出你没有考虑到的问题。

21.2.2 Claude 的输出

Claude Code 在阅读了你的项目结构后,会输出类似这样的分析:

markdown
## 用户认证模块分析

### 1. 数据模型

**users 表:**
- id: UUID (主键)
- email: VARCHAR(255) UNIQUE NOT NULL
- password_hash: VARCHAR(255) NOT NULL
- is_verified: BOOLEAN DEFAULT false
- created_at: TIMESTAMP DEFAULT NOW()
- updated_at: TIMESTAMP DEFAULT NOW()

**refresh_tokens 表:**
- id: UUID (主键)
- user_id: UUID (外键 → users.id)
- token: VARCHAR(512) NOT NULL
- expires_at: TIMESTAMP NOT NULL
- created_at: TIMESTAMP DEFAULT NOW()

**password_reset_tokens 表:**
- id: UUID (主键)
- user_id: UUID (外键 → users.id)
- token: VARCHAR(512) NOT NULL
- expires_at: TIMESTAMP NOT NULL
- used: BOOLEAN DEFAULT false

### 2. API 路由规划

POST   /api/auth/register          # 注册
POST   /api/auth/login              # 登录
POST   /api/auth/refresh            # 刷新 token
POST   /api/auth/logout             # 登出(使 refresh token 失效)
POST   /api/auth/forgot-password    # 发送重置密码邮件
POST   /api/auth/reset-password     # 重置密码
GET    /api/auth/verify-email/:token # 邮箱验证

### 3. 前端组件清单

- LoginPage:登录表单
- RegisterPage:注册表单
- ForgotPasswordPage:忘记密码(输入邮箱)
- ResetPasswordPage:重置密码(输入新密码)
- ProtectedRoute:路由守卫组件
- AuthContext:认证状态管理(Context API)
- useAuth Hook:封装认证相关逻辑

### 4. 安全注意事项

- 密码必须使用 bcrypt 哈希,绝不可明文存储
- JWT secret 必须通过环境变量管理,不可硬编码
- refresh token 应使用 httpOnly cookie 或安全存储
- 登录接口需要限流(rate limiting),防止暴力破解
- 重置密码 token 必须设置短过期时间(15分钟)
- 注册时需要验证邮箱格式和密码强度

### 5. 你需要考虑但未提及的点

- 是否支持第三方登录(Google/GitHub OAuth)?如果未来需要,建议预留扩展接口
- 密码强度策略:最少字符数?是否需要特殊字符?
- 同一个邮箱的并发登录如何处理(互踢 / 允许多设备)?
- 是否需要在注册时发送欢迎邮件?
- 是否需要用户注销账号的功能?
- 前端 token 存储方案:localStorage 还是 httpOnly cookie?

这个分析的价值在于:它在你动手写第一行代码之前,就把可能踩的坑提前暴露了出来。比如"密码强度策略"和"并发登录处理",这些在需求阶段没有明确的问题,Claude Code 帮你提了出来,你可以拿着这些问题去和产品经理确认,而不是写了一半再返工。

21.2.3 使用 brainstorming skill 进行需求澄清

在需求分析阶段,你还可以通过 brainstorming skill 来进一步澄清需求:

/brainstorming

我要为 React + Express 应用添加 JWT 认证。帮我思考:
1. access token 和 refresh token 的过期时间应该分别设多少?为什么?
2. refresh token 存在哪里更安全?(localStorage vs sessionStorage vs httpOnly cookie vs memory)
3. token 过期后,用户体验应该是什么样的?(静默刷新 vs 提示重新登录)
4. 如何处理多标签页同时打开时的认证状态同步?

Claude Code(在 brainstorming 模式下)会从多个角度分析每种方案的利弊,帮你做出更合理的架构决策——例如,它会解释为什么 access token 一般设为 15 分钟、refresh token 设 7 天,以及为什么 httpOnly cookie 比 localStorage 更安全但实现更复杂。

提示:关于 brainstorming skill 的详细用法,见第 17 章:Skills 技能系统。brainstorming 模式的核心理念是"先发散再收敛"——让 Claude Code 列举多种方案,你选择最适合的那个——而不是直接接受第一个建议。

这一步完成后,你应该对以下问题有了明确答案:

  • 需要哪些数据表和 API 路由
  • 密码策略和安全要求
  • Token 存储方案和过期策略
  • 前端架构(路由守卫 + Context + Hook)

有了这些答案,不要急着让 Claude Code 写代码。下一步:先做架构设计。

21.3 Step 2: 架构设计

需求分析告诉你"要做什么",架构设计告诉你"怎么做、按什么顺序做"。这是新功能开发中最容易被跳过的步骤——很多人打开 Claude Code 直接说"帮我写一个登录页面",然后在一个个零散的"微需求"中迷失方向。

21.3.1 切换到 Plan mode

在进行架构设计时,切换 Claude Code 到 Plan mode/plan),这样它只输出计划,不会直接写代码

/plan

基于前面的需求分析,帮我制定一个完整的实现计划。
请不要写代码,只输出执行计划。

要求:
1. 列出所有需要创建和修改的文件,按依赖关系排序
2. 标注每个文件的职责和关键内容
3. 指出文件之间的依赖关系(A 必须先于 B 完成)
4. 将实施过程分成若干个可独立验证的阶段
5. 每个阶段完成后,我希望能立即运行测试来验证该阶段是否正确

21.3.2 Claude 输出的实现计划

Claude Code 在 Plan mode 下会输出结构化的实现计划:

markdown
## 用户认证模块实现计划

### 阶段 0:项目结构调整
**目标**:搭建 Express 后端骨架,调整前端目录结构

需要创建/修改的文件:
1. server/package.json — 后端依赖(express, pg, bcrypt, jsonwebtoken, nodemailer)
2. server/src/index.ts — Express 入口,挂载中间件和路由
3. server/src/config.ts — 环境变量集中管理(DATABASE_URL, JWT_SECRET, SMTP 配置)
4. server/src/db.ts — PostgreSQL 连接池初始化

### 阶段 1:数据模型与数据库迁移
**目标**:创建 users、refresh_tokens、password_reset_tokens 三张表

需要创建/修改的文件:
5. server/src/db/migrations/001_create_users.sql
6. server/src/db/migrations/002_create_tokens.sql
7. server/src/db/run-migrations.ts — 迁移执行脚本

**验证方式**:运行迁移脚本后,在 psql 中检查表结构

### 阶段 2:认证 API 实现
**目标**:实现注册、登录、登出、token 刷新、密码重置接口

需要创建/修改的文件:
8. server/src/models/user.ts — User 模型(CRUD + 密码哈希)
9. server/src/models/refresh-token.ts — RefreshToken 模型
10. server/src/models/reset-token.ts — PasswordResetToken 模型
11. server/src/middleware/auth.ts — JWT 验证中间件
12. server/src/middleware/rate-limit.ts — 登录限流中间件
13. server/src/routes/auth.ts — 认证路由(register/login/logout/refresh/forgot/reset)
14. server/src/services/email.ts — 邮件发送服务

**依赖关系**:模型 → 中间件 → 路由 → 邮件服务
**验证方式**:用 curl 或 Postman 手动测试每个接口

### 阶段 3:前端认证流程
**目标**:前端添加登录/注册页面、认证状态管理、路由守卫

需要创建/修改的文件:
15. src/contexts/AuthContext.tsx — 认证状态管理
16. src/hooks/useAuth.ts — 认证逻辑 Hook
17. src/pages/LoginPage.tsx — 登录页面
18. src/pages/RegisterPage.tsx — 注册页面
19. src/pages/ForgotPasswordPage.tsx — 忘记密码页面
20. src/pages/ResetPasswordPage.tsx — 重置密码页面
21. src/components/ProtectedRoute.tsx — 路由守卫
22. src/App.tsx — 修改路由配置
23. src/api/auth.ts — 认证 API 调用封装

**依赖关系**:AuthContext → useAuth → 页面和路由守卫 → 路由配置
**验证方式**:启动应用,走通注册→登录→访问受保护页面的完整流程

### 阶段 4:测试编写
**目标**:为认证模块编写单元测试和集成测试

需要创建/修改的文件:
24. server/src/__tests__/auth.test.ts — 后端认证集成测试
25. server/src/__tests__/jwt.test.ts — JWT 工具函数单元测试
26. src/__tests__/AuthContext.test.tsx — 前端 AuthContext 单元测试
27. src/__tests__/LoginPage.test.tsx — 登录页面组件测试

**验证方式**:运行 `pnpm test`,确保所有测试通过

### 阶段 5:提交与文档
**目标**:提交代码、更新文档

需要创建/修改的文件:
28. API_DOCS.md — 认证接口文档
29. server/README.md — 后端启动说明

**验证方式**:所有测试通过 + 文档 review

21.3.3 审查与调整计划

拿到计划后,不要直接说"执行"。先花 5 分钟审查:

  1. 文件遗漏检查:你有没有想到但计划里没有的文件?比如你是否需要一个 server/src/utils/jwt.ts 来封装 JWT 生成和验证的逻辑?提出来让 Claude Code 补充。

  2. 顺序合理性:这个顺序是否合理?例如阶段 3(前端)确实依赖阶段 2(后端 API),但如果你想让两个开发者并行工作,可以把阶段 3 放在阶段 2 之前(前端先 mock API)。

  3. 验证方式的可行性:每个阶段的"验证方式"是否可执行?"用 curl 手动测试"在初期 OK,但在阶段 4 就应该用自动化测试取代手动验证。

  4. 风险识别:有没有风险被忽略?例如数据库迁移脚本的"回滚"策略——如果迁移失败怎么办?

审查后,你可以提出调整:

计划整体 OK。做以下调整:
1. 在阶段 1 增加 server/src/utils/jwt.ts,封装 JWT 生成和验证逻辑
2. 阶段 4 的密码重置邮件发送测试建议用 mock,不要真的发邮件
3. 每个阶段的"验证方式"增加一条:运行已有的测试套件确保不破坏现有功能

确认修改后,开始执行阶段 0。

关键习惯:Plan mode 是新功能开发中最重要的防线。跳过这一步直接写代码,结果是"改了一个文件又想起漏了另一个,来回跳转,最后忘记自己改了哪些"。花 10 分钟做好计划,省下的是 2 小时的来回返工。

关于 Plan mode 的更多策略,见第 9 章:模式切换

21.4 Step 3: 编码实现

有了计划,编码阶段就变成了按计划逐步推进,每一步都有明确的目标和验证方式。这里的关键不是"让 Claude Code 一次写完所有代码",而是分阶段、逐文件、即时审查

21.4.1 原则一:先读后写

在修改或创建任何文件之前,让 Claude Code 先读取相关文件,确认理解上下文后再动手。这是一个看似简单但很多人不做的习惯。

先读一下 server/src/index.ts 和 server/src/config.ts,
理解现有后端架构后再创建 auth 路由文件。

Claude Code 会先读这两个文件,在理解现有路由注册方式、中间件挂载位置、错误处理风格之后,再创建新的路由文件。这样生成的代码风格一致,不会出现"新代码用 try-catch 而老代码用 .catch() "这种不一致。

21.4.2 原则二:按阶段推进,每阶段可验证

阶段 0 是搭建后端骨架。先从它开始:

开始执行阶段 0:项目结构调整

1. 创建 server/package.json,依赖包括 express, pg, bcryptjs, jsonwebtoken, nodemailer
2. 创建 server/src/index.ts,Express 入口文件,挂载 CORS 和 JSON body parser
3. 创建 server/src/config.ts,从环境变量读取 DATABASE_URL, JWT_SECRET, JWT_REFRESH_SECRET, SMTP_*
4. 创建 server/src/db.ts,初始化 pg Pool

完成阶段 0 后告诉我,我会验证。

Claude Code 依次创建这些文件。在它创建每个文件时,VSCode 会弹出 Diff 视图——不要批量 Accept 所有变更。逐文件审查:

  • package.json:版本号是否合适?有没有多余的依赖?
  • config.ts:环境变量名是否和团队约定一致?有没有默认值?
  • db.ts:连接池配置是否合理?max 连接数设了多少?

审查完一个,Accept 一个。发现不对的,直接在当前对话中指出来:

config.ts 中 JWT_EXPIRES_IN 的默认值应该用 '15m' 而不是 '1h'——access token 不宜过长。
db.ts 需要添加连接错误的事件监听,避免连接断开后应用崩溃。

这种即时审查 + 即时修正的模式,比"先让 Claude Code 写完 10 个文件,再回头看"高效得多——因为你发现问题时上下文还是热的,你和 Claude Code 都还在这个细节上。

阶段 0 完成后,验证:cd server && pnpm install && pnpm dev,确认 Express 能启动且没有报错。

21.4.3 原则三:模型代码先于路由代码

阶段 1 创建数据模型。让 Claude Code 先创建迁移脚本:

开始执行阶段 1:数据模型与数据库迁移

先读取现有的数据库配置和表结构(如果有),
然后创建 users、refresh_tokens、password_reset_tokens 三张表的迁移脚本。
表结构参考需求分析阶段的定义。
同时创建 server/src/utils/jwt.ts,封装 generateAccessToken 和 generateRefreshToken 函数。

Claude Code 会创建:

  • 001_create_users.sql:users 表,包含 id、email、password_hash、is_verified、时间戳
  • 002_create_tokens.sql:refresh_tokens 和 password_reset_tokens 表
  • server/src/utils/jwt.ts:JWT 生成和验证的工具函数

在这一步,Claude Code 写的 SQL 你需要重点审查:字段类型是否正确?UNIQUE 约束是否加了?外键关系的 ON DELETE CASCADE 是否需要?

阶段 1 验证:运行迁移脚本,psql 连接数据库检查表结构。

21.4.4 阶段 2:认证 API 实现

这是工作量最大的阶段。Claude Code 需要创建 7 个文件(3 个 model + 2 个 middleware + 1 个 route + 1 个 service)。做法仍然是逐文件推进

开始阶段 2:认证 API

先创建 server/src/models/user.ts,包含方法:
- createUser(email, password) — 创建用户,密码用 bcrypt 哈希
- findByEmail(email) — 按邮箱查找
- verifyPassword(userId, password) — 验证密码
- updatePassword(userId, newPassword) — 更新密码
- setVerified(userId) — 设置邮箱已验证

Claude Code 创建 user.ts,你审查后 Accept。然后继续:

User model OK。接下来创建 server/src/models/refresh-token.ts 和 server/src/models/reset-token.ts。
这两个模型结构类似,可以一起创建。

然后是 middleware 和 routes。在创建 auth 路由时,需要特别注意安全性:

创建 server/src/routes/auth.ts。注意:
1. 登录接口需要限流——先创建 server/src/middleware/rate-limit.ts
2. 密码重置 token 需要验证是否过期和是否已使用
3. refresh token 需要验证是否过期
4. 所有错误信息要模糊处理——不要告诉用户"该邮箱未注册",统一用"邮箱或密码错误"

安全提醒:第 4 点是很多开发者忽略的细节。如果返回"该邮箱未注册",攻击者可以用它来枚举系统中的有效邮箱。统一错误信息是基本的安全实践。

阶段 2 验证:用 curl 测试每个接口:

bash
# 注册
curl -X POST http://localhost:3001/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"Test1234!"}'

# 登录
curl -X POST http://localhost:3001/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"Test1234!"}'

# 访问受保护路由
curl http://localhost:3001/api/protected \
  -H "Authorization: Bearer <access_token>"

21.4.5 阶段 3:前端认证流程

前端开发同样按依赖关系推进:

开始阶段 3:前端认证流程

先创建 src/contexts/AuthContext.tsx。这个 Context 需要管理:
- user 状态(当前登录用户信息,null 表示未登录)
- accessToken 和 refreshToken
- login(email, password) 方法
- register(email, password) 方法
- logout() 方法
- isAuthenticated 计算属性

然后是 useAuth.ts Hook、登录/注册页面、路由守卫。创建页面时,Claude Code 会同时处理表单验证、错误提示、加载状态等细节:

创建 src/pages/LoginPage.tsx:
- 邮箱和密码两个输入框
- 前端表单验证(邮箱格式、密码不为空)
- 登录按钮 + 加载状态(防止重复提交)
- 错误信息展示(提交失败时显示)
- 登录成功后跳转到首页
- "忘记密码?"链接指向 ForgotPasswordPage
- "还没有账号?注册"链接指向 RegisterPage

每个前端文件创建后,启动开发服务器在浏览器中实际测试。不要只依赖"看起来没问题"——真正输入一组邮箱和密码,走通注册到登录的流程。

阶段 3 验证:浏览器中完整走通注册→登录→访问受保护页面→登出→再次访问被重定向的流程。

21.4.6 编码阶段的核心纪律

复盘编码阶段,有几个纪律值得强调:

  1. 不要一次让 Claude Code 创建太多文件:一次控制在 2-3 个相关文件以内。超过这个数量,审查质量会下降——你会不由自主地点 "Accept All",失去对改动的把控。

  2. 每完成一个阶段,立即验证:不要等到所有阶段都完成再测试。阶段 2(后端 API)完成后立刻用 curl 测试,而不是等阶段 3(前端)也完成才一起测。问题发现得越早,修复成本越低。

  3. 对安全性相关的代码提高审查标准:JWT 验证、密码哈希、SQL 查询——这些代码不只要"能跑",还要"安全地跑"。特别关注:有没有 SQL 注入风险?密码有没有用 bcrypt 哈希?JWT secret 有没有硬编码?

  4. 保持对话的连贯性:如果在一个阶段完成后你离开了(关掉了 VSCode),回来时要用 /resume 恢复之前的会话上下文。如果对话已经很长,用 /compact 压缩后再继续。关于对话管理,见第 11 章:上下文管理

21.5 Step 4: 测试验证

功能能跑通是一回事,功能能正确、稳定、安全地跑是另一回事。测试不是"可选的加分项",而是新功能开发的必要环节。

21.5.1 让 Claude Code 写单元测试

从最小粒度的单元测试开始——JWT 工具函数和密码哈希:

帮我为 server/src/utils/jwt.ts 写单元测试。

测试用例:
1. generateAccessToken 生成的 token 可以通过 verifyAccessToken 验证
2. 过期的 token 验证失败(使用短过期时间模拟)
3. 用错误 secret 签名的 token 验证失败
4. generateRefreshToken 生成的是随机字符串,两次调用结果不同

测试文件放在 server/src/__tests__/jwt.test.ts,使用 Jest。

Claude Code 会读取 jwt.ts 的实现代码,然后编写对应的测试。对于密码哈希:

为 server/src/models/user.ts 中的密码哈希逻辑写测试:

1. 同一密码两次哈希结果不同(salt 不同)
2. 验证正确密码返回 true
3. 验证错误密码返回 false
4. 哈希结果是 60 字符的 bcrypt 格式

21.5.2 集成测试:端到端流程

单元测试验证"每个零件是否正常",集成测试验证"组装起来后是否协同工作":

为认证模块写集成测试,覆盖完整的用户流程:

1. 注册新用户 → 返回 201 + 用户信息(不含密码)
2. 重复注册相同邮箱 → 返回 409
3. 登录 → 返回 access token + refresh token
4. 使用 access token 访问受保护路由 → 返回 200
5. 无 token 访问受保护路由 → 返回 401
6. 使用过期 token 访问受保护路由 → 返回 401
7. 刷新 token → 返回新的 access token
8. 使用被刷新的旧 refresh token → 返回 401
9. 请求重置密码 → 返回 200(即使邮箱不存在也返回 200,防止枚举)
10. 使用重置 token 修改密码 → 返回 200
11. 使用新密码登录 → 返回 access token

测试文件:server/src/__tests__/auth.test.ts
数据库:使用测试数据库,每个测试前重置数据

注意:集成测试需要一个独立的测试数据库。在测试配置中设置 DATABASE_URL 指向测试库,并在每个测试用例前后清理数据。Claude Code 会帮你处理 beforeEach / afterEach 的 setup 和 teardown。

21.5.3 运行测试,修复失败

测试写好后,让 Claude Code 运行它们:

运行 pnpm test,如果测试失败,分析失败原因并修复,直到全部通过。

这时很可能有测试失败——也许是 mock 没配置对,也许是测试数据和实际逻辑不匹配。关键流程是:

  1. Claude Code 读取测试失败的输出
  2. 分析失败原因(是测试写错了还是实现有 Bug)
  3. 修复后重新运行
  4. 循环直到全部通过

不要手动修复测试失败——让 Claude Code 自己分析失败输出并修复。这正是"AI 辅助调试"的价值所在:它能比你更快地定位失败原因(因为它最清楚代码的实现细节),并能自动完成"修改→运行→看结果"的循环。

bash
# Claude Code 会执行类似这样的循环
$ pnpm test                          # 运行,4 个测试通过,2 个失败
$ # Claude 读取失败输出,分析原因
$ # Claude 修改代码(比如修改了 mock 数据或修正了边界条件)
$ pnpm test                          # 再次运行
$ # 全部通过 ✓

21.5.4 前端组件测试(可选)

如果你的项目配置了前端测试框架(如 Jest + React Testing Library),还可以为认证相关组件写测试:

为 src/components/ProtectedRoute.tsx 写测试:

1. 用户未登录 → 重定向到 /login
2. 用户已登录 → 渲染子组件
3. 登录状态加载中 → 显示 loading 指示器

为 src/contexts/AuthContext.tsx 写测试:

1. login 成功后 user 状态更新
2. logout 后 user 状态清空
3. register 成功后自动登录

提示:前端测试涉及 DOM 渲染和路由,配置比后端测试复杂。如果你的项目尚未搭建前端测试环境,本章的测试重点放在后端。关于测试编写的完整方法论,见第 25 章:场景六——测试编写

21.6 Step 5: 提交与文档

所有测试通过后,最后一步是将代码提交到版本管理,并补充相关文档。

21.6.1 生成 Commit Message

/commit 命令让 Claude Code 分析所有变更并生成 commit message:

/commit

Claude Code 会读取 git diff,分析所有新增和修改的文件,生成中文 commit message(根据本项目的 CLAUDE.md 约定)。典型的输出:

feat: 新增用户认证模块(注册/登录/密码重置/JWT)

- 创建 Express 后端 API(server/),包含 auth 路由、JWT 中间件、限流中间件
- 新增数据库模型:users、refresh_tokens、password_reset_tokens
- 前端新增 AuthContext 认证状态管理、useAuth Hook、路由守卫
- 新增登录/注册/忘记密码/重置密码页面
- 编写后端单元测试和集成测试(JWT、密码哈希、认证流程)
- 更新 API 文档和项目 README

关键习惯:让 Claude Code 写 commit message,不是因为你懒,而是因为它比你更清楚这次变更的全部细节。它知道每个文件的改动是为了什么,能写出更精准、更全面的描述。你只需要审查通过。

Claude Code 生成的 commit message 会展示给你审查,确认无误后执行提交。

21.6.2 更新文档

提交完成后,更新 API 文档:

帮我更新 API_DOCS.md,添加认证相关接口的说明:

1. 每个接口的请求方法和路径
2. 请求体参数说明(类型、是否必填)
3. 成功响应的数据结构
4. 常见错误码和错误信息
5. 认证方式说明(Bearer Token)
6. Token 刷新机制说明

格式参考现有 API_DOCS.md 的风格。

以及后端的 README:

更新 server/README.md,添加:
1. 环境变量配置说明(DATABASE_URL、JWT_SECRET 等)
2. 数据库迁移命令
3. 如何启动开发服务器
4. 如何运行测试

这些文档不只是给别人看的——两周后你回头维护这段代码时,它们就是你自己的"记忆外挂"。而 Claude Code 生成文档的效率远高于你手写——它知道每个接口的入参出参,知道每个环境变量的用途,你只需审查和微调。

21.6.3 提交 PR(可选)

如果你的项目使用 GitHub PR 工作流:

/commit-push-pr

这个命令会完成提交→推送→创建 PR 的完整流程。PR 描述中会自动总结本次变更的要点。

21.7 复盘与技巧总结

走完一个完整的新功能开发流程,让我们做一次复盘——不只是回顾"做了什么",更是提炼"学到了什么"。

21.7.1 完整流程回顾

需求分析(21.2)
  → 向 Claude Code 描述完整需求
  → Claude 分析:数据模型、API 路由、组件清单、安全事项
  → 用 brainstorming 澄清模糊点
  → 产出:需求文档 + 模块清单

架构设计(21.3)
  → 切换到 Plan mode(/plan)
  → Claude 输出:文件清单、修改顺序、依赖关系、分阶段计划
  → 审查计划,调整后再执行
  → 产出:可执行的分阶段实现计划

编码实现(21.4)
  → 按阶段逐步推进(每个阶段 2-3 个文件)
  → 先读文件、再写代码
  → 逐文件 Diff 审查,即时反馈修正
  → 每阶段完成后立即验证
  → 产出:可运行的功能代码

测试验证(21.5)
  → 单元测试(JWT 工具函数、密码哈希)
  → 集成测试(完整用户流程 11 个用例)
  → 运行测试 → 分析失败 → 修复 → 循环直到通过
  → 产出:可验证的正确性保证

提交与文档(21.6)
  → /commit 生成 commit message
  → 更新 API 文档和 README
  → 提交 PR(可选)
  → 产出:可追溯的版本记录 + 可查阅的文档

21.7.2 五个关键技巧

技巧一:Plan mode 先设计,再动手

这是整个流程中回报率最高的一个习惯。花 10 分钟做计划,你可能发现:"哦,我还需要一个 email 服务模块"、"token 刷新逻辑比你想象中复杂,应该独立封装"。在计划阶段发现这些问题,修改计划只需要一句话;在编码阶段发现,你可能需要回退代码、重写接口、调整数据模型——成本是 10 倍以上。

什么时候用 Plan mode:涉及 3 个以上文件的新功能、多个模块之间有依赖关系、你不确定从哪个文件开始改。——这些场景都符合。

技巧二:逐文件审查,不批量接受

Claude Code 每次编辑或创建文件后,VSCode 会弹出 Diff 视图。养成逐文件审查的习惯——看清楚 Claude 改了什么、为什么这么改、有没有边界条件没处理。审查完一个文件再让 Claude Code 继续下一个。

警惕 "Accept All":当你面对 5 个以上的 Diff 视图时,大脑会本能地想要一键接受。但恰恰是这个时候最容易漏掉问题。把每次的变更量控制在 2-3 个文件以内。

技巧三:每个阶段完成后立即验证

"Code → Test → Fix → Code → Test → Fix" 是一个循环。但这个循环的"周期"越短越好。理想情况下,每完成 2-3 个文件就验证一次——而不是写完 15 个文件后才第一次运行测试。

实际的节奏是:

  • 写完数据模型 → 运行迁移脚本,检查表结构
  • 写完 auth 路由 → curl 测试注册和登录
  • 写完前端认证流程 → 浏览器中走通注册到登录
  • 写完测试 → pnpm test 确保全部通过

技巧四:让 Claude 自己修复测试失败

测试写好后运行,几乎必然有失败。不要自己去改代码修测试——把失败的输出原样告诉 Claude Code:"测试 3 失败了,expected 200 but got 401,帮我分析原因并修复。" Claude Code 自己最清楚它写的代码逻辑,能比你快得多地定位问题。

技巧五:用 AI 写 commit 和文档,不是偷懒

有些人觉得让 AI 写 commit message 是"偷懒"。正好相反——AI 写的 commit message 往往比人写的更好。因为它知道这次变更改了 28 个文件,知道每个文件之间的关系,知道变更的整体意图。这些信息你也有,但你不会在写 commit message 时逐一回顾每个文件的 diff——AI 会。

21.7.3 常见陷阱

陷阱一:跳过 Plan mode,直接写代码

"这个需求很简单,我直接告诉 Claude Code 帮我写一个登录功能就行。"

——然后你会发现:token 存在哪?access token 过期了怎么办?密码重置的邮件谁发?前端路由守卫怎么和 API 联动?每一个你"当时没想清楚"的问题,都会在编码阶段变成一次返工。

陷阱二:一次性改太多文件

"帮我创建所有 auth 相关的文件:model、route、middleware、前端页面、测试……"

——Claude Code 确实可以一次性创建 15 个文件。但你能审查得过来吗?一次性审查 15 个 Diff 视图的结果是:你点了 "Accept All",然后发现 user.ts 里有个 SQL 查询没加 WHERE 条件,auth.ts 里密码重置 token 没检查过期时间。但这些你已经 Accept 了——你需要回退然后重新生成。

陷阱三:写完不测试,留到最后一起测

"先让 Claude 把前后端都写完,写完了一起测。"

——然后你启动应用,点注册按钮,报了三个错。你分不清是后端的问题还是前端的问题,因为两端都是刚写的、都没测过。逐阶段验证的好处是:每个阶段出问题时,你能确定问题就在刚写的 2-3 个文件中

陷阱四:不写测试

"功能能跑就行,测试回头再补。"

——"回头再补"的测试,99% 不会补。而没测试的代码,每次改需求都是一场赌博——你不知道改了这里会不会破坏那里。在 Claude Code 的帮助下,写测试的成本已经大幅降低了:你说"帮我为这个模块写测试",它就能生成。不写的代价远大于写的代价。

21.7.4 对比:有 Claude Code vs 没有 Claude Code

环节没有 Claude Code有 Claude Code
需求分析自己脑子里过一遍,不确定的问同事Claude Code 输出完整分析,brainstorming 辅助决策
架构设计在纸上画或者脑子里想Plan mode 输出结构化执行计划,可分阶段验证
编码实现逐个文件手写,查文档、查 APIClaude Code 按计划逐步生成,Diff 审查后 Accept
测试编写手动编写测试用例,手写断言告诉 Claude Code 要测什么,它生成完整测试代码
调试修复逐个排查错误,改完再测Claude Code 读取失败输出,自动分析 + 修复
提交文档手写 commit + 手写文档/commit 自动生成,文档让 Claude Code 整理

新功能开发的效率提升不是某个环节的单项提升,而是整个流程的加速 + 质量的提升。你不需要在每个环节都从头做起——需求分析有 Claude 的全面检查,架构设计有 Plan mode 的系统输出,测试有自动生成,文档有自动整理。你真正花时间的,是审查、决策、验证——这些才是开发者不可替代的价值。

本章小结

本章通过一个完整的"从零搭建用户认证模块"案例,展示了用 Claude Code 开发新功能的标准流程:

  1. 需求分析:向 Claude Code 描述完整需求,让它帮你分析模块组成、数据模型、安全注意事项——在你写代码之前暴露遗漏点。
  2. 架构设计:切换到 Plan mode,让 Claude Code 输出分阶段的实现计划——按依赖关系排序、每阶段可独立验证。
  3. 编码实现:按阶段逐步推进,每阶段 2-3 个文件;先读文件再写代码;逐文件 Diff 审查;每阶段完成后立即验证。
  4. 测试验证:从单元测试到集成测试,让 Claude Code 自动生成;遇到失败让它自己分析并修复。
  5. 提交与文档:用 /commit 生成精准的 commit message,更新 API 文档和 README。

本章的核心信息可以浓缩为五个字:分析→设计→实现→测试→提交。这不是新颖的方法论,但 Claude Code 让你在每个环节都更快、更全面、更少遗漏。

下一章我们将面对一个更难啃的骨头——大规模重构。与"从零搭建"不同,重构是在现有代码上做手术,你需要更谨慎的策略。见第 22 章:场景三——大规模重构