# 贡献指南 (CONTRIBUTING)

**适用范围**: 企微 IT 智能服务台 (`wecom_it_smart_desk`)
**维护者**: 宋献（项目负责人）+ Claude（评审协作）+ workbuddy（自动化开发）
**最后更新**: 2026-06-14

---

## 📌 仓库入口

- **Gitea（公网 Funnel）**: `https://ds923plus.tail58d872.ts.net/simon/wecom_it_smart_desk`
- **Gitea（内网 LAN）**: `http://100.85.152.112:8418/simon/wecom_it_smart_desk`
- **Tailscale 私网**: `100.85.152.112:8418`

---

## 🌿 分支模型

| 分支 | 用途 | 保护规则 |
|---|---|---|
| `main` | 稳定可发布版本 | 🔒 禁止直推,需 PR + 1 reviewer |
| `develop` | 主开发分支 | 🟡 允许 push |
| `feature/*` | 新功能(从 develop 拉) | 🟢 自由 |
| `hotfix/*` | 紧急修复(从 main 拉) | 🟢 自由,合入需评审 |
| `release/*` | 发布准备 | 🟡 自由,合入 main 需评审 |

**主分支**: `main`(默认推送目标)

---

## 📝 Commit 规范

**格式** (Conventional Commits):

```
<type>(<scope>): <subject>

<body>

<footer>
```

**type 取值**:

| type | 用途 | 示例 |
|---|---|---|
| `feat` | 新功能 | `feat(messages): 撤回消息端点` |
| `fix` | Bug 修复 | `fix(h5): 修复参与者权限校验` |
| `refactor` | 重构(无新功能 / 无 Bug 修复) | `refactor(agents): 提取鉴权中间件` |
| `docs` | 文档变更 | `docs: 评审报告 workbuddy-2026-06-14` |
| `chore` | 构建/工具/依赖 | `chore: 强化 .gitignore` |
| `security` | 安全相关 | `security: P0 鉴权止血` |
| `perf` | 性能优化 | `perf(messages): 消息批量插入` |
| `test` | 测试相关 | `test: 加 mark_read 鉴权测试` |

**scope 取值**: 模块名,如 `agents` / `messages` / `h5` / `frontend-agent` / `nginx` / `workbuddy`

**subject**: 中文,不超过 50 字,**祈使句**,如 "修复 xx" 而非 "修复了 xx"

**body** (可选): 详细说明,**每行 ≤ 72 字**

**footer** (可选): 关联 Issue / workbuddy 任务编号,如:
```
Refs: #18
Refs: workbuddy-2026-06-14-任务-修遗留
```

**示例**:
```
security(ws): WS token 从 URL 改 header 鉴权

【workbuddy 推送 2026-06-14】
- ws.py 服务端: 优先 Authorization: Bearer header, query 降级
- ws.ts 前端: 待 workbuddy 改 Sec-WebSocket-Protocol 方案
- 详见 docs/评审报告/workbuddy-2026-06-14-P0安全.md

Refs: #18
Refs: workbuddy-2026-06-14-任务-修遗留
```

---

## 🔄 PR 流程

### 推送前自检清单

**所有 P0 修复推送前必须 4 件套自检**:

- [ ] **鉴权**: 新增/修改端点是否有 `Depends(get_current_agent)` 或 `_get_current_employee`?
- [ ] **依赖**: 改代码是否同步 `requirements.txt` / `package.json`?
- [ ] **alembic**: 数据库 schema 变化是否生成迁移脚本?
- [ ] **配置**: nginx / docker / conf 变化 plan 写了是否做完?

### PR 流程

1. **本地开发**
   ```bash
   git checkout develop
   git pull
   git checkout -b feature/xxx
   # 改代码
   git add .
   git commit -m "feat(xxx): ..."
   git push origin feature/xxx
   ```

2. **开 PR**(走 Gitea Web 或 API)
   - 标题 = commit subject
   - 描述 = body 内容 + 关联评审报告 / workbuddy 任务
   - Reviewer: `simon`(主) + 可选 workbuddy auto-review

3. **评审员评审**(Gitea UI)
   - 🟢 **P0 鉴权 / 安全**: 必须 Claude 评审 + 通过
   - 🟡 **功能 / 重构**: 至少 1 reviewer 通过
   - 🟢 **docs / chore**: 自审即可

4. **合并**
   - 评审通过 + status check 绿 → squash merge → 删 feature 分支

---

## 🔒 main 分支保护规则

由 Gitea API 配置,目前设定:

| 项 | 值 |
|---|---|
| 禁止直推 | ✅ |
| 需 PR | ✅ |
| Approvals 数 | 1 |
| Dismiss stale approvals | ✅ |
| 状态检查必须通过 | ✅(待配) |
| 管理员限制 | ✅(管理员也走 PR) |

**配分支保护**:
```bash
curl -X POST \
  -H "Authorization: token <ADMIN_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "enable_push": false,
    "enable_pull_request": true,
    "required_approvals": 1,
    "dismiss_stale_approvals": true,
    "block_admin_merge": true
  }' \
  "https://ds923plus.tail58d872.ts.net/api/v1/repos/simon/wecom_it_smart_desk/branch_protections/main"
```

---

## 🤖 workbuddy 推送规则

workbuddy 自动化开发,推送必须满足:

1. **完整自检**: 鉴权 + 依赖 + alembic + 配置 4 件套
2. **评审报告**: 每次推送**生成** `docs/评审报告/workbuddy-{日期}-{主题}.md`
3. **workbuddy 记忆更新**: `.workbuddy/memory/{日期}-{主题}.md`
4. **5 项遗留**: 上一轮评审遗留的 5 项必须修完才能合入下一轮
5. **不叠加新功能**: 评审未消化前不推新功能(见 `docs/评审报告/` 历次教训)

**评审失败处理**:
- 评审标 🔴 P0 → 立即修,不接受反驳(除非评审员改判)
- 评审标 🟡 P1 → 列入遗留表(workbuddy 记忆 + 风险跟踪表)
- 评审标 🟢 P2 → 知识库积累,不强制修

---

## 🆘 紧急修复 (hotfix)

**场景**: 生产 P0 漏洞 / 数据丢失风险

**流程**:
1. 从 main 拉 `hotfix/xxx`
2. 改 + 测(用预生产环境)
3. PR → main(快通道,reviewer 优先 @ 宋献)
4. 评审通过 → 立即合并 + 部署
5. 同步 cherry-pick 回 develop

**禁止**:
- ❌ 跳过评审
- ❌ 推 main 直接部署
- ❌ 评审未通过就部署

---

## 📚 关联文档

- [`README.md`](README.md) — 项目总览
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — 架构设计
- [`docs/风险跟踪表.md`](docs/风险跟踪表.md) — 22 项审计追踪
- [`docs/评审报告/`](docs/评审报告/) — workbuddy 推送评审
- [`.workbuddy/memory/`](.workbuddy/memory/) — workbuddy 任务记忆
