docs: 文档体系修正 - 模块边界强化与按需阅读架构

This commit is contained in:
SpecialX
2026-07-10 13:33:31 +08:00
parent faaaf29f67
commit f15912c7ee
5 changed files with 594 additions and 918 deletions

View File

@@ -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 + PRPR 至少 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 |
| -------------------------- | ---------------------------------------- | ------------- | ------- | ----------- | --------- | --------------- |
| **协调 AICoordinator** | PR 审核、合并、冲突仲裁、发布 | ✅ | ✅ | ✅ | ❌ | ⚠️(仅事故) |
| **开发 AIDev** | 按模块分工写代码、提 PR | ✅ | | ❌ | ❌ | ❌ |
| **SRE AI** | `infra/` 维护、部署 | ✅infra | ✅ | ✅infra | ❌ | ⚠️(仅事故) |
| **人类决策者** | 架构决策、Breaking Change 审批、发布确认 | — | — | — | — | — |
| 角色 | 职责 | 直接 push main | 修改他人模块 | force push main |
| -------------------------- | ---------------------------------------- | -------------- | ----------------------------- | --------------- |
| **协调 AICoordinator** | 契约管理、交叉审查、冲突仲裁、发布 | ✅ | ✅shared-proto/infra/docs | ⚠️(仅事故) |
| **开发 AIDev** | 按模块分工写代码、直接 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见 §7commit message 末尾标注 AI 身份(见 §14.6
5. **不阻塞审查**push 不等待 review问题通过事后 commit revert 或后续 commit 修正
- `type`feat / fix / refactor / docs / chore / test
- `scope`:见 §7 提交规范 scope-enum26 项)
- `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. **跨模块变更拆分**:按依赖顺序拆多个 PRproto → 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. BFFteacher-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 追溯。

View File

@@ -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-05TS 服务) | `services/classes/src/` 黄金模板源码(首次实现新服务时参考横切关注点,不强制全读) |
| ai01 / ai06 / ai07 | 按需参考 classes 的横切关注点实现模式(错误处理/可观测/健康检查等),不强制读源码 |
---
@@ -185,7 +216,7 @@
## 6. 阶段 1 交付物模板
每个 AI 阅读完 §4 的文档清单后,必须产出以下确认书:
每个 AI 按需阅读完 §4 对应文档后,必须产出以下确认书:
```markdown
## 模块理解确认书 — [模块名]

View File

@@ -1,8 +1,8 @@
# Edu Git 工作流规范
> 版本1.1
> 日期2026-07-08
> 状态基线发布v1.1scope-enum 对齐 + CODEOWNERS
> 版本1.2
> 日期2026-07-10
> 状态基线发布v1.2移除分支/PR 流程,改为直接 push main
> 适用范围Edu 多语言 monorepopnpm 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+ CIproject_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 messageConventional 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): 实现用户注册接口"
- 索引式:场景→技术/规则映射
- 不写代码示例和错误示范
- 同类问题在原条目补充,不重复创建
- "工作经验日志"区按时间倒序追加记录
- **不设"工作经验日志"区**:模块内经验沉淀在各自服务 READMEknown-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` 后 pushCI 自动重新部署。
```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 mainCI 自动触发重新部署)
git push origin main
```
### 8.3 K8s 部署回滚
@@ -955,30 +843,31 @@ pnpm --filter identity run migrate:down -- --to <version>
## 九、附录CICD 与 Edu Git 工作流差异
| 维度 | CICDNext.js 单应用) | Edu微服务 monorepo |
| --------------------- | -------------------------------- | ---------------------------------------------------------------- |
| 仓库结构 | 单一 Next.js 应用 | 多语言 monorepopnpm + 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/` 目录独立记录 |
| 维度 | CICDNext.js 单应用) | Edu微服务 monorepo |
| --------------------- | -------------------------------- | ----------------------------------------------------------------- |
| 仓库结构 | 单一 Next.js 应用 | 多语言 monorepopnpm + 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 与 CODEOWNERShusky 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 与 CODEOWNERShusky 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

View File

