来源: everything-claude-code by Affaan Mustafa 原始文件: agents/code-reviewer.md + commands/code-review.md
代码评审(Code Review)
概述
一套系统化的代码评审流程,包含安全审查、代码质量检查和最佳实践验证。通过置信度过滤和严重等级分类,确保评审结果聚焦于真正重要的问题,避免噪音干扰。适合在每次代码修改后立即使用。
二、评审清单
安全问题(CRITICAL -- 严重)
以下问题必须标记 -- 它们可能造成真正的损害:
- 硬编码凭据(Hardcoded credentials) -- 源代码中的 API 密钥、密码、令牌(Token)、连接字符串
- SQL 注入(SQL injection) -- 查询中使用字符串拼接而非参数化查询
- XSS 漏洞(XSS vulnerabilities) -- 未转义的用户输入渲染在 HTML/JSX 中
- 路径遍历(Path traversal) -- 未经清理的用户控制文件路径
- CSRF 漏洞(CSRF vulnerabilities) -- 状态修改端点(Endpoint)缺少 CSRF 防护
- 身份验证绕过(Authentication bypasses) -- 受保护路由缺少身份验证检查
- 不安全的依赖(Insecure dependencies) -- 已知有漏洞的软件包
- 日志中暴露敏感信息(Exposed secrets in logs) -- 记录敏感数据(令牌、密码、个人身份信息)
// 错误:通过字符串拼接导致 SQL 注入
const query = `SELECT * FROM users WHERE id = ${userId}`;
// 正确:参数化查询
const query = `SELECT * FROM users WHERE id = $1`;
const result = await db.query(query, [userId]);
// 错误:未经清理就渲染原始用户 HTML
// 始终使用 DOMPurify.sanitize() 或等效方法清理用户内容
// 正确:使用文本内容或进行清理
<div>{userComment}</div>
代码质量(HIGH -- 高)
- 过长函数(>50 行)-- 拆分为更小、更专注的函数
- 过大文件(>800 行)-- 按职责提取模块
- 深层嵌套(>4 层)-- 使用提前返回(Early return)、提取辅助函数
- 缺少错误处理 -- 未处理的 Promise 拒绝、空 catch 块
- 可变模式(Mutation patterns) -- 优先使用不可变操作(展开运算符、map、filter)
- console.log 语句 -- 合并前移除调试日志
- 缺少测试 -- 新代码路径没有测试覆盖
- 死代码(Dead code) -- 注释掉的代码、未使用的导入、不可达的分支
// 错误:深层嵌套 + 可变操作
function processUsers(users) {
if (users) {
for (const user of users) {
if (user.active) {
if (user.email) {
user.verified = true; // 可变操作!
results.push(user);
}
}
}
}
return results;
}
// 正确:提前返回 + 不可变 + 扁平结构
function processUsers(users) {
if (!users) return [];
return users
.filter(user => user.active && user.email)
.map(user => ({ ...user, verified: true }));
}
React/Next.js 模式(HIGH -- 高)
审查 React/Next.js 代码时,还需检查:
- 缺少依赖数组 --
useEffect/useMemo/useCallback的依赖不完整 - 渲染中更新状态(State updates in render) -- 渲染期间调用 setState 会导致无限循环
- 列表缺少 key -- 当项目可以重新排序时使用数组索引作为 key
- 属性透传(Prop drilling) -- 属性传递超过 3 层(应使用 Context 或组合模式)
- 不必要的重新渲染 -- 对昂贵计算缺少记忆化(Memoization)
- 客户端/服务端边界 -- 在服务端组件(Server Components)中使用
useState/useEffect - 缺少加载/错误状态 -- 数据获取没有回退 UI
- 过期闭包(Stale closures) -- 事件处理器捕获了过期的状态值
// 错误:缺少依赖,过期闭包
useEffect(() => {
fetchData(userId);
}, []); // userId 缺失于依赖列表中
// 正确:完整的依赖
useEffect(() => {
fetchData(userId);
}, [userId]);
// 错误:使用索引作为 key,列表可重新排序
{items.map((item, i) => <ListItem key={i} item={item} />)}
// 正确:稳定的唯一 key
{items.map(item => <ListItem key={item.id} item={item} />)}
Node.js/后端模式(HIGH -- 高)
审查后端代码时:
- 未验证的输入 -- 请求体/参数未经 Schema 验证就使用
- 缺少速率限制(Rate limiting) -- 公开端点没有限流
- 无限制查询 -- 面向用户的端点使用
SELECT *或没有 LIMIT 的查询 - N+1 查询 -- 在循环中获取关联数据而非使用 JOIN/批量查询
- 缺少超时配置 -- 外部 HTTP 调用没有超时设置
- 错误信息泄露 -- 向客户端发送内部错误详情
- 缺少 CORS 配置 -- API 可被意外的来源访问
// 错误:N+1 查询模式
const users = await db.query('SELECT * FROM users');
for (const user of users) {
user.posts = await db.query('SELECT * FROM posts WHERE user_id = $1', [user.id]);
}
// 正确:使用 JOIN 或批量查询
const usersWithPosts = await db.query(`
SELECT u.*, json_agg(p.*) as posts
FROM users u
LEFT JOIN posts p ON p.user_id = u.id
GROUP BY u.id
`);
性能(MEDIUM -- 中)
- 低效算法 -- 可以用 O(n log n) 或 O(n) 时却使用了 O(n^2)
- 不必要的重新渲染 -- 缺少 React.memo、useMemo、useCallback
- 过大的包体积(Bundle size) -- 导入整个库而非使用可摇树(Tree-shakeable)的替代方案
- 缺少缓存 -- 重复的昂贵计算没有记忆化
- 未优化的图片 -- 大图片没有压缩或懒加载
- 同步 I/O -- 在异步上下文中执行阻塞操作
最佳实践(LOW -- 低)
- TODO/FIXME 没有关联工单 -- TODO 应引用 Issue 编号
- 公共 API 缺少 JSDoc -- 导出的函数没有文档
- 命名不佳 -- 在非简单上下文中使用单字母变量(x、tmp、data)
- 魔法数字(Magic numbers) -- 未解释的数字常量
- 格式不一致 -- 混合使用分号、引号风格、缩进
三、评审命令(Command)
快速评审流程
对未提交变更进行全面的安全和质量审查:
获取变更文件:
git diff --name-only HEAD对每个变更文件,检查:
安全问题(CRITICAL -- 严重):
- 硬编码的凭据、API 密钥、令牌
- SQL 注入漏洞
- XSS 漏洞
- 缺少输入验证
- 不安全的依赖
- 路径遍历风险
代码质量(HIGH -- 高):
- 函数超过 50 行
- 文件超过 800 行
- 嵌套深度超过 4 层
- 缺少错误处理
- console.log 语句
- TODO/FIXME 注释
- 公共 API 缺少 JSDoc
最佳实践(MEDIUM -- 中):
- 可变模式(应使用不可变方式)
- 代码/注释中使用 Emoji
- 新代码缺少测试
- 无障碍性(a11y)问题
生成报告,包含:
- 严重等级:CRITICAL、HIGH、MEDIUM、LOW
- 文件位置和行号
- 问题描述
- 建议修复方案
如果发现 CRITICAL 或 HIGH 问题,阻止提交
绝不批准含有安全漏洞的代码!
四、评审输出格式
按严重等级组织评审结果。对于每个问题:
[CRITICAL] 源代码中硬编码了 API 密钥
文件: src/api/client.ts:42
问题: API 密钥 "sk-abc..." 暴露在源代码中。这将被提交到 git 历史记录中。
修复: 移至环境变量并添加到 .gitignore/.env.example
const apiKey = "sk-abc123"; // 错误
const apiKey = process.env.API_KEY; // 正确
评审摘要格式
每次评审结束时输出:
## 评审摘要
| 严重等级 | 数量 | 状态 |
|----------|------|------|
| CRITICAL | 0 | 通过 |
| HIGH | 2 | 警告 |
| MEDIUM | 3 | 信息 |
| LOW | 1 | 备注 |
结论: 警告 -- 2 个 HIGH 问题应在合并前解决。
五、审批标准
- 批准(Approve):无 CRITICAL 或 HIGH 问题
- 警告(Warning):仅有 HIGH 问题(可谨慎合并)
- 阻止(Block):发现 CRITICAL 问题 -- 必须在合并前修复
六、项目特定指南
在可用时,还应检查来自 CLAUDE.md 或项目规则的项目特定约定:
- 文件大小限制(例如:典型 200-400 行,最大 800 行)
- Emoji 策略(许多项目禁止在代码中使用 Emoji)
- 不可变性要求(展开运算符优于修改操作)
- 数据库策略(RLS、数据库迁移模式)
- 错误处理模式(自定义错误类、错误边界)
- 状态管理约定(Zustand、Redux、Context)
根据项目已建立的模式调整你的评审。如有疑问,与代码库的其余部分保持一致。