# PR 代码审查完整工作流示例

**场景**：团队成员提交了一个 PR，需要进行代码审查。

## 前置条件

- `gitlink-cli` 已安装并登录
- 用户拥有 PR 所在仓库的读取权限

## 工作流步骤

### Step 1：获取 PR 上下文

```bash
# 查看 PR 列表，找到待审查的 PR
gitlink-cli pr +list --state open --format json

# 获取特定 PR 详情
gitlink-cli pr +view --id 42 --format json
```

**输出示例：**
```json
{
  "ok": true,
  "data": {
    "id": 42,
    "title": "feat: add user authentication module",
    "body": "实现了基于 JWT 的用户认证模块，包含登录、注册、Token 刷新功能。",
    "state": "open",
    "author": "developer_a",
    "created_at": "2026-05-18T10:30:00+08:00",
    "source_branch": "feat/auth-module",
    "target_branch": "master"
  }
}
```

### Step 2：获取变更文件

```bash
gitlink-cli pr +files --id 42 --format json
```

**输出示例：**
```json
{
  "ok": true,
  "data": [
    { "filename": "src/auth/login.py", "status": "added", "additions": 120, "deletions": 0 },
    { "filename": "src/auth/token.py", "status": "added", "additions": 85, "deletions": 0 },
    { "filename": "src/config.py", "status": "modified", "additions": 5, "deletions": 2 },
    { "filename": "tests/test_auth.py", "status": "added", "additions": 200, "deletions": 0 },
    { "filename": "requirements.txt", "status": "modified", "additions": 3, "deletions": 0 }
  ]
}
```

### Step 3：获取 Diff 内容

```bash
gitlink-cli pr +diff --id 42 --format json
```

### Step 4：逐文件审查

对每个变更文件，分析代码质量。以下是审查结果示例：

```markdown
## PR #42 代码审查报告

### 🔴 Critical

1. **JWT Secret 硬编码** — `src/config.py:15`
   > `JWT_SECRET = "my-secret-key-123"` 硬编码在源码中，存在泄露风险。建议：
   > - 使用环境变量：`JWT_SECRET = os.getenv("JWT_SECRET")`
   > - 或使用配置文件（不提交到版本控制）

2. **SQL 注入风险** — `src/auth/login.py:42`
   > `cursor.execute(f"SELECT * FROM users WHERE username = '{username}'")` 直接拼接用户输入，存在 SQL 注入风险。建议使用参数化查询：
   > ```python
   > cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
   > ```

### 🟡 Warning

1. **密码明文存储** — `src/auth/login.py:88`
   > 密码直接存储到数据库，建议使用 `bcrypt` 或 `argon2` 进行哈希处理。

2. **缺少输入验证** — `src/auth/login.py:15`
   > `login()` 函数没有对 `username` 和 `password` 进行长度和格式校验。建议：
   > ```python
   > if len(username) < 3 or len(username) > 50:
   >     raise ValueError("用户名长度应在 3-50 个字符之间")
   > ```

### 🔵 Suggestion

1. **Token 过期时间可配置** — `src/auth/token.py:30`
   > `ACCESS_TOKEN_EXPIRE_MINUTES = 30` 建议改为从环境变量读取，方便不同环境配置。

2. **测试可增加边界用例** — `tests/test_auth.py`
   > 现有测试覆盖了正常流程，建议补充：
   > - 空用户名/密码
   > - 超长输入
   > - Token 过期处理
   > - 并发登录场景

### ✅ Positive

- 完整的测试覆盖（200 行测试代码，覆盖主要功能路径）
- 清晰的模块划分（login / token 职责分离）
- 有类型注解，代码可读性好
```

### Step 5：dry-run 预览（用户确认报告后）

报告含 2 个 Critical，评审状态取 `rejected`（Request changes）。先 dry-run 预览，**不实际提交**：

```bash
gitlink-cli pr +review --id 42 \
  --status rejected \
  --content "## PR #42 代码审查报告

### 🔴 Critical
1. **JWT Secret 硬编码** — src/config.py:15。建议 os.getenv(\"JWT_SECRET\")。
2. **SQL 注入风险** — src/auth/login.py:42。建议参数化查询。

### 🟡 Warning
1. **密码明文存储** — 建议使用 bcrypt 哈希处理。

### 总体评价
代码整体结构清晰，测试覆盖良好。建议修复 Critical 问题后合并。" \
  --dry-run --format json
```

→ 核对预览无误，请用户二次确认。

### Step 6：提交评审（用户确认 dry-run 后）

去掉 `--dry-run` 正式提交：

```bash
gitlink-cli pr +review --id 42 --status rejected --content "<同上审查报告>" --format json
```

### Step 7：行内评论（可选，针对具体行）

把 Critical 意见精准挂到对应行（行号取文件真实行号，注意 import/头注释偏移；不确定则并入上面的总报告）：

```bash
gitlink-cli pr +create-comment --id 42 --path src/config.py --line 15 \
  --body "Critical: JWT_SECRET 硬编码，存在泄露风险。改用 os.getenv(\"JWT_SECRET\")。" --format json

gitlink-cli pr +create-comment --id 42 --path src/auth/login.py --line 42 \
  --body "Critical: SQL 注入风险，用户输入直接拼接。改用参数化查询。" --format json
```

### Step 8：输出审查摘要

```markdown
## 📋 审查摘要 — PR #42 feat: add user authentication module

| 指标 | 数据 |
|------|------|
| 审查文件数 | 5 |
| 变更行数 | +413 / -2 |
| Critical 问题 | 2 |
| Warning | 2 |
| Suggestion | 2 |

### 主要发现
1. **[Critical]** JWT Secret 硬编码在源码中
2. **[Critical]** SQL 查询存在注入风险
3. **[Warning]** 密码明文存储

### 总体评价
代码结构良好，测试覆盖完整。修复两个安全关键问题后即可合并。
```

---

## 完整命令速览

```bash
# 获取 PR 详情
gitlink-cli pr +view --id <id> --format json

# 获取变更文件
gitlink-cli pr +files --id <id> --format json

# 获取 Diff
gitlink-cli pr +diff --id <id> --format json

# 提交评审（首选；Critical→rejected / 仅建议→common / 无问题→approved）
gitlink-cli pr +review --id <id> --status <common|approved|rejected> --content "<审查报告>" [--dry-run]

# 行内评论（绑定文件+行；行号不确定时勿用，改用 +comment 或并入 --content）
gitlink-cli pr +create-comment --id <id> --path <path> --line <n> --body "<意见>"

# 普通评论（不绑行）
gitlink-cli pr +comment --id <id> --body "<评论>"
```
