fix(docs): 修复 project_rules.md P0 损坏并同步所有引用

- 根目录 project_rules.md 损坏(72 字节乱码),已删除
- 从 CICD 项目迁移完整版至 .trae/rules/project_rules.md(17881 字节)
- 更新 MIGRATION_GUIDE/README/coding-standards 引用至 .trae/rules/
- P0 紧急修复,影响所有 AI 工作流程
This commit is contained in:
SpecialX
2026-07-08 12:50:00 +08:00
parent 4629de1926
commit 3fbb97791d
5 changed files with 644 additions and 242 deletions

View File

@@ -0,0 +1,372 @@
# Edu 项目规则(微服务版)
> 版本1.0
> 日期2026-07-08
> 适用范围Edu 微服务架构DDD + EDA + CQRS多语言 monorepo
> 关联文档:
>
> - [004 架构影响地图](../../docs/architecture/004_architecture_impact_map.md)
> - [理想蓝图 0010](../../docs/architecture/0010_architecture.md)
> - [迁移指南](../../MIGRATION_GUIDE.md)
> - [known-issues 速查](../../docs/troubleshooting/known-issues.md)
---
## 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 不替代 004**arch.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 lint``pnpm 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{}`,用 `any`Go 1.18+
- 包内文件命名 lowercase不使用下划线`_test.go`
- 中间件位于 `internal/middleware/`,路由位于 `internal/routing/`
### 3.6 Python 规则
- 类型注解强制(所有函数签名、变量声明)
- FastAPI 路由用 `APIRouter`
- 异步优先:`async def`IO 密集场景禁止同步阻塞调用
- 模块名 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` 前缀 | `isActive``hasPermission` |
### 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.css``email-channel``manifest.ts`
---
## 4. 安全规范
- **JWT RS256**IAM 签发Gateway 公钥校验(不共享密钥)
- **Cookie**`httpOnly + 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 lint**`STANDARD` 规则集
- **buf breaking**`FILE` 级别检查CI 强制)
- **proto 文件位置**`packages/shared-proto/proto/`
- **包名规范**`edu.<domain>.v1`(如 `edu.iam.v1``edu.core_edu.v1`
- **生成代码**`buf generate`TS 走 `buf.gen.yaml`Go/Python 各自配置)
- **gRPC 服务端口**:每服务独立端口,见 004 服务清单
---
## 6. 事件驱动规范
- **Outbox 模式**:事务内写业务表 + outbox 表,独立 publisher 投递到 Kafka保证 at-least-once
- **事件命名**`<Aggregate>.<Action>`(如 `ExamCreated``HomeworkSubmitted``GradeReleased`
- **TOPIC_MAP 路由**:每个服务维护 `事件 → topic` 映射(见 `shared/outbox/`
- **幂等性**
- Kafka producer`idempotent=true` + `transactionalId`
- Consumer基于 `event_id` 去重Redis SETNX 或 DB 唯一索引)
- **CDC**MySQL → Debezium → Kafka可选用于读模型同步
- **事件版本**schema 演化用 `v1`/`v2` 后缀,禁止破坏性变更
---
## 7. 提交规范
- 使用 Conventional Commits 格式:`feat(scope): description`
- **类型**`feat``fix``chore``docs``style``refactor``test``perf``ci`
- **scope**(服务名或包名):
- 服务:`iam``classes``core-edu``content``msg``ai``data-ana``api-gateway``push-gateway``teacher-bff`
- 包:`shared-proto``shared-ts``shared-go``shared-py``shared-tokens`
- 基础设施:`infra``k8s``helm``ci`
- 文档:`docs`
- **提交前必须运行**`pnpm run lint` + `pnpm run typecheck`TS`go vet ./...`Go`ruff check src/`Python
- **commitlint + husky**:强制校验(见 `.commitlintrc.js``.husky/commit-msg`
---
## 8. Git 工作流
- **分支策略**trunk-based直接提交 main 分支,小项目)
- **大型团队**feature branch + PRPR 至少 1 人 review
- **pre-commit hook**`lint-staged` 自动修复 + 校验(见 `lint-staged.config.js`
- **commit-msg hook**commitlint 校验格式
- **禁止 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" |
### 记录格式
索引式表格,指明"场景→技术/规则"映射,不写多行代码示例:
```markdown
### 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. 运行质量校验确保零错误:
- TS`pnpm run lint` + `pnpm run typecheck`
- Go`go vet ./...` + `go build ./...`
- Python`ruff check src/`
### 阶段 3经验沉淀强制不可跳过
1.`docs/troubleshooting/known-issues.md` "工作经验日志"区追加一条记录:
- 日期 + 时间
- 模块
- 做了什么 + 学到什么
2. 若发现新的"场景→技术"映射 → 提炼到对应模块分区
3. 若发现新的架构决策 → 更新 004
4. 若代码结构变化 → `pnpm run arch:scan` 确认 arch.db 已更新
---
## 11. 多语言 monorepo 规则
- **包管理器分工**
- TypeScriptpnpm workspace`pnpm-workspace.yaml`
- Gogo.work`go.work`
- Pythonuv workspace`pyproject.toml``[tool.uv.workspace]`
- **共享包**`packages/`
- `shared-proto`protobuf 契约定义(跨语言共享)
- `shared-ts`TypeScript 共享类型与工具(待建立)
- `shared-go`Go 共享工具(待建立)
- `shared-py`Python 共享工具(待建立)
- `shared-tokens`:设计令牌(待建立)
- **跨语言契约**:通过 protobuf禁止 JSON Schema 或 OpenAPI 作为内部契约
- **依赖版本对齐**:共享依赖(如 uuid、jwt在多语言版本号保持一致
---
## 12. 可观测性规范
- **三支柱必须同时启用**(所有服务):
- **日志**pinoTS/ zapGo/ structlogPython—— 结构化 JSON
- **指标**prom-clientTS/ prometheusGo/ prometheus-clientPython—— `/metrics` 端点
- **链路**OpenTelemetry SDK + OTLP exporter —— 统一 traceparent
- **健康检查**`/health`liveness+ `/ready`readiness见各服务 `shared/health/`
- **请求 ID**Gateway 注入 `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. 部署与基础设施规范
- **容器化**:每服务独立 Dockerfile`services/[service]/Dockerfile`
- **K8s**:基础设施 manifest 位于 `infra/k8s/`,演化目标为 Helm chart`infra/k8s/helm/`
- **命名空间**`edu-system``edu-monitoring``edu-chaos``edu-backup`
- **配置分离**
- ConfigMap非敏感配置环境变量、特性开关
- Secret敏感配置DB 密码、JWT 密钥、API key—— 见 `infra/security/secrets.example.env`
- **备份**:见 `infra/backup/backup-mysql.sh`,每服务独立备份,保留 7 天
- **监控栈**Prometheus + Grafana + Alertmanager`infra/docker-compose.monitoring.yml`
- **混沌工程**:见 `infra/chaos/experiments.yaml`
---
**本规则文件是项目的强制约束,所有 contributor含 AI必须遵守。规则变更需同步更新 004 与 arch.db。**