# 微信小程序多人协作分支管理规范

## 一、分支结构

```
main (主分支/生产环境)
  └── test (测试分支)
        └── feature/xxx (个人开发分支)
```

| 分支 | 用途 | 稳定性 |
|------|------|--------|
| main | 生产环境代码 | 最高，仅接受测试通过的代码合并 |
| test | 测试环境，用于体验版发布 | 中，需验证后合并到 main |
| feature/xxx | 个人开发分支 | 低，按需命名，如 `feature/user-center` |

---

## 二、开发流程

### 1. 开始开发

```bash
# 确保本地 main 最新
git checkout main
git pull origin main

# 从 main 创建自己的开发分支
git checkout -b feature/your-name-work
```

### 2. 开发阶段

- 在个人分支上开发功能
- 频繁提交，保持原子性提交
- 定期 `git pull origin main` 同步主线变更，避免合并冲突累积

```bash
git add .
git commit -m "feat: 完成xxx功能"
```

### 3. 合并到 test 分支

```bash
# 切换到 test
git checkout test
git pull origin test

# 合并个人分支
git merge feature/your-name-work

# 推送 test 分支
git push origin test
```

### 4. 打包上传体验版

```bash
# 执行打包
npm run build
```

打包完成后：

1. 打开 **微信开发者工具**
2. 导入项目，选择 `dist/build/mp-weixin` 目录
3. 在开发者工具中点击 **上传**
4. 登录 [微信公众平台](https://mp.weixin.qq.com)
5. 进入 **管理->版本管理**
6. 找到刚上传的版本，点击 **选为体验版**

---

## 三、合并到 main 分支

当 test 分支验证通过后，将其合并到 main：

```bash
git checkout main
git pull origin main

git merge origin/test

git push origin main
```

---

## 四、冲突处理

合并时如有冲突，在个人分支解决后再合并：

```bash
git checkout feature/your-name-work
git merge main
# 解决冲突后
git add .
git commit -m "merge: 解决与main的冲突"
git push origin feature/your-name-work

# 重新合并到 test
git checkout test
git merge feature/your-name-work
git push origin test
```

---

## 五、注意事项

1. **禁止直接向 main 和 test 分支提交代码**，必须通过合并
2. **每次合并前先拉取最新代码**，避免覆盖他人改动
3. **体验版发布前确认代码已提交**，避免遗漏
4. **开发分支命名建议**：`feature/姓名-功能名`，如 `feature/zhangsan-login`
5. **删除已合并的开发分支**：`git branch -d feature/your-name-work`

---

## 六、比赛服 Proto 更新流程

### 1. 新开发人员快速接手

首次拉取项目后，先安装依赖并确认当前协议与运行时解码器一致：

```bash
npm install
npm run proto:check
npm run build
```

如果 `proto:check` 提示协议不同步，先执行 `npm run proto:generate`，不要直接修改生成区块。

### 2. 相关文件职责

| 文件 | 职责 | 修改规则 |
|------|------|----------|
| `src/utils/match.min.js` | 后端比赛服协议描述，是生成字段表的输入文件 | 后端协议更新时整体替换；禁止在小程序运行时代码中导入 |
| `scripts/generate-match-schema.mjs` | 解析协议、校验字段并生成运行时字段表 | 只有新增通用协议能力时才修改 |
| `src/utils/matchProtocol.js` | 小程序实际使用的 protobuf 编解码器 | `<match-schema-generated>` 标记区间内禁止手动修改 |
| `src/matchWebsocket.js` | 服务端消息路由、ACK 和业务事件分发 | 新增消息业务行为时人工接入 |
| `src/utils/matchAdapter.js` | 将解码结果从 snake_case 统一转换为 camelCase | 页面继续使用适配后的字段名 |

`match.min.js` 不是小程序运行时解码器。运行时仍使用 `protobufjs/minimal.js` 的 `Reader/Writer`，`int64` 字段统一保留为字符串，避免大整数精度丢失。

### 3. 日常协议更新步骤

```text
替换 src/utils/match.min.js
        ↓
执行 npm run proto:update
        ↓
检查生成差异和业务接入范围
        ↓
执行 git diff --check
        ↓
微信开发者工具检查包体并上传
```

具体操作：

1. 从后端获取最新的 `match.min.js`，整体覆盖 `src/utils/match.min.js`。
2. 执行推荐命令：

```bash
npm run proto:update
```

3. 该命令会依次完成：
   - 解析 `match.min.js`
   - 更新 `matchProtocol.js` 内的生成区块
   - 校验生成区块与协议源文件一致
   - 执行微信小程序正式构建
4. 检查 Git 差异。普通字段更新通常只应涉及：
   - `src/utils/match.min.js`
   - `src/utils/matchProtocol.js` 的生成区块
5. 如果新增了消息业务行为，再单独检查 `src/matchWebsocket.js`、页面或组件的接入改动。
6. 执行空白和换行检查：

```bash
git diff --check
```

7. 打开微信开发者工具，导入 `dist/build/mp-weixin`，检查代码依赖分析和主包体积后再上传。

### 4. Proto 命令说明

| 命令 | 用途 | 是否修改文件 |
|------|------|--------------|
| `npm run proto:generate` | 根据 `match.min.js` 更新生成区块 | 是 |
| `npm run proto:check` | 检查生成区块是否与协议同步 | 否 |
| `npm run proto:update` | 执行生成，然后运行正式构建 | 是，日常更新推荐使用 |
| `npm run dev` | 启动开发构建，启动前自动执行 `proto:check` | 协议不同步时直接中止 |
| `npm run build` | 执行正式构建，构建前自动执行 `proto:check` | 协议不同步时直接中止 |

`npm run dev` 和 `npm run build` 只负责检查，不会自动改写协议；发现不同步时应执行 `npm run proto:generate` 或 `npm run proto:update`。

### 5. 自动生成与人工接入边界

以下内容由生成器自动处理：

- 服务端和客户端消息枚举
- 普通 scalar 字段
- 嵌套 message
- repeated message
- 当前解码器支持的 map
- snake_case 字段名和 oneof 兼容信息

以下情况仍需人工处理：

- **新增服务端消息类型**：枚举会自动生成，但 `matchWebsocket.js` 的路由、ACK、音频或页面事件仍需接入。
- **新增客户端指令**：枚举会自动生成，但发送函数、字段编码和业务调用入口仍需接入。
- **修改既有字段编号或类型**：属于协议兼容性变更，必须先与后端确认，不能只看构建是否通过。
- **新增解码器不支持的类型**：生成器会直接报错，需要同时扩展生成器和 `matchProtocol.js` 的通用解码能力。

当前生成器会拒绝不支持的 scalar、map key、字段规则以及 packed scalar repeated，避免继续构建后静默丢字段。

### 6. 常见报错处理

| 报错或现象 | 原因 | 处理方式 |
|------------|------|----------|
| 生成区块与 `match.min.js` 不同步 | 替换协议后没有重新生成 | 执行 `npm run proto:update` |
| 找不到 `Root.create(...)` | 后端提供的文件格式发生变化或文件不完整 | 停止更新，确认协议文件来源和生成格式 |
| 使用了不支持的类型、规则或 map key | 新协议超出当前通用解码器能力 | 不要手补生成区块，先扩展生成器和解码器并补充验证 |
| packed scalar repeated 不支持 | protobuf 默认可能使用 packed 编码，当前通用解码器未覆盖 | 增加 packed 解码能力后再重新生成 |
| `matchProtocol.js` 缺少生成区块标记 | 标记被误删或生成区块被手改 | 恢复 `<match-schema-generated>` 标记，重新执行生成 |
| 协议生成成功但构建失败 | 问题位于项目构建或业务代码，不是字段表同步 | 保留生成结果，按构建错误继续定位 |

### 7. 禁止事项与验收清单

禁止：

- 禁止在运行时代码中导入 `match.min.js`。
- 禁止手动修改 `<match-schema-generated>` 与 `</match-schema-generated>` 之间的内容。
- 禁止绕过 `proto:check` 后直接上传。
- 禁止把 `int64` 字段直接转换为普通 `Number`。
- 禁止把“枚举已经生成”等同于“业务消息已经完成接入”。

每次协议更新至少确认：

1. `npm run proto:check` 通过。
2. `npm run build` 通过，或直接确认 `npm run proto:update` 已完整通过。
3. `git diff --check` 通过。
4. 生成区块之外没有意外改动。
5. 新消息已完成必要的 WebSocket 路由和页面验证。
6. 微信开发者工具中的主包、分包体积符合上传限制。
