Files
Edu/.trae/rules/project_rules.md
SpecialX 68ddff1065
Some checks failed
CI / quality-go (push) Failing after 3s
CI / quality-proto (push) Failing after 2s
CI / quality-ts (push) Failing after 47s
CI / deploy (push) Has been skipped
refactor(infra): 重构为 no-push 本地构建部署模式
- 删除 6 个分散 workflow(ci-ts/ci-go/ci-proto/ci-py/docker/deploy)
- 合并为单个 ci.yml:3 个 quality job 并行 + deploy job 串行
- 全部使用官方镜像(node:22-alpine/golang:1.22-alpine/bufbuild/buf/docker:25-git)
- deploy job 用 DooD 模式挂载 /var/run/docker.sock
- docker-compose.deploy.yml 改用 build: 替代 image:(no-push)
- 新增 docker-compose.tools.yml 一次性预拉所有 CI 镜像
- 支持 workflow_dispatch 指定 commit_sha 回滚
- 更新 project_rules §15 与 cicd-runbook.md 为 no-push 模式
- 新增设计文档 docs/superpowers/specs/2026-07-08-cicd-no-push-local-build-design.md
2026-07-08 17:12:57 +08:00

26 KiB
Raw Blame History

Edu 项目规则(微服务版)

版本1.0 日期2026-07-08 适用范围Edu 微服务架构DDD + EDA + CQRS多语言 monorepo 关联文档:


1. 架构图优先规则

任何任务开始前,必须先查阅架构影响地图,通过图定位代码和模块。

  1. 先图后码:执行任何分析、修改、搜索任务时,首先运行 pnpm run arch:scan 更新 arch.db再通过 pnpm run arch:query 查询目标模块、函数、依赖关系,结合阅读 docs/architecture/004_architecture_impact_map.md 定位架构设计意图,最后按图索骥读取源码
  2. 图未覆盖则先补图:如果发现项目中存在 arch.db 未记录的模块、函数、表、路由、proto 等结构,必须先运行 pnpm run arch:scan 重新扫描多语言扫描器TS + Go + Python + Proto然后检查 004 是否需要补充
  3. 改码必同步图:对源码的任何修改完成后,必须运行 pnpm run arch:scan 更新 arch.db若架构设计意图有变化同步更新 004

架构文档清单

文档 用途
docs/architecture/004_architecture_impact_map.md 架构设计意图唯一源(人类可读)
docs/architecture/0010_architecture.md 理想蓝图(目标态)
docs/architecture/roadmap/ 长远规划tech-debt / pending-features
docs/architecture/runbooks/ 运维手册P6 硬化、post-p6-followup、incident-response
docs/troubleshooting/known-issues.md 已知问题速查(场景→技术映射 + 工作经验日志)

需要同步图的场景

  • 新增/删除/重命名导出函数、组件、Hook、类型
  • 修改函数签名(参数、返回类型)
  • 修改权限点Permissions 常量)或角色-权限映射
  • 新增/删除数据库表
  • 新增/删除路由页面、API 路由、gRPC 服务、proto message
  • 修改模块间依赖关系或服务间调用关系
  • 新增服务、新增模块、新增 proto 定义
  • 修改 Kafka topic、Outbox 事件命名

同步方式

  • 修改源码后运行 pnpm run arch:scan 更新 arch.db强制
  • 若架构设计意图变化,同步更新 docs/architecture/004_architecture_impact_map.md
  • 若发现新的"场景→技术"映射或工作经验,更新 docs/troubleshooting/known-issues.md

2. 架构元数据库规则arch.db

arch.db 是代码结构唯一源AI 工作前必须运行 pnpm run arch:scan 更新。

  1. 多语言扫描arch.db 覆盖 TypeScriptts-morph、Gotree-sitter-go、Pythontree-sitter-python、Protobuf AST四类语言
  2. 查询命令
    • pnpm run arch:query -- sql "<SQL>" 自定义 SQL 查询
    • pnpm run arch:query -- module-deps 查模块依赖
    • pnpm run arch:query -- module-reverse-deps <module> 查反向依赖
    • pnpm run arch:query -- symbol-refs <symbol> 查符号引用链
    • pnpm run arch:query -- tech-usage <tag> 查技术使用
    • pnpm run arch:query -- violations 查架构违规
    • pnpm run arch:query -- stats 查总体统计
    • pnpm run arch:query -- modules 查模块列表
  3. arch.db 不替代 004arch.db 是"代码现状"004 是"设计意图",两者互补
  4. 预期规模:模块数 ≥ 10api-gateway、push-gateway、teacher-bff、iam、classes、core-edu、content、msg、data-ana、ai符号数 ≥ 100

