# GitLab CI 自動 Claude Code Review

## 背景與目標

GitLab 後端 repo 缺少自動化 code review 機制。希望 MR 建立或 push 新 commit 時，自動觸發 Claude AI 審查並將結果以 comment 形式貼到 MR，作為 human reviewer 的輔助。

**目標：**
- MR pipeline 自動觸發，不需人工操作
- Review 結果聚焦本專案規範（DDD / RLS / jedi-* / 權限模型）
- 不阻擋 MR 合併（`allow_failure: true`），僅為建議
- 無需額外依賴（原生 Node.js，不引入 npm 套件管線）

## 需求範圍

### 觸發條件
- GitLab CI pipeline `rules`：只在 `$CI_PIPELINE_SOURCE == "merge_request_event"` 觸發
- 新 MR 建立、MR 有新 commit push、MR rebase 皆會觸發

### Diff 篩選規則
- 副檔名白名單：`.py`, `.sql`, `.yml`, `.yaml`, `.json`
- 路徑排除：`migrations/`, `tests/`, `__pycache__/`
- Diff 長度上限 80,000 chars，超過截斷並於 prompt 標註

### 審查面向（Claude prompt 覆蓋）

| 面向 | 重點 |
|------|------|
| 架構合規性 | DDD / hexagonal 分層（route 不存取 DB、app service 不 import ORM model、domain 不依賴 infra） |
| 多租戶安全 | tenant / org filter、RLS 是否可能被繞過、跨租戶洩漏風險 |
| 資料庫 | SQLAlchemy N+1、lazy/selectin/joined load 使用、缺失 index |
| API 設計 | response envelope 一致性、HTTP status code、錯誤處理（jedi_common exception + ErrorCode） |
| 安全性 | SQL injection、敏感資料（password/token/PII）洩漏、角色權限檢查（manager / reviewer / auditor / viewer） |

### 輸出格式（繁體中文 Markdown）

1. **整體評分** 1-10，附一句話評語
2. **摘要** ≤3 句
3. **問題清單**：每項含檔案路徑、行號、嚴重程度（🔴 高 / 🟡 中 / 🟢 低）、說明、建議修法
4. **優點**：具體指出做得好的檔案 / 設計決策

### 行為細節

| 情境 | 行為 |
|------|------|
| MR pipeline | 產出 `claude-review.md` artifact + POST comment 至 MR |
| 非 MR pipeline | 只產檔、不呼叫 API、不發 comment |
| 無相關檔案變更 | 只產檔（內容為「無符合審查條件的檔案變更」），不呼叫 API |
| diff 為空 | 只產檔、不呼叫 API |
| Anthropic / GitLab API 呼叫失敗 | job 失敗，但 `allow_failure: true` 不擋 MR |

## 架構

```
┌─────────────────────────────────────────────────────────────┐
│ GitLab CI Pipeline (merge_request_event 觸發)               │
│                                                             │
│  .gitlab-ci.yml                                             │
│   └─ review stage                                           │
│       └─ claude-review job (node:20-alpine)                 │
│           1. apk add git curl jq                            │
│           2. node scripts/claude-review.js                  │
│           3. artifact: claude-review.md (2 weeks)           │
└─────────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────┐
│ scripts/claude-review.js (原生 Node.js)                     │
│                                                             │
│  1. git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME   │
│  2. git diff origin/<target>...HEAD                         │
│     → 過濾副檔名 + 排除路徑                                 │
│     → 80k 截斷                                              │
│  3. Anthropic Messages API (claude-sonnet-4-5)              │
│  4. 寫入 claude-review.md                                   │
│  5. POST GitLab Notes API                                   │
└─────────────────────────────────────────────────────────────┘
```

## 技術選型

| 項目 | 選擇 | 原因 |
|------|------|------|
| Runtime | Node.js 20 (alpine) | 原生 `https` / `child_process` 夠用，不用 python 生態 |
| HTTP client | 內建 `https` 模組 | 不引入第三方依賴（無 package.json 維護成本） |
| 子行程 | `execFileSync` + 參數陣列 | 避免 shell injection |
| Model | `claude-sonnet-4-5` | 平衡速度與審查品質 |
| `max_tokens` | 4096 | 足以容納結構化 review 輸出 |

## 環境變數需求

| 變數 | 來源 | 用途 |
|------|------|------|
| `ANTHROPIC_API_KEY` | GitLab Settings → CI/CD → Variables（Masked） | Anthropic API 認證 |
| `GITLAB_TOKEN` | GitLab Settings → CI/CD → Variables（Masked，Project Access Token `api` scope） | POST comment 至 MR |
| `CI_SERVER_URL` | GitLab CI 預設 | GitLab API base URL |
| `CI_PROJECT_ID` | GitLab CI 預設 | 專案 ID |
| `CI_MERGE_REQUEST_IID` | GitLab CI 預設（MR pipeline） | MR 編號 |
| `CI_MERGE_REQUEST_TARGET_BRANCH_NAME` | GitLab CI 預設（MR pipeline） | 目標 branch |
| `CI_COMMIT_SHA` | GitLab CI 預設 | Comment 標頭顯示 short SHA |

## 安全性考量

- 子行程透過參數陣列傳入（`execFileSync('git', [...])`），避免 shell injection
- `ANTHROPIC_API_KEY` / `GITLAB_TOKEN` 僅透過環境變數讀取，不寫入 log 或 artifact
- `claude-review.md` artifact 內容僅為 review 結果，不包含原始 diff
- `GIT_DEPTH: 0` 完整抓取 commit 歷史以確保能 `git fetch origin <target>` 成功

## 未來延伸（非本次範圍）

- [ ] 根據檔案路徑動態選擇 review template（e.g. migrations SQL 走另一套 prompt）
- [ ] 於 MR comment 中以 inline discussion 指向具體行號（目前僅 Notes API）
- [ ] 快取上一版 review 結果，只對新 commit 增量 review
- [ ] 整合 GitLab Reviewer Bot，對 🔴 高嚴重度問題 auto-request-changes

## 相關檔案

| 檔案 | 用途 |
|------|------|
| `.gitlab-ci.yml` | GitLab CI 設定 |
| `scripts/claude-review.js` | Review 腳本 |
| `docs/changelog/2026-04-24-gitlab-ci-claude-auto-code-review.md` | 本次變更紀錄 |
