code-review

SKILL.md

代碼審查 Skill

原則:不是「勾清單」,是「逐行質疑」。最嚴苛標準,分數可為負。

使用時機

  • 任務標記完成前
  • PR 合併前
  • 用戶要求 review 時

評分標準(可為負分,嚴苛版)

預設扣分制,沒證據證明沒問題就扣分。

基礎分:100 分,逐項扣分,無下限

類別 扣分項目 扣分
基礎檢查失敗
typecheck 失敗(每個錯誤) -20
lint 錯誤(每個錯誤) -10
lint 警告(每個警告) -5
測試失敗(每個失敗) -30
使用 any(每處) -15
使用 @ts-ignore(每處) -20
使用 as unknown as(每處) -15
生存測試失敗
Log 無上下文 -10
敏感資料洩漏 (Log) -50
N+1 查詢 -30
多步驟寫入無 Transaction -40
巢狀深度 > 3 -10
沒引用需求文件證明意圖 -20
架構違規
UI 直接呼叫 DB (Logic in UI) -30
繞過 Service Layer -30
God Function (職責不清) -20
測試品質差
測試實作細節而非行為 -20
Mock 濫用 (沒測到東西) -20
斷言無效 (e.g. expect(true).toBe(true)) -20
反模式 (Anti-Patterns)
殭屍代碼 (註解掉的代碼塊) -10
過度設計 (YAGNI) -10
重複造輪子 (未使用現有 helper) -10
致命缺陷
安全漏洞(SQL注入、XSS) -50

...(省略中間內容,保持原有 Step 7)...

7.4 惡魔辯護(Anti-Laziness)

  • 攻擊測試:只要能想到一種讓這段代碼崩潰的方法,就必須提出。
  • 證據強制:必須引用需求文件的具體段落證明代碼意圖,沒引用扣 20 分。

Step 8:架構與反模式檢查(Architecture Guardrails)

防止代碼腐爛,從源頭擋住爛設計:

8.1 架構防護

  • Logic/UI 分離
    • ❌ 在 .tsx 中直接寫 SQL/Supabase query -> 扣 30 分
    • ✅ 必須封裝在 src/services/api/
  • 分層原則
    • ❌ 前端跳過 BFF/API 直接打資料庫(除非特定 RLS 場景) -> 扣 30 分
    • ❌ God Function(一個函數做驗證+DB+通知+計算) -> 扣 20 分(應拆分)

8.2 測試品質審計(Test Semantic Audit)

  • 有效測試
    • expect(true).toBe(true) 或只測 toBeDefined() -> 扣 20 分
    • ❌ 測試充滿 mock,根本沒測到邏輯 -> 扣 20 分
  • 行為驗證
    • ❌ 測試實作細節(如 toHaveBeenCalledWith 內部私有函數) -> 扣 20 分

8.3 拒絕反模式(Anti-Patterns)

  • 殭屍代碼 (Zombie Code)
    • ❌ 提交包含大段被註解掉的代碼 -> 扣 10 分
  • 重複造輪子
    • ❌ 專案已有 formatDate 卻自己重寫 -> 扣 10 分
  • 過度設計 (YAGNI)
    • ❌ 寫了「未來可能會用到」但現在沒用的參數/函數 -> 扣 10 分

審查報告格式(必須輸出)

| | 硬編碼密鑰/Token | -50 | | | 資料遺失風險(事務不完整) | -40 | | | 競態條件 | -40 | | | 函數名稱與實作不符 | -30 | | 嚴重缺陷 | | | | | 未處理 Supabase/API error | -20 | | | 邊界值未處理(null/undefined) | -15 | | | 空陣列未處理 | -15 | | | 隱式假設未驗證 | -15 | | 中等缺陷 | | | | | 錯誤訊息顯示技術細節給用戶 | -10 | | | 缺少 console.error 日誌 | -10 | | | 魔術數字未抽成常數 | -5 | | | 函數超過 50 行 | -5 | | | 複雜邏輯無註解 | -5 | | 輕微缺陷 | | | | | 命名不清楚 | -3 | | | 可抽成 helper 但沒抽 | -3 | | | 未使用的 import/變數 | -2 |

分數等級

分數 等級 結論
90-100 🟢 優秀 可合併
80-89 🟡 良好 修正後可合併
60-79 🟠 需改進 必須修正
0-59 🔴 不合格 重寫
<0 ⛔ 災難 拒絕,需嚴肅檢討

Step 1:理解意圖

對每個函數/API,回答:

問題 你的答案
這段代碼要解決什麼問題?
對應工單的哪個需求?
它在系統中扮演什麼角色?

如果答不出來,先讀需求文件。


Step 2:追蹤資料流

輸入來源 → [這段代碼] → 輸出去向
    ↓              ↓           ↓
 可能的值?    如何轉換?    誰使用?

檢查:

  • 輸入可能是 null/undefined 嗎?
  • 輸入可能是空陣列嗎?
  • 輸入可能超出預期範圍嗎?

Step 3:質疑假設