3. 编码规范

详细规范见 docs/standards/coding-standards.md,以下为核心强制规则。

3.1 代码质量规则

  • 每次修改后运行 pnpm run lintpnpm run typecheck 确保零错误
  • TypeScript 服务必须用 @RequirePermission() 装饰器进行权限校验
  • 前端组件禁止使用 role === "xxx" 硬编码,统一使用 usePermission().hasPermission()
  • 单文件行数遵循企业级规范:
    • 配置文件、常量文件、类型定义文件、proto无限制
    • Controller / Service建议 ≤ 500 行
    • Repository / data-access建议 ≤ 800 行
    • 工具函数:建议 ≤ 40 行
    • 自定义 Hook建议 ≤ 80 行
    • 硬性上限:任何文件不超过 1000 行,超过必须拆分

3.2 架构分层规则(微服务)

  • 四层分层Gateway → BFF → Services → Data
  • 依赖方向单向Gateway → BFF → Services → Data禁止反向依赖
  • 服务间通信:通过 protobuf gRPC 或 Kafka 事件,禁止直接访问对方 DB
  • Gateway 职责JWT 校验、限流、熔断、CORS、请求 ID 注入
  • BFF 职责:聚合多个 Service 的数据,为前端提供场景化 API
  • Service 职责:业务逻辑,每服务独占 DBDDD 限界上下文)

3.3 模块标准结构DDD

services/[service]/src/
├─ [domain]/                  # 限界上下文
│  ├─ *.controller.ts         # ControllerHTTP/gRPC 入口)
│  ├─ *.service.ts            # Application Service编排层
│  ├─ *.repository.ts         # Repository数据访问
│  ├─ *.schema.ts             # Zod 验证
│  └─ *.dto.ts                # DTO
├─ config/                    # 配置database / env / kafka / neo4j / elasticsearch
├─ middleware/                # 中间件auth.middleware / permission.guard
├─ shared/                    # 共享
│  ├─ errors/                 # 错误application-error / global-error.filter
│  ├─ health/                 # 健康检查
│  ├─ lifecycle/              # 生命周期
│  ├─ observability/          # 可观测性logger / metrics / tracer
│  └─ outbox/                 # Outbox仅事件驱动服务
├─ app.module.ts              # 根模块
└─ main.ts                    # 入口

3.4 TypeScript 规则

  • 禁止 any:未知类型用 unknown 并做类型守卫
  • 禁止 as 断言(除非从 unknown 转换或测试中,需注释原因)
  • 函数返回值必须显式标注,特别是 Promise<T>
  • 仅用于类型的导入必须使用 import type
  • 可选链后禁止跟非空断言 !
  • ESM 模式NestJS ESM 模式下,相对 import 的 .js 后缀(构建产物)

3.5 Go 规则

  • 包名小写单词,不使用下划线或驼峰
  • 导出函数必须有 doc comment// FuncName ...
  • 错误处理:if err != nil { return err },禁止 _ = err
  • 不使用 interface{},用 anyGo 1.18+
  • 包内文件命名 lowercase不使用下划线_test.go
  • 中间件位于 internal/middleware/,路由位于 internal/routing/