@@ -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 层状态管理 | nuqsURL 同步)/ TanStack Query服务端缓存/ Zustand客户端业务状态/ Zustand UIUI 临时态)/ 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/aiai06 | **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 份 protoiam/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.mddata-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.mddata-ana 设计含 Mermaid 内部分层图Entry/Middleware/Service/Repo/Consumer/Storage 6 层)+ ClickHouse 4 张宽表 DDLstudent_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 ProviderOpenAI/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/ALLClickHouse ReplacingMergeTree 查询必须加 FINAL 关键字否则读到重复版本数据Python 服务无 MySQL 写事务故不能用 Outbox 模式派生数据事件mastery.updated/ai.usage建议直接 Kafka producer已提请 coord 仲裁是否豁免 §12.2 Outbox 强制约束ai 服务无 DB 设计stateless与 data-ana 有 ClickHouseOLAP形成对比需在审计表区分标注gRPC streamingStreamChat在 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.db10 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 为 Shellstudent: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-gatewayai01 | **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 份 protoiam/msg/events+ api-gateway/push-gateway 全部 Go 源码。(2) 运行 `pnpm run arch:scan` 更新 arch.db10 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.mdapi-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-eduai03 | **ai03 阶段 1 全局理解交付**(1) 按 ai-allocation.md §4 必读清单读完 7 份全局文档 + classes 黄金模板全部源码 + shared-proto 8 份 proto + teacher-bff/core-edu 现有实现。(2) 运行 arch:scan 更新 arch.db10 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` 全局 GuardDEV_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 默认 `*` 改为开发白名单 + warningJWT 密钥非 DevMode fail-fastpush-gateway `/internal/*` 添加 `X-Internal-Key` 鉴权;`interface{}` → `any`;删除死代码 `RequestIDMiddleware`/`generateUUID`/`getEnvInt`;补充 doc commentapi-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 验证 schemauuid 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 认为无变化跳过 emitdist/ 不生成 → `Cannot find module dist/main`。(2) 修复6 个 NestJS 服务classes/iam/teacher-bff/core-edu/content/msgtsconfig.json 显式加 `"incremental": false` 覆盖 base 配置,删除所有残留 .tsbuildinfo 文件。(3) classes AppModule 缺 HealthModule 导入导致 /healthz 404iam 同样问题,修复 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-bfftracer.ts 补 `getNodeAutoInstrumentations()`NodeSDK 传 instrumentations 参数自动埋点 HTTP/Express/DB。(2) Python 2 服务data-ana/aimain.py 补 `FastAPIInstrumentor.instrument_app(app)`ai 补缺失的 `opentelemetry-exporter-otlp` 依赖。(3) teacher-bff 从零补完整 OTelenv.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.goOTLP 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 解析出 hostotelgin.Middleware 必须在 Recovery 之后其他中间件之前注册,确保所有后续 handler 都被 tracePython 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-exporterGrafana 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-errorESLint 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 必须配置双 listenerINSIDE:kafka:29092 + OUTSIDE:localhost:9092否则 Debezium 拿到 advertised.listeners 中的 localhost metadata 后切换失败Debezium 2.x 容器环境变量名用 BOOTSTRAP_SERVERS不带 KAFKA_ 前缀),通过 envsubst 替换到 connect-distributed.properties。(3) 注册 connectorPOST :8083/connectors配置 topic.prefix=edu-cdc, database.include.list=next_edu_cloud, snapshot.mode=initial4 张表core_edu_grades/exams/classes/iam_users成功产生快照事件。(4) data-ana 消费者实现:新建 cdc_consumer.py 用 aiokafka AIOKafkaConsumerlifespan 中 asyncio.create_task 后台运行;按 source.table 路由exams→内存缓存 exam_id→class_id 映射grades→查缓存填 class_id 后 upsert ClickHousereadyz 端点附加 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 后切换失败,必须用双 listenerClickHouse 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_URLelasticsearch.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.pyhttpx 异步调 OpenAI REST APImain.py 加 /ai 前缀 + 降级模式(无 key 返回骨架 + degraded: true+ /readyz 端点。(4) Gateway 路由扩展:/notifications → msg/ai → ai 服务。**学到**gorilla/websocket 不支持并发写,必须用 send chan 串行化所有写入FastAPI APIRouter prefix 与 Gateway 代理路径要协调ai 服务加 /ai 前缀Gateway 代理 /ai/*pathLLM 降级策略统一返回 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_MODEneo4j.ts driver 惰性创建+try/catch+connectionTimeout:3000health/lifecycle 改用 Drizzleglobal-error.filter 移除 @types/express 依赖textbooks.schema 修复 integer→int + 导出 NewTextbook/NewChapter 类型textbooks.controller 移除 body as any + 加 PUT/DELETE。(2) 新建 3 模块chaptersCRUD + 按 textbook 查询、knowledge-pointsCRUD + Neo4j 前置依赖图非阻塞查询、questionsCRUD + 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 201Neo4j 不可用 MySQL 正常写入)→ POST /questions 201 → GET 各列表 200。**学到**Drizzle schema TS 字段名与 DB 列名解耦order→order_numAPI 请求体用 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_MODEkafka.ts connectKafka 加 try/catch 不阻塞启动main.ts 去全局 /api 前缀 + connectKafka 改 void 非阻塞app.module 移除未用 AuthMiddleware/ClassesesModule 加 HealthModule3 个 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.goconfig.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 调 toISOStringGo 项目 .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 含 dataScoperegister 自动分配 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> 避免 TS2769ESLint 9 需 flat config 留 P6AppShell 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 用 Drizzlehealth.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 gradeId201 → 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-*.ymlci-ts.yml 加 arch-scan + docker-build jobci-go.yml 去掉 golangci-lintlint-staged 预存问题),加 docker-buildci-proto.yml 修复 buf breaking URL从 github.com 改为 .git 本地比较)。(3) 新增 `docker.yml`main/tag 触发,构建推送 3 服务镜像到 Gitea Container Registrygit.eazygame.cn/xiner/edu/<service>:latest + sha tag + version tag用 GITHUB_TOKEN 自动认证。(4) 新增 `deploy.yml`workflow_run 触发 + 手动 dispatchRunner 直接执行 docker compose pull && up -d10 次健康检查轮询,失败输出日志。(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")`),否则 404Next.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/tunago.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 限界上下文 subgraphD1 身份/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.go5 用例ClosedToOpen/OpenToHalfOpen/HalfOpenToClosed/HalfOpenToOpen/4xxNotCounted+ ratelimit_test.go5 用例AllowUnderBurst/RejectOverBurst/RefillTokens/PerIPIsolation/CleanupExpiredBuckets+ test-backup-mysql.sh8 用例 17 断言)。**学到**gobreaker v2 ReadyToTrip 在 1 次失败后就触发(`TotalFailures*2 > Requests` 当 Requests=1 时 1*2>1=trueHALF_OPEN 状态只在探测执行期间可见,探测完成后立即转 CLOSED 或回 OPEN测试需通过行为503 vs 500而非状态字段验证rateLimiter cleanup 测试需用短周期参数50ms/500ms加速且新鲜桶要在旧桶清理后再创建避免被一起清掉。 |
| 2026-07-08 | 下午 | infra/k8s | Helm Chart 演化:安装 Helm v4.2.2,创建 edu-platform 平台级 chartnamespace/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\CICDNext.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 硬化。 |