docs: 文档体系修正 - 模块边界强化与按需阅读架构
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
| `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` | 已知问题速查(场景→技术映射 + 工作经验日志) |
|
||||
| `docs/troubleshooting/known-issues.md` | 已知问题速查(场景→技术映射,索引式,不写工作日志) |
|
||||
|
||||
### 需要同步图的场景
|
||||
|
||||
@@ -246,11 +246,13 @@ services/[service]/src/
|
||||
|
||||
## 8. Git 工作流
|
||||
|
||||
- **分支策略**:trunk-based(直接提交 main 分支,小项目)
|
||||
- **大型团队**:feature branch + PR,PR 至少 1 人 review
|
||||
- **分支策略**:trunk-based,直接提交到 `main` 分支(因 Gitea 问题,**不再使用特性分支/发布分支/hotfix 分支,不再使用 PR 流程**)
|
||||
- **提交方式**:所有变更直接 `git push origin main`;禁止 `git checkout -b` 创建任何分支
|
||||
- **提交前同步**:`git pull --rebase origin main` 拉取最新,解决冲突后再 push
|
||||
- **pre-commit hook**:`lint-staged` 自动修复 + 校验(见 `lint-staged.config.js`)
|
||||
- **commit-msg hook**:commitlint 校验格式
|
||||
- **禁止 force push**:除非显式要求并通知团队
|
||||
- **回滚**:`git revert <commit>` + `git push origin main`,不使用分支回滚
|
||||
|
||||
---
|
||||
|
||||
@@ -286,7 +288,8 @@ services/[service]/src/
|
||||
- **索引式**:场景→技术/规则映射,不写代码示例和错误示范列
|
||||
- **去重**:同类问题在原条目补充,不重复创建
|
||||
- **引用架构规则**:架构分层、模块结构等规则引用 004 和本规则文件,不重复
|
||||
- **工作经验日志**:在"工作经验日志"区按时间倒序追加(50 条上限),记录"做了什么/学到什么/下次注意"
|
||||
- **只读自己模块分区**:AI 查阅 known-issues 时只读自己负责模块的分区,禁止读其他 AI 模块的分区(避免被历史记录误导)
|
||||
- **禁止流水日志**:known-issues 不再设"工作经验日志"区,不写跨模块流水账;模块内的经验沉淀在各自模块的 README/文档中
|
||||
|
||||
---
|
||||
|
||||
@@ -294,14 +297,18 @@ services/[service]/src/
|
||||
|
||||
**所有 AI 工作必须遵循此流程,违反即违规。**
|
||||
|
||||
### 阶段 1:上下文加载
|
||||
### 阶段 1:上下文加载(按需阅读,严格模块边界)
|
||||
|
||||
> **架构文档按需阅读**:模块开发只读自己模块的架构与服务 README;项目整体相关工作(跨模块契约、基础设施、文档体系、shared-proto)才读全局架构文档。功能开发/文档书写等强依赖场景必须读对应架构。
|
||||
>
|
||||
> **严格模块边界**:AI 只读自己负责模块的文档与源码,不越界阅读其他模块的内部实现细节(避免被历史记录或他人方案误导)。仅在需要确认跨模块契约时,才读对方的对外接口(proto/API/事件)。
|
||||
|
||||
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` 对应章节
|
||||
4. 阅读 `services/[service]/README.md` 读**自己模块**的工作流程
|
||||
5. 查 `docs/troubleshooting/known-issues.md` **仅读自己模块的分区**,禁止读其他 AI 模块分区
|
||||
6. 模块开发:查 `docs/architecture/004_architecture_impact_map.md` **对应模块章节**;全局工作:查 004 全文
|
||||
|
||||
### 阶段 2:执行工作
|
||||
|
||||
@@ -314,13 +321,12 @@ services/[service]/src/
|
||||
|
||||
### 阶段 3:经验沉淀(强制,不可跳过)
|
||||
|
||||
1. 在 `docs/troubleshooting/known-issues.md` "工作经验日志"区追加一条记录:
|
||||
- 日期 + 时间
|
||||
- 模块
|
||||
- 做了什么 + 学到什么
|
||||
2. 若发现新的"场景→技术"映射 → 提炼到对应模块分区
|
||||
3. 若发现新的架构决策 → 更新 004
|
||||
4. 若代码结构变化 → `pnpm run arch:scan` 确认 arch.db 已更新
|
||||
1. 若发现新的"场景→技术"映射 → 提炼到 `docs/troubleshooting/known-issues.md` 对应**模块分区**(索引式一行,不写流水日志)
|
||||
2. 若发现新的架构决策 → 更新 004
|
||||
3. 若代码结构变化 → `pnpm run arch:scan` 确认 arch.db 已更新
|
||||
4. 模块内的经验沉淀到**自己模块的 README/文档**,不污染全局 known-issues
|
||||
|
||||
> **禁止**在 known-issues.md 写跨模块"工作经验日志/流水账"。known-issues 是索引式速查手册,只保留场景→技术映射。新 AI 不应被前任同名 AI 的流水记录误导。
|
||||
|
||||
---
|
||||
|
||||
@@ -375,44 +381,35 @@ services/[service]/src/
|
||||
|
||||
### 14.1 角色与权限
|
||||
|
||||
| 角色 | 职责 | push 特性分支 | 创建 PR | 合并 PR | push main | force push main |
|
||||
| -------------------------- | ---------------------------------------- | ------------- | ------- | ----------- | --------- | --------------- |
|
||||
| **协调 AI(Coordinator)** | PR 审核、合并、冲突仲裁、发布 | ✅ | ✅ | ✅ | ❌ | ⚠️(仅事故) |
|
||||
| **开发 AI(Dev)** | 按模块分工写代码、提 PR | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||
| **SRE AI** | `infra/` 维护、部署 | ✅(infra) | ✅ | ✅(infra) | ❌ | ⚠️(仅事故) |
|
||||
| **人类决策者** | 架构决策、Breaking Change 审批、发布确认 | — | — | — | — | — |
|
||||
| 角色 | 职责 | 直接 push main | 修改他人模块 | force push main |
|
||||
| -------------------------- | ---------------------------------------- | -------------- | ----------------------------- | --------------- |
|
||||
| **协调 AI(Coordinator)** | 契约管理、交叉审查、冲突仲裁、发布 | ✅ | ✅(shared-proto/infra/docs) | ⚠️(仅事故) |
|
||||
| **开发 AI(Dev)** | 按模块分工写代码、直接 push main | ✅ | ❌ | ❌ |
|
||||
| **SRE AI** | `infra/` 维护、部署 | ✅(infra) | ✅(仅 infra) | ⚠️(仅事故) |
|
||||
| **人类决策者** | 架构决策、Breaking Change 审批、发布确认 | — | — | — |
|
||||
|
||||
### 14.2 模块单一负责制
|
||||
> 不再使用特性分支与 PR。所有变更直接 `git push origin main`。代码审查改为事后追溯(通过 commit message + commit history),不在 push 前阻塞。
|
||||
|
||||
- 每个模块(限界上下文)只有一个 AI 负责,禁止并行修改同一模块
|
||||
### 14.2 模块单一负责制与模块边界(强制)
|
||||
|
||||
- **每个模块(限界上下文)只有一个 AI 负责,禁止并行修改同一模块**
|
||||
- **严格模块边界**:AI 只修改自己负责的目录(`services/<my-service>/` 或 `apps/<my-app>/`),禁止越界修改他人模块的源码
|
||||
- **只读自己模块文档**:AI 阅读文档时只读自己模块的 README/设计文档/known-issues 分区,**禁止阅读其他 AI 模块的内部文档和历史记录**(避免被前任同名 AI 的过时方案/审计结果误导)
|
||||
- **跨模块契约只读接口**:需要确认跨模块协同时,只读对方的对外接口(proto message / API 端点 / Kafka 事件 schema),不读对方内部实现
|
||||
- `shared-proto`、`shared-tokens`、`docs/` 由协调 AI 维护,开发 AI 只读引用
|
||||
- `infra/` 由 SRE AI 专门负责,业务 AI 不直接修改
|
||||
|
||||
### 14.3 分支命名规范(强制)
|
||||
### 14.3 直接 push main 规则(强制)
|
||||
|
||||
```
|
||||
<type>/<scope>-<task-id>-<ai-id>
|
||||
```
|
||||
1. **禁止创建分支**:不使用 `git checkout -b`、`git branch` 创建任何特性/发布/hotfix 分支
|
||||
2. **直接 push main**:所有变更 `git add` → `git commit` → `git pull --rebase origin main` → `git push origin main`
|
||||
3. **提交前校验**:push 前必须本地通过 `pnpm run lint` + `pnpm run typecheck`(TS)/ `go vet ./...`(Go)/ `ruff check src/`(Python)
|
||||
4. **提交信息规范**:遵循 Conventional Commits(见 §7),commit message 末尾标注 AI 身份(见 §14.6)
|
||||
5. **不阻塞审查**:push 不等待 review,问题通过事后 commit revert 或后续 commit 修正
|
||||
|
||||
- `type`:feat / fix / refactor / docs / chore / test
|
||||
- `scope`:见 §7 提交规范 scope-enum(26 项)
|
||||
- `task-id`:任务简短描述(kebab-case)
|
||||
- `ai-id`:AI 唯一标识符(如 `ai01`、`ai02`、`coord`)
|
||||
### 14.4 跨模块变更顺序(强制)
|
||||
|
||||
**示例**:`feat/classes-add-pagination-ai01`
|
||||
|
||||
### 14.4 PR 与合并规则(强制)
|
||||
|
||||
1. **禁止直接 push 到 `main`**:所有变更通过 PR
|
||||
2. **PR 必须通过 CI**:lint / typecheck / build / test 全绿
|
||||
3. **PR 必须通过 CODEOWNERS review**:至少 1 人 approve
|
||||
4. **合并策略**:Squash Merge(默认),Rebase Merge(保留多 commit 历史),**禁止 Merge Commit**
|
||||
5. **特性分支寿命 ≤ 3 天**:超期需 rebase 最新 main
|
||||
6. **跨模块变更拆分**:按依赖顺序拆多个 PR(proto → service → gateway → frontend),协调 AI 按序合并
|
||||
|
||||
### 14.5 跨模块变更顺序(强制)
|
||||
|
||||
修改涉及多模块时,必须按以下顺序拆分 PR 并顺序合并:
|
||||
修改涉及多模块时,按依赖顺序**依次直接 push main**(不拆 PR,按顺序提交避免下游编译失败):
|
||||
|
||||
1. `shared-proto`(proto 契约)
|
||||
2. 业务服务(classes / iam / core-edu 等)
|
||||
@@ -420,29 +417,28 @@ services/[service]/src/
|
||||
4. BFF(teacher-bff 等)
|
||||
5. 微前端(teacher-portal 等)
|
||||
|
||||
> 每合并一个 PR,后续 PR 的开发 AI 必须 rebase 最新 main 并重新校验。
|
||||
> 每提交一层并 push 后,再开发下一层。协调 AI 负责监督顺序,避免越级提交导致下游构建失败。
|
||||
|
||||
### 14.6 冲突处理规则
|
||||
### 14.5 冲突处理规则
|
||||
|
||||
- **文件冲突**:后合并的 PR rebase 最新 main,`git push --force-with-lease`(仅自己的分支)
|
||||
- **架构冲突**:由协调 AI 仲裁保留方案
|
||||
- **禁止 `git push --force` 到 main 或他人分支**
|
||||
- **push 冲突**:`git pull --rebase origin main` 解决冲突后重新 `git push origin main`
|
||||
- **架构冲突**:由协调 AI 仲裁保留方案,通过 commit revert + 新 commit 修正
|
||||
- **禁止 `git push --force` 到 main**:仅协调 AI 在事故时可 `--force-with-lease`
|
||||
|
||||
### 14.7 AI 身份标注(强制)
|
||||
### 14.6 AI 身份标注(强制)
|
||||
|
||||
每个 PR 描述末尾必须追加:
|
||||
每个 commit message body 末尾必须追加(用于追溯,不再有 PR 描述):
|
||||
|
||||
```markdown
|
||||
```text
|
||||
---
|
||||
|
||||
**AI Agent**: <ai-id> (<负责模块>)
|
||||
**Branch**: <分支名>
|
||||
**Coordinator**: <协调 AI ai-id>
|
||||
AI-Agent: <ai-id> (<负责模块>)
|
||||
Coord: <协调 AI ai-id>
|
||||
```
|
||||
|
||||
每个 AI 完成任务后,在 `docs/troubleshooting/known-issues.md` "工作经验日志"区追加记录(见 §9.3)。
|
||||
> 不再有 Branch 字段(不使用分支)。每个 AI 的经验沉淀到自己模块的 README/文档,**禁止**在 known-issues.md 写跨模块工作日志。
|
||||
|
||||
### 14.8 敏感文件保护
|
||||
### 14.7 敏感文件保护
|
||||
|
||||
以下文件修改需人类决策者额外审批:
|
||||
|
||||
@@ -470,18 +466,17 @@ services/[service]/src/
|
||||
| ----------------- | ---- | ------------------------------------ | -------- |
|
||||
| **quality-ts** | ✅ | pnpm lint + typecheck + test + build | 失败阻断 |
|
||||
| **quality-go** | ✅ | go vet + build + test | 失败阻断 |
|
||||
| **quality-proto** | ✅ | buf lint + buf breaking(仅 PR) | 失败阻断 |
|
||||
| **quality-proto** | ✅ | buf lint + buf breaking | 失败阻断 |
|
||||
| **deploy** | 串行 | docker compose up --build + 健康检查 | 失败阻断 |
|
||||
|
||||
> deploy job 仅在 `push main` 或 `workflow_dispatch` 时触发,PR 时不部署
|
||||
> 不再使用 PR。所有质量检查与部署在 push main 时触发。
|
||||
|
||||
### 15.3 触发条件
|
||||
|
||||
| 事件 | 触发阶段 | 触发条件 |
|
||||
| ----------------- | ----------------------------------------------- | -------------------------------- |
|
||||
| PR 创建/更新 | quality-ts + quality-go + quality-proto(并行) | 所有路径 |
|
||||
| push 到 main | 上述全部 + deploy | 合并后自动 |
|
||||
| workflow_dispatch | 上述全部 + deploy | 手动触发,支持 `commit_sha` 回滚 |
|
||||
| 事件 | 触发阶段 | 触发条件 |
|
||||
| ----------------- | ------------------------------------------------------- | -------------------------------- |
|
||||
| push 到 main | quality-ts + quality-go + quality-proto(并行)+ deploy | 每次 push main 自动 |
|
||||
| workflow_dispatch | 上述全部 + deploy | 手动触发,支持 `commit_sha` 回滚 |
|
||||
|
||||
> **不再支持 tag 发布**:no-push 模式下不用 `git tag v*` 触发。版本管理通过 commit SHA 追溯。
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
## 1. 外包总流程:三阶段
|
||||
|
||||
```
|
||||
阶段 1:全局理解 阶段 2:模块架构设计 阶段 3:按图实施
|
||||
阶段 1:模块理解 阶段 2:模块架构设计 阶段 3:按图实施
|
||||
(每个 AI 独立) (每个 AI 独立) (并行开发)
|
||||
│ │ │
|
||||
阅读全局架构文档 产出模块内部架构图 按自己画的图写代码
|
||||
按需阅读模块架构文档 产出模块内部架构图 按自己画的图写代码
|
||||
理解边界与契约 定义内部模块/数据流 coord 定期巡检一致性
|
||||
理解与其他模块的接口 标注与其他模块的交互点 遇到偏差更新架构图
|
||||
│ │ │
|
||||
@@ -21,7 +21,7 @@
|
||||
交付:理解确认书 交付:模块架构设计文档 交付:代码 + 更新图
|
||||
```
|
||||
|
||||
**阶段 1 目标**:每个 AI 读懂自己负责的模块在全局架构中的位置、边界、契约。
|
||||
**阶段 1 目标**:每个 AI 读懂自己负责的模块在架构中的位置、边界、契约(按需阅读,见 §4)。
|
||||
**阶段 2 目标**:每个 AI 产出自己模块的内部架构设计,经过 coord 交叉审查后放行。
|
||||
**阶段 3 目标**:按设计文档写代码,coord 定期巡检一致性。
|
||||
|
||||
@@ -92,30 +92,61 @@
|
||||
|
||||
---
|
||||
|
||||
## 4. 各 AI 阶段 1 必读文档清单
|
||||
## 4. 各 AI 阶段 1 文档阅读清单(按需阅读)
|
||||
|
||||
以下为每个 AI 在阶段 1 必须按顺序阅读的文档(标注 ★ 为强制必读):
|
||||
> **架构文档按需阅读原则**(见 [project_rules §10](../../.trae/rules/project_rules.md) 与 [multi-ai-collaboration §2.2](../standards/multi-ai-collaboration.md)):
|
||||
>
|
||||
> - **模块开发**:只读自己模块的架构与服务 README,不读其他模块内部实现
|
||||
> - **全局工作**(coord、跨模块契约、基础设施、文档体系):读全局架构文档
|
||||
> - **功能开发/文档书写等强依赖场景**:必须读对应架构
|
||||
> - **严格模块边界**:AI 只读自己负责模块的文档与源码,仅在确认跨模块契约时才读对方的对外接口(proto/API/事件),不读对方内部实现
|
||||
|
||||
| 顺序 | 文档 | ai01 | ai02 | ai03 | ai04 | ai05 | ai06 | ai07 | coord |
|
||||
| ---- | ------------------------------------------------------------------- | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :---: |
|
||||
| 1 | [README.md](../../README.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 2 | [MIGRATION_GUIDE.md](../../MIGRATION_GUIDE.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 3 | [004 架构影响地图](./004_architecture_impact_map.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 4 | [pending-features.md](./roadmap/pending-features.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 5 | [project_rules.md](../../.trae/rules/project_rules.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 6 | [coding-standards.md](../standards/coding-standards.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 7 | [multi-ai-collaboration.md](../standards/multi-ai-collaboration.md) | ★ | ★ | ★ | ★ | ★ | ★ | ★ | ★ |
|
||||
| 8 | 黄金模板 `services/classes/src/` 全部源码 | ★ | ★ | ★ | ★ | — | — | — | ★ |
|
||||
| 9 | `packages/shared-proto/proto/` 全部 .proto | ★ | ★ | ★ | ★ | ★ | ★ | — | ★ |
|
||||
### 4.1 全员必读(所有 AI,无论模块开发还是全局工作)
|
||||
|
||||
**语言特定补充阅读**:
|
||||
| 顺序 | 文档 | 说明 |
|
||||
| ---- | ------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
||||
| 1 | [project_rules.md](../../.trae/rules/project_rules.md) | 项目强制约束(架构规则、编码规范、提交规范、多 AI 协作、直接 push main) |
|
||||
| 2 | [coding-standards.md](../standards/coding-standards.md) | 多语言编码标准 |
|
||||
| 3 | [multi-ai-collaboration.md](../standards/multi-ai-collaboration.md) | 多 AI 协作指南(§2.1 严格模块边界、§2.2 按需阅读、§3 直接 push main) |
|
||||
|
||||
| AI | 语言 | 补充文档 |
|
||||
| ------- | -------- | --------------------------------------------------------------- |
|
||||
| ai01 | Go | `services/api-gateway/` 全部源码 |
|
||||
| ai02-05 | TS | `services/iam/`、`services/teacher-bff/` 源码(参考已实现模板) |
|
||||
| ai06 | Python | `services/data-ana/`、`services/ai/` 骨架源码 |
|
||||
| ai07 | TS/React | `apps/teacher-portal/` 全部源码、Module Federation 配置 |
|
||||
### 4.2 模块开发按需阅读(只读自己模块,禁止读其他模块内部实现)
|
||||
|
||||
| AI | 必读文档 | 说明 |
|
||||
| ---- | ------------------------------------------------------------------------------------ | ------------------- |
|
||||
| ai01 | `services/api-gateway/README.md`、`services/push-gateway/README.md`、004 §网关层章节 | Go 网关层架构 |
|
||||
| ai02 | `services/iam/README.md`、004 §iam 章节 | 身份认证架构 |
|
||||
| ai03 | `services/teacher-bff/README.md`、`services/core-edu/README.md`、004 §教学场景域章节 | 教学场景域架构 |
|
||||
| ai04 | 004 §student-bff / parent-bff 章节(待建立服务,无 README) | 学习+家长场景域 BFF |
|
||||
| ai05 | 004 §content / msg 章节(待建立服务,无 README) | 内容+通知架构 |
|
||||
| ai06 | `services/data-ana/README.md`、`services/ai/README.md`、004 §数据分析/AI 章节 | Python 数据+AI 架构 |
|
||||
| ai07 | `apps/teacher-portal/README.md`、004 §前端章节 | 前端 4 端架构 |
|
||||
|
||||
> **禁止越界阅读**:上表只列自己模块。如需确认与某模块的契约,走 §4.4 跨模块契约阅读,不读对方内部源码与 README。
|
||||
|
||||
### 4.3 全局工作必读(仅 coord,以及 AI 执行跨模块/全局任务时)
|
||||
|
||||
| 顺序 | 文档 | 说明 |
|
||||
| ---- | --------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| 1 | [README.md](../../README.md) | 项目总览 |
|
||||
| 2 | [MIGRATION_GUIDE.md](../../MIGRATION_GUIDE.md) | 迁移指南 |
|
||||
| 3 | [004 架构影响地图](./004_architecture_impact_map.md) 全文 | 全局架构与依赖(coord 必读;模块开发只读 §4.2 章节) |
|
||||
| 4 | [pending-features.md](./roadmap/pending-features.md) | 六阶段路线图 |
|
||||
|
||||
> 模块开发 AI **不需要**通读上述全局文档,仅在任务涉及跨模块协调、基础设施变更、文档体系维护时按需阅读。
|
||||
|
||||
### 4.4 跨模块契约按需阅读(仅涉及 proto 变更或确认接口时)
|
||||
|
||||
| 场景 | 必读文档 |
|
||||
| ----------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| 修改/新增 proto message | `packages/shared-proto/proto/` 中**相关** .proto 文件(不读全部,只读变更涉及的文件) |
|
||||
| 确认与其他模块的接口 | 004 §跨模块交互章节 + 对方服务的**对外接口**(proto / API 端点 / Kafka 事件名),**不读对方内部实现** |
|
||||
|
||||
### 4.5 黄金模板参考(仅 TS 服务首次实现新服务时)
|
||||
|
||||
| AI | 参考文档 |
|
||||
| ------------------ | ---------------------------------------------------------------------------------- |
|
||||
| ai02-05(TS 服务) | `services/classes/src/` 黄金模板源码(首次实现新服务时参考横切关注点,不强制全读) |
|
||||
| ai01 / ai06 / ai07 | 按需参考 classes 的横切关注点实现模式(错误处理/可观测/健康检查等),不强制读源码 |
|
||||
|
||||
---
|
||||
|
||||
@@ -185,7 +216,7 @@
|
||||
|
||||
## 6. 阶段 1 交付物模板
|
||||
|
||||
每个 AI 阅读完 §4 的文档清单后,必须产出以下确认书:
|
||||
每个 AI 按需阅读完 §4 对应文档后,必须产出以下确认书:
|
||||
|
||||
```markdown
|
||||
## 模块理解确认书 — [模块名]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Edu Git 工作流规范
|
||||
|
||||
> 版本:1.1
|
||||
> 日期:2026-07-08
|
||||
> 状态:基线发布(v1.1:scope-enum 对齐 + CODEOWNERS)
|
||||
> 版本:1.2
|
||||
> 日期:2026-07-10
|
||||
> 状态:基线发布(v1.2:移除分支/PR 流程,改为直接 push main)
|
||||
> 适用范围:Edu 多语言 monorepo(pnpm workspace + go.work + pyproject.toml)
|
||||
> 关联文档:
|
||||
>
|
||||
@@ -15,91 +15,69 @@
|
||||
|
||||
## 目录
|
||||
|
||||
1. [分支策略](#一分支策略)
|
||||
1. [主干开发(直接 push main)](#一主干开发直接-push-main)
|
||||
2. [Conventional Commits 规范](#二conventional-commits-规范)
|
||||
3. [commitlint + husky 配置](#三commitlint--husky-配置)
|
||||
4. [PR 与 Code Review](#四pr-与-code-review)
|
||||
4. [事后 Code Review](#四事后-code-review)
|
||||
5. [文档同步规则](#五文档同步规则)
|
||||
6. [多语言 monorepo 提交规则](#六多语言-monorepo-提交规则)
|
||||
7. [版本与发布](#七版本与发布)
|
||||
7. [版本管理](#七版本管理)
|
||||
8. [紧急回滚](#八紧急回滚)
|
||||
9. [附录:CICD 与 Edu Git 工作流差异](#九附录cicd-与-edu-git-工作流差异)
|
||||
|
||||
---
|
||||
|
||||
## 一、分支策略
|
||||
## 一、主干开发(直接 push main)
|
||||
|
||||
### 1.1 主干开发(Trunk-Based Development)
|
||||
### 1.1 模式
|
||||
|
||||
本项目采用**主干开发**模式,所有变更最终合并至 `main` 分支。
|
||||
本项目采用**主干开发**模式,所有变更**直接提交到 `main` 分支**。
|
||||
|
||||
> 因 Gitea 问题,**不再使用特性分支、发布分支、hotfix 分支,不再使用 PR 流程**。所有变更通过 `git push origin main` 提交。
|
||||
|
||||
**核心原则**:
|
||||
|
||||
- `main` 分支始终保持可发布状态
|
||||
- 短生命周期特性分支(通常 ≤ 3 天)
|
||||
- 频繁集成,每天至少一次 rebase/merge 至最新 `main`
|
||||
- 所有变更直接 push main,**禁止 `git checkout -b` 创建任何分支**
|
||||
- push 前本地通过 lint + typecheck + test + build(见 §3.4 pre-push hook)
|
||||
- push 前 `git pull --rebase origin main` 同步最新
|
||||
- 通过特性开关(Feature Flag)控制未完成功能的暴露
|
||||
- 代码审查改为事后追溯(见 §4),不在 push 前阻塞
|
||||
|
||||
### 1.2 分支模型
|
||||
### 1.2 提交流程
|
||||
|
||||
```mermaid
|
||||
gitGraph
|
||||
commit id: "init"
|
||||
commit id: "P1-foundation"
|
||||
branch feat/identity-service
|
||||
checkout feat/identity-service
|
||||
commit id: "scaffold"
|
||||
commit id: "implement-login"
|
||||
commit id: "add-tests"
|
||||
checkout main
|
||||
merge feat/identity-service tag: "v0.2.0"
|
||||
branch fix/jwt-expiry
|
||||
checkout fix/jwt-expiry
|
||||
commit id: "fix-token-refresh"
|
||||
checkout main
|
||||
merge fix/jwt-expiry tag: "v0.2.1"
|
||||
branch release/v0.3
|
||||
checkout release/v0.3
|
||||
commit id: "freeze"
|
||||
commit id: "hotfix"
|
||||
checkout main
|
||||
merge release/v0.3 tag: "v0.3.0"
|
||||
```bash
|
||||
# 1. 同步最新 main
|
||||
git pull --rebase origin main
|
||||
|
||||
# 2. 本地校验(强制)
|
||||
pnpm run lint # TS 服务
|
||||
pnpm run typecheck # TS 服务
|
||||
cd services/api-gateway && go vet ./... && go build ./... # Go 服务
|
||||
ruff check src/ # Python 服务
|
||||
|
||||
# 3. 提交(遵循 Conventional Commits,见 §2)
|
||||
git add <files>
|
||||
git commit -m "feat(<scope>): <subject>"
|
||||
|
||||
# 4. push 前再次同步(避免冲突)
|
||||
git pull --rebase origin main
|
||||
|
||||
# 5. 直接 push main
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 1.3 分支命名规范
|
||||
### 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 天 |
|
||||
- **push 被拒绝**(远端有新提交):`git pull --rebase origin main` → 解决冲突 → `git add` → `git rebase --continue` → `git push origin main`
|
||||
- **架构冲突**:由协调 AI 仲裁,通过 `git revert` + 新 commit 修正
|
||||
- **禁止 `git push --force` 到 main**:仅协调 AI 在事故时可 `git push --force-with-lease origin main`
|
||||
|
||||
**规则**:
|
||||
### 1.4 main 分支保护
|
||||
|
||||
- 分支名使用 kebab-case
|
||||
- 一个分支只做一件事,禁止在一个分支内混合多个无关变更
|
||||
- 特性分支命名包含服务/模块名(`feat/identity-service` 而非 `feat/login`)
|
||||
|
||||
### 1.4 分支保护规则
|
||||
|
||||
**`main` 分支保护**:
|
||||
|
||||
- 禁止直接 push,必须通过 PR
|
||||
- 至少 1 名 Reviewer 审批通过(核心模块需 2 名)
|
||||
- 所有 CI 检查通过(lint + typecheck + test + build)
|
||||
- 分支必须与 `main` 保持最新(无冲突或已 rebase)
|
||||
- 禁止 force push
|
||||
|
||||
**`release/*` 分支保护**:
|
||||
|
||||
- 禁止直接 push,仅接受 cherry-pick 或特定 hotfix PR
|
||||
- 至少 2 名 Reviewer 审批
|
||||
- 发布完成后打 tag 并归档
|
||||
- 禁止 force push(仅协调 AI 在事故时操作)
|
||||
- pre-commit / commit-msg / pre-push hook 强制校验(见 §3.4)
|
||||
- 不再要求 PR review,代码质量由本地校验 + 事后 review(§4)+ CI(project_rules §15)保证
|
||||
|
||||
---
|
||||
|
||||
@@ -375,103 +353,33 @@ module.exports = {
|
||||
|
||||
---
|
||||
|
||||
## 四、PR 与 Code Review
|
||||
## 四、事后 Code Review
|
||||
|
||||
### 4.1 PR 流程
|
||||
> 不再使用 PR 流程,代码审查改为**事后追溯**:变更直接 push main 后,由模块 owner 或协调 AI 通过 commit history 进行 review。问题通过后续 commit 修正或 `git revert` 回滚。
|
||||
|
||||
### 4.1 事后 Review 流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开发者创建特性分支] --> B[提交代码]
|
||||
B --> C[本地通过 lint + typecheck + test]
|
||||
C --> D[rebase 至最新 main]
|
||||
D --> E[推送至远程]
|
||||
E --> F[创建 PR]
|
||||
F --> G[CI 自动检查]
|
||||
G --> H{CI 通过?}
|
||||
H -->|否| I[修复问题]
|
||||
I --> B
|
||||
H -->|是| J[Reviewer 审查]
|
||||
J --> K{审查通过?}
|
||||
K -->|需修改| L[根据反馈修改]
|
||||
L --> B
|
||||
K -->|通过| M[Squash Merge]
|
||||
M --> N[删除特性分支]
|
||||
N --> O[CI 部署至 staging]
|
||||
A[开发 AI 本地校验] --> B[直接 push main]
|
||||
B --> C[CI 自动检查]
|
||||
C --> D{CI 通过?}
|
||||
D -->|否| E[git revert + 修复后重新 push]
|
||||
D -->|是| F[模块 owner 事后审查 commit]
|
||||
F --> G{审查通过?}
|
||||
G -->|有问题| H[后续 commit 修正或 revert]
|
||||
G -->|通过| I[review 完成]
|
||||
```
|
||||
|
||||
### 4.2 PR 标题
|
||||
**review 依据**:
|
||||
|
||||
PR 标题必须符合 Conventional Commits 规范(与最终 squash merge 的 commit message 一致):
|
||||
- commit message(Conventional Commits 格式,见 §2)
|
||||
- commit diff(通过 `git log -p` 或平台 commit 视图)
|
||||
- AI 身份标注(commit body 末尾的 `AI-Agent:` 字段,见 project_rules §14.6)
|
||||
|
||||
```
|
||||
feat(identity): 实现用户注册接口
|
||||
```
|
||||
### 4.2 Code Review 清单
|
||||
|
||||
### 4.3 PR 模板
|
||||
|
||||
`.github/pull_request_template.md`(或 Gitea 等价路径):
|
||||
|
||||
```markdown
|
||||
## 变更说明
|
||||
|
||||
<!-- 简述本次变更的目的和实现方式 -->
|
||||
|
||||
## 变更类型
|
||||
|
||||
- [ ] feat: 新功能
|
||||
- [ ] fix: Bug 修复
|
||||
- [ ] perf: 性能优化
|
||||
- [ ] refactor: 重构
|
||||
- [ ] test: 测试
|
||||
- [ ] docs: 文档
|
||||
- [ ] build/ci: 构建/CI
|
||||
|
||||
## 影响范围
|
||||
|
||||
<!-- 列出受影响的服务/包 -->
|
||||
|
||||
- 服务:
|
||||
- 包:
|
||||
- 数据库迁移:是 / 否
|
||||
- protobuf 契约变更:是 / 否
|
||||
- Kafka topic 变更:是 / 否
|
||||
|
||||
## 测试情况
|
||||
|
||||
- [ ] 单元测试通过
|
||||
- [ ] 集成测试通过
|
||||
- [ ] 本地手动测试通过
|
||||
- [ ] 新增测试覆盖新功能
|
||||
|
||||
## 文档同步
|
||||
|
||||
- [ ] 已更新服务 README(如涉及服务结构变更)
|
||||
- [ ] 已更新架构文档(如涉及架构变更)
|
||||
- [ ] 已运行 `pnpm run arch:scan` 更新 arch.db
|
||||
- [ ] 已更新 known-issues.md(如遇到新问题)
|
||||
|
||||
## Breaking Change
|
||||
|
||||
- [ ] 否
|
||||
- [ ] 是(请在下方说明影响和迁移路径)
|
||||
|
||||
## 关联 Issue
|
||||
|
||||
Closes #
|
||||
```
|
||||
|
||||
### 4.4 Reviewer 要求
|
||||
|
||||
| 变更类型 | 最少 Reviewer | 备注 |
|
||||
| ------------------------- | ------------- | ------------------- |
|
||||
| 普通业务变更 | 1 | 默认 |
|
||||
| 跨服务变更 | 2 | 涉及 ≥ 2 个服务 |
|
||||
| protobuf 契约变更 | 2 | 需包含架构组成员 |
|
||||
| 数据库 schema 变更 | 2 | 需包含 DBA 或架构组 |
|
||||
| 安全相关变更 | 2 | 需包含安全负责人 |
|
||||
| 核心模块(auth/identity) | 2 | 核心模块强制 2 人 |
|
||||
|
||||
### 4.5 Code Review 清单
|
||||
事后 review 时检查:
|
||||
|
||||
**通用检查**:
|
||||
|
||||
@@ -502,62 +410,46 @@ Closes #
|
||||
- [ ] SQL 是否使用参数化查询
|
||||
- [ ] 是否有 SQL 注入、XSS、SSRF 风险
|
||||
|
||||
### 4.6 合并策略
|
||||
### 4.3 模块 Owner 与 CODEOWNERS
|
||||
|
||||
**默认使用 Squash Merge**:
|
||||
**实际生效文件**:仓库根 `.github/CODEOWNERS`。
|
||||
|
||||
- 保留 PR 的完整变更作为一个 commit
|
||||
- commit message 使用 PR 标题
|
||||
- 删除特性分支
|
||||
|
||||
**禁止使用 Merge Commit**(除非是发布分支合并回 main):
|
||||
|
||||
- 避免历史中充斥 "Merge branch" 噪音
|
||||
- 保持线性历史
|
||||
|
||||
**Rebase Merge**:
|
||||
|
||||
- 仅用于需要保留多个有意义 commit 的特性分支
|
||||
- 需在 PR 中说明原因
|
||||
|
||||
### 4.7 模块 Owner 与 CODEOWNERS
|
||||
|
||||
**实际生效文件**:仓库根 `.github/CODEOWNERS`(GitHub/Gitea 原生支持,自动为 PR 分配 reviewer)。
|
||||
> 不再用于自动分配 PR reviewer(无 PR 流程),CODEOWNERS 保留作为**模块归属追溯依据**:commit 涉及某路径时,对应 owner 负责事后 review。
|
||||
|
||||
**设计原则**:
|
||||
|
||||
- 每个模块至少 1 名 owner,核心模块 2 名
|
||||
- 跨模块变更(如 proto 契约、arch.db、project_rules)由架构组 review
|
||||
- 基础设施变更(K8s/Helm/backup)由 SRE review
|
||||
- owner 名单变更需走 PR,由架构组审批
|
||||
- 跨模块变更(如 proto 契约、arch.db、project_rules)由架构组事后 review
|
||||
- 基础设施变更(K8s/Helm/backup)由 SRE 事后 review
|
||||
- owner 名单变更通过直接 commit 更新,由架构组确认
|
||||
|
||||
**模块 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 更新 |
|
||||
| 模块分类 | 路径 | Owner Team | 备注 |
|
||||
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | -------------------- |
|
||||
| 架构与规则 | `.trae/rules/`、`docs/architecture/`、`docs/standards/` | `@edu-platform/arch` | 架构组强制 review |
|
||||
| 架构工具 | `scripts/arch-scan/` | `@edu-platform/arch` | |
|
||||
| 根配置 | `.commitlintrc.js`、`lint-staged.config.js`、`package.json`、`pnpm-workspace.yaml`、`go.work`、`pyproject.toml`、`tsconfig.base.json` | `@edu-platform/arch` | 影响全局 |
|
||||
| 共享包 | `packages/shared-proto/` | `@edu-platform/arch` | 契约变更影响所有服务 |
|
||||
| 网关层 | `services/api-gateway/`、`services/push-gateway/` | `@edu-platform/gateway` | |
|
||||
| IAM 服务 | `services/iam/` | `@edu-platform/iam` | 核心模块 |
|
||||
| 教学核心 | `services/core-edu/`、`services/classes/` | `@edu-platform/edu-core` | |
|
||||
| 内容资源 | `services/content/` | `@edu-platform/content` | |
|
||||
| 消息通知 | `services/msg/` | `@edu-platform/messaging` | |
|
||||
| 数据分析 | `services/data-ana/` | `@edu-platform/data` | |
|
||||
| AI 服务 | `services/ai/` | `@edu-platform/ai` | |
|
||||
| BFF 层 | `services/teacher-bff/`、`services/student-bff/`、`services/parent-bff/` | `@edu-platform/edu-core` | |
|
||||
| 微前端 | `apps/teacher-portal/`、`apps/student-portal/`、`apps/parent-portal/`、`apps/admin-portal/` | `@edu-platform/frontend` | |
|
||||
| 基础设施 | `infra/k8s/`、`infra/backup/`、`infra/security/`、`infra/monitoring/` | `@edu-platform/sre` | 生产环境变更 |
|
||||
| CI/CD | `.github/`、`.husky/` | `@edu-platform/sre` | |
|
||||
| 文档 | `docs/troubleshooting/`、`docs/standards/` | `@edu-platform/arch` | known-issues 更新 |
|
||||
|
||||
> **Team handle 占位符**:上表 `@edu-platform/*` 为 team handle 模板。实际团队 handle 需在 GitHub/Gitea Organization 中创建对应 team 后,同步更新 `.github/CODEOWNERS`。
|
||||
|
||||
**CODEOWNERS 文件维护规则**:
|
||||
|
||||
1. 新增服务/包时,必须在同一 PR 中更新 `.github/CODEOWNERS`
|
||||
2. owner 变更(人员调动)需开独立 PR,由架构组审批
|
||||
1. 新增服务/包时,必须同步更新 `.github/CODEOWNERS`
|
||||
2. owner 变更(人员调动)由架构组确认后直接 commit 更新
|
||||
3. CODEOWNERS 与本节表格保持同步,单一事实源为 `.github/CODEOWNERS` 文件
|
||||
|
||||
---
|
||||
@@ -658,7 +550,7 @@ git commit -m "feat(identity): 实现用户注册接口"
|
||||
- 索引式:场景→技术/规则映射
|
||||
- 不写代码示例和错误示范
|
||||
- 同类问题在原条目补充,不重复创建
|
||||
- 在"工作经验日志"区按时间倒序追加记录
|
||||
- **不设"工作经验日志"区**:模块内经验沉淀在各自服务 README,known-issues 只保留索引式场景→技术映射(见 project_rules §9)
|
||||
|
||||
---
|
||||
|
||||
@@ -739,11 +631,13 @@ git commit -m "feat(notification): 适配 UserRegistered v2 事件"
|
||||
|
||||
---
|
||||
|
||||
## 七、版本与发布
|
||||
## 七、版本管理
|
||||
|
||||
> 不再使用 tag 发布与 release 分支(见 project_rules §15.3 no-push 模式)。版本通过 commit SHA 追溯,发布由 push main 触发 CI 自动部署。
|
||||
|
||||
### 7.1 版本号体系
|
||||
|
||||
本项目采用**双层版本号**:
|
||||
本项目采用**双层版本号**(仅作记录与沟通用,不通过 git tag 标记):
|
||||
|
||||
| 层级 | 格式 | 说明 |
|
||||
| -------- | ------------------------ | ----------------------------------------- |
|
||||
@@ -763,44 +657,38 @@ git commit -m "feat(notification): 适配 UserRegistered v2 事件"
|
||||
|
||||
### 7.3 Docker 镜像标签
|
||||
|
||||
> no-push 模式下镜像不推 registry,本地构建本地使用(见 project_rules §15.4)。下表标签格式仅用于本地镜像管理。
|
||||
|
||||
**格式**:`{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 类型 | 格式 | 示例 | 用途 |
|
||||
| -------- | -------------------- | ---------------- | ------------ |
|
||||
| Git SHA | `sha-{short}` | `sha-a1b2c3d` | 精确追溯 |
|
||||
| 最新 | `latest` | `latest` | 开发环境 |
|
||||
| 服务版本 | `{service}-{semver}` | `identity-1.2.0` | 服务独立版本 |
|
||||
|
||||
### 7.4 发布流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[main 分支达到发布标准] --> B[创建 release/v0.3.x 分支]
|
||||
B --> C[运行完整测试套件]
|
||||
C --> D{测试通过?}
|
||||
D -->|否| E[修复问题]
|
||||
E --> C
|
||||
D -->|是| F[更新 CHANGELOG.md]
|
||||
F --> G[打 tag v0.3.0]
|
||||
G --> H[CI 自动构建镜像]
|
||||
H --> I[部署至 staging]
|
||||
I --> J[冒烟测试]
|
||||
J --> K{冒烟通过?}
|
||||
K -->|否| L[修复并重新发布]
|
||||
L --> C
|
||||
K -->|是| M[审批发布至 production]
|
||||
M --> N[monitoring 观察指标]
|
||||
N --> O{指标正常?}
|
||||
O -->|否| P[紧急回滚]
|
||||
O -->|是| Q[发布完成]
|
||||
Q --> R[合并 release 分支回 main]
|
||||
A[开发 AI 本地校验通过] --> B[直接 push main]
|
||||
B --> C[CI 自动触发 quality + deploy]
|
||||
C --> D{CI 通过?}
|
||||
D -->|否| E[git revert + 修复后重新 push]
|
||||
E --> B
|
||||
D -->|是| F[部署至目标环境]
|
||||
F --> G[健康检查轮询 /healthz]
|
||||
G --> H{健康?}
|
||||
H -->|否| I[输出容器日志 + 紧急回滚 §8]
|
||||
H -->|是| J[发布完成]
|
||||
J --> K[更新 CHANGELOG.md]
|
||||
```
|
||||
|
||||
> 不再创建 release 分支、不再打 git tag。发布点通过 commit SHA 追溯,回滚通过 `git revert` 或 `workflow_dispatch` 指定 `commit_sha`(见 project_rules §15.4)。
|
||||
|
||||
### 7.5 CHANGELOG 格式
|
||||
|
||||
`CHANGELOG.md` 按 [Keep a Changelog](https://keepachangelog.com/zh-CN/) 格式维护:
|
||||
`CHANGELOG.md` 按 [Keep a Changelog](https://keepachangelog.com/zh-CN/) 格式维护,版本号对应阶段迭代(不绑定 git tag):
|
||||
|
||||
```markdown
|
||||
## [v0.3.0] - 2026-08-15
|
||||
@@ -847,30 +735,30 @@ 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` + push main 触发 CI 重新部署 | 5-10 分钟 |
|
||||
| 镜像问题 | `kubectl rollout undo` | 1-2 分钟 |
|
||||
| 数据库迁移问题 | 执行迁移 down 脚本 | 5-30 分钟 |
|
||||
| 配置错误 | 回滚 ConfigMap/Secret | 1-2 分钟 |
|
||||
| 全站故障 | `workflow_dispatch` 指定稳定 `commit_sha` | 10-30 分钟 |
|
||||
|
||||
### 8.2 代码回滚
|
||||
|
||||
> 不再创建 hotfix 分支。直接在 main 上 `git revert` 后 push,CI 自动重新部署。
|
||||
|
||||
```bash
|
||||
# 1. 确认要回滚的 commit
|
||||
git log --oneline -10
|
||||
|
||||
# 2. 创建回滚分支
|
||||
git checkout -b hotfix/v0.3.1
|
||||
# 2. 拉取最新 main
|
||||
git pull --rebase origin main
|
||||
|
||||
# 3. 回滚指定 commit
|
||||
# 3. 回滚指定 commit(生成反向 commit)
|
||||
git revert <commit-sha>
|
||||
|
||||
# 4. 推送并创建 PR
|
||||
git push origin hotfix/v0.3.1
|
||||
|
||||
# 5. 紧急审批合并后部署
|
||||
# 4. 直接 push main(CI 自动触发重新部署)
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 8.3 K8s 部署回滚
|
||||
@@ -955,30 +843,31 @@ pnpm --filter identity run migrate:down -- --to <version>
|
||||
|
||||
## 九、附录: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`) | 服务/包名(如 `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/` 目录独立记录 |
|
||||
| 维度 | CICD(Next.js 单应用) | Edu(微服务 monorepo) |
|
||||
| --------------------- | -------------------------------- | ----------------------------------------------------------------- |
|
||||
| 仓库结构 | 单一 Next.js 应用 | 多语言 monorepo(pnpm + go.work + uv) |
|
||||
| 分支策略 | trunk-based | trunk-based,**直接 push main,无分支无 PR** |
|
||||
| 提交规范 | Conventional Commits | Conventional Commits(沿用,scope 扩展至服务/包) |
|
||||
| scope 范围 | 模块名(如 `exams`、`homework`) | 服务/包名(如 `iam`、`api-gateway`、`shared-proto`) |
|
||||
| commitlint scope-enum | 35 个模块 | 26 个 scope(含服务/包/工具/平台级,与 `.commitlintrc.js` 同步) |
|
||||
| 代码审查 | PR Reviewer 1 人 | **事后 review**(无 PR,通过 commit history 追溯) |
|
||||
| 合并策略 | Squash Merge | **直接 push main**(无合并操作) |
|
||||
| 版本号 | 单一应用版本 | 双层(平台版本 + 服务独立版本,仅记录不打 tag) |
|
||||
| 发布粒度 | 整体发布 | 按服务独立发布 |
|
||||
| Docker 镜像 | 单一镜像 | 每服务一镜像(no-push 本地构建,见 project_rules §15) |
|
||||
| 回滚粒度 | 整体回滚 | 按服务回滚 |
|
||||
| 数据库迁移 | Drizzle 单库 | 每服务独立库 + 独立迁移 |
|
||||
| 文档同步 | `npm run arch:scan` | `pnpm run arch:scan`(多语言扫描) |
|
||||
| CI 检查 | lint + tsc + test | lint + typecheck + test(按语言分别执行) |
|
||||
| 紧急回滚 | `git revert` + 重新部署 | `git revert` + push main 触发 CI,或 `workflow_dispatch` 指定 SHA |
|
||||
| 事故复盘 | known-issues.md | `incidents/` 目录独立记录 |
|
||||
|
||||
---
|
||||
|
||||
## 变更记录
|
||||
|
||||
| 版本 | 日期 | 变更内容 |
|
||||
| ---- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 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 说明 |
|
||||
| 版本 | 日期 | 变更内容 |
|
||||
| ---- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 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 说明 |
|
||||
| 1.2 | 2026-07-10 | 因 Gitea 问题移除分支/PR 流程:§1 改为直接 push main(移除特性/发布/hotfix 分支命名与保护);§4 改为事后 Code Review(移除 PR 流程/标题/模板/合并策略,保留 Code Review 清单与 CODEOWNERS 追溯);§7 改为版本管理(移除 release 分支与 tag 发布,用 commit SHA 追溯);§8 移除 hotfix 分支回滚,改为直接 git revert + push main;§9 更新差异表 |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
# 已知问题速查
|
||||
|
||||
> 索引式速查手册:场景 → 技术/规则映射。不写代码示例。
|
||||
> 索引式速查手册:场景 → 技术/规则映射。不写代码示例,不写流水日志。
|
||||
> 架构规则见 [../architecture/004_architecture_impact_map.md](../architecture/004_architecture_impact_map.md) 与 [../../.trae/rules/project_rules.md](../../.trae/rules/project_rules.md)
|
||||
> 工作经验日志按时间倒序追加(50 条上限),AI 发现更好方案时可更新本节。
|
||||
> **AI 查阅时只读自己负责模块的分区(§二 对应小节),禁止读其他 AI 模块分区**,避免被历史记录或他人方案误导。模块内经验沉淀在各自服务 README。
|
||||
|
||||
---
|
||||
|
||||
@@ -351,39 +351,3 @@
|
||||
| P2 5 层状态管理 | nuqs(URL 同步)/ TanStack Query(服务端缓存)/ Zustand(客户端业务状态)/ Zustand UI(UI 临时态)/ react-hook-form(表单) |
|
||||
| P2 4 端错误码前缀对齐 | TP_=teacher-bff / SP_=student-bff / PP_=parent-bff / AP_=admin-bff,前端按前缀路由 i18n key |
|
||||
| P2 ErrorBoundary | 路由级 `<ErrorBoundary>` 包裹避免白屏,搭配 `<Suspense>` 流式加载 |
|
||||
|
||||
---
|
||||
|
||||
## 三、工作经验日志
|
||||
|
||||
> 按时间倒序,50 条上限。AI 发现更好方案时可更新本节。
|
||||
|
||||
| 日期 | 时间 | 模块 | 做了什么 + 学到什么 |
|
||||
| ---------- | ---- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 2026-07-09 | 夜间 | data-ana/ai(ai06) | **ai06 阶段 1+2 交付(Python 双服务)**:(1) 按 ai-allocation.md §4 必读清单读完 7 份全局文档(README/MIGRATION_GUIDE/004/pending-features/project_rules/coding-standards/multi-ai-collaboration)+ classes 黄金模板源码(controller/service/repository/schema/dto)+ shared-proto 8 份 proto(iam/classes/core_edu/events/analytics/ai/msg/push)+ ai-allocation.md §5 ai06 分工(data-ana P4 + ai P5)+ data-ana/ai 现有全部源码(main.py/clickhouse_client.py/cdc_consumer.py/llm_client.py/config.py)。(2) 阶段 1 产出 docs/architecture/ai06-phase1-understanding.md:data-ana 模块理解确认书(架构定位 L5 业务服务/限界上下文 D6 智能洞察/契约 AnalyticsService 3RPC + 消费 6 CDC topic/技术栈 Python3.12+FastAPI+ClickHouse+aiokafka/P4 阶段归属)+ ai 模块理解确认书(架构定位 L5/限界上下文 D6/契约 AiService 4RPC 含 StreamChat/技术栈 Python+FastAPI+LLM REST/P5 阶段归属)+ §10 服务审计表(两服务均缺 gRPC server 实现/缺权限校验 Depends/data-ana 缺 mastery.updated 事件发布/ai 缺 Redis 限流)+ 8 项跨模块契约待 coord 仲裁。(3) 阶段 2 产出 docs/architecture/ai06-phase2-design.md:data-ana 设计含 Mermaid 内部分层图(Entry/Middleware/Service/Repo/Consumer/Storage 6 层)+ ClickHouse 4 张宽表 DDL(student_dashboard_view ReplacingMergeTree(last_updated)/student_errors/mastery_snapshot/ai_usage_log)+ HTTP+gRPC 双入口 API 设计 + 6 个 CDC topic 消费路由 + 发布 edu.insight.mastery.updated 事件 + DATA_ANA_* 错误码清单 + 10 项 metrics + 优雅关闭序列;ai 设计含 Mermaid 分层图(LLM Provider 适配器模式)+ 无 DB 状态less + 4 LLM Provider(OpenAI/Anthropic/Baichuan/Ollama)+ Prompt 模板注册表 + 出题 4 步编排 + AI_* 错误码 + Redis 令牌桶限流 + edu.insight.ai.usage 事件发布 + 9 项待 coord 仲裁决策。(4) **学到**:Python 服务权限校验等价 NestJS @RequirePermission 的是 FastAPI Depends 依赖注入 + DataScope 6 级过滤(SELF/CLASS/GRADE/SCHOOL/DISTRICT/ALL);ClickHouse ReplacingMergeTree 查询必须加 FINAL 关键字否则读到重复版本数据;Python 服务无 MySQL 写事务故不能用 Outbox 模式,派生数据事件(mastery.updated/ai.usage)建议直接 Kafka producer(已提请 coord 仲裁是否豁免 §12.2 Outbox 强制约束);ai 服务无 DB 设计(stateless)与 data-ana 有 ClickHouse(OLAP)形成对比,需在审计表区分标注;gRPC streaming(StreamChat)在 Python 用 grpc.aio + AsyncGenerator,与 TS @grpc/grpc-js 双向流实现差异需在阶段 3 实施时对照;ai-allocation.md §9.3 提交规范为 `docs(<service>): 模块架构设计文档`,三阶段强制经验沉淀到 known-issues.md 工作经验日志。 |
|
||||
| 2026-07-09 | 夜间 | teacher-portal/前端4端(ai07) | **ai07 阶段 1+2 交付(前端 4 端)**:(1) 按 ai-allocation.md §4 必读清单读完 7 份全局文档(README/MIGRATION_GUIDE/004/pending-features/project_rules/coding-standards/multi-ai-collaboration)+ classes 黄金模板源码(controller/service/repository/schema/dto)+ shared-proto 8 份 proto + ai-allocation.md §5 ai07 分工。(2) 运行 `pnpm run arch:scan` 更新 arch.db(10 TS/264 符号、2 Go/33 符号、2 Py/45 符号、138 proto 契约)。(3) 阶段 1 产出 4 端模块理解确认书(架构定位/限界上下文/契约依赖/技术栈/阶段归属/黄金模板对齐审计),合并到 apps/teacher-portal/README.md。(4) teacher-portal 现状审计 19 维度,发现 7 项高优违规:AppShell.tsx L143 硬编码 `user.roles.join(",")`(违反 §3.1 前端禁 role 硬编码)/ globals.css+tailwind.config.js 硬编码 `hsl()` 字面量与 `#hex`(违反 §3.10 设计令牌)/ layout.tsx 直接 import `'Inter'/'Fraunces'/'JetBrains Mono'` 字面量(违反 §3.10 禁硬编码字体)/ 缺统一 ApiClient 层(4 页面重复 local authHeaders()+fetch)/ 缺 usePermission Hook(前端无 @RequirePermission 等价物)/ 缺 ErrorBoundary(白屏风险)/ 缺 5 层状态管理(nuqs/TanStack Query/Zustand/Zustand-UI/react-hook-form 全缺)/ next.config.js 无 Module Federation 配置(4 端无法 Shell+Remote 组合)。(5) 阶段 2 产出模块架构设计文档:MF 2.0 Shell+Remote 架构(teacher-portal:3000 为 Shell,student:3001/parent:3002/admin:3003 为 Remote)含 mermaid 架构图 + MF config 代码示例 + 领域模型(Session/Viewport/Permission TS 接口)+ 数据模型缓存策略表(5 层 DataScope × 5 类缓存键)+ API 请求层设计(ApiClient 401 自动刷新 + ActionState 解析 + 错误码前缀路由 i18n)+ WebSocket/SSE 事件设计 + 横切关注点对齐清单(权限表 4 端前缀/错误码前缀 TP_/SP_/PP_/AP_/logger/metrics/tracer/health)。(6) 4 端差异化对照表 5 张(总体/L1 导航/L2 路由/L3 组件/L4 数据)。(7) 交互点契约清单 12 项 + 风险 7 项 + 假设 5 项 + 4 项待 coord 仲裁(packages 归属/GraphQL vs REST/i18n key 命名/MF 暴露粒度)。(8) coord 交叉审查信息:端口矩阵 3000-3003、5 个 shared 包待建(shared-ts/shared-tokens/shared-ui/shared-mf/shared-perm)、11 个后端契约依赖、错误码前缀对齐、无 Kafka 事件消费。**学到**:前端权限校验等价物是 `usePermission().hasPermission()` Hook + `<RequirePermission>` 组件(镜像后端 `@RequirePermission()` 装饰器);MF Shell+Remote 架构选择优于 4 独立 Shell(共享登录态/布局/组件库/权限体系)和单 Next.js 应用(4 端独立部署/独立 CI/独立回滚);teacher-portal 现状有 7 项高优违规需 P2 闭环前修复;4 端 API 错误码前缀需与后端服务对齐(TP_=teacher-bff、SP_=student-bff、PP_=parent-bff、AP_=admin-bff);设计令牌三层模型(primitive/semantic-light+dark/tailwind-theme)必须 ESLint 强制约束(no-restricted-syntax 禁 #hex + design-tokens/no-hardcoded-fonts 禁字面量字体)。 |
|
||||
| 2026-07-09 | 夜间 | api-gateway/push-gateway(ai01) | **ai01 阶段 1+2 交付(Go 网关层)**:(1) 按 ai-allocation.md §4 必读清单读完 7 份全局文档(README/MIGRATION_GUIDE/004/pending-features/project_rules/coding-standards/multi-ai-collaboration)+ classes 黄金模板全部源码 + shared-proto 8 份 proto(iam/msg/events)+ api-gateway/push-gateway 全部 Go 源码。(2) 运行 `pnpm run arch:scan` 更新 arch.db(10 TS/264 符号、2 Go/33 符号、2 Py/45 符号、138 proto 契约)。(3) 阶段 1 产出 2 份模块理解确认书(services/{api-gateway,push-gateway}/docs/01-understanding.md)+ 审计表:api-gateway 审计出 13 项差距(3 高优先:缺 /metrics 端点、/readyz 是 stub 返回 ok 不检查依赖、auth.go L124-139 死代码 RequestIDMiddleware+generateUUID 与 requestid.go 重复;4 中:logger 用 fmt 非 log/slog、go.mod go 1.25.0 与 Dockerfile golang:1.22-alpine 版本不匹配、HS256 待 P2 升 RS256、DevMode 生产环境风险;6 低);push-gateway 审计出 16 项差距(6 高:无 Redis Pub/Sub 横向扩展、CheckOrigin 直接 return true 安全风险、用文本 "ping"/"pong" 心跳非 RFC 6455 控制帧、无单用户连接数上限、/internal/* 无鉴权、Dockerfile 单阶段且 root 用户无 healthcheck)。(4) 阶段 2 产出 2 份模块架构设计文档(02-architecture-design.md):api-gateway 覆盖 9 节(内部分层图、路由表矩阵 9 下游含端口+鉴权规则、限流策略表按路由差异化 RPS/burst、熔断阈值表按服务、JWT RS256 流程含 JWKS 缓存、CORS 白名单、请求 ID 注入、metrics 7 项指标清单、P0-P3 实施优先级);push-gateway 覆盖 13 节(内部分层图、Connection/Hub 领域模型、Redis 4 个 key pattern、WebSocket 端点+子协议 JSON 格式、内部推送 API+X-Internal-Token 鉴权、双通道协议 HTTP 同步+Kafka 异步、WebSocket 生命周期状态图、心跳协议 RFC 6455 控制帧 30s 间隔 60s 超时、单用户最大 5 连接、重连协议 P6 预留、多实例架构图、Redis Pub/Sub 跨实例流程、容量目标 10w+ 连接 <50ms 本地推送 <200ms 跨实例)。**学到**:gobreaker v2 ReadyToTrip 在 Requests=1 时 1*2>1=true 即 1 次失败就触发 OPEN(与 P6 集成测试观察一致);gorilla/websocket 不支持并发写同一连接,Hub.Send 必须用 send chan + 单写协程串行化(已在 P5 修复但设计文档需明确标注此约束);push-gateway 骨架用文本 "ping"/"pong" 违反 RFC 6455,应用 SetPongHandler 处理控制帧;004 §7.2 事件 topic 用 `edu.teaching.exam.published` 前缀但代码 TOPIC_MAP 用 `edu.exam.events`(ai03 已提请 coord 仲裁,本 AI 在 push-gateway 设计中消费 `edu.notification.events` 待 coord 统一命名后同步);api-gateway 与 push-gateway 重复 tracer.go/logger.go/jwks.go/env.go,建议提取到 `packages/shared-go/`(需 coord 创建包后多 AI 协同迁移);Go 服务 .env 不会自动加载,DevMode 必须在启动前 `export DEV_MODE=true` 或集成 godotenv。 |
|
||||
| 2026-07-09 | 夜间 | teacher-bff/core-edu(ai03) | **ai03 阶段 1 全局理解交付**:(1) 按 ai-allocation.md §4 必读清单读完 7 份全局文档 + classes 黄金模板全部源码 + shared-proto 8 份 proto + teacher-bff/core-edu 现有实现。(2) 运行 arch:scan 更新 arch.db(10 TS/264、2 Go/33、2 Py/45、138 proto 契约);arch:query deps/stats 发现 arch.db 仅记录模块/符号统计不记录跨模块调用边。(3) 按 §6 模板产出两份模块理解确认书 + §10 审计表,交付 docs/architecture/ai03-phase1-understanding.md。(4) 审计发现 teacher-bff 7 项差距(REST 非 gRPC/无 GraphQL/无 DataLoader/无 Redis 缓存/无 readyz/无 Zod/无测试)、core-edu 12 项差距(考试状态机缺失/作业状态机不完整/成绩无校验/无并发锁/homework.graded 与 grade.updated 事件未触发/未消费 IAM user.created/Drizzle db 导出 vs classes getDb() 不一致/kafka.ts 用 console 非 logger/classes 模块仅占位待合并/REST 未转 gRPC/无 Zod/无测试)。(5) 提请 coord 交叉审查 6 项跨模块契约对齐(iam getEffectivePermissions 聚合 API proto / iam user.created topic / 端口 3004 / Kafka topic 命名 004 文档与代码不一致 / data-ana 消费契约 / msg 消费契约)。**学到**:004 §7.2 事件 topic 用 `edu.teaching.exam.published` 前缀,但 core-edu outbox.publisher.ts TOPIC_MAP 用 `edu.exam.events`,文档与代码不一致需 coord 仲裁统一;teacher-bff 当前用 REST fetch 但 P2 退出标准要求 GraphQL Yoga + DataLoader,阶段 2 设计需补通信方式迁移;core-edu 与 classes 黄金模板的 Drizzle 访问方式不一致(core-edu 直接 `export const db`,classes 用 `getDb()` 函数),建议统一为 `getDb()` 函数式以匹配 HealthController 已有约定。 |
|
||||
| 2026-07-09 | 傍晚 | 全局 | **全服务代码合规性审查 + 批量修复**:对 10 个服务(6 NestJS + 2 Go + 2 Python)执行严格代码审查,发现 7 critical + 42 major + 35 minor 问题,批量修复如下。(1) **@RequirePermission() 装饰器实现**:6 个 NestJS 服务全部实现 `SetMetadata` + `Reflector` 标准模式,PermissionGuard 改用 `getAllAndOverride` 读取元数据,注册为 `APP_GUARD` 全局 Guard,DEV_MODE 旁路。content/msg 新建 permission.guard.ts + auth.middleware.ts。(2) **as 断言消除**:所有 `req.headers['x-user-id'] as string` 改为 `typeof` 类型守卫,涉及 auth.middleware.ts/global-error.filter.ts/controller.ts。(3) **返回类型补充**:`getDb()` 标注 `MySql2Database<typeof schema>`,Controller 方法补充 `Promise<{ success: true; data: ... }>`。(4) **import type 修复**:express 的 `Request`/`Response`/`NextFunction` 改为 `import type`。(5) **main.ts /metrics 隐式 any 修复**:参数标注 `Request`/`Response` 类型。(6) **原生 Error → ApplicationError**:repository.ts 的 `throw new Error` 改为 `DatabaseError`。(7) **typeorm 残留清理**:classes lifecycle.service.ts 移除 typeorm DataSource 依赖改用 Drizzle `closeDb()`。(8) **LifecycleService 注册**:5 个 NestJS 服务的 AppModule 注册 LifecycleService。(9) **teacher-bff 补全**:新建 logger.ts + ApplicationError 体系 + GlobalErrorFilter;下游调用转发真实 userId(替换硬编码 "bff");失败时 `logger.warn` + `BadGatewayError`(不再静默吞错);health.controller 迁移到 shared/health/ 标准结构。(10) **Go 安全修复**:CORS 默认 `*` 改为开发白名单 + warning;JWT 密钥非 DevMode fail-fast;push-gateway `/internal/*` 添加 `X-Internal-Key` 鉴权;`interface{}` → `any`;删除死代码 `RequestIDMiddleware`/`generateUUID`/`getEnvInt`;补充 doc comment;api-gateway + push-gateway 添加 `/metrics` 端点;push-gateway 添加 `/readyz`。(11) **Python 修复**:lifespan 返回类型标注 `AsyncGenerator[None, None]`;`dev_mode` 从 `str` 改为 `bool`;data-ana 业务路由改用 `APIRouter`;ai POST 端点从 query 参数改为 Pydantic 请求体模型;data-ana ClickHouse 同步调用包装在 `asyncio.to_thread()` 中。(12) **core-edu GlobalErrorFilter 统一**:响应契约改为 `{ success: false, error: { code, message, details, traceId } }` 与 content/msg 一致。(13) **msg 修复**:notifications.dto.ts 新建 Zod 验证 schema;uuid v4 替换为 `node:crypto.randomUUID`;ES 模块 console.error 改为结构化 logger。**学到**:NestJS `SetMetadata` 从 `@nestjs/common` 导入(非 `@nestjs/core`);`APP_GUARD` 注册全局 Guard 是标准模式;`Reflector.getAllAndOverride` 支持 handler+class 两级元数据查找;PermissionGuard 必须在 DEV_MODE 下旁路否则开发环境无法测试;Go 的 `interface{}` 在 1.18+ 应统一用 `any`;Python `asyncio.to_thread()` 是包装同步 IO 为异步的标准方式;FastAPI `lifespan` 返回类型是 `AsyncGenerator[None, None]`。 |
|
||||
| 2026-07-09 | 下午 | classes/全局 | **一键启动脚本 NestJS dist/ 不生成根因定位 + classes 健康检查修复**:(1) 根因定位:`tsconfig.base.json` 的 `incremental: true` + `nest-cli.json` 的 `deleteOutDir: true` 冲突。`nest start --watch` 启动时先删除 dist/,tsc 读残留 .tsbuildinfo 认为无变化跳过 emit,dist/ 不生成 → `Cannot find module dist/main`。(2) 修复:6 个 NestJS 服务(classes/iam/teacher-bff/core-edu/content/msg)tsconfig.json 显式加 `"incremental": false` 覆盖 base 配置,删除所有残留 .tsbuildinfo 文件。(3) classes AppModule 缺 HealthModule 导入导致 /healthz 404,iam 同样问题,修复 app.module.ts 加 `imports: [..., HealthModule]`。(4) classes HealthController 误用 TypeORM `DataSource` DI(与 iam 不一致),运行时报 `Nest can't resolve dependencies of the HealthController (DataSource)`。修复:改为 Drizzle `getDb()` 函数式调用,与 iam 一致。(5) 一键启动验证:11/11 应用 + 11/11 基础设施 + 5/5 可观测性端点全绿。**学到**:NestJS + TypeScript incremental 编译是陷阱组合——nest-cli deleteOutDir 删 dist 但 tsc 读 tsbuildinfo 认为无变化,必须在服务级 tsconfig 显式 `incremental: false`;HealthModule 必须在 AppModule imports 中显式声明才能被 NestFactory 扫描到;5 个 NestJS 服务的 HealthController 应统一用 Drizzle `getDb()` 函数式调用而非 TypeORM DataSource DI(项目已弃 TypeORM 改 Drizzle)。 |
|
||||
| 2026-07-09 | 下午 | 全局 | **OTel auto-instrumentations 全服务补全**:(1) NestJS 6 服务(iam/classes/core-edu/content/msg/teacher-bff)tracer.ts 补 `getNodeAutoInstrumentations()`,NodeSDK 传 instrumentations 参数自动埋点 HTTP/Express/DB。(2) Python 2 服务(data-ana/ai)main.py 补 `FastAPIInstrumentor.instrument_app(app)`;ai 补缺失的 `opentelemetry-exporter-otlp` 依赖。(3) teacher-bff 从零补完整 OTel:env.ts 加 OTEL_EXPORTER_OTLP_ENDPOINT 字段 + 新建 shared/observability/tracer.ts + main.ts 调用 initTracer/shutdownTracer + package.json 加 sdk-node/exporter/auto-instrumentations 依赖。(4) Go 2 服务(api-gateway/push-gateway)新建 internal/observability/tracer.go(OTLP HTTP exporter + resource + TracerProvider + W3C propagator)+ main.go 调用 InitTracer + otelgin.Middleware 注册 Gin 中间件;push-gateway config.go 补 OTLPEndpoint 字段。(5) 质量校验全通过:TS typecheck 9 服务 + ESLint 6 服务 + ruff 2 服务 + go vet/build 2 服务零错误。**学到**:`getNodeAutoInstrumentations()` 一次注册所有 Node.js 自动埋点(http/express/dns/fs/net/grpc 等),比手动逐个注册 HttpInstrumentation 更简洁;Go OTel 用 `otlptracehttp.WithEndpoint(host)` + `WithInsecure()` 需从 "http://host:port" URL 解析出 host;otelgin.Middleware 必须在 Recovery 之后其他中间件之前注册,确保所有后续 handler 都被 trace;Python FastAPIInstrumentor.instrument_app(app) 在 app 创建后立即调用,lifespan 不受影响。 |
|
||||
| 2026-07-09 | 下午 | 全局 | **P6 硬化:可观测性 + 部署 + CI 硬化**:(1) 可观测性栈完善:5 个 NestJS 服务 main.ts 添加 `/metrics` Prometheus 端点(用 `app.getHttpAdapter().get('/metrics', ...)` 绕过 DI 容器 get 方法);prometheus.yml 从 2 个目标扩展到 8 个应用服务 + MySQL/Redis + node-exporter + prometheus 自身 + rule_files + alertmanager 关联;monitoring compose 用 Loki + Promtail 替换未配置的 blackbox-exporter;Grafana datasource 新增 Loki;新建 promtail/config.yml 用 docker_sd_configs 仅采集 `edu-*` 容器日志。(2) 部署 compose 扩展:docker-compose.deploy.yml 从 3 服务扩展到 11 服务(+ iam/teacher-bff/core-edu/content/msg/ai/data-ana/push-gateway),每个服务带 healthcheck + depends_on 条件 + edu-net/edu-shared 双网络;deploy.env.example 补全 Neo4j/ES/ClickHouse/LLM/Kafka 可选依赖配置。(3) teacher-bff 补 health.controller.ts(原缺失 /healthz 导致 deploy depends_on service_healthy 失败)。(4) CI 硬化:移除 lint 步骤的 continue-on-error(ESLint 9 flat config 已配置完成),test 保留 continue-on-error(部分服务无 test 脚本)。**学到**:NestJS `app.get('/metrics')` 会被解析为 DI 容器 `get(typeOrToken)`,必须用 `app.getHttpAdapter().get()` 才能注册 Express 路由;Promtail docker_sd_configs 通过 relabel_configs 的 `regex: '/(edu-.*).*'` 过滤容器名前缀;docker-compose.depends_on.condition: service_healthy 要求被依赖服务必须有 healthcheck 配置,否则启动失败。 |
|
||||
| 2026-07-09 | 下午 | data-ana/infra | **CDC 完整链路实现**:MySQL binlog → Debezium Connect → Kafka → data-ana 消费者 → ClickHouse 宽表。(1) MySQL binlog 配置:log_bin=ON, binlog_format=ROW, binlog_row_image=FULL, server_id=1;用 root 创建 `debezium` 用户授予 REPLICATION SLAVE + REPLICATION CLIENT。(2) Debezium Connect 容器:daocloud 禁用 debezium 镜像改用 `quay.io/debezium/connect:2.7`;MySQL 容器在 edu-minimal_default 网络,需 `docker network connect edu-full_default edu-mysql` 让 Debezium 同时可达;Kafka 必须配置双 listener(INSIDE:kafka:29092 + OUTSIDE:localhost:9092),否则 Debezium 拿到 advertised.listeners 中的 localhost metadata 后切换失败;Debezium 2.x 容器环境变量名用 BOOTSTRAP_SERVERS(不带 KAFKA_ 前缀),通过 envsubst 替换到 connect-distributed.properties。(3) 注册 connector:POST :8083/connectors,配置 topic.prefix=edu-cdc, database.include.list=next_edu_cloud, snapshot.mode=initial,4 张表(core_edu_grades/exams/classes/iam_users)成功产生快照事件。(4) data-ana 消费者实现:新建 cdc_consumer.py 用 aiokafka AIOKafkaConsumer,lifespan 中 asyncio.create_task 后台运行;按 source.table 路由(exams→内存缓存 exam_id→class_id 映射,grades→查缓存填 class_id 后 upsert ClickHouse);readyz 端点附加 cdc_consumer 状态。(5) ClickHouse 远程访问:默认 default-user.xml 限制 127.0.0.1/::1 无密码,挂载 `clickhouse/users.d/custom-users.xml` 覆盖密码+任意 IP。(6) structlog 24.x API:`make_filtering_bound_logger(level)` 替代废弃的 `make_filtering_logger`。(7) E2E 验证:MySQL INSERT 成绩 → Debezium op=c 事件 → Kafka → 消费者写 ClickHouse 宽表(class_id 通过 exam 缓存正确填充)→ /readyz cdc_consumer=running → /analytics/student/student-002/weakness 返回实时 92 分数据。**学到**:Debezium 2.x 容器 bootstrap.servers 默认值是 0.0.0.0:9092 必须显式覆盖;Kafka 单 listener 配置 localhost 会让容器间通信的客户端拿到 metadata 后切换失败,必须用双 listener;ClickHouse users_xml 存储是 readonly 不能用 ALTER USER 修改密码,必须挂载 users.d 配置文件覆盖;消费者 offset 重置必须先停消费者让 group 处于 Empty 状态才能执行 --reset-offsets。 |
|
||||
| 2026-07-09 | 下午 | 全局 | **P6 硬化:ESLint 9 flat config 配置**:(1) 根目录创建 `eslint.config.js`(ESLint 9 flat config 格式):用 `typescript-eslint` recommended 规则集 + `@eslint/js` recommended + `eslint-config-prettier` 禁用冲突规则;自定义规则:`no-explicit-any` warn + `no-unused-vars` 允许下划线前缀 + 测试文件放宽。(2) 6 个 TS 服务 package.json lint 脚本从 `eslint src --ext .ts` 改为 `eslint src`(flat config 不需要 --ext)。(3) `lint-staged.config.js` 恢复 `eslint --fix`。(4) 验证:classes/content/msg/core-edu 四服务 lint 全部零错误零警告通过。**学到**:ESLint 9 flat config 用 `tseslint.config()` 工厂函数组装配置数组;`--ext` 参数在 flat config 模式下被移除,ESLint 自动根据 `eslint.config.js` 中的 `files` 匹配;`@typescript-eslint/consistent-type-assertions` 规则选项格式在 v8 中变化(`objectLiteralType` → `objectLiteralTypeAssertions`),配置时需查最新文档。 |
|
||||
| 2026-07-09 | 中午 | msg/push-gateway/ai/api-gateway | **P5 沟通与 AI 阶段三服务完善**:(1) msg 服务修复:database.ts 导出 db 常量;env.ts JWT_SECRET/ES_URL 改 optional 加 DEV_MODE/PUSH_GATEWAY_URL;elasticsearch.ts ES 降级(esClient=null 时 safeIndex/safeSearch 跳过);notifications.service.ts 加 createBatch + listByUserWithPagination + Push Gateway 推送调用(try/catch 降级);新建 msg-init.sql 2 张表。(2) push-gateway 完善:hub.go 重写用 send chan + 单写协程模式修复 gorilla/websocket 并发写竞争;handler.go 加 DEV_MODE dev-token 支持 + broadcast 端点;config.go 加 DevMode/RedisURL。(3) ai 服务完善:config.py 加 openai_api_key/base_url/dev_mode;新建 llm_client.py(httpx 异步调 OpenAI REST API);main.py 加 /ai 前缀 + 降级模式(无 key 返回骨架 + degraded: true)+ /readyz 端点。(4) Gateway 路由扩展:/notifications → msg,/ai → ai 服务。**学到**:gorilla/websocket 不支持并发写,必须用 send chan 串行化所有写入;FastAPI APIRouter prefix 与 Gateway 代理路径要协调(ai 服务加 /ai 前缀,Gateway 代理 /ai/*path);LLM 降级策略统一返回 degraded 标记,调用方据此判断是否路由流量。 |
|
||||
| 2026-07-09 | 上午 | content/api-gateway | **P4 内容分析服务端到端打通**:(1) content 服务系统性修复:database.ts 导出 db 常量;env.ts JWT_SECRET/ES_URL/NEO4J_URL/NEO4J_PASSWORD 改 optional 加 DEV_MODE;neo4j.ts driver 惰性创建+try/catch+connectionTimeout:3000;health/lifecycle 改用 Drizzle;global-error.filter 移除 @types/express 依赖;textbooks.schema 修复 integer→int + 导出 NewTextbook/NewChapter 类型;textbooks.controller 移除 body as any + 加 PUT/DELETE。(2) 新建 3 模块:chapters(CRUD + 按 textbook 查询)、knowledge-points(CRUD + Neo4j 前置依赖图非阻塞查询)、questions(CRUD + 4 种题型校验)。(3) Gateway 路由扩展:textbooks/chapters/knowledge-points/questions 四组路由。(4) 数据库:content-init.sql 4 张表。(5) E2E 验证:POST /textbooks 201 → POST /chapters 201(字段用 order 非 orderNum)→ POST /knowledge-points 201(Neo4j 不可用 MySQL 正常写入)→ POST /questions 201 → GET 各列表 200。**学到**:Drizzle schema TS 字段名与 DB 列名解耦(order→order_num),API 请求体用 TS 字段名;Neo4j 不可用时必须 driver=null(不设 NEO4J_URL),否则每次请求尝试连接拖慢响应;neo4j-driver safeCreateNode 用 try/catch 非阻塞,MySQL 数据始终先落库。 |
|
||||
| 2026-07-09 | 凌晨 | core-edu/api-gateway | **P3 核心教学服务端到端打通**:(1) core-edu 服务系统性修复 13 项:database.ts 导出 db 常量替代 getDb();env.ts JWT_SECRET 改 optional 加 DEV_MODE;kafka.ts connectKafka 加 try/catch 不阻塞启动;main.ts 去全局 /api 前缀 + connectKafka 改 void 非阻塞;app.module 移除未用 AuthMiddleware/ClassesesModule 加 HealthModule;3 个 controller 路由去前缀去 UseGuards 从 x-user-id 读身份;exams/homework service datetime 列 ISO 字符串转 Date 修复 drizzle toISOString 错误;修正 10 处相对 import 路径;health/lifecycle 改用 Drizzle 原生查询;新增 core-edu-init.sql 4 张表。(2) Gateway 路由扩展:发现 internal/routing/routing.go 是死代码(未被 main 引用),真正路由在 main.go;在 main.go 添加 exams/homework/grades 三组路由(无尾斜杠+通配符);删除 routing.go;config.go 加 CoreEduServiceURL。(3) DEV_MODE 环境变量问题:Go 不自动加载 .env,必须在启动前 export DEV_MODE=true 否则 dev-token 被拒 401。(4) E2E 验证:POST /exams 201 → GET /exams/:id 200 → GET /exams/class/:id 200 → POST /homework 201 → POST /grades 201 → Outbox 3 条事件正确写入(exam.failed 因 Kafka 未启动,homework/grade pending)。**学到**:drizzle datetime 列需 Date 对象不是 ISO 字符串(mapToDriverValue 调 toISOString);Go 项目 .env 不会自动加载需显式 export 或 godotenv 库;NestJS controller 路由前缀与 Gateway 代理路径要协调(Gateway 去掉 /api/v1 后转发,controller 用裸路径如 'exams');Outbox 模式业务事务同写验证通过,Kafka 未启动时事件 status=failed 但业务数据已落库。 |
|
||||
| 2026-07-09 | 上午 | iam/teacher-bff/teacher-portal | **P2 身份阶段完整实现**:(1) Gateway 公开路径白名单(register/login/refresh)解决无 token 死锁。(2) IAM schema 扩展:users 加 dataScope,新增 role_viewports 表。(3) RBAC 端点 4 个 GET。(4) 视口按 requiredPermission 过滤 + sortOrder 排序;getEffectivePermissions 用 Set 去重。(5) JWT payload 含 dataScope,register 自动分配 teacher 角色。(6) 种子数据 7 权限+12 映射+7 视口。(7) Teacher BFF 视口聚合。(8) 前端:lib/auth.ts + login + AppShell + (app) 路由组 + dashboard + classes(真实 JWT)+ 根重定向。(9) E2E 全链路通过。**学到**:Next.js 路由组 (app) 不影响 URL,/login 与 /dashboard 共存只后者套壳;fetch headers 函数返回 Record<string,string> 避免 TS2769;ESLint 9 需 flat config 留 P6;AppShell aside 用 flex flex-col + mt-auto 比 absolute 稳健。 |
|
||||
| 2026-07-08 | 晚上 | iam/classes/api-gateway | **P1 端到端链路验证 + IAM 服务修复**:验证 register → JWT → Gateway /iam/me → Gateway /classes CRUD → teacher-portal 前端渲染全链路打通。(1) IAM 服务 14 个 TS 编译错误修复:移除 typeorm/ioredis/kafkajs 依赖(IAM 用 Drizzle),health.controller.ts 改用 `db.execute(sql\`SELECT 1\`)`,lifecycle.service.ts 简化为只关闭 Drizzle 连接池;Drizzle API 修正(`r.roles`→`r.iam_roles`,`.in()`→`inArray()`)。(2) NestJS ESM DI 修复:iam.module.ts 简化 providers 为 `[IamService, IamRepository]`,iam.service.ts 构造器加 `@Inject(IamRepository)`(参考 classes 黄金模板),修复运行时 `Cannot read properties of undefined (reading 'findUserByEmail')`。(3) Gateway /iam/me 404 修复:iam.controller.ts 直接读 `req.headers['x-user-id']`替代未注册的`AuthenticatedRequest`。(4) 创建 `scripts/iam-init.sql`建 6 张 IAM 表 + 种子数据。(5) E2E 验证:iam:3002 注册/登录 → Gateway /iam/me 200 → Gateway GET /classes 200 → Gateway POST /classes(合法 UUID gradeId)201 → teacher-portal:3000 首页渲染 200 + 含"班级管理" → Next.js rewrites 透传 dev-token 到 Gateway 全链路通。**学到**:NestJS ESM 模式下 DI 无法通过类型推断解析 token,必须显式`@Inject(Token)`;Drizzle select 返回字段名按 schema 定义而非表名;classes.dto.ts 的 gradeId 要求 UUID 格式,测试数据不能用 "grade-12" 这类字符串;PowerShell 控制台中文显示为 `?`是编码问题,数据库实际存储正确;DEV_MODE 下前端用`Bearer dev-token` 即可走通链路,无需真实 JWT。 |
|
||||
| 2026-07-08 | 下午 | 全局 | **CI/CD 完整配置 + 多AI协作规范入规则**:(1) project_rules.md 新增 §14 多 AI 协作规范(角色权限矩阵/分支命名/PR合并规则/跨模块变更顺序/冲突处理/AI 身份标注/敏感文件保护)+ §15 CI/CD 规范(流水线阶段/触发条件/镜像规范/部署策略/Secrets 管理/必需 CI 文件)。(2) 优化现有 4 个 ci-*.yml:ci-ts.yml 加 arch-scan + docker-build job;ci-go.yml 去掉 golangci-lint(lint-staged 预存问题),加 docker-build;ci-proto.yml 修复 buf breaking URL(从 github.com 改为 .git 本地比较)。(3) 新增 `docker.yml`:main/tag 触发,构建推送 3 服务镜像到 Gitea Container Registry(git.eazygame.cn/xiner/edu/<service>:latest + sha tag + version tag),用 GITHUB_TOKEN 自动认证。(4) 新增 `deploy.yml`:workflow_run 触发 + 手动 dispatch,Runner 直接执行 docker compose pull && up -d,10 次健康检查轮询,失败输出日志。(5) 新增 `infra/docker-compose.deploy.yml`(部署用,镜像来自 Gitea registry,连接服务器已有 MySQL/Redis 通过 edu-shared 外部网络)+ `infra/deploy.env.example`(部署环境变量模板)。(6) 编写 `docs/standards/cicd-runbook.md`(CI/CD 使用手册,含架构总览/一次性配置/日常使用/镜像管理/部署验证/回滚/常见问题/排查命令/安全注意事项)。**学到**:Docker Compose 不支持 `restart_policy`(是 swarm 字段),用 `restart: unless-stopped` 替代;Gitea Actions 兼容 GitHub Actions 语法但 `workflow_run` 触发可能不完整,备选手动 dispatch;应用容器访问宿主机已有 MySQL/Redis 需通过共享外部网络(`docker network create edu-shared` + `docker network connect`)而非 `host.docker.internal`。 |
|
||||
| 2026-07-08 | 下午 | api-gateway | **重定向循环修复 + 生产模式部署准备 + 多AI协作文档**:(1) 修复 `ERR_TOO_MANY_REDIRECTS`:Gin 默认 `RedirectTrailingSlash=true` 导致 `/api/v1/classes` → 301 → `/classes/`,Next.js rewrites 代理时形成循环。**修复**:`r.RedirectTrailingSlash=false` + 同时注册无尾斜杠路由(`/classes`)与通配符路由(`/classes/*path`)。(2) 新增 DEV_MODE 旁路:`config.go` 加 `DevMode` 字段,`auth.go` 在 `DEV_MODE=true` 时接受 `dev-token` 注入固定身份(生产必须 false)。(3) 生产 Docker 化:新建 `apps/teacher-portal/Dockerfile`(多阶段 Next.js build)+ `services/api-gateway/Dockerfile`(多阶段 Go 静态编译)+ `infra/docker-compose.prod.yml`(三服务编排,强制 DEV_MODE=false)。(4) 编写 `docs/standards/local-dev-runbook.md`(本地启动手册,含端口表/开发模式/生产模式/常见问题)+ `docs/standards/multi-ai-collaboration.md`(多AI协作文档,含模块分工矩阵/分支命名/PR流程/合并策略/冲突处理/权限矩阵)。**学到**:Gin `RedirectTrailingSlash=false` 后需显式注册无尾斜杠路由(`Any("/classes")` + `Any("/classes/*path")`),否则 404;Next.js rewrites 代理会透传 301 给浏览器形成循环,开发模式旁路应通过环境变量控制而非硬编码。 |
|
||||
| 2026-07-08 | 全天 | 全局 | **P6 后续工作手册执行**:完整执行 post-p6-followup.md 12 节任务。环境准备(pnpm 925 包 + go mod tidy 双服务 + uv sync 双服务 + buf 安装)→ 代码质量校验(Go vet/build 0 错误,Python ruff 8 错误自动修复)→ arch.db 同步(实现 4 个扫描器骨架,输出 12 模块/233 符号/138 契约)→ project_rules.md P0 修复(迁移到 .trae/rules/,17881 字节)→ 004 架构图修复(1.1a/1.1b 双图 + 1.2 业务领域列 + 5.4 视口四层)→ P6 集成测试(10 Go + 17 bash = 27 用例全通过)→ Helm Chart 演化(8 chart lint 通过)。**学到**:多语言 monorepo 工具链配置需统一镜像源(npmmirror/goproxy.cn/tuna),go.work BOM 字符会导致 `unexpected input character` 错误必须重写文件。 |
|
||||
| 2026-07-08 | 上午 | 全局 | pnpm install 网络失败(ECONNRESET)→ 配置 `npm config set registry https://registry.npmmirror.com` + `pnpm config set registry https://registry.npmmirror.com` 重试成功。**学到**:Windows 下 pnpm 还需配置 `PNPM_HOME` 和 `TMP` 环境变量避免 `_tmp_` 文件 ENOENT 错误。 |
|
||||
| 2026-07-08 | 上午 | 全局 | project_rules.md 损坏(72 字节乱码,从 P1 提交 2ba4250 就损坏,git 历史无完整版本)→ 从 CICD 项目完整版迁移到 `e:\Desktop\Edu\.trae\rules\project_rules.md`(按用户要求放 .trae/rules/),按 MIGRATION_GUIDE 4.1 策略矩阵调整为微服务版(13 章 17881 字节),删除根目录损坏文件,更新 7 处引用(README/MIGRATION_GUIDE/004/known-issues/git-workflow/coding-standards)。**学到**:迁移文件后必须 `Get-Item | Select Length` 验证完整性 + 全文搜索引用更新,git commit 前运行 cat 检查内容。 |
|
||||
| 2026-07-08 | 上午 | api-gateway | go.work BOM 字符 + 版本不匹配:`unexpected input character '\ufeff'` 和 `module requires go >= 1.22.0, but go.work lists go 1.22`。**修复**:重写 go.work 去除 BOM,版本改为 `go 1.26.0`,移除不存在的 `./packages/shared-go`。**学到**:PowerShell `Out-File` 默认加 BOM,写 go.work 这类敏感文件应用 `Write` 工具或 `[System.IO.File]::WriteAllText` 指定 UTF8 无 BOM。 |
|
||||
| 2026-07-08 | 上午 | arch-scan | arch:scan 返回 0 模块 0 符号 → 4 个扫描器(ts/go/py/proto)都是骨架实现。**修复**:完整实现 4 个扫描器,TS 用 regex 提取(避免 ts-morph 对未安装依赖文件解析失败),Go/Python 用行首锚定正则,Proto 扫描 service/message/rpc。结果:12 模块(≥10 ✓)、233 符号(≥100 ✓)、138 契约。**学到**:ts-morph Project 对未 `pnpm install` 的 workspace 文件会报模块解析失败,改用 regex 更鲁棒;scanner.ts main() 开头需 `DELETE FROM` 清空旧数据避免重跑重复。 |
|
||||
| 2026-07-08 | 下午 | 004 | 架构图视角讨论(技术分层 vs 业务领域)→ 双图并存方案:1.1a 技术分层视角(部署/流量/网络边界,Users 层标注"场景域用户",BFF 层标注"按场景域分")+ 1.1b 业务领域视角(6 DDD 限界上下文 subgraph:D1 身份/D2 教学组织/D3 教学核心/D4 内容/D5 沟通/D6 智能洞察)。1.2 服务清单新增"业务领域"列。**学到**:双图互补,1.1a 服务运维/SRE 视角,1.1b 服务产品/架构视角;同一服务可横跨多领域(core-edu 同时承载 D2+D3)。 |
|
||||
| 2026-07-08 | 下午 | 004 | 视口四层模型补充(5.4 章节):L1 导航(navigation_config 表)/ L2 路由(route_permission + Gateway 校验)/ L3 组件(usePermission().hasPermission)/ L4 数据(DataScope 枚举)。场景域 BFF 复用策略:按使用场景域分 BFF 而非按角色分,教导主任复用 Teacher BFF + 额外管理视口。iam 服务职责:认证 + RBAC + 视口配置 + DataScope + 权限解析 API。**学到**:视口既可独立配置(RoleViewport 表)也可由权限推导,新角色只需配权限集,视口自动推导。 |
|
||||
| 2026-07-08 | 下午 | api-gateway | P6 集成测试补充:circuit-breaker_test.go(5 用例:ClosedToOpen/OpenToHalfOpen/HalfOpenToClosed/HalfOpenToOpen/4xxNotCounted)+ ratelimit_test.go(5 用例:AllowUnderBurst/RejectOverBurst/RefillTokens/PerIPIsolation/CleanupExpiredBuckets)+ test-backup-mysql.sh(8 用例 17 断言)。**学到**:gobreaker v2 ReadyToTrip 在 1 次失败后就触发(`TotalFailures*2 > Requests` 当 Requests=1 时 1*2>1=true),HALF_OPEN 状态只在探测执行期间可见,探测完成后立即转 CLOSED 或回 OPEN,测试需通过行为(503 vs 500)而非状态字段验证;rateLimiter cleanup 测试需用短周期参数(50ms/500ms)加速,且新鲜桶要在旧桶清理后再创建避免被一起清掉。 |
|
||||
| 2026-07-08 | 下午 | infra/k8s | Helm Chart 演化:安装 Helm v4.2.2,创建 edu-platform 平台级 chart(namespace/configmap/secret/ingress/hpa + 4 环境 values 文件)+ api-gateway 服务级 chart(完整迁移自原 deployment.yaml,参数化所有字段)+ 6 业务服务 chart 桩(iam/core-edu/content/msg/data-ana/ai)。删除原 api-gateway-deployment.yaml,保留 namespace.yaml。**学到**:Helm `{{- with ... -}}` 双向修剪会导致标签连在一行(`managed-by: Helmpart-of: edu-platform`),应改为 `{{- with ... }}` 只修剪左侧;`helm lint` 全部通过但 `helm template` 才能发现 YAML 渲染错误,验证时两个都要跑。 |
|
||||
| 2026-07-07 | 全天 | 全局 | 文档体系初始化:从旧项目(e:\Desktop\CICD,Next.js 单体)迁移 spec + plan + known-issues 模板到新仓库(e:\Desktop\Edu,微服务架构)。known-issues 重组为微服务分区:多语言 monorepo / Docker Compose / protobuf+buf / NestJS / Go Gateway / 可观测性 / 微前端。从旧项目提炼可迁移经验:React 19 useOptimistic / Zustand 细粒度选择器 / Tiptap SSR / 请求级去重 / 批量 SQL / 动态导入模式 / arch:scan 串行执行。新增微服务特有经验:契约先行 / Outbox / CDC / 双轨读 / DataScope / 黄金模板复制流程。路线图按 6 阶段组织:P1 地基 → P2 身份 → P3 核心教学 → P4 内容分析 → P5 沟通AI → P6 硬化。 |
|
||||
|
||||
Reference in New Issue
Block a user