3.6 Python 规则

  • 类型注解强制(所有函数签名、变量声明)
  • FastAPI 路由用 APIRouter
  • 异步优先:async defIO 密集场景禁止同步阻塞调用
  • 模块名 snake_case类名 PascalCase
  • 配置统一通过 pydantic-settings 管理(config.py

3.7 命名规范(多语言)

对象 规范 示例
目录 kebab-case api-gateway/core-edu/
TS 组件 PascalCase UserController.ts
TS Hook camelCase useAuth.ts
Go 文件 lowercase circuitbreaker.go
Python 文件 snake_case clickhouse_client.py
Proto 文件 snake_case core_edu.proto
变量/函数 camelCaseTS/ lowercaseGo/ snake_casePy getUserById / getUserById / get_user_by_id
常量 UPPER_SNAKE_CASE MAX_RETRY_COUNT
类/接口 PascalCase接口不加 I 前缀 UserService
布尔值 is/has/can/should 前缀 isActivehasPermission

3.8 Controller / Server Action 规范

  • 每个 Controller 方法必须用 @RequirePermission() 装饰器声明权限
  • 输入用 Zod / class-validator 验证,验证失败返回结构化错误
  • 返回 protobuf message 或 DTO结构同 ActionState
  • 错误统一走 GlobalErrorFilter
  • BFF Controller 聚合多个 Service 调用,禁止直接访问 DB

3.9 Tailwind 规范

  • 使用 cn() 工具函数管理条件类名
  • 禁止字符串拼接动态类名(bg-${color}-500
  • 禁止使用任意值(w-[137px]),除非有充分理由并注释
  • 设计令牌在 packages/shared-tokens/(待建立)或 apps/teacher-portal/src/app/styles/tokens/

3.10 设计令牌规范(强制)

  • 禁止硬编码颜色TSX/TS/CSS 中不得出现 #hex 颜色字面量,统一使用 hsl(var(--*)) 或 Tailwind 类 bg-*
  • 禁止硬编码字体:不得出现 'Inter'/'Fraunces'/'JetBrains Mono' 字面量,使用 var(--font-family-sans/serif/mono)
  • 禁止硬编码字号:不得出现 font-size: Npx,使用 var(--font-size-1~9)
  • 禁止 Tailwind 任意值:不得使用 w-[Npx]/h-[Npx]/p-[Npx] 等,映射到 --space-* 或 Tailwind 默认阶梯
  • 三层令牌
    • Layer 1 Primitive原始色板/字号/间距/阴影,业务代码不直接引用
    • Layer 2 Semantic语义令牌light/dark业务代码唯一引用入口
    • Layer 3 Tailwind Theme@theme inline 将 Semantic 令牌暴露为 bg-*/text-*/font-*
  • 改令牌必同步图:修改令牌定义后,同步更新 004 与 arch.db
  • ESLint 强制约束
    • no-restricted-syntax:禁止 #hex 字面量
    • design-tokens/no-hardcoded-fonts:禁止 'Inter'/'Fraunces' 字面量
    • 白名单:primitive.cssemail-channelmanifest.ts

4. 安全规范

  • JWT RS256IAM 签发Gateway 公钥校验(不共享密钥)
  • CookiehttpOnly + Secure + SameSite=Strict
  • 环境变量:服务端变量不加 NEXT_PUBLIC_ 前缀;前端变量必须加
  • 环境校验:用 @t3-oss/env-nextjs + Zod 或 pydantic-settings 校验
  • 禁止 dangerouslySetInnerHTML(如必须使用,先用 DOMPurify 清洗)
  • 密码哈希bcryptcost ≥ 12禁止 MD5/SHA1
  • 限流Gateway 层 IP 级令牌桶,登录接口额外加用户级限流
  • CORS:白名单域名,禁止 *
  • WAF:见 infra/security/waf-rules.conf

5. 契约规范

  • 契约先行:服务间通信先定 .proto,再写实现
  • 工具链protobuf + buf v2
  • buf lintSTANDARD 规则集
  • buf breakingFILE 级别检查CI 强制)
  • proto 文件位置packages/shared-proto/proto/
  • 包名规范edu.<domain>.v1(如 edu.iam.v1edu.core_edu.v1
  • 生成代码buf generateTS 走 buf.gen.yamlGo/Python 各自配置)
  • gRPC 服务端口:每服务独立端口,见 004 服务清单

6. 事件驱动规范

  • Outbox 模式:事务内写业务表 + outbox 表,独立 publisher 投递到 Kafka保证 at-least-once
  • 事件命名<Aggregate>.<Action>(如 ExamCreatedHomeworkSubmittedGradeReleased
  • TOPIC_MAP 路由:每个服务维护 事件 → topic 映射(见 shared/outbox/
  • 幂等性
    • Kafka produceridempotent=true + transactionalId
    • Consumer基于 event_id 去重Redis SETNX 或 DB 唯一索引)
  • CDCMySQL → Debezium → Kafka可选用于读模型同步
  • 事件版本schema 演化用 v1/v2 后缀,禁止破坏性变更

7. 提交规范

  • 使用 Conventional Commits 格式:feat(scope): description
  • 类型featfixchoredocsstylerefactortestperfci
  • scope(服务名或包名):
    • 服务:iamclassescore-educontentmsgaidata-anaapi-gatewaypush-gatewayteacher-bff
    • 包:shared-protoshared-tsshared-goshared-pyshared-tokens
    • 基础设施:infrak8shelmci
    • 文档:docs
  • 提交前必须运行pnpm run lint + pnpm run typecheckTSgo vet ./...Goruff check src/Python
  • commitlint + husky:强制校验(见 .commitlintrc.js.husky/commit-msg

8. Git 工作流

  • 分支策略trunk-based直接提交 main 分支,小项目)
  • 大型团队feature branch + PRPR 至少 1 人 review
  • pre-commit hooklint-staged 自动修复 + 校验(见 lint-staged.config.js
  • commit-msg hookcommitlint 校验格式
  • 禁止 force push:除非显式要求并通知团队

9. 问题记录规则

所有工作完成后,必须将遇到的问题记录到 docs/troubleshooting/known-issues.md(索引式速查手册)。

必须记录的场景

场景 记录要求
构建报错dev/build/lint/tsc/go vet/ruff 记录到"全局经验"对应主题分区
运行时异常(白屏/API 报错/数据加载失败/gRPC 错误) 记录到"模块经验"对应模块分区
框架/库版本兼容问题 记录到"全局经验: 框架与运行时"
依赖配置问题go mod / uv / pnpm workspace 记录到"全局经验: 依赖管理"
架构约束违规(跨服务访问 DB / 缺契约) 记录到"全局经验: 架构约束"
多语言 monorepo 问题(共享包链接失败等) 记录到"全局经验: 多语言 monorepo"

记录格式

索引式表格,指明"场景→技术/规则"映射,不写多行代码示例:

### X.X 主题分区

| 场景     | 技术/规则          |
| -------- | ------------------ |
| 简述场景 | 正确做法(一句话) |

记录要求

  • 索引式:场景→技术/规则映射,不写代码示例和错误示范列
  • 去重:同类问题在原条目补充,不重复创建
  • 引用架构规则:架构分层、模块结构等规则引用 004 和本规则文件,不重复
  • 工作经验日志:在"工作经验日志"区按时间倒序追加50 条上限),记录"做了什么/学到什么/下次注意"

10. AI 工作强制流程

所有 AI 工作必须遵循此流程,违反即违规。

阶段 1上下文加载

  1. pnpm run arch:scan 更新 arch.db
  2. pnpm run arch:query -- module-deps 查目标模块依赖
  3. pnpm run arch:query -- symbol-refs <目标函数> 查调用链
  4. 阅读 services/[service]/README.md 读模块工作流程
  5. docs/troubleshooting/known-issues.md "模块经验"分区读相关经验
  6. docs/architecture/004_architecture_impact_map.md 对应章节

阶段 2执行工作

  1. 按规划执行(契约先行:先 proto再实现
  2. 修改代码后立即运行 pnpm run arch:scan 更新 arch.db
  3. 运行质量校验确保零错误:
    • TSpnpm run lint + pnpm run typecheck
    • Gogo vet ./... + go build ./...
    • Pythonruff check src/

阶段 3经验沉淀强制不可跳过

  1. docs/troubleshooting/known-issues.md "工作经验日志"区追加一条记录:
    • 日期 + 时间
    • 模块
    • 做了什么 + 学到什么
  2. 若发现新的"场景→技术"映射 → 提炼到对应模块分区
  3. 若发现新的架构决策 → 更新 004
  4. 若代码结构变化 → pnpm run arch:scan 确认 arch.db 已更新

11. 多语言 monorepo 规则

  • 包管理器分工
    • TypeScriptpnpm workspacepnpm-workspace.yaml
    • Gogo.workgo.work
    • Pythonuv workspacepyproject.toml[tool.uv.workspace]
  • 共享包packages/
    • shared-protoprotobuf 契约定义(跨语言共享)
    • shared-tsTypeScript 共享类型与工具(待建立)
    • shared-goGo 共享工具(待建立)
    • shared-pyPython 共享工具(待建立)
    • shared-tokens:设计令牌(待建立)
  • 跨语言契约:通过 protobuf禁止 JSON Schema 或 OpenAPI 作为内部契约
  • 依赖版本对齐:共享依赖(如 uuid、jwt在多语言版本号保持一致

12. 可观测性规范

  • 三支柱必须同时启用(所有服务):
    • 日志pinoTS/ zapGo/ structlogPython—— 结构化 JSON
    • 指标prom-clientTS/ prometheusGo/ prometheus-clientPython—— /metrics 端点
    • 链路OpenTelemetry SDK + OTLP exporter —— 统一 traceparent
  • 健康检查/healthliveness+ /readyreadiness见各服务 shared/health/
  • 请求 IDGateway 注入 X-Request-Id全链路传递日志、metrics、trace
  • 指标命名<service>_<module>_<operation>_<unit>(如 iam_login_duration_seconds
  • 告警规则:见 infra/prometheus/rules.yml + infra/alertmanager/alertmanager.yml
  • Grafana 面板:见 infra/grafana/dashboards/

13. 部署与基础设施规范

  • 容器化:每服务独立 Dockerfileservices/[service]/Dockerfile
  • K8s:基础设施 manifest 位于 infra/k8s/,演化目标为 Helm chartinfra/k8s/helm/
  • 命名空间edu-systemedu-monitoringedu-chaosedu-backup
  • 配置分离
    • ConfigMap非敏感配置环境变量、特性开关
    • Secret敏感配置DB 密码、JWT 密钥、API key—— 见 infra/security/secrets.example.env
  • 备份:见 infra/backup/backup-mysql.sh,每服务独立备份,保留 7 天
  • 监控栈Prometheus + Grafana + Alertmanagerinfra/docker-compose.monitoring.yml
  • 混沌工程:见 infra/chaos/experiments.yaml

14. 多 AI 协作规范

详细流程见 多 AI 协作指南,本节为强制约束摘要。

14.1 角色与权限

角色 职责 push 特性分支 创建 PR 合并 PR push main force push main
协调 AICoordinator PR 审核、合并、冲突仲裁、发布 ⚠️(仅事故)
开发 AIDev 按模块分工写代码、提 PR
SRE AI infra/ 维护、部署 infra infra ⚠️(仅事故)
人类决策者 架构决策、Breaking Change 审批、发布确认

14.2 模块单一负责制

  • 每个模块(限界上下文)只有一个 AI 负责,禁止并行修改同一模块
  • shared-protoshared-tokensdocs/ 由协调 AI 维护,开发 AI 只读引用
  • infra/ 由 SRE AI 专门负责,业务 AI 不直接修改

14.3 分支命名规范(强制)

<type>/<scope>-<task-id>-<ai-id>
  • typefeat / fix / refactor / docs / chore / test
  • scope:见 §7 提交规范 scope-enum26 项)
  • task-id任务简短描述kebab-case
  • ai-idAI 唯一标识符(如 ai01ai02coord

示例feat/classes-add-pagination-ai01

14.4 PR 与合并规则(强制)

  1. 禁止直接 push 到 main:所有变更通过 PR
  2. PR 必须通过 CIlint / typecheck / build / test 全绿
  3. PR 必须通过 CODEOWNERS review:至少 1 人 approve
  4. 合并策略Squash Merge默认Rebase Merge保留多 commit 历史),禁止 Merge Commit
  5. 特性分支寿命 ≤ 3 天:超期需 rebase 最新 main
  6. 跨模块变更拆分:按依赖顺序拆多个 PRproto → service → gateway → frontend协调 AI 按序合并

14.5 跨模块变更顺序(强制)

修改涉及多模块时,必须按以下顺序拆分 PR 并顺序合并:

  1. shared-protoproto 契约)
  2. 业务服务classes / iam / core-edu 等)
  3. api-gateway(路由)
  4. BFFteacher-bff 等)
  5. 微前端teacher-portal 等)

