From d19285a977556d5fd851135ae1d6da946ea034a0 Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Wed, 8 Jul 2026 15:14:30 +0800 Subject: [PATCH] =?UTF-8?q?docs(docs):=20=E6=96=B0=E5=A2=9E=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=90=AF=E5=8A=A8/=E5=A4=9AAI=E5=8D=8F=E4=BD=9C/CI-CD?= =?UTF-8?q?=20=E4=BD=BF=E7=94=A8=E6=89=8B=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - local-dev-runbook.md: 8 章本地启动手册(环境依赖/端口分配/开发模式/生产模式/裸机运行/常见问题) - multi-ai-collaboration.md: 15 章多AI协作文档(角色定义/模块分工/分支策略/PR流程/审核合并/跨模块变更) - cicd-runbook.md: 10 章 CI/CD 使用手册(架构总览/一次性配置/日常使用/镜像管理/部署验证/回滚) - README.md: 文档清单新增三个 runbook 链接 --- README.md | 3 + docs/standards/cicd-runbook.md | 445 ++++++++++++++ docs/standards/local-dev-runbook.md | 333 ++++++++++ docs/standards/multi-ai-collaboration.md | 735 +++++++++++++++++++++++ 4 files changed, 1516 insertions(+) create mode 100644 docs/standards/cicd-runbook.md create mode 100644 docs/standards/local-dev-runbook.md create mode 100644 docs/standards/multi-ai-collaboration.md diff --git a/README.md b/README.md index ea42a93..8315a12 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,9 @@ pnpm dev - [编码规范](docs/standards/coding-standards.md) - [UI 设计系统](docs/standards/ui-design-system.md) - [Git 工作流](docs/standards/git-workflow.md) +- [本地启动手册](docs/standards/local-dev-runbook.md) +- [多 AI 协作指南](docs/standards/multi-ai-collaboration.md) +- [CI/CD 使用手册](docs/standards/cicd-runbook.md) - [已知问题](docs/troubleshooting/known-issues.md) - [项目规则](.trae/rules/project_rules.md) - [迁移指南](MIGRATION_GUIDE.md) diff --git a/docs/standards/cicd-runbook.md b/docs/standards/cicd-runbook.md new file mode 100644 index 0000000..6844f51 --- /dev/null +++ b/docs/standards/cicd-runbook.md @@ -0,0 +1,445 @@ +# CI/CD 使用手册(CI/CD Runbook) + +> 版本:1.0 +> 日期:2026-07-08 +> 适用范围:Edu 微服务项目(Gitea Actions + Gitea Container Registry + Runner 直接部署) +> 关联文档:[project_rules §15](../../.trae/rules/project_rules.md)、[本地启动手册](./local-dev-runbook.md)、[多 AI 协作指南](./multi-ai-collaboration.md) + +--- + +## 1. 架构总览 + +``` +开发 AI 推送 PR 协调 AI 合并到 main + │ │ + ▼ ▼ +┌─────────────┐ ┌─────────────┐ +│ ci-*.yml │ │ docker.yml │ +│ lint+test+ │ │ build+push │ +│ build+scan │ │ 镜像到 Gitea│ +└─────────────┘ │ Registry │ + └──────┬──────┘ + │ + ▼ + ┌─────────────┐ + │ deploy.yml │ + │ Runner 直接 │ + │ docker │ + │ compose up │ + └─────────────┘ +``` + +### 1.1 组件清单 + +| 组件 | 说明 | +| ---------------------------- | --------------------------------------------------------------- | +| **Gitea** | `git.eazygame.cn`,代码托管 + Actions + Container Registry | +| **Gitea Actions** | CI 运行器,兼容 GitHub Actions 语法 | +| **Gitea Container Registry** | 镜像仓库,地址 `git.eazygame.cn/xiner/edu/:` | +| **Deploy Runner** | 跑在服务器上的 self-hosted runner,标签 `[self-hosted, deploy]` | +| **服务器 MySQL** | 已有容器,端口 3306,容器名 `edu-mysql`(假设) | +| **服务器 Redis** | 已有容器,端口 6379,容器名 `edu-redis`(假设) | + +### 1.2 流水线文件 + +| 文件 | 触发 | 作用 | +| -------------------------------- | ------------------------ | ---------------------------------------------------------- | +| `.github/workflows/ci-ts.yml` | TS 路径变更 | lint + typecheck + test + build + arch:scan + docker-build | +| `.github/workflows/ci-go.yml` | Go 路径变更 | vet + build + test + docker-build | +| `.github/workflows/ci-py.yml` | Python 路径变更 | ruff + pytest(P4 阶段) | +| `.github/workflows/ci-proto.yml` | proto 变更 | buf lint + buf breaking | +| `.github/workflows/docker.yml` | push main / tag `v*` | 构建并推送镜像到 Gitea Registry | +| `.github/workflows/deploy.yml` | docker.yml 完成后 / 手动 | Runner 执行 docker compose up | + +--- + +## 2. 一次性配置(SRE AI 或人类执行) + +### 2.1 启用 Gitea Actions + +在 Gitea 仓库 `xiner/Edu` 设置: + +1. **仓库设置 → Actions → 启用** +2. 安装 actrunner(若未安装): + ```bash + # 在服务器上 + wget https://gitea.com/gitea/act_runner/raw/branch/main/act_runner + chmod +x act_runner + ./act_runner register --instance https://git.eazygame.cn --token + ``` +3. 配置 runner 标签为 `self-hosted,deploy`(部署用)和 `self-hosted,linux`(CI 用) + +### 2.2 启用 Gitea Container Registry + +Gitea 1.20+ 自带 Container Registry,无需额外启用。确认: + +```bash +# 测试登录 +docker login git.eazygame.cn -u <你的用户名> +# 输入密码或 token +``` + +### 2.3 准备服务器网络 + +确保 MySQL/Redis 容器与应用容器在同一 Docker 网络: + +```bash +# 创建共享网络(若不存在) +docker network create edu-shared + +# 将已有的 MySQL/Redis 加入网络(容器名按实际替换) +docker network connect edu-shared edu-mysql # 或实际容器名 +docker network connect edu-shared edu-redis # 或实际容器名 +``` + +> 查看实际容器名:`docker ps --format "{{.Names}}" | grep -E "mysql|redis"` + +### 2.4 初始化部署目录 + +```bash +# 1. 创建部署目录 +sudo mkdir -p /opt/edu +sudo chown -R $USER:$USER /opt/edu + +# 2. 拷贝 compose 文件 +cd /path/to/Edu +cp infra/docker-compose.deploy.yml /opt/edu/docker-compose.yml + +# 3. 创建生产 .env(从模板) +cp infra/deploy.env.example /opt/edu/.env +vim /opt/edu/.env +# 必须修改: +# JWT_SECRET= +# DATABASE_URL=mysql://:@:3306/ +# REDIS_URL=redis://:6379 + +# 4. 登录 Gitea Container Registry(Runner 用户) +docker login git.eazygame.cn -u -p +# token 在 Gitea → 设置 → 应用 → 生成新 token +``` + +### 2.5 配置 Gitea Secrets + +在 Gitea 仓库 → 设置 → Actions → Secrets,添加: + +| Secret 名 | 用途 | 必填 | +| ---------------------- | -------------------------------- | ---- | +| `GITHUB_TOKEN` | Gitea 自动注入,推送镜像用 | 自动 | +| `GITEA_REGISTRY_USER` | deploy.yml 登录 registry(可选) | 否 | +| `GITEA_REGISTRY_TOKEN` | deploy.yml 登录 registry(可选) | 否 | + +> `GITHUB_TOKEN` 由 Gitea Actions 自动注入,无需手动配置。`docker.yml` 用它推送镜像。 +> `deploy.yml` 中 Runner 已在服务器上,若已 `docker login` 过则无需 secrets。 + +--- + +## 3. 日常使用 + +### 3.1 开发 AI 提 PR + +开发 AI 推送特性分支后创建 PR,自动触发 CI: + +``` +PR 创建 → ci-ts.yml / ci-go.yml 运行 + ├─ quality(lint + typecheck + test + build) + ├─ arch-scan(架构扫描) + └─ docker-build(构建不推送) + +CI 全绿 → 协调 AI 审核合并 +``` + +### 3.2 协调 AI 合并 PR + +PR 合并到 main 后,自动触发: + +``` +push main → + ├─ ci-*.yml(确保 main 稳定) + └─ docker.yml → 构建并推送镜像到 git.eazygame.cn/xiner/edu/:latest + │ + ▼ + deploy.yml → Runner 执行 docker compose pull && up -d + │ + ▼ + 健康检查(轮询 /healthz) +``` + +### 3.3 手动部署 + +在 Gitea → Actions → Deploy → Run workflow: + +| 参数 | 说明 | +| ----------- | --------------------------------------- | +| `image_tag` | 部署指定 tag(默认 `latest`) | +| `rollback` | 勾选则跳过 pull,用本地已有镜像重新启动 | + +### 3.4 发布正式版本(tag) + +```bash +git tag -a v1.0.0 -m "P1 阶段首次发布" +git push origin v1.0.0 +``` + +触发 `docker.yml` 推送 `v1.0.0` tag 镜像,再手动触发 deploy.yml 部署 `v1.0.0`。 + +--- + +## 4. 镜像管理 + +### 4.1 镜像地址 + +``` +git.eazygame.cn/xiner/edu/: +``` + +| service | 说明 | +| ---------------- | --------------- | +| `api-gateway` | Go 网关 | +| `classes` | NestJS 班级服务 | +| `teacher-portal` | Next.js 前端 | + +### 4.2 Tag 策略 + +| tag | 来源 | 用途 | +| ------------------ | ----------------- | ---------- | +| `latest` | main 分支最新构建 | 默认部署 | +| `main-` | main 分支每次构建 | 可追溯 | +| `v` | 打 `v*` tag 触发 | 正式版本 | +| `v.` | 打 `v*` tag 触发 | 大版本追踪 | + +### 4.3 查看与清理镜像 + +在 Gitea → 用户设置 → Packages,可查看与管理所有镜像。 + +清理旧 tag(手动): + +```bash +# 列出所有 tag +docker images git.eazygame.cn/xiner/edu/classes --format "{{.Tag}}" + +# 删除本地旧镜像 +docker rmi git.eazygame.cn/xiner/edu/classes:main-abc1234 +``` + +--- + +## 5. 部署验证 + +### 5.1 CI 自动验证 + +`deploy.yml` 部署后会自动轮询健康检查(最多 10 次,每次间隔 6 秒): + +- `http://localhost:8080/healthz` — api-gateway +- `http://localhost:3001/healthz` — classes +- `http://localhost:3000/` — teacher-portal + +失败时输出容器日志,方便排查。 + +### 5.2 手动验证 + +```bash +# SSH 到服务器后 +cd /opt/edu + +# 容器状态 +docker compose ps + +# 健康检查 +curl http://localhost:8080/healthz # api-gateway +curl http://localhost:3001/healthz # classes +curl http://localhost:3000/ # teacher-portal + +# 鉴权验证(生产模式 dev-token 应被拒绝) +curl -H "Authorization: Bearer dev-token" http://localhost:8080/api/v1/classes +# 预期:401 INVALID_TOKEN + +# 查看日志 +docker compose logs -f api-gateway +docker compose logs -f classes +docker compose logs -f teacher-portal +``` + +### 5.3 外部访问 + +若服务器有公网 IP(如 `1.2.3.4`): + +- 前端:`http://1.2.3.4:3000` +- API 网关:`http://1.2.3.4:8080` +- 健康检查:`http://1.2.3.4:8080/healthz` + +--- + +## 6. 回滚 + +### 6.1 CI 回滚(推荐) + +在 Gitea → Actions → Deploy → Run workflow: + +- `image_tag`:填入上一个稳定版本的 tag(如 `main-abc1234`) +- `rollback`:勾选(跳过 pull,用本地已有镜像) + +### 6.2 手动回滚 + +```bash +cd /opt/edu + +# 查看本地镜像 +docker images git.eazygame.cn/xiner/edu/classes --format "{{.Tag}}" + +# 回滚到指定版本 +IMAGE_TAG=main-abc1234 docker compose up -d +``` + +### 6.3 紧急回滚(Git revert) + +若代码有问题: + +```bash +git revert +git push origin main +# CI 自动重新构建部署 +``` + +--- + +## 7. 常见问题 + +### 7.1 CI: pnpm install 失败 + +**症状**:`pnpm install --frozen-lockfile` 报错。 + +**排查**: + +1. `pnpm-lock.yaml` 未提交:`git add pnpm-lock.yaml && git commit -m "chore(deps): 更新 lockfile"` +2. Node 版本不匹配:确认 CI 用 Node 20,本地一致 + +### 7.2 CI: docker-build 失败 + +**症状**:`docker/build-push-action` 报错。 + +**排查**: + +1. Dockerfile 语法错误:本地 `docker build` 验证 +2. 路径错误:确认 `context` 与 `file` 参数 + +### 7.3 CD: 镜像拉取失败 + +**症状**:`docker compose pull` 报 `unauthorized`。 + +**修复**: + +```bash +# 服务器上重新登录 +docker login git.eazygame.cn -u -p + +# 或配置 Gitea secrets GITEA_REGISTRY_USER / GITEA_REGISTRY_TOKEN +``` + +### 7.4 CD: 健康检查失败 + +**症状**:`deploy.yml` 健康检查 10 次后失败。 + +**排查**: + +1. 查看日志:`cd /opt/edu && docker compose logs api-gateway` +2. 常见原因: + - `DATABASE_URL` 连不上 MySQL(检查容器名与网络) + - `JWT_SECRET` 未配置 + - 端口被占用:`docker ps` 检查冲突 + +### 7.5 CD: 连不上 MySQL/Redis + +**症状**:classes 容器报 `ECONNREFUSED edu-mysql:3306`。 + +**修复**: + +```bash +# 1. 确认 MySQL 容器名 +docker ps --format "{{.Names}}" | grep mysql + +# 2. 确认 MySQL 在 edu-shared 网络 +docker network inspect edu-shared | grep -A5 Containers + +# 3. 若不在,加入网络 +docker network connect edu-shared <实际mysql容器名> + +# 4. 修改 /opt/edu/.env 的 DATABASE_URL +# DATABASE_URL=mysql://edu:changeme@<实际容器名>:3306/next_edu_cloud +``` + +### 7.6 Gitea Actions 未触发 + +**症状**:push 后 Actions 不运行。 + +**排查**: + +1. 仓库设置 → Actions → 确认已启用 +2. Runner 在线:Gitea → 设置 → Actions → Runners +3. workflow 文件在 `.github/workflows/` 目录(非 `.gitea/workflows/`) +4. `on:` 触发条件匹配(paths 过滤) + +### 7.7 workflow_run 不触发 + +**症状**:`docker.yml` 完成后 `deploy.yml` 不自动运行。 + +**原因**:Gitea Actions 对 `workflow_run` 触发支持可能不完整。 + +**解决**: + +- 改用手动触发:Actions → Deploy → Run workflow +- 或在 `docker.yml` 末尾加 job 调用 deploy(需要 `workflow_call`) + +--- + +## 8. 排查命令速查 + +```bash +# === 在服务器上 === + +# 查看所有 edu 容器 +docker compose -f /opt/edu/docker-compose.yml ps + +# 查看实时日志 +docker compose -f /opt/edu/docker-compose.yml logs -f + +# 重启单个服务 +docker compose -f /opt/edu/docker-compose.yml restart api-gateway + +# 进入容器 +docker exec -it edu-api-gateway sh +docker exec -it edu-classes sh + +# 查看网络 +docker network inspect edu-shared + +# 查看镜像列表 +docker images git.eazygame.cn/xiner/edu + +# === 在 Gitea Web UI === +# 仓库 → Actions → 查看流水线运行记录 +# 用户设置 → Packages → 管理镜像 +# 仓库 → 设置 → Secrets → 管理 CI 密钥 +# 仓库 → 设置 → Actions → Runners → 查看 Runner 状态 +``` + +--- + +## 9. 安全注意事项 + +1. **`.env` 文件不入库**:`.gitignore` 已忽略,仅存在于服务器 `/opt/edu/.env` +2. **JWT_SECRET 强随机**:生产必须用 `openssl rand -hex 32` 生成 +3. **DEV_MODE=false**:docker-compose.deploy.yml 强制设为 `false` +4. **Gitea Token 权限最小化**:仅给 `package:write` 和 `contents:read` +5. **Runner 隔离**:deploy runner 仅跑在目标服务器,不暴露公网 SSH +6. **镜像扫描**(P6):`docker.yml` 后续加 Trivy 扫描步骤 + +--- + +## 10. 相关文档 + +- [project_rules §15 CI/CD 规范](../../.trae/rules/project_rules.md) +- [project_rules §14 多 AI 协作规范](../../.trae/rules/project_rules.md) +- [本地启动手册](./local-dev-runbook.md) +- [多 AI 协作指南](./multi-ai-collaboration.md) +- [Git 工作流](./git-workflow.md) +- [known-issues](../troubleshooting/known-issues.md) diff --git a/docs/standards/local-dev-runbook.md b/docs/standards/local-dev-runbook.md new file mode 100644 index 0000000..2324d36 --- /dev/null +++ b/docs/standards/local-dev-runbook.md @@ -0,0 +1,333 @@ +# 本地启动手册(Local Dev Runbook) + +> 版本:1.0 +> 日期:2026-07-08 +> 适用范围:Edu 微服务(P1 阶段:api-gateway + classes + teacher-portal) +> 关联文档:[project_rules](../../.trae/rules/project_rules.md)、[004 架构影响地图](../architecture/004_architecture_impact_map.md)、[known-issues](../troubleshooting/known-issues.md) + +--- + +## 1. 环境依赖 + +| 工具 | 版本要求 | 验证命令 | 说明 | +| -------------- | -------- | ------------------------ | -------------------------- | +| Node.js | ≥ 20 | `node -v` | LTS 版本 | +| pnpm | ≥ 9 | `pnpm -v` | `corepack enable` 自动启用 | +| Go | 1.22+ | `go version` | api-gateway 编译 | +| Docker | 24+ | `docker version` | 基础设施容器化 | +| Docker Compose | v2+ | `docker compose version` | 编排基础设施 | +| Git | 2.30+ | `git --version` | husky hooks 需要 | + +> Windows 用户:建议在 PowerShell 或 Git Bash 中执行。Go 工具链若不在 PATH,临时加入:`$env:Path = "C:\Program Files\Go\bin;" + $env:Path` + +--- + +## 2. 服务端口分配 + +| 服务 | 端口 | 语言/框架 | 启动方式 | 健康检查 | +| -------------- | ---- | ------------ | ------------------- | ----------------- | +| MySQL | 3306 | Docker | `docker compose up` | `mysqladmin ping` | +| Redis | 6379 | Docker | `docker compose up` | `redis-cli ping` | +| api-gateway | 8080 | Go (Gin) | `go run main.go` | `GET /healthz` | +| classes | 3001 | NestJS (TS) | `pnpm dev` | `GET /healthz` | +| teacher-portal | 3000 | Next.js (TS) | `pnpm dev` | `GET /` | +| iam | 3002 | NestJS | P2 阶段 | — | +| teacher-bff | 3003 | NestJS | P2 阶段 | — | + +> 端口冲突排查:`netstat -ano \| findstr :8080`(Windows) + +--- + +## 3. 本地开发模式(DEV_MODE) + +### 3.1 首次准备 + +```bash +# 1. 克隆仓库 +git clone Edu +cd Edu + +# 2. 安装依赖 +pnpm install + +# 3. 配置环境变量 +cp .env.example .env +# 编辑 .env,确认: +# DEV_MODE=true ← 本地联调用 +# JWT_SECRET=p1-dev-secret-change-in-production +# DATABASE_URL=mysql://edu:changeme@localhost:3306/next_edu_cloud +# REDIS_URL=redis://localhost:6379 + +# 4. 架构扫描(更新 arch.db) +pnpm run arch:scan +``` + +### 3.2 启动基础设施 + +```bash +# 启动 MySQL + Redis(最小基础设施) +docker compose -f infra/docker-compose.minimal.yml up -d + +# 验证健康 +docker compose -f infra/docker-compose.minimal.yml ps +# 状态应为 healthy + +# (可选)国内镜像源加速:infra/docker-compose.minimal.override.yml 已配置 daocloud 镜像 +``` + +### 3.3 启动应用服务(三个终端) + +#### 终端 1:api-gateway(:8080) + +```bash +cd services/api-gateway + +# Windows:若 Go 不在 PATH,先设置 +$env:Path = "C:\Program Files\Go\bin;" + $env:Path + +# 设置开发模式环境变量 +$env:DEV_MODE="true" +$env:JWT_SECRET="p1-dev-secret-change-in-production" + +# 启动 +go run main.go +``` + +验证:`curl http://localhost:8080/healthz` → 200 OK + +#### 终端 2:classes 服务(:3001) + +```bash +# 在项目根目录 +pnpm --filter @edu/classes-service dev +``` + +验证:`curl http://localhost:3001/healthz` → 200 OK + +> 注:classes 的 HealthModule 需注册到 AppModule,当前若返回 404 见 [known-issues] + +#### 终端 3:teacher-portal(:3000) + +```bash +# 在项目根目录 +pnpm --filter @edu/teacher-portal dev +``` + +验证:浏览器访问 `http://localhost:3000` → 班级管理页面 + +### 3.4 一键启动(可选) + +```bash +# 并行启动所有子包的 dev 脚本(含 api-gateway 需 go run,不会自动启动) +pnpm dev +``` + +> 注:`pnpm dev` 仅启动 pnpm workspace 内的 TS 服务。api-gateway 是 Go 服务,需单独 `go run`。 + +### 3.5 联调验证 + +```bash +# 1. 直接访问 api-gateway(带 dev-token) +curl -H "Authorization: Bearer dev-token" http://localhost:8080/api/v1/classes +# 预期:200 OK + 班级列表 JSON + +# 2. 通过 teacher-portal 代理访问 +curl -H "Authorization: Bearer dev-token" http://localhost:3000/api/v1/classes +# 预期:200 OK(经 Next.js rewrites → api-gateway → classes) + +# 3. 浏览器访问 +# http://localhost:3000 → 班级管理页面,自动加载班级列表 +``` + +### 3.6 dev-token 说明 + +- `DEV_MODE=true` 时,api-gateway 接受 `Authorization: Bearer dev-token` +- 注入固定身份:`x-user-id: dev-user`,`x-user-roles: teacher,admin` +- **仅限本地联调,生产环境必须 `DEV_MODE=false`** + +--- + +## 4. 生产模式(Docker Compose) + +### 4.1 构建镜像 + +```bash +# 构建三个应用服务镜像 +docker compose -f infra/docker-compose.prod.yml build +``` + +### 4.2 启动完整栈 + +```bash +# 1. 先启动基础设施(MySQL + Redis) +docker compose -f infra/docker-compose.minimal.yml up -d + +# 2. 启动应用服务 +docker compose -f infra/docker-compose.prod.yml up -d + +# 3. 查看状态 +docker compose -f infra/docker-compose.prod.yml ps +# 所有服务应为 healthy + +# 4. 查看日志 +docker compose -f infra/docker-compose.prod.yml logs -f api-gateway +``` + +### 4.3 生产环境配置要点 + +| 配置项 | 生产值 | 说明 | +| -------------- | ---------------- | ----------------------------------------------- | +| `DEV_MODE` | `false` | docker-compose.prod.yml 强制设为 false | +| `JWT_SECRET` | 强随机值 | 替换 `p1-dev-secret-change-in-production` | +| `DATABASE_URL` | 生产数据库连接 | 容器内用 `host.docker.internal` 或 compose 网络 | +| `NODE_ENV` | `production` | teacher-portal 启用生产优化 | +| `LOG_LEVEL` | `info` 或 `warn` | 生产日志级别 | + +### 4.4 生产验证 + +```bash +# 健康检查 +curl http://localhost:8080/healthz # api-gateway +curl http://localhost:3001/healthz # classes +curl http://localhost:3000/ # teacher-portal + +# 鉴权验证(生产模式 dev-token 应被拒绝) +curl -H "Authorization: Bearer dev-token" http://localhost:8080/api/v1/classes +# 预期:401 INVALID_TOKEN + +# 真实 JWT 访问(需 IAM 签发) +curl -H "Authorization: Bearer " http://localhost:8080/api/v1/classes +# 预期:200 OK +``` + +### 4.5 停止与清理 + +```bash +# 停止应用服务 +docker compose -f infra/docker-compose.prod.yml down + +# 停止基础设施 +docker compose -f infra/docker-compose.minimal.yml down + +# 清理数据卷(谨慎!会删除数据库数据) +docker compose -f infra/docker-compose.minimal.yml down -v +``` + +--- + +## 5. 单独构建与运行(裸机生产) + +### 5.1 api-gateway + +```bash +cd services/api-gateway + +# 编译 +go build -o bin/api-gateway ./main.go + +# 运行(生产环境变量) +DEV_MODE=false JWT_SECRET= ./bin/api-gateway +``` + +### 5.2 classes 服务 + +```bash +# 构建 +pnpm --filter @edu/classes-service build + +# 运行(从 dist/ 启动) +NODE_ENV=production PORT=3001 \ + DATABASE_URL=mysql://edu:changeme@localhost:3306/next_edu_cloud \ + REDIS_URL=redis://localhost:6379 \ + node services/classes/dist/main.js +``` + +### 5.3 teacher-portal + +```bash +# 构建 +pnpm --filter @edu/teacher-portal build + +# 运行 +NODE_ENV=production PORT=3000 \ + API_GATEWAY_URL=http://localhost:8080 \ + node apps/teacher-portal/node_modules/.bin/next start -p 3000 +``` + +--- + +## 6. 常见问题 + +### 6.1 ERR_TOO_MANY_REDIRECTS + +**症状**:浏览器访问 `:3000/api/v1/classes` 无限重定向。 + +**根因**:Gin 默认 `RedirectTrailingSlash=true`,`/classes` → 301 → `/classes/`,Next.js rewrites 代理形成循环。 + +**修复**:`main.go` 已设 `r.RedirectTrailingSlash = false`,并同时注册无尾斜杠与通配符路由。 + +### 6.2 Docker Hub 拉取超时 + +**症状**:`docker compose up` 时 MySQL/Redis 镜像拉取超时。 + +**修复**:`infra/docker-compose.minimal.override.yml` 已配置 daocloud 镜像源,docker compose 会自动加载。 + +### 6.3 classes DI 注入失败 + +**症状**:`TypeError: Cannot read properties of undefined (reading 'create')`。 + +**根因**:NestJS ESM 模式下 `emitDecoratorMetadata` 不工作。 + +**修复**:`ClassesService` 构造函数已加 `@Inject(ClassesRepository)` 显式指定 token。 + +### 6.4 ESM import 缺 .js 后缀 + +**症状**:`error TS2307: Cannot find module './health.controller'`。 + +**修复**:ESM 模式下相对 import 必须带 `.js` 后缀(详见 project_rules §3.4)。 + +### 6.5 JWT 401 INVALID_TOKEN + +**症状**:带 `dev-token` 仍返回 401。 + +**排查**: + +1. 确认 `DEV_MODE=true` 环境变量已设置(api-gateway 进程) +2. 确认请求头格式:`Authorization: Bearer dev-token`(注意 Bearer 后空格) +3. 生产模式(`DEV_MODE=false`)下 dev-token 被拒绝是预期行为 + +### 6.6 Go 工具链不在 PATH + +**症状**:Git Bash 或 PowerShell 中 `go: command not found`。 + +**修复**: + +```powershell +$env:Path = "C:\Program Files\Go\bin;" + $env:Path +``` + +--- + +## 7. 数据库初始化 + +classes 服务使用 Drizzle ORM,首次运行需建表: + +```bash +# 生成迁移 +pnpm --filter @edu/classes-service drizzle-kit generate + +# 执行迁移 +pnpm --filter @edu/classes-service drizzle-kit migrate +``` + +> 若 `drizzle-kit` 未配置,可手动执行 `services/classes/src/db/schema.sql`(如存在)。 + +--- + +## 8. 相关文档 + +- [项目规则](../../.trae/rules/project_rules.md) — 强制约束 +- [004 架构影响地图](../architecture/004_architecture_impact_map.md) — 服务清单与调用关系 +- [known-issues](../troubleshooting/known-issues.md) — 已知问题速查 +- [Git 工作流](./git-workflow.md) — 提交与 PR 规范 +- [多 AI 协作指南](./multi-ai-collaboration.md) — 多 Agent 并行开发流程 diff --git a/docs/standards/multi-ai-collaboration.md b/docs/standards/multi-ai-collaboration.md new file mode 100644 index 0000000..88980cf --- /dev/null +++ b/docs/standards/multi-ai-collaboration.md @@ -0,0 +1,735 @@ +# 多 AI 协作开发指南(Multi-AI Collaboration Guide) + +> 版本:1.0 +> 日期:2026-07-08 +> 适用范围:Edu 微服务项目多 Agent 并行开发 +> 关联文档:[Git 工作流](./git-workflow.md)、[项目规则](../../.trae/rules/project_rules.md)、[004 架构影响地图](../architecture/004_architecture_impact_map.md)、[CODEOWNERS](../../.github/CODEOWNERS) + +--- + +## 1. 总体模式 + +### 1.1 角色定义 + +| 角色 | 职责 | 数量 | 备注 | +| ----------------------------- | -------------------------------------------- | ---- | ------------------- | +| **协调 AI(Coordinator AI)** | PR 审核、合并、冲突仲裁、分支管理、发布 | 1 | 不直接写业务代码 | +| **开发 AI(Dev AI)** | 按模块分工,写代码、提 PR | N | 每个负责 1-2 个模块 | +| **人类决策者(Human)** | 架构决策、Breaking Change 审批、最终发布确认 | 1 | 只在关键节点介入 | + +### 1.2 工作流总览 + +``` +开发 AI-A (classes模块) 开发 AI-B (iam模块) 协调 AI + │ │ │ + │ 1.拉取最新 main │ 1.拉取最新 main │ + │ 2.创建特性分支 │ 2.创建特性分支 │ + │ 3.开发+提交 │ 3.开发+提交 │ + │ 4.推送+创建 PR │ 4.推送+创建 PR │ + │──────────────────────────────────────────────────────→│ + │ │ │ 5.CI校验 + │ │ │ 6.代码审核 + │ │ │ 7.合并到 main + │ │ │ 8.通知开发 AI 同步 + │←─────────────────────────────────────────────────────│ + │ 9.拉取最新 main │ │ +``` + +--- + +## 2. 模块分工矩阵 + +### 2.1 模块清单与 AI 分配 + +每个 AI 负责一个"限界上下文",避免跨模块修改导致冲突。 + +| 模块 | scope | 路径 | 负责阶段 | 建议 AI 数 | +| -------------- | ---------------- | ------------------------- | -------- | ------------ | +| api-gateway | `api-gateway` | `services/api-gateway/` | P1 | 1 | +| classes | `classes` | `services/classes/` | P1 | 1 | +| teacher-portal | `teacher-portal` | `apps/teacher-portal/` | P1-P2 | 1 | +| iam | `iam` | `services/iam/` | P2 | 1 | +| teacher-bff | `teacher-bff` | `services/teacher-bff/` | P2 | 1 | +| core-edu | `core-edu` | `services/core-edu/` | P3 | 1 | +| content | `content` | `services/content/` | P4 | 1 | +| data-ana | `data-ana` | `services/data-ana/` | P4 | 1 | +| msg | `msg` | `services/msg/` | P5 | 1 | +| ai | `ai` | `services/ai/` | P5 | 1 | +| push-gateway | `push-gateway` | `services/push-gateway/` | P5 | 1 | +| shared-proto | `shared-proto` | `packages/shared-proto/` | 跨阶段 | 协调 AI 维护 | +| shared-tokens | `shared-tokens` | `packages/shared-tokens/` | 跨阶段 | 协调 AI 维护 | +| infra | `infra` | `infra/` | 跨阶段 | 1 (SRE AI) | +| docs | `docs` | `docs/` | 跨阶段 | 协调 AI 维护 | + +### 2.2 分工原则 + +1. **单一负责制**:每个模块只有一个 AI 负责,避免并行修改同一文件 +2. **契约集中管理**:`shared-proto` 由协调 AI 维护,开发 AI 只读引用 +3. **跨模块变更拆分**:需要修改多个模块时,拆成多个 PR,按依赖顺序合并 +4. **基础设施独立**:`infra/` 由 SRE AI 专门负责,业务 AI 不直接修改 + +--- + +## 3. 分支策略 + +### 3.1 分支命名规范 + +``` +/-- +``` + +| 字段 | 说明 | 示例 | +| --------- | ------------------------------------------- | ---------------- | +| `type` | feat / fix / refactor / docs / chore / test | `feat` | +| `scope` | 模块名(见 §2.1) | `classes` | +| `task-id` | 任务简短描述(kebab-case) | `add-pagination` | +| `ai-id` | AI 标识符(避免多 AI 同名冲突) | `ai01` | + +**完整示例**: + +- `feat/classes-add-pagination-ai01` +- `fix/api-gateway-redirect-loop-ai02` +- `docs/git-workflow-update-coord` + +### 3.2 分支生命周期 + +1. **创建**:从最新 `main` 拉取:`git checkout main && git pull && git checkout -b feat/classes-xxx-ai01` +2. **开发**:在特性分支上提交(遵循 Conventional Commits) +3. **推送**:`git push -u origin feat/classes-xxx-ai01` +4. **合并后删除**:PR 合并后,删除本地与远程特性分支 + +> 特性分支寿命 ≤ 3 天(见 git-workflow.md §1)。超期需 rebase 最新 main。 + +### 3.3 多 AI 分支隔离规则 + +- **禁止多 AI 共用同一分支** +- **禁止直接 push 到 `main`**(由协调 AI 通过 PR 合并) +- **跨模块变更**:各自在模块分支开发,最后由协调 AI 按依赖顺序合并 + +--- + +## 4. 推送与提交流程 + +### 4.1 提交规范(Conventional Commits) + +```bash +git commit -m "feat(classes): 新增班级分页查询" +git commit -m "fix(api-gateway): 修复尾斜杠重定向循环" +git commit -m "docs(standards): 更新多AI协作文档" +``` + +**scope 必须匹配 `.commitlintrc.js` 的 scope-enum**(26 项,见 git-workflow.md §3.3)。 + +### 4.2 标准推送流程 + +开发 AI 执行: + +```bash +# 1. 确认在正确的特性分支 +git branch --show-current +# 输出:feat/classes-add-pagination-ai01 + +# 2. 拉取最新 main(rebase 保持线性) +git fetch origin +git rebase origin/main + +# 3. 解决冲突(如有) +# 编辑冲突文件 → git add → git rebase --continue + +# 4. 本地校验(强制,见 project_rules §7) +pnpm run lint # TS 服务 +pnpm run typecheck # TS 服务 +cd services/api-gateway && go vet ./... && go build ./... # Go 服务 + +# 5. 推送 +git push -u origin feat/classes-add-pagination-ai01 + +# 6. 创建 PR(见 §5) +``` + +### 4.3 多 AI 推送冲突处理 + +当多个 AI 的 PR 修改了同一文件(如 `package.json`、`004_architecture_impact_map.md`): + +1. **先合并的 PR 正常合并** +2. **后合并的 PR 需 rebase**: + ```bash + git fetch origin + git rebase origin/main + # 解决冲突 + git push --force-with-lease # 安全强推(仅自己的分支) + ``` +3. **协调 AI 仲裁**:若冲突涉及架构决策,由协调 AI 决定保留方案 + +> **禁止 `git push --force` 到 main 或他人分支**。只允许 `--force-with-lease` 到自己的特性分支。 + +--- + +## 5. PR 流程 + +### 5.1 创建 PR + +推送后,开发 AI 通过 Git 平台(GitHub/Gitea)创建 PR: + +```bash +# 使用 gh CLI(GitHub) +gh pr create \ + --title "feat(classes): 新增班级分页查询" \ + --body "## 变更说明 +- 新增 GET /api/v1/classes?page=&size= 分页参数 +- 响应增加 total/hasMore 字段 + +## 变更类型 +- [x] feat(新功能) + +## 影响范围 +- [x] classes 服务 + +## 测试 +- [x] 单元测试通过 +- [x] 本地联调验证 + +## 校验 +- [x] pnpm run lint +- [x] pnpm run typecheck +" \ + --base main \ + --head feat/classes-add-pagination-ai01 +``` + +### 5.2 PR 标题规范 + +PR 标题必须与首个 commit 的 subject 一致(Squash Merge 时自动取首个 commit): + +``` +(): +``` + +**示例**: + +- `feat(classes): 新增班级分页查询` +- `fix(api-gateway): 修复尾斜杠重定向循环` + +### 5.3 PR 模板 + +使用 `.github/pull_request_template.md`(已存在)。必填项: + +- 变更说明 +- 变更类型 +- 影响范围 +- 测试情况 +- 按语言校验结果 +- 文档同步(arch:scan、CODEOWNERS) + +### 5.4 PR 标注 AI 身份 + +在 PR 描述末尾追加(用于统计与审计): + +```markdown +--- + +**AI Agent**: ai01 (classes-module) +**Branch**: feat/classes-add-pagination-ai01 +**Coordinator**: coord-ai +``` + +--- + +## 6. 代码审核与合并 + +### 6.1 Reviewer 分配 + +由 `.github/CODEOWNERS` 自动分配: + +| 模块 | 自动 Reviewer | 实际映射 | +| ------------ | ----------------------- | -------- | +| classes | `@edu-platform/classes` | 协调 AI | +| api-gateway | `@edu-platform/gateway` | 协调 AI | +| shared-proto | `@edu-platform/arch` | 协调 AI | +| infra | `@edu-platform/sre` | SRE AI | + +> 当前 `@edu-platform/*` 为占位符。多 AI 场景下,协调 AI 账号加入对应 team 即可自动收到 review 请求。 + +### 6.2 审核 checklist + +协调 AI 审核 PR 时检查: + +- [ ] **Commit 格式**:符合 Conventional Commits +- [ ] **Scope 正确**:scope 与修改的模块一致 +- [ ] **架构合规**:无跨层依赖、无直接访问他人 DB +- [ ] **权限校验**:Controller 有 `@RequirePermission()` +- [ ] **设计令牌**:无硬编码颜色/字体(project_rules §3.10) +- [ ] **ESM 规则**:相对 import 带 `.js` 后缀(TS 服务) +- [ ] **契约同步**:proto 变更已同步 shared-proto +- [ ] **文档同步**:arch.db 已更新、004 已同步(如涉及) +- [ ] **CI 通过**:lint / typecheck / go vet / ruff 全绿 +- [ ] **测试覆盖**:关键逻辑有单测 + +### 6.3 合并策略 + +| 策略 | 适用场景 | 操作 | +| ------------------------ | ------------------------------------ | ---------------------- | +| **Squash Merge**(默认) | 单 commit 或多个小 commit 合并为一个 | `gh pr merge --squash` | +| **Rebase Merge** | 多个有意义的 commit 需保留历史 | `gh pr merge --rebase` | +| **Merge Commit**(禁止) | — | 不允许 | + +> 项目规则 git-workflow.md §1.4:**禁止 Merge Commit**,保持 main 历史线性。 + +### 6.4 合并流程(协调 AI 执行) + +```bash +# 1. 确认 CI 通过 +gh pr checks + +# 2. 确认 review 通过(CODEOWNERS 已 approve) +gh pr view --json reviews + +# 3. Squash 合并(删除源分支) +gh pr merge --squash --delete-branch + +# 4. 通知开发 AI 同步本地 main +# (通过 commit message 或 issue 评论) +``` + +### 6.5 合并后同步 + +开发 AI 收到合并通知后: + +```bash +# 切回 main +git checkout main + +# 拉取最新(含已合并的 PR) +git pull origin main + +# 删除本地特性分支 +git branch -d feat/classes-add-pagination-ai01 + +# 开始下一个任务:从最新 main 拉新分支 +git checkout -b feat/classes-next-task-ai01 +``` + +--- + +## 7. 多 AI 并行开发流程 + +### 7.1 启动并行任务 + +人类决策者分配任务给多个 AI: + +``` +任务 1:classes 服务新增分页查询 → 开发 AI-A (ai01) +任务 2:api-gateway 新增限流规则 → 开发 AI-B (ai02) +任务 3:teacher-portal 优化班级列表 → 开发 AI-C (ai03) +``` + +### 7.2 并行执行 + +每个 AI 独立工作,互不干扰: + +```bash +# AI-A +git checkout -b feat/classes-add-pagination-ai01 +# ... 开发 ... +git push -u origin feat/classes-add-pagination-ai01 +gh pr create --title "feat(classes): 新增班级分页查询" ... + +# AI-B(同时) +git checkout -b feat/api-gateway-rate-limit-ai02 +# ... 开发 ... +git push -u origin feat/api-gateway-rate-limit-ai02 +gh pr create --title "feat(api-gateway): 新增 IP 级限流规则" ... + +# AI-C(同时) +git checkout -b feat/teacher-portal-class-list-ux-ai03 +# ... 开发 ... +``` + +### 7.3 顺序合并(有依赖时) + +若 PR 间有依赖(如 AI-C 依赖 AI-A 的接口),协调 AI 按顺序合并: + +1. 合并 AI-A 的 PR(classes 分页接口) +2. AI-C rebase 最新 main,解决冲突,更新 PR +3. 合并 AI-C 的 PR(前端调用新接口) + +### 7.4 冲突预防 + +1. **契约先行**:proto 变更先合并,再合并依赖它的服务 +2. **通知机制**:修改 `shared-proto/` 或 `004_architecture_impact_map.md` 时,在 PR 描述 @ 所有关联模块 AI +3. **频繁同步**:每天至少 `git pull origin main` 一次,避免长期分叉 + +--- + +## 8. 跨模块变更流程 + +### 8.1 变更拆分原则 + +修改涉及多模块时,按依赖顺序拆成多个 PR: + +``` +原始任务:classes 服务新增"班级导入"功能 +涉及: + 1. shared-proto 新增 ImportClassesRequest message + 2. classes 服务实现 import 接口 + 3. api-gateway 路由 /api/v1/classes/import + 4. teacher-portal 前端上传按钮 +``` + +### 8.2 拆分与合并顺序 + +| 顺序 | PR | scope | 负责人 | 依赖 | +| ---- | ----------------------------------------------- | -------------- | --------- | ---- | +| 1 | `feat(shared-proto): 新增 ImportClassesRequest` | shared-proto | 协调 AI | 无 | +| 2 | `feat(classes): 实现班级批量导入` | classes | 开发 AI-A | PR-1 | +| 3 | `feat(api-gateway): 新增 import 路由` | api-gateway | 开发 AI-B | PR-2 | +| 4 | `feat(teacher-portal): 新增班级导入按钮` | teacher-portal | 开发 AI-C | PR-3 | + +协调 AI 按顺序合并,每合并一个,后续 PR 的开发 AI rebase 最新 main。 + +### 8.3 Breaking Change 流程 + +涉及 Breaking Change(proto 字段删除、API 签名变更): + +1. **人类决策者审批**:在 issue 中讨论,获批准后才开发 +2. **版本号升级**:proto 加 `v2` 后缀,服务同时支持 v1/v2 过渡期 +3. **迁移文档**:更新 `MIGRATION_GUIDE.md` +4. **协调 AI 通知所有相关 AI**:在 PR 描述中列出影响范围 + +--- + +## 9. 完整工作流示例 + +### 9.1 场景:开发 AI-A 为 classes 新增分页查询 + +```bash +# ============ 开发 AI-A ============ + +# 1. 同步 main +git checkout main +git pull origin main + +# 2. 创建特性分支 +git checkout -b feat/classes-add-pagination-ai01 + +# 3. 开发 +# 编辑 services/classes/src/classes/classes.controller.ts +# 编辑 services/classes/src/classes/classes.service.ts +# 编辑 services/classes/src/classes/classes.repository.ts + +# 4. 本地校验 +pnpm --filter @edu/classes-service lint +pnpm --filter @edu/classes-service typecheck +pnpm --filter @edu/classes-service test + +# 5. 架构扫描(若新增了导出函数/路由) +pnpm run arch:scan + +# 6. 提交 +git add services/classes/ +git commit -m "feat(classes): 新增班级分页查询 + +- GET /api/v1/classes 支持 page、size 参数 +- 响应增加 total、hasMore 字段 +- 单测覆盖分页逻辑" + +# 7. 推送 +git push -u origin feat/classes-add-pagination-ai01 + +# 8. 创建 PR +gh pr create \ + --title "feat(classes): 新增班级分页查询" \ + --body "..." \ + --base main + +# ============ 协调 AI ============ + +# 9. 收到 PR 通知,审核 +gh pr view +gh pr checks + +# 10. 代码审核(见 §6.2 checklist) +# 若需修改,评论要求开发 AI-A 修改 + +# 11. 合并 +gh pr merge --squash --delete-branch + +# 12. 通知开发 AI-A +# 评论:"已合并,请同步本地 main" + +# ============ 开发 AI-A ============ + +# 13. 同步 +git checkout main +git pull origin main +git branch -d feat/classes-add-pagination-ai01 +``` + +--- + +## 10. 常见问题与解决方案 + +### 10.1 多 AI 修改同一文件冲突 + +**场景**:AI-A 和 AI-B 都修改了 `package.json` 添加依赖。 + +**解决**: + +1. AI-A 的 PR 先合并 +2. AI-B 执行: + ```bash + git fetch origin + git rebase origin/main + # 解决 package.json 冲突(保留两边依赖) + git add package.json + git rebase --continue + git push --force-with-lease + ``` +3. 协调 AI 重新审核 + +### 10.2 CI 失败但本地通过 + +**场景**:开发 AI 本地 lint 通过,CI 报错。 + +**排查**: + +1. 检查 Node/Go/pnpm 版本是否一致(见 local-dev-runbook §1) +2. 检查 `pnpm-lock.yaml` 是否最新(`pnpm install --frozen-lockfile`) +3. 检查环境变量是否齐全(`.env` vs CI secrets) + +**修复后**: + +```bash +git add +git commit -m "fix(classes): 修复 CI lint 失败" +git push +``` + +### 10.3 husky pre-commit hook 失败 + +**场景**:commit 时 hook 报错(lint-staged、commitlint)。 + +**排查**: + +1. commitlint:检查 commit message 格式(type 小写、scope 在 enum 内、subject 不大写开头) +2. lint-staged:检查暂存文件是否通过 ESLint/gofmt +3. husky 9 Windows bug:若 pre-push hook "Bad file descriptor",见 known-issues + +**修复**:修正后重新 `git commit`,不要用 `--no-verify` 跳过。 + +### 10.4 proto 变更导致下游编译失败 + +**场景**:shared-proto 合并后,classes 服务 `buf generate` 报错。 + +**解决**: + +1. 协调 AI 合并 proto PR 前,先在 PR 评论中通知所有依赖服务的 AI +2. 下游 AI 在自己的分支 rebase 最新 main 后重新 `buf generate` +3. 更新生成代码并提交: + ```bash + git add packages/shared-proto/gen/ + git commit -m "chore(shared-proto): 重新生成 TS 类型" + ``` + +### 10.5 分支长期未合并(超 3 天) + +**场景**:特性分支超过 3 天未合并。 + +**处理**: + +1. rebase 最新 main:`git rebase origin/main` +2. 解决冲突后 `git push --force-with-lease` +3. 若仍无法合并,协调 AI 介入评估是否拆分 PR + +### 10.6 误推到 main + +**场景**:开发 AI 误将 commit 推到 main。 + +**修复**(协调 AI 执行): + +```bash +# 1. 确认误推的 commit +git log origin/main -5 + +# 2. 回退(保留误推 commit 到临时分支) +git checkout origin/main -b temp/backup-mispush +git checkout main +git reset --hard origin/main~1 # 回退 1 个 commit + +# 3. 强推(仅协调 AI 有权限) +git push --force-with-lease origin main + +# 4. 通知开发 AI 从 temp 分支重新提 PR +``` + +> **禁止开发 AI 自行 force push main**。只有协调 AI 有权操作。 + +### 10.7 AI 身份冲突(同名分支) + +**场景**:两个 AI 都叫 "ai01",创建了同名分支。 + +**预防**:每个 AI 启动前分配唯一 `ai-id`(如 `ai01`、`ai02`、`coord`)。 + +**修复**:后启动的 AI 重命名分支: + +```bash +git branch -m feat/classes-xxx-ai01 feat/classes-xxx-ai01b +git push -u origin feat/classes-xxx-ai01b +``` + +--- + +## 11. AI 协作通信约定 + +### 11.1 通信渠道 + +| 场景 | 方式 | +| -------- | ----------------------------- | +| PR 审核 | PR 评论(`@ai01 请修改 xxx`) | +| 任务分配 | Issue(`@ai01 负责实现 xxx`) | +| 紧急通知 | PR 评论 + @ 相关人员 | +| 架构讨论 | Issue 标签 `discussion` | + +### 11.2 PR 评论规范 + +协调 AI 审核评论格式: + +``` +## 审核结果:需修改 / 通过 / 拒绝 + +### 需修改项 +1. [classes.controller.ts:42] 缺少 @RequirePermission() 装饰器 +2. [classes.service.ts:88] 返回值未标注 Promise + +### 建议 +- 考虑抽取分页逻辑到 shared-ts + +--- +协调 AI(coord) +``` + +### 11.3 AI 工作日志 + +每个 AI 完成任务后,在 `docs/troubleshooting/known-issues.md` "工作经验日志"区追加(project_rules §9.3): + +```markdown +| 日期 | 模块 | 做了什么 + 学到什么 | +| ---------------- | ------- | ----------------------------------------------- | +| 2026-07-08 14:00 | classes | 实现分页查询,学到 Drizzle 的 limit/offset 用法 | +``` + +--- + +## 12. 安全与权限 + +### 12.1 分支保护规则(main) + +- **禁止直接 push**:必须通过 PR +- **必须 PR review**:至少 1 人(CODEOWNERS 自动分配) +- **必须 CI 通过**:lint / typecheck / build +- **禁止 force push**:开发 AI 无权,仅协调 AI 在事故时操作 + +### 12.2 AI 账号权限 + +| 角色 | push 特性分支 | 创建 PR | 合并 PR | push main | force push main | +| ------- | ------------- | ------- | ----------- | --------- | --------------- | +| 开发 AI | ✅ | ✅ | ❌ | ❌ | ❌ | +| 协调 AI | ✅ | ✅ | ✅ | ❌ | ⚠️(仅事故) | +| SRE AI | ✅(infra) | ✅ | ✅(infra) | ❌ | ⚠️(仅事故) | + +### 12.3 敏感文件保护 + +以下文件修改需人类决策者额外审批: + +- `.env`、`.env.example`(密钥相关) +- `infra/security/secrets.example.env` +- `infra/k8s/`(生产部署) +- `.github/workflows/`(CI 配置) + +--- + +## 13. 发布流程 + +### 13.1 版本号规则(见 git-workflow.md §7) + +- 平台版本:`v{阶段}.{迭代}.{patch}`(如 `v1.2.0`) +- 服务版本:`{service}:{semver}`(如 `classes:1.0.1`) + +### 13.2 发布步骤(协调 AI 执行) + +```bash +# 1. 确认 main 稳定(CI 全绿) +gh run list --branch main --limit 5 + +# 2. 打 tag +git tag -a v1.2.0 -m "P1 阶段第 2 次迭代发布" +git push origin v1.2.0 + +# 3. 触发 CI 构建镜像 +# (CI 由 tag push 触发,见 .github/workflows/) + +# 4. 人类决策者确认部署到生产 +``` + +### 13.3 回滚(见 git-workflow.md §8) + +```bash +# K8s 回滚 +kubectl rollout undo deployment/api-gateway -n edu-system + +# Git 回退(紧急) +git revert +git push origin main +``` + +--- + +## 14. 快速参考卡 + +### 开发 AI 日常工作流 + +```bash +# 拉新分支 +git checkout main && git pull && git checkout -b feat/-- + +# 开发 → 校验 → 提交 +pnpm run lint && pnpm run typecheck +git add . && git commit -m "feat(): " + +# 推送 → 创建 PR +git push -u origin feat/-- +gh pr create --title "feat(): " --body "..." + +# 等待审核 → 修改 → 重新推送 +# (协调 AI 合并后) +git checkout main && git pull && git branch -d feat/-- +``` + +### 协调 AI 日常工作流 + +```bash +# 查看待审核 PR +gh pr list --state open --reviewer @edu-platform/arch + +# 审核 +gh pr view +gh pr checks + +# 合并 +gh pr merge --squash --delete-branch + +# 发布 +git tag -a v -m "..." && git push origin v +``` + +--- + +## 15. 相关文档 + +- [Git 工作流](./git-workflow.md) — 提交规范、分支策略、CODEOWNERS +- [本地启动手册](./local-dev-runbook.md) — 手动启动服务 +- [项目规则](../../.trae/rules/project_rules.md) — 强制约束 +- [004 架构影响地图](../architecture/004_architecture_impact_map.md) — 模块与依赖关系 +- [CODEOWNERS](../../.github/CODEOWNERS) — Reviewer 自动分配 +- [PR 模板](../../.github/pull_request_template.md) — PR 必填项 +- [known-issues](../troubleshooting/known-issues.md) — 已知问题速查