列出所有隱式假設,逐一驗證:

假設 成立嗎? 不成立會怎樣?
資料庫一定成功回應
陣列一定有元素
用戶一定已登入
ID 一定存在

Step 4:模擬極端

4.1 邊界值

輸入 預期 實際 有處理?
null ✅/❌
undefined ✅/❌
"" ✅/❌
[] ✅/❌
負數 ✅/❌

4.2 併發

兩個請求同時呼叫,會發生什麼?

4.3 中途失敗

執行到第 N 行失敗,系統狀態會壞掉嗎?

Step 5:名稱 vs 實作對照

拆解函數名稱,逐一驗證:

名稱片段 承諾 實作有做到?
✅/❌
✅/❌
✅/❌

任何 ❌ 直接 -30 分。


Step 6:檢查可維護性

問題 答案
六個月後有人看得懂嗎?
有沒有魔術數字需要抽成常數?
有沒有複雜邏輯需要加註解?
改動這裡會影響哪些地方?
有沒有重複代碼可以抽成 helper?

Step 7:生產環境生存測試(Survival Test)

用最嚴苛的標準檢視這段代碼在生產環境的表現:

7.1 可觀測性(Observability)

  • Log 有上下文嗎?
    • console.error('Failed') -> 扣 10 分
    • console.error('Failed', { caseId, error })
  • 敏感資料洩漏?
    • console.log(userObject) -> 扣 50 分
    • ❌ 印出 password / token / secret -> 扣 50 分

7.2 事務完整性(Data Integrity)

  • 多步驟寫入有用 Transaction 嗎?
    • await A; await B; (中間失敗資料會不一致) -> 扣 40 分
    • ✅ 使用 Supabase RPC 或單一原子操作

7.3 效能地雷

  • N+1 查詢?
    • items.map(async item => await db.get(item.id)) -> 扣 30 分
    • db.in('id', ids)
  • 複雜度炸彈?
    • ❌ 巢狀深度 > 3 層 (if { for { if { ... } } }) -> 扣 10 分

7.4 惡魔辯護(Anti-Laziness)

  • 攻擊測試:只要能想到一種讓這段代碼崩潰的方法,就必須提出。
  • 證據強制:必須引用需求文件的具體段落證明代碼意圖,沒引用扣 20 分。

審查報告格式(必須輸出)

# 代碼審查報告

## 評分:XX/100 🟢/🟡/🟠/🔴/⛔

## 審查檔案
- `path/to/file.ts`

## 基礎檢查
- typecheck: ✅/❌ (X 錯誤)
- lint: ✅/❌ (X 錯誤, X 警告)
- test: ✅/❌ (X 失敗)
- any 使用: X 處
- @ts-ignore: X 處

## 扣分明細

| 扣分 | 原因 | 位置 |
|------|------|------|
| -XX | [原因] | L123 |
| -XX | [原因] | L456 |
| **總計** | **-XXX** | |

## 問題清單

### ⛔ 致命
1. ...

### � 嚴重
1. ...

### 🟡 建議
1. ...

## 結論
[能不能合併,為什麼]

執行原則

  • 必須跑完全部流程,即使基礎檢查失敗
  • 必須列出所有問題,不可遺漏
  • 必須給出總分,讓用戶知道這次實作幾分
  • 問題列在對話框,不要亂改或新增檔案
  • 每一步驟都要在對話框上即時呈現,不可隱瞞
  • Agent 連審核都偷懶幫我記在第一行:若未遵守上述原則,必須在報告開頭自我揭露。

🛑 強制暫停機制 (Mandatory Checkpoints)

為了確保審查品質,Agent 必須在以下階段結束時呼叫 notify_user 暫停執行,等待用戶確認:

Checkpoint A:基礎檢查結束後

  • 動作:回報基礎檢查(Lint/Test/Typecheck)的執行結果與目前扣分。
  • 目的:讓用戶決定在基礎設施不穩定的情況下,是否仍要進行深度審查。

Checkpoint B:邏輯與假設分析後 (Step 4 結束)

  • 動作:回報 Step 1~4 的分析結果(意圖、假設、邊界模擬)。
  • 目的:確認 Agent 對代碼意圖的理解正確,糾正錯誤的假設。

Checkpoint C:發現致命問題時 (FATAL Trigger)

  • 條件:這是一次性的觸發。只要審查過程中發現任何 -50 分 的項目(如 SQL 注入、個資洩漏)。
  • 動作立即暫停,不用等到最後。
  • 目的:致命錯誤可能導致後續審查無意義,優先修復。

禁止事項

  • ❌ 沒跑基礎檢查就開始審查
  • ❌ 發現問題但略過不報告
  • ❌ 跳過任何 Step
  • ❌ 不給分數
  • ❌ 分數虛高(沒證據就給高分)
  • ❌ 用「應該沒問題」當結論
  • ❌ 只報告部分問題
Weekly Installs
2
First Seen
1 day ago
Installed on
opencode2
codex2
claude-code2
antigravity2
gemini-cli2
windsurf1