每合并一个 PR后续 PR 的开发 AI 必须 rebase 最新 main 并重新校验。

14.6 冲突处理规则

  • 文件冲突:后合并的 PR rebase 最新 maingit push --force-with-lease(仅自己的分支)
  • 架构冲突:由协调 AI 仲裁保留方案
  • 禁止 git push --force 到 main 或他人分支

14.7 AI 身份标注(强制)

每个 PR 描述末尾必须追加:

---

**AI Agent**: <ai-id> (<负责模块>)
**Branch**: <分支名>
**Coordinator**: <协调 AI ai-id>

每个 AI 完成任务后,在 docs/troubleshooting/known-issues.md "工作经验日志"区追加记录(见 §9.3)。

14.8 敏感文件保护

以下文件修改需人类决策者额外审批:

  • .env.env.exampleinfra/security/secrets.example.env
  • infra/k8s/(生产部署)
  • .github/workflows/CI 配置)
  • .trae/rules/project_rules.md(项目规则)

15. CI/CD 规范

详细配置见 .github/workflows/ci.yml,使用手册见 cicd-runbook,设计文档见 no-push-local-build-design

15.1 核心模式no-push 本地构建

  • 不推送镜像到 registry:构建即部署,镜像只存在于构建机本地
  • 不依赖自建镜像全部使用官方镜像node:22-alpine / golang:1.22-alpine / bufbuild/buf / docker:25-git
  • DooD 模式deploy job 容器挂载 /var/run/docker.sock,容器内 docker 命令作用于宿主机
  • 单文件管理:一个 .github/workflows/ci.yml 管全部 CI/CD

