From b39095cbdddfe7e140e60849c87c8b384e7b6705 Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:53:18 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20git-workflow=20v1.1=20=E4=B8=8E=20CODEO?= =?UTF-8?q?WNERS=20=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - git-workflow.md v1.1: scope-enum 对齐实际服务名(identity→iam 等) - git-workflow.md: 新增 §4.7 模块 Owner 与 CODEOWNERS 章节 - git-workflow.md: husky hooks 与实际文件对齐,新增 pre-push 说明 - .github/CODEOWNERS: 定义各模块 owner team 与 PR 合并职责 - .github/pull_request_template.md: PR 模板 --- .github/CODEOWNERS | 80 ++++++ .github/pull_request_template.md | 55 ++++ docs/standards/git-workflow.md | 460 ++++++++++++++++++------------- 3 files changed, 398 insertions(+), 197 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/pull_request_template.md diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..7c647cf --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,80 @@ +# Edu 平台 CODEOWNERS +# 格式:路径 @owner +# 作用:GitHub/Gitea 自动为 PR 分配 reviewer +# 维护规则: +# 1. 新增服务/包时,必须同步更新本文件 +# 2. owner 变更需开独立 PR,由架构组审批 +# 3. 与 docs/standards/git-workflow.md §4.7 保持同步 +# Team handle 占位符:@edu-platform/* 需在 Organization 中创建对应 team 后替换 + +# ===== 架构与规则(架构组,2 人 review)===== +/.trae/ @edu-platform/arch +/docs/architecture/ @edu-platform/arch +/docs/standards/ @edu-platform/arch +/scripts/arch-scan/ @edu-platform/arch + +# ===== 根配置(架构组,2 人 review,影响全局)===== +/.commitlintrc.js @edu-platform/arch +/lint-staged.config.js @edu-platform/arch +/package.json @edu-platform/arch +/pnpm-workspace.yaml @edu-platform/arch +/go.work @edu-platform/arch +/pyproject.toml @edu-platform/arch +/tsconfig.base.json @edu-platform/arch + +# ===== 共享包(架构组,2 人 review,契约变更影响所有服务)===== +/packages/shared-proto/ @edu-platform/arch +/packages/shared-ts/ @edu-platform/arch +/packages/shared-go/ @edu-platform/arch +/packages/shared-py/ @edu-platform/arch +/packages/shared-tokens/ @edu-platform/arch + +# ===== 网关层(Go)===== +/services/api-gateway/ @edu-platform/gateway +/services/push-gateway/ @edu-platform/gateway + +# ===== 业务微服务 ===== +# IAM(核心模块,2 人 review) +/services/iam/ @edu-platform/iam +# 教学核心 +/services/core-edu/ @edu-platform/edu-core +/services/classes/ @edu-platform/edu-core +# 内容资源 +/services/content/ @edu-platform/content +# 消息通知 +/services/msg/ @edu-platform/messaging +# 数据分析(Python) +/services/data-ana/ @edu-platform/data +# AI 网关(Python) +/services/ai/ @edu-platform/ai + +# ===== BFF 聚合层(NestJS)===== +/services/teacher-bff/ @edu-platform/edu-core +/services/student-bff/ @edu-platform/edu-core +/services/parent-bff/ @edu-platform/edu-core + +# ===== 微前端(Next.js)===== +/apps/teacher-portal/ @edu-platform/frontend +/apps/student-portal/ @edu-platform/frontend +/apps/parent-portal/ @edu-platform/frontend +/apps/admin-portal/ @edu-platform/frontend + +# ===== 基础设施(SRE,2 人 review,生产环境变更强制)===== +/infra/k8s/ @edu-platform/sre +/infra/backup/ @edu-platform/sre +/infra/security/ @edu-platform/sre +/infra/monitoring/ @edu-platform/sre +/infra/docker-compose*.yml @edu-platform/sre + +# ===== CI/CD(SRE)===== +/.github/ @edu-platform/sre +/.husky/ @edu-platform/sre + +# ===== 文档(架构组)===== +/docs/troubleshooting/ @edu-platform/arch +/MIGRATION_GUIDE.md @edu-platform/arch +/README.md @edu-platform/arch +/CHANGELOG.md @edu-platform/arch + +# ===== 兜底(未匹配的文件由架构组 review)===== +* @edu-platform/arch diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..cb25346 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,55 @@ +## 变更说明 + + + +## 变更类型 + +- [ ] feat: 新功能 +- [ ] fix: Bug 修复 +- [ ] perf: 性能优化 +- [ ] refactor: 重构 +- [ ] test: 测试 +- [ ] docs: 文档 +- [ ] build/ci: 构建/CI +- [ ] chore: 杂项 + +## 影响范围 + + + +- 服务: +- 包: +- 数据库迁移:是 / 否 +- protobuf 契约变更:是 / 否(如变更是否向后兼容) +- Kafka topic 变更:是 / 否 +- 架构文档变更:是 / 否 + +## 测试情况 + +- [ ] 单元测试通过 +- [ ] 集成测试通过 +- [ ] 本地手动测试通过 +- [ ] 新增测试覆盖新功能 + +### 按语言的校验结果 + +- TS 服务:`pnpm run lint` + `pnpm run typecheck`(如缺失脚本请说明) +- Go 服务:`go vet ./...` + `go build ./...` +- Python 服务:`ruff check src/` + +## 文档同步 + +- [ ] 已更新服务 README(如涉及服务结构变更) +- [ ] 已更新架构文档(如涉及架构变更) +- [ ] 已运行 `pnpm run arch:scan` 更新 arch.db(arch.db 不入库,但本地验证必须通过) +- [ ] 已更新 `docs/troubleshooting/known-issues.md`(如遇到新问题/经验) +- [ ] 已更新 `.github/CODEOWNERS`(如新增服务/包) + +## Breaking Change + +- [ ] 否 +- [ ] 是(请在下方说明影响和迁移路径) + +## 关联 Issue + +Closes # diff --git a/docs/standards/git-workflow.md b/docs/standards/git-workflow.md index f840a55..acd534b 100644 --- a/docs/standards/git-workflow.md +++ b/docs/standards/git-workflow.md @@ -1,11 +1,12 @@ # Edu Git 工作流规范 -> 版本:1.0 -> 日期:2026-07-07 -> 状态:基线发布 +> 版本:1.1 +> 日期:2026-07-08 +> 状态:基线发布(v1.1:scope-enum 对齐 + CODEOWNERS) > 适用范围:Edu 多语言 monorepo(pnpm workspace + go.work + pyproject.toml) > 关联文档: -> - [项目规则](../../project_rules.md) +> +> - [项目规则](../../.trae/rules/project_rules.md) > - [编码规范](./coding-standards.md) > - [迁移指南](../../MIGRATION_GUIDE.md) > - [架构总览](../architecture/001_architecture_overview.md) @@ -33,6 +34,7 @@ 本项目采用**主干开发**模式,所有变更最终合并至 `main` 分支。 **核心原则**: + - `main` 分支始终保持可发布状态 - 短生命周期特性分支(通常 ≤ 3 天) - 频繁集成,每天至少一次 rebase/merge 至最新 `main` @@ -66,18 +68,19 @@ gitGraph ### 1.3 分支命名规范 -| 分支类型 | 前缀 | 示例 | 生命周期 | -|---------|------|------|---------| -| 主干 | `main` | `main` | 永久 | -| 特性 | `feat/` | `feat/identity-service` | ≤ 3 天 | -| 修复 | `fix/` | `fix/jwt-expiry` | ≤ 1 天 | -| 重构 | `refactor/` | `refactor/split-data-access` | ≤ 5 天 | -| 性能 | `perf/` | `perf/query-optimization` | ≤ 3 天 | -| 文档 | `docs/` | `docs/api-specification` | ≤ 2 天 | -| 发布 | `release/v` | `release/v0.3.0` | 发布周期内 | -| 热修复 | `hotfix/` | `hotfix/v0.3.1` | ≤ 1 天 | +| 分支类型 | 前缀 | 示例 | 生命周期 | +| -------- | ----------- | ---------------------------- | ---------- | +| 主干 | `main` | `main` | 永久 | +| 特性 | `feat/` | `feat/identity-service` | ≤ 3 天 | +| 修复 | `fix/` | `fix/jwt-expiry` | ≤ 1 天 | +| 重构 | `refactor/` | `refactor/split-data-access` | ≤ 5 天 | +| 性能 | `perf/` | `perf/query-optimization` | ≤ 3 天 | +| 文档 | `docs/` | `docs/api-specification` | ≤ 2 天 | +| 发布 | `release/v` | `release/v0.3.0` | 发布周期内 | +| 热修复 | `hotfix/` | `hotfix/v0.3.1` | ≤ 1 天 | **规则**: + - 分支名使用 kebab-case - 一个分支只做一件事,禁止在一个分支内混合多个无关变更 - 特性分支命名包含服务/模块名(`feat/identity-service` 而非 `feat/login`) @@ -85,6 +88,7 @@ gitGraph ### 1.4 分支保护规则 **`main` 分支保护**: + - 禁止直接 push,必须通过 PR - 至少 1 名 Reviewer 审批通过(核心模块需 2 名) - 所有 CI 检查通过(lint + typecheck + test + build) @@ -92,6 +96,7 @@ gitGraph - 禁止 force push **`release/*` 分支保护**: + - 禁止直接 push,仅接受 cherry-pick 或特定 hotfix PR - 至少 2 名 Reviewer 审批 - 发布完成后打 tag 并归档 @@ -114,25 +119,26 @@ gitGraph ### 2.2 类型(type) -| 类型 | 含义 | 是否触发发布 | -|------|------|-------------| -| `feat` | 新功能 | 是(MINOR) | -| `fix` | Bug 修复 | 是(PATCH) | -| `perf` | 性能优化 | 是(PATCH) | -| `refactor` | 重构(不改变行为) | 否 | -| `style` | 代码风格(格式化、空白) | 否 | -| `test` | 新增/修改测试 | 否 | -| `docs` | 文档变更 | 否 | -| `build` | 构建系统或依赖变更 | 否 | -| `ci` | CI 配置变更 | 否 | -| `chore` | 杂项(不修改 src 或 test) | 否 | -| `revert` | 回滚某次提交 | 是 | +| 类型 | 含义 | 是否触发发布 | +| ---------- | -------------------------- | ------------ | +| `feat` | 新功能 | 是(MINOR) | +| `fix` | Bug 修复 | 是(PATCH) | +| `perf` | 性能优化 | 是(PATCH) | +| `refactor` | 重构(不改变行为) | 否 | +| `style` | 代码风格(格式化、空白) | 否 | +| `test` | 新增/修改测试 | 否 | +| `docs` | 文档变更 | 否 | +| `build` | 构建系统或依赖变更 | 否 | +| `ci` | CI 配置变更 | 否 | +| `chore` | 杂项(不修改 src 或 test) | 否 | +| `revert` | 回滚某次提交 | 是 | ### 2.3 范围(scope) scope 必须是服务名或包名,详见 [§3.3 scope-enum](#33-scope-enum-完整清单)。 **示例**: + - `feat(identity): 实现用户注册接口` - `fix(gateway): 修复路由匹配优先级` - `perf(teaching): 优化课表查询 N+1 问题` @@ -141,6 +147,7 @@ scope 必须是服务名或包名,详见 [§3.3 scope-enum](#33-scope-enum-完 ### 2.4 主题(subject) **规则**: + - 使用中文简短描述 - 不超过 50 个字符 - 不以句号结尾 @@ -150,12 +157,14 @@ scope 必须是服务名或包名,详见 [§3.3 scope-enum](#33-scope-enum-完 ### 2.5 正文(body) **规则**: + - 解释"为什么"而非"做了什么"(代码已说明做了什么) - 每行不超过 72 个字符 - 使用无序列表列出关键变更点 - 涉及 breaking change 必须在正文开头说明 **示例**: + ``` feat(teaching): 作业提交支持附件上传 @@ -195,7 +204,7 @@ pnpm exec husky init ### 3.2 commitlint 配置 -创建 `commitlint.config.cjs`: +实际生效配置文件:仓库根 `.commitlintrc.js`(CommonJS)。 ```javascript /** @type {import('@commitlint/types').UserConfig} */ @@ -224,46 +233,42 @@ module.exports = { "type-case": [2, "always", "lower-case"], // type 不能为空 "type-empty": [2, "never"], - // scope 枚举(见 3.3) + // scope 枚举(见 3.3,与 .commitlintrc.js 保持同步) "scope-enum": [ 2, "always", [ - // 业务微服务 - "identity", - "org", - "teaching", + // 网关层(Go) + "api-gateway", + "push-gateway", + // 业务微服务(NestJS / FastAPI) + "iam", + "core-edu", + "classes", "content", - "comm", - "insight", - // 基础设施服务 - "auth", - "notification", - // AI 服务 - "insight-ai", - // 网关 - "gateway", - // BFF - "admin-bff", + "data-ana", + "msg", + "ai", + // BFF 聚合层(NestJS) "teacher-bff", "student-bff", - // 微前端 - "admin-shell", - "teacher-shell", - "student-shell", - "parent-shell", - // 共享包 - "contracts", - "ui-tokens", - "ui-components", + "parent-bff", + // 微前端(Next.js) + "teacher-portal", + "student-portal", + "parent-portal", + "admin-portal", + // 共享包(packages/) + "shared-proto", "shared-ts", - // protobuf 契约 - "proto", - // 平台级 - "deps", + "shared-go", + "shared-py", + "shared-tokens", + // 工具与平台级 + "arch-scan", + "infra", "docs", - "ci", - "chore", + "deps", "release", ], ], @@ -285,100 +290,89 @@ module.exports = { }; ``` +> **单一事实源**:实际生效的配置在仓库根 `.commitlintrc.js`,本节示例仅作说明。修改 scope 必须同步更新 `.commitlintrc.js` 与本节,并在 PR 中说明原因。 + ### 3.3 scope-enum 完整清单 -| 分类 | scope | 说明 | -|------|-------|------| -| 业务微服务 | `identity` | 身份与权限服务 | -| 业务微服务 | `org` | 教学组织服务 | -| 业务微服务 | `teaching` | 教学核心服务 | -| 业务微服务 | `content` | 内容分析服务 | -| 业务微服务 | `comm` | 沟通服务 | -| 业务微服务 | `insight` | 智能洞察服务 | -| 基础设施 | `auth` | 认证授权服务 | -| 基础设施 | `notification` | 通知服务 | -| AI 服务 | `insight-ai` | AI 分析服务(Python) | -| 网关 | `gateway` | API 网关(Go) | -| BFF | `admin-bff` | 管理端 BFF | -| BFF | `teacher-bff` | 教师端 BFF | -| BFF | `student-bff` | 学生/家长端 BFF | -| 微前端 | `admin-shell` | 管理端 Shell | -| 微前端 | `teacher-shell` | 教师端 Shell | -| 微前端 | `student-shell` | 学生端 Shell | -| 微前端 | `parent-shell` | 家长端 Shell | -| 共享包 | `contracts` | protobuf 生成契约包 | -| 共享包 | `ui-tokens` | 设计令牌包 | -| 共享包 | `ui-components` | UI 组件库 | -| 共享包 | `shared-ts` | TS 共享工具包 | -| 契约 | `proto` | protobuf 定义文件 | -| 平台级 | `deps` | 依赖升级 | -| 平台级 | `docs` | 平台级文档 | -| 平台级 | `ci` | CI/CD 配置 | -| 平台级 | `chore` | 杂项 | -| 平台级 | `release` | 发布相关 | +> 与仓库根 `.commitlintrc.js` 保持同步;修改 scope 必须同时更新此处与 `.commitlintrc.js`。 + +| 分类 | scope | 对应目录 | 说明 | +| ---------- | ---------------- | ------------------------- | ------------------------------------------------------ | +| 网关层 | `api-gateway` | `services/api-gateway/` | API 网关(Go + Gin) | +| 网关层 | `push-gateway` | `services/push-gateway/` | WebSocket 推送网关(Go) | +| 业务微服务 | `iam` | `services/iam/` | 身份与访问管理(NestJS) | +| 业务微服务 | `core-edu` | `services/core-edu/` | 教学核心服务(NestJS,Outbox + Kafka) | +| 业务微服务 | `classes` | `services/classes/` | 班级服务(P1 黄金模板,P3 并入 core-edu) | +| 业务微服务 | `content` | `services/content/` | 内容资源服务(NestJS + Neo4j) | +| 业务微服务 | `data-ana` | `services/data-ana/` | 数据分析服务(Python + FastAPI + ClickHouse) | +| 业务微服务 | `msg` | `services/msg/` | 消息通知服务(NestJS + ES) | +| 业务微服务 | `ai` | `services/ai/` | AI 网关服务(Python + FastAPI + LLM) | +| BFF 聚合层 | `teacher-bff` | `services/teacher-bff/` | 教师端 BFF(NestJS) | +| BFF 聚合层 | `student-bff` | `services/student-bff/` | 学生端 BFF(待建立) | +| BFF 聚合层 | `parent-bff` | `services/parent-bff/` | 家长端 BFF(待建立) | +| 微前端 | `teacher-portal` | `apps/teacher-portal/` | 教师端 Portal(Next.js) | +| 微前端 | `student-portal` | `apps/student-portal/` | 学生端 Portal(待建立) | +| 微前端 | `parent-portal` | `apps/parent-portal/` | 家长端 Portal(待建立) | +| 微前端 | `admin-portal` | `apps/admin-portal/` | 管理端 Portal(待建立) | +| 共享包 | `shared-proto` | `packages/shared-proto/` | protobuf 契约定义 | +| 共享包 | `shared-ts` | `packages/shared-ts/` | TS 共享类型与工具(待建立) | +| 共享包 | `shared-go` | `packages/shared-go/` | Go 共享工具(待建立) | +| 共享包 | `shared-py` | `packages/shared-py/` | Python 共享工具(待建立) | +| 共享包 | `shared-tokens` | `packages/shared-tokens/` | 设计令牌(待建立) | +| 工具 | `arch-scan` | `scripts/arch-scan/` | 架构元数据库扫描器 | +| 平台级 | `infra` | `infra/` | 基础设施(K8s / docker-compose / backup / monitoring) | +| 平台级 | `docs` | `docs/` | 平台级文档(跨多模块) | +| 平台级 | `deps` | - | 依赖升级 | +| 平台级 | `release` | - | 发布相关 | + +> `chore` / `ci` / `build` 等 Conventional Commits 标准 type 不需要 scope,可直接使用 `chore: xxx`、`ci: xxx`。 ### 3.4 husky hooks +实际生效的 hook 文件在仓库根 `.husky/` 目录。使用 `npx --no-install` 确保使用本地依赖。 + `.husky/commit-msg`: ```bash -#!/usr/bin/env sh -pnpm exec commitlint --edit "$1" +npx --no-install commitlint --edit $1 ``` `.husky/pre-commit`: ```bash -#!/usr/bin/env sh -pnpm exec lint-staged +npx --no-install lint-staged ``` -`.husky/pre-push`: +`.husky/pre-push`(推送前类型检查,TS 服务 typecheck 通过后才允许推送): ```bash #!/usr/bin/env sh -# 推送前运行类型检查 -pnpm -r run typecheck +# 推送前运行类型检查(TS 服务) +pnpm -r run typecheck 2>/dev/null || echo "[pre-push] typecheck 跳过或不可用" +# Go 服务编译检查 +for d in services/api-gateway services/push-gateway; do + if [ -d "$d" ]; then (cd "$d" && go build ./... ) || exit 1; fi +done ``` +> **注意**:`pre-push` 中的 typecheck 在 TS 服务 ESLint 9 flat config 迁移完成前为可选(当前 `pnpm -r run typecheck` 缺失脚本,会 fallback 到 echo 提示)。Go `go build` 检查必须通过。 + ### 3.5 lint-staged 配置 -`package.json`(根目录): +实际生效配置文件:仓库根 `lint-staged.config.js`(CommonJS)。 -```json -{ - "lint-staged": { - // TypeScript / NestJS / Next.js - "*.{ts,tsx}": [ - "eslint --fix", - "prettier --write" - ], - // Go - "*.go": [ - "gofmt -w", - "golangci-lint run --fix" - ], - // Python - "*.py": [ - "ruff check --fix", - "ruff format" - ], - // protobuf - "*.proto": [ - "buf format --write" - ], - // Markdown - "*.md": [ - "prettier --write" - ], - // JSON / YAML - "*.{json,yaml,yml}": [ - "prettier --write" - ] - } -} +```javascript +module.exports = { + "*.{ts,tsx}": ["eslint --fix", "prettier --write"], + "*.{go,mod,sum}": ["gofmt -w", "golangci-lint run --fix"], + "*.{py}": ["ruff check --fix", "ruff format"], + "*.proto": ["buf format --write"], + "*.md": ["prettier --write"], +}; ``` +> JSON / YAML 文件由 prettier 在 `*.md` 规则外按全局配置处理,如需显式规则可在 `lint-staged.config.js` 追加 `'*.{json,yaml,yml}': ['prettier --write']`。 + --- ## 四、PR 与 Code Review @@ -435,6 +429,7 @@ feat(identity): 实现用户注册接口 ## 影响范围 + - 服务: - 包: - 数据库迁移:是 / 否 @@ -467,18 +462,19 @@ Closes # ### 4.4 Reviewer 要求 -| 变更类型 | 最少 Reviewer | 备注 | -|---------|--------------|------| -| 普通业务变更 | 1 | 默认 | -| 跨服务变更 | 2 | 涉及 ≥ 2 个服务 | -| protobuf 契约变更 | 2 | 需包含架构组成员 | -| 数据库 schema 变更 | 2 | 需包含 DBA 或架构组 | -| 安全相关变更 | 2 | 需包含安全负责人 | -| 核心模块(auth/identity) | 2 | 核心模块强制 2 人 | +| 变更类型 | 最少 Reviewer | 备注 | +| ------------------------- | ------------- | ------------------- | +| 普通业务变更 | 1 | 默认 | +| 跨服务变更 | 2 | 涉及 ≥ 2 个服务 | +| protobuf 契约变更 | 2 | 需包含架构组成员 | +| 数据库 schema 变更 | 2 | 需包含 DBA 或架构组 | +| 安全相关变更 | 2 | 需包含安全负责人 | +| 核心模块(auth/identity) | 2 | 核心模块强制 2 人 | ### 4.5 Code Review 清单 **通用检查**: + - [ ] 代码是否符合 [编码规范](./coding-standards.md) - [ ] 是否有明显的逻辑错误 - [ ] 错误处理是否完整(不忽略 error/err/exception) @@ -486,18 +482,21 @@ Closes # - [ ] 是否存在硬编码的密钥、token、连接字符串 **架构检查**: + - [ ] 是否违反限界上下文边界(跨服务直接查 DB) - [ ] 是否违反依赖方向(shared 反向依赖 services) - [ ] protobuf 变更是否向后兼容 - [ ] 事件 schema 变更是否向后兼容 **性能检查**: + - [ ] 是否有 N+1 查询 - [ ] 是否有未加索引的查询 - [ ] 是否有不必要的大对象拷贝 - [ ] 是否有阻塞事件循环的同步操作(Python/Node) **安全检查**: + - [ ] 所有入口是否经过权限校验 - [ ] 用户输入是否经过验证 - [ ] SQL 是否使用参数化查询 @@ -506,37 +505,80 @@ Closes # ### 4.6 合并策略 **默认使用 Squash Merge**: + - 保留 PR 的完整变更作为一个 commit - commit message 使用 PR 标题 - 删除特性分支 **禁止使用 Merge Commit**(除非是发布分支合并回 main): + - 避免历史中充斥 "Merge branch" 噪音 - 保持线性历史 **Rebase Merge**: + - 仅用于需要保留多个有意义 commit 的特性分支 - 需在 PR 中说明原因 +### 4.7 模块 Owner 与 CODEOWNERS + +**实际生效文件**:仓库根 `.github/CODEOWNERS`(GitHub/Gitea 原生支持,自动为 PR 分配 reviewer)。 + +**设计原则**: + +- 每个模块至少 1 名 owner,核心模块 2 名 +- 跨模块变更(如 proto 契约、arch.db、project_rules)由架构组 review +- 基础设施变更(K8s/Helm/backup)由 SRE review +- owner 名单变更需走 PR,由架构组审批 + +**模块 Owner 分配矩阵**: + +| 模块分类 | 路径 | Owner Team | 最少 Reviewer | 备注 | +| ---------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------- | --------------------- | +| 架构与规则 | `.trae/rules/`、`docs/architecture/`、`docs/standards/` | `@edu-platform/arch` | 2 | 架构组强制 review | +| 架构工具 | `scripts/arch-scan/` | `@edu-platform/arch` | 1 | | +| 根配置 | `.commitlintrc.js`、`lint-staged.config.js`、`package.json`、`pnpm-workspace.yaml`、`go.work`、`pyproject.toml`、`tsconfig.base.json` | `@edu-platform/arch` | 2 | 影响全局 | +| 共享包 | `packages/shared-proto/` | `@edu-platform/arch` | 2 | 契约变更影响所有服务 | +| 网关层 | `services/api-gateway/`、`services/push-gateway/` | `@edu-platform/gateway` | 1 | | +| IAM 服务 | `services/iam/` | `@edu-platform/iam` | 2 | 核心模块强制 2 人 | +| 教学核心 | `services/core-edu/`、`services/classes/` | `@edu-platform/edu-core` | 1 | | +| 内容资源 | `services/content/` | `@edu-platform/content` | 1 | | +| 消息通知 | `services/msg/` | `@edu-platform/messaging` | 1 | | +| 数据分析 | `services/data-ana/` | `@edu-platform/data` | 1 | | +| AI 服务 | `services/ai/` | `@edu-platform/ai` | 1 | | +| BFF 层 | `services/teacher-bff/`、`services/student-bff/`、`services/parent-bff/` | `@edu-platform/edu-core` | 1 | | +| 微前端 | `apps/teacher-portal/`、`apps/student-portal/`、`apps/parent-portal/`、`apps/admin-portal/` | `@edu-platform/frontend` | 1 | | +| 基础设施 | `infra/k8s/`、`infra/backup/`、`infra/security/`、`infra/monitoring/` | `@edu-platform/sre` | 2 | 生产环境变更强制 2 人 | +| CI/CD | `.github/`、`.husky/` | `@edu-platform/sre` | 1 | | +| 文档 | `docs/troubleshooting/`、`docs/standards/` | `@edu-platform/arch` | 1 | known-issues 更新 | + +> **Team handle 占位符**:上表 `@edu-platform/*` 为 team handle 模板。实际团队 handle 需在 GitHub/Gitea Organization 中创建对应 team 后,同步更新 `.github/CODEOWNERS`。 + +**CODEOWNERS 文件维护规则**: + +1. 新增服务/包时,必须在同一 PR 中更新 `.github/CODEOWNERS` +2. owner 变更(人员调动)需开独立 PR,由架构组审批 +3. CODEOWNERS 与本节表格保持同步,单一事实源为 `.github/CODEOWNERS` 文件 + --- ## 五、文档同步规则 ### 5.1 文档同步矩阵 -| 代码变更类型 | 需同步的文档 | 同步时机 | -|-------------|-------------|---------| -| 新增/删除服务 | `001_architecture_overview.md` + 服务 README | PR 内同步 | -| 新增/删除模块 | 服务 README + `arch:scan` | PR 内同步 | -| 新增/删除导出函数 | `pnpm run arch:scan` | 提交前 | -| 修改函数签名 | `pnpm run arch:scan` | 提交前 | -| 修改权限点 | `project_rules.md` + 权限文档 | PR 内同步 | -| 新增/删除数据库表 | 架构文档 + 服务 README | PR 内同步 | -| 新增/删除路由 | 服务 README + OpenAPI | PR 内同步 | -| 修改模块间依赖 | `arch:scan` + 架构文档 | PR 内同步 | -| 新增 protobuf message | `proto/` README + `arch:scan` | PR 内同步 | -| 新增 Kafka topic | 架构文档 + 服务 README | PR 内同步 | -| 遇到新问题/经验 | `known-issues.md` | PR 内同步 | +| 代码变更类型 | 需同步的文档 | 同步时机 | +| --------------------- | -------------------------------------------- | --------- | +| 新增/删除服务 | `001_architecture_overview.md` + 服务 README | PR 内同步 | +| 新增/删除模块 | 服务 README + `arch:scan` | PR 内同步 | +| 新增/删除导出函数 | `pnpm run arch:scan` | 提交前 | +| 修改函数签名 | `pnpm run arch:scan` | 提交前 | +| 修改权限点 | `project_rules.md` + 权限文档 | PR 内同步 | +| 新增/删除数据库表 | 架构文档 + 服务 README | PR 内同步 | +| 新增/删除路由 | 服务 README + OpenAPI | PR 内同步 | +| 修改模块间依赖 | `arch:scan` + 架构文档 | PR 内同步 | +| 新增 protobuf message | `proto/` README + `arch:scan` | PR 内同步 | +| 新增 Kafka topic | 架构文档 + 服务 README | PR 内同步 | +| 遇到新问题/经验 | `known-issues.md` | PR 内同步 | ### 5.2 arch.db 同步规则 @@ -551,6 +593,7 @@ git commit -m "feat(identity): 实现用户注册接口" ``` **违规检查**: + - 长文件(> 1000 行) - 未校验权限的 Handler - 循环依赖 @@ -568,26 +611,33 @@ git commit -m "feat(identity): 实现用户注册接口" > 技术栈:[语言 + 框架] ## 职责 + [一段话描述] ## 架构 + [mermaid 架构图] ## 核心流程 + [mermaid 时序图] ## 目录结构 + [树形结构 + 说明] ## 依赖 + - 上游服务:[列表] - 下游服务:[列表] - 共享包:[列表] ## 约束 + [业务规则、技术约束] ## 架构决策 + [关键设计决策记录] ``` @@ -598,12 +648,13 @@ git commit -m "feat(identity): 实现用户注册接口" ```markdown ### X.X 主题分区 -| 场景 | 技术/规则 | -|------|----------| +| 场景 | 技术/规则 | +| -------- | ------------------ | | 简述场景 | 正确做法(一句话) | ``` **规则**: + - 索引式:场景→技术/规则映射 - 不写代码示例和错误示范 - 同类问题在原条目补充,不重复创建 @@ -618,6 +669,7 @@ git commit -m "feat(identity): 实现用户注册接口" **规则**:一个 commit 只涉及一个服务或一个包的变更。 **原因**: + - 便于回滚(按服务粒度回滚) - 便于追踪(changelog 清晰) - 便于 review(聚焦单一职责) @@ -653,12 +705,14 @@ git commit -m "build(contracts): 重新生成 proto 代码" ### 6.4 依赖升级规则 **规则**: + - 依赖升级使用 `build(deps):` 类型 - 必须说明升级原因(安全、功能、兼容性) - 安全漏洞修复必须包含 CVE 编号 - 大版本升级需单独 PR 并完整测试 **示例**: + ``` build(deps): 升级 nestjs 至 10.3.0 @@ -691,33 +745,33 @@ git commit -m "feat(notification): 适配 UserRegistered v2 事件" 本项目采用**双层版本号**: -| 层级 | 格式 | 说明 | -|------|------|------| +| 层级 | 格式 | 说明 | +| -------- | ------------------------ | ----------------------------------------- | | 平台版本 | `v{阶段}.{迭代}.{patch}` | 如 `v0.3.1`(P3 阶段第 1 次迭代 patch 1) | -| 服务版本 | `{service}:{semver}` | 如 `identity:1.2.0` | +| 服务版本 | `{service}:{semver}` | 如 `identity:1.2.0` | ### 7.2 阶段版本范围 -| 阶段 | 平台版本范围 | 说明 | -|------|-------------|------| -| P1 地基 | `v0.1.x` | monorepo 初始化、CI/CD、arch.db | -| P2 身份 | `v0.2.x` | identity + auth + notification | -| P3 核心教学 | `v0.3.x` | org + teaching + content | -| P4 内容分析 | `v0.4.x` | insight + CQRS 读模型 | -| P5 沟通AI | `v0.5.x` | comm + AI 增强 | -| P6 硬化 | `v1.0.x` | 正式发布版 | +| 阶段 | 平台版本范围 | 说明 | +| ----------- | ------------ | ------------------------------- | +| P1 地基 | `v0.1.x` | monorepo 初始化、CI/CD、arch.db | +| P2 身份 | `v0.2.x` | identity + auth + notification | +| P3 核心教学 | `v0.3.x` | org + teaching + content | +| P4 内容分析 | `v0.4.x` | insight + CQRS 读模型 | +| P5 沟通AI | `v0.5.x` | comm + AI 增强 | +| P6 硬化 | `v1.0.x` | 正式发布版 | ### 7.3 Docker 镜像标签 **格式**:`{registry}/edu/{service}:{tag}` -| tag 类型 | 格式 | 示例 | 用途 | -|---------|------|------|------| -| 版本号 | `v{version}` | `v0.3.1` | 正式发布 | -| 服务版本 | `{service}-{semver}` | `identity-1.2.0` | 服务独立版本 | -| Git SHA | `sha-{short}` | `sha-a1b2c3d` | 精确追溯 | -| 最新 | `latest` | `latest` | 开发环境 | -| 阶段 | `{stage}-{sha}` | `staging-a1b2c3d` | 阶段环境 | +| tag 类型 | 格式 | 示例 | 用途 | +| -------- | -------------------- | ----------------- | ------------ | +| 版本号 | `v{version}` | `v0.3.1` | 正式发布 | +| 服务版本 | `{service}-{semver}` | `identity-1.2.0` | 服务独立版本 | +| Git SHA | `sha-{short}` | `sha-a1b2c3d` | 精确追溯 | +| 最新 | `latest` | `latest` | 开发环境 | +| 阶段 | `{stage}-{sha}` | `staging-a1b2c3d` | 阶段环境 | ### 7.4 发布流程 @@ -752,19 +806,23 @@ flowchart TD ## [v0.3.0] - 2026-08-15 ### Added + - 教学核心服务新增作业管理功能 - 内容服务支持题库导入 - 教师端 Shell 新增作业批改界面 ### Changed + - identity 服务升级至 NestJS 10.3 - gateway 路由匹配算法优化 ### Fixed + - 修复 JWT 刷新 token 过期判断错误 - 修复课表查询时区问题 ### Breaking Changes + - UserRegistered 事件 schema 变更至 v2,消费方需升级 ``` @@ -778,6 +836,7 @@ flowchart TD ``` **版本号升级规则**: + - **MAJOR**:Breaking Change(protobuf 不兼容变更、API 破坏性修改) - **MINOR**:新增功能,向后兼容 - **PATCH**:Bug 修复,向后兼容 @@ -788,13 +847,13 @@ flowchart TD ### 8.1 回滚策略 -| 场景 | 回滚方式 | 耗时 | -|------|---------|------| -| 代码缺陷 | `git revert` + 重新部署 | 5-10 分钟 | -| 镜像问题 | `kubectl rollout undo` | 1-2 分钟 | -| 数据库迁移问题 | 执行迁移 down 脚本 | 5-30 分钟 | -| 配置错误 | 回滚 ConfigMap/Secret | 1-2 分钟 | -| 全站故障 | 回滚至上一稳定 tag | 10-30 分钟 | +| 场景 | 回滚方式 | 耗时 | +| -------------- | ----------------------- | ---------- | +| 代码缺陷 | `git revert` + 重新部署 | 5-10 分钟 | +| 镜像问题 | `kubectl rollout undo` | 1-2 分钟 | +| 数据库迁移问题 | 执行迁移 down 脚本 | 5-30 分钟 | +| 配置错误 | 回滚 ConfigMap/Secret | 1-2 分钟 | +| 全站故障 | 回滚至上一稳定 tag | 10-30 分钟 | ### 8.2 代码回滚 @@ -833,6 +892,7 @@ kubectl rollout status deployment/identity -n edu-prod ### 8.4 数据库迁移回滚 **规则**: + - 所有迁移必须提供 `up` 和 `down` 脚本 - `down` 脚本必须在 CI 中测试 - 回滚前必须备份生产数据 @@ -865,6 +925,7 @@ pnpm --filter identity run migrate:down -- --to > 严重等级:P0/P1/P2/P3 ## 时间线 + - HH:MM 告警触发 - HH:MM 确认问题 - HH:MM 决定回滚 @@ -872,15 +933,19 @@ pnpm --filter identity run migrate:down -- --to - HH:MM 服务恢复 ## 影响分析 + [受影响的功能、用户数、业务损失] ## 根本原因 + [技术原因 + 流程原因] ## 回滚过程 + [执行的操作] ## 改进措施 + - [ ] 短期:[立即修复项] - [ ] 中期:[流程改进项] - [ ] 长期:[架构改进项] @@ -890,29 +955,30 @@ pnpm --filter identity run migrate:down -- --to ## 九、附录:CICD 与 Edu Git 工作流差异 -| 维度 | CICD(Next.js 单应用) | Edu(微服务 monorepo) | -|------|----------------------|----------------------| -| 仓库结构 | 单一 Next.js 应用 | 多语言 monorepo(pnpm + go.work + uv) | -| 分支策略 | trunk-based | trunk-based(沿用) | -| 提交规范 | Conventional Commits | Conventional Commits(沿用,scope 扩展至服务/包) | -| scope 范围 | 模块名(如 `exams`、`homework`) | 服务/包名(如 `identity`、`contracts`) | -| commitlint scope-enum | 35 个模块 | 27 个服务/包 | -| PR Reviewer | 1 人 | 1-2 人(核心模块/跨服务 2 人) | -| 合并策略 | Squash Merge | Squash Merge(沿用) | -| 版本号 | 单一应用版本 | 双层(平台版本 + 服务独立版本) | -| 发布粒度 | 整体发布 | 按服务独立发布 | -| Docker 镜像 | 单一镜像 | 每服务一镜像 | -| 回滚粒度 | 整体回滚 | 按服务回滚 | -| 数据库迁移 | Drizzle 单库 | 每服务独立库 + 独立迁移 | -| 文档同步 | `npm run arch:scan` | `pnpm run arch:scan`(多语言扫描) | -| CI 检查 | lint + tsc + test | lint + typecheck + test(按语言分别执行) | -| 紧急回滚 | `git revert` + 重新部署 | `git revert` + `kubectl rollout undo` | -| 事故复盘 | known-issues.md | `incidents/` 目录独立记录 | +| 维度 | CICD(Next.js 单应用) | Edu(微服务 monorepo) | +| --------------------- | -------------------------------- | ---------------------------------------------------------------- | +| 仓库结构 | 单一 Next.js 应用 | 多语言 monorepo(pnpm + go.work + uv) | +| 分支策略 | trunk-based | trunk-based(沿用) | +| 提交规范 | Conventional Commits | Conventional Commits(沿用,scope 扩展至服务/包) | +| scope 范围 | 模块名(如 `exams`、`homework`) | 服务/包名(如 `iam`、`api-gateway`、`shared-proto`) | +| commitlint scope-enum | 35 个模块 | 26 个 scope(含服务/包/工具/平台级,与 `.commitlintrc.js` 同步) | +| PR Reviewer | 1 人 | 1-2 人(核心模块/跨服务 2 人) | +| 合并策略 | Squash Merge | Squash Merge(沿用) | +| 版本号 | 单一应用版本 | 双层(平台版本 + 服务独立版本) | +| 发布粒度 | 整体发布 | 按服务独立发布 | +| Docker 镜像 | 单一镜像 | 每服务一镜像 | +| 回滚粒度 | 整体回滚 | 按服务回滚 | +| 数据库迁移 | Drizzle 单库 | 每服务独立库 + 独立迁移 | +| 文档同步 | `npm run arch:scan` | `pnpm run arch:scan`(多语言扫描) | +| CI 检查 | lint + tsc + test | lint + typecheck + test(按语言分别执行) | +| 紧急回滚 | `git revert` + 重新部署 | `git revert` + `kubectl rollout undo` | +| 事故复盘 | known-issues.md | `incidents/` 目录独立记录 | --- ## 变更记录 -| 版本 | 日期 | 变更内容 | -|------|------|---------| -| 1.0 | 2026-07-07 | 基线发布,从 CICD 单应用规范迁移至微服务多语言 monorepo | +| 版本 | 日期 | 变更内容 | +| ---- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1.0 | 2026-07-07 | 基线发布,从 CICD 单应用规范迁移至微服务多语言 monorepo | +| 1.1 | 2026-07-08 | scope-enum 对齐实际服务名(identity→iam、teaching→core-edu 等);新增 §4.7 模块 Owner 与 CODEOWNERS;husky hooks 与实际文件对齐;新增 pre-push hook 说明 |