Files
vibe_coding/.cursor/skills/code-review/SKILL.md
2026-03-05 21:27:11 +08:00

210 lines
5.4 KiB
Markdown
Raw 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.
---
name: code-review
version: 2.0.0
description: "从六个维度系统化代码审查(安全/正确/可维护/性能/可测试/一致性)。当需要 Review 代码、检查质量或预提交检查时使用。"
---
> ⚠️ 核心执行流程已在 `.cursor/rules/skill-code-review.mdc` 中由 Cursor 自动注入。
> 本文件提供完整模板、代码示例和边缘场景处理,供 Agent 按需深入 Read。
# Code Review
## 触发条件
用户要求审查代码、检查 PR、评估代码质量或执行预提交检查。
## 执行流程
### 1. 确定审查范围
- 具体文件 → 审查指定文件
- 目录范围 → 审查目录下所有变更
- Git diff → `git diff HEAD~1` 审查最近变更
### 2. 六维度审查
按以下顺序逐一审查:
**🔴 安全性 (Security)**
- 硬编码密钥/凭证?
- SQL 注入 / XSS 风险?
- 未验证的用户输入?
- 不安全的认证/授权?
```php
// ❌ BAD: 直接拼接用户输入到 SQL
$users = Db::select("SELECT * FROM users WHERE name = '{$name}'");
// ✅ GOOD: 参数绑定
$users = Db::select("SELECT * FROM users WHERE name = ?", [$name]);
// ✅ GOOD: Hyperf ORM
$users = User::where('name', $name)->get();
```
```vue
<!-- BAD: 直接渲染用户输入的 HTML -->
<div v-html="userInput" />
<!-- GOOD: 文本插值自动转义 -->
<div>{{ userInput }}</div>
<!-- GOOD: 如必须用 v-html先经过 DOMPurify 清洗 -->
<div v-html="sanitize(userInput)" />
```
**🟠 正确性 (Correctness)**
- 逻辑是否正确?
- 边界条件处理?
- 错误处理完善?
- null/undefined 安全?
```php
// ❌ BAD: 无空值保护
$userName = $user->profile->name;
// ✅ GOOD: 空安全访问
$userName = $user?->profile?->name ?? 'Unknown';
```
```typescript
// ❌ BAD: 解构可能为 null 的响应
const { data } = await api.getUser(id)
// ✅ GOOD: 防御性解构
const response = await api.getUser(id)
const data = response?.data ?? null
```
**🟡 可维护性 (Maintainability)**
- 命名清晰?
- 函数长度合理(< 50 行)?
- 单一职责?
- 业务逻辑是否已提取到纯函数/composable
```vue
<!-- BAD: 组件内嵌大量业务逻辑 -->
<script setup>
const result = computed(() => {
// 30 行复杂计算逻辑...
})
</script>
<!-- GOOD: 逻辑提取到 .utils.ts -->
<script setup>
import { calculateResult } from './MyComponent.utils'
const result = computed(() => calculateResult(props.data))
</script>
```
**🔵 性能 (Performance)**
- 不必要的渲染?
- N+1 查询?
- 大数据集未分页?
- 缺少缓存机会?
```php
// ❌ BAD: N+1 查询
$orders = Order::all();
foreach ($orders as $order) {
echo $order->user->name; // each iteration queries DB
}
// ✅ GOOD: 预加载关联
$orders = Order::with('user')->get();
```
```vue
<!-- BAD: v-for 内使用复杂计算 -->
<div v-for="item in list" :key="item.id">
{{ heavyCompute(item) }}
</div>
<!-- GOOD: 预计算或使用 computed -->
<div v-for="item in computedList" :key="item.id">
{{ item.computedValue }}
</div>
```
**🟣 可测试性 (Testability)**
- 纯函数是否已提取到 `.utils.ts`
- composable 是否可独立测试?
- 关键路径是否有 `data-testid`
- 是否有过度耦合使测试困难?
```typescript
// ❌ BAD: 逻辑耦合在组件中,无法独立测试
// 必须 mount 整个组件才能测试 formatDate
// ✅ GOOD: 提取为可独立测试的纯函数
// date.utils.ts
export function formatDate(date, format = 'YYYY-MM-DD') { ... }
// date.utils.test.ts
it('should format date correctly', () => { ... })
```
**⚪ 一致性 (Consistency)**
- 命名风格统一?
- 遵循项目模式?
- import 顺序统一?
- 错误处理模式统一?
### 3. 预提交检查联动
审查代码时,同步执行以下自动化检查:
```bash
# PHP 后端
cd Case-Database-Backend
vendor/bin/phpstan analyse --level=5 --no-progress # 静态分析
vendor/bin/php-cs-fixer fix --dry-run --diff # 代码格式
# Vue 前端
cd Case-Database-Frontend-user
npx eslint --quiet src/ # ESLint
npx vitest run --reporter=verbose # 单元测试
cd ..
```
如果项目配置了 husky + lint-staged确认 `.husky/pre-commit` 钩子覆盖:
- [ ] ESLint (前端)
- [ ] PHPStan (后端)
- [ ] 代码格式检查 (Prettier / PHP CS Fixer)
### 4. 输出格式
```markdown
## 代码审查报告
**范围**: <文件/目录/PR>
**总体评价**: ✅ 建议合并 | ⚠️ 需修改后合并 | ❌ 需重写
### 自动化检查
- ESLint: ✅ 通过 | ❌ N 个错误
- PHPStan: ✅ 通过 | ❌ N 个错误
- 测试: ✅ 通过 | ❌ N 个失败
### 发现
#### 🔴 Must Fix
1. **[SEC]** `file.ts:23` — 硬编码 API Key
→ 修复:移入环境变量
#### 🟡 Should Fix
2. **[MAINT]** `service.ts:45` — 函数过长87 行)
→ 建议:拆分为 3 个私有方法
3. **[TEST]** `OrderForm.vue` — 价格计算逻辑未提取到 .utils.ts
→ 建议:提取为纯函数并添加单元测试
#### 🟢 Suggestion
4. **[PERF]** `list.vue:12` — 列表项未使用 `v-memo`
→ 建议:添加 `v-memo="[item.id]"` 减少重渲染
```
## 验证
1. [ ] 六个维度全部覆盖(含可测试性)
2. [ ] 每个发现有具体文件和行号
3. [ ] 每个发现有修复建议(含 BAD/GOOD 代码对比)
4. [ ] 发现按严重程度分级
5. [ ] 预提交检查已执行ESLint + PHPStan + 测试)