15.2 流水线阶段

阶段 并行 内容 失败策略
quality-ts pnpm lint + typecheck + test + build 失败阻断
quality-go go vet + build + test 失败阻断
quality-proto buf lint + buf breaking仅 PR 失败阻断
deploy 串行 docker compose up --build + 健康检查 失败阻断

deploy job 仅在 push mainworkflow_dispatch 时触发PR 时不部署

15.3 触发条件

事件 触发阶段 触发条件
PR 创建/更新 quality-ts + quality-go + quality-proto并行 所有路径
push 到 main 上述全部 + deploy 合并后自动
workflow_dispatch 上述全部 + deploy 手动触发,支持 commit_sha 回滚

不再支持 tag 发布no-push 模式下不用 git tag v* 触发。版本管理通过 commit SHA 追溯。

15.4 镜像规范

  • 不推送到 registry,本地构建本地使用
  • 不保留历史镜像layer cache 在宿主机本地,未变更的层秒过
  • 回滚git revert 重跑 CIworkflow_dispatch 指定 commit_sha

15.5 部署策略

  • 目标环境:服务器 Docker ComposeP1-P2 阶段K8sP3+ 阶段)
  • 部署方式docker compose up -d --build --remove-orphans(在 /opt/edu/ 目录)
  • 部署目录/opt/edu/compose 文件)+ /opt/edu/repo/CI 同步的源码,供 build.context 使用)
  • 健康检查:部署后轮询 /healthz 端点10 次 × 6 秒),失败输出容器日志
  • 回滚git revert + pushworkflow_dispatch 指定 commit_sha

15.6 必需的 CI 文件

文件 用途
.github/workflows/ci.yml 唯一 CI/CD 流水线quality + deploy
infra/docker-compose.deploy.yml 部署用 composebuild: 替代 image:
infra/docker-compose.tools.yml 一次性预拉所有 CI 镜像
infra/deploy.env.example 部署环境变量模板

15.7 actrunner 配置

# /etc/gitea/act_runner/config.yaml
container:
  valid_volumes:
    - /var/run/docker.sock

15.8 镜像预拉(一次性)

部署前在服务器执行:

docker compose -f infra/docker-compose.tools.yml pull

拉取清单node:22-alpine、golang:1.22-alpine、bufbuild/buf:latest、docker:25-git、node:20-alpine、alpine:3.20、mysql:8.0开发测试、redis:7-alpine开发测试


本规则文件是项目的强制约束,所有 contributor含 AI必须遵守。规则变更需同步更新 004 与 arch.db。