Files
Edu/docs/architecture/coord-cross-review.md

334 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# coord 交叉审查报告(架构设计外包阶段 2
> 版本1.0(历史文档)
> 日期2026-07-09
> 审查执行coord协调 AI
>
> **⚠️ 历史声明**:本文件为**架构设计外包阶段 2**2026-07-09的过程性审查产物。项目已于 2026-07-10 切换为**全并行开发模式**。
>
> - 本文件正文保留原始审查记录(含 ai07 引用),作为历史追溯凭证
> - **当前权威文档**[ai-allocation.md](./ai-allocation.md) v2.0 + [issues/README.md](./issues/README.md) + [issues/matrix.md](./issues/matrix.md)
> - ai07 已移除classes 合并到 core-eduai08 负责)
> - 审查中涉及"架构设计意图"的结论已沉淀到 [004 架构影响地图](./004_architecture_impact_map.md)
>
> 关联文档:
>
> - [004 架构影响地图](./004_architecture_impact_map.md) — 架构设计意图唯一源
> - [AI 分配方案](./ai-allocation.md) §8 交叉审查规则
> - [项目规则](../../.trae/rules/project_rules.md)
>
> **本文档定位**:架构设计外包阶段 2 的过程性审查产物,记录 coord 对 18 份模块架构设计文档的跨模块一致性审查与裁决。裁决中涉及"架构设计意图"的结论已同步沉淀到 [004 架构影响地图](./004_architecture_impact_map.md) 对应章节,本文件保留完整审查过程与裁决依据作为追溯凭证。
---
## 1. 审查范围
| 维度 | 内容 |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| 审查文档 | 18 份 AI 架构设计文档(`services/*/docs/01-understanding.md` + `02-architecture-design.md` + `apps/teacher-portal/README.md` |
| 审查维度 | ① 跨模块接口签名一致性 ② Kafka topic 不重复 ③ 端口不冲突 ④ 错误码前缀不重叠 |
| 审查方式 | 4 个 search subagent 并行提取 4 类信息coord 整合裁决 |
| 审查依据 | [004 架构影响地图](./004_architecture_impact_map.md)、[project_rules](../../.trae/rules/project_rules.md)、[ai-allocation §8](./ai-allocation.md) |
---
## 2. 接口签名一致性审查
### 2.1 Proto 包名规范冲突P0 全局)
| 实际使用 | 规则要求 | 涉及 proto | 裁决 |
| ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `next_edu_cloud.<domain>.v1` | `edu.<domain>.v1`project_rules §5 | iam.proto / content.proto / msg.proto / core_edu.proto / analytics.proto / ai.proto / events.proto / push.proto全部 8 份) | **裁决:保持现状 `next_edu_cloud.*`**。理由:全量迁移成本高且无功能收益,仅 project_rules §5 文字与实际不符。**整改**:修订 project_rules §5 包名规范为 `next_edu_cloud.<domain>.v1`,同步 004 §11.2 契约规则表。 |
### 2.2 Proto 契约缺口P0 阻塞 parent-bff / P1 高优)
| # | 缺口 proto | 缺失内容 | 阻塞方 | 裁决 |
| --- | -------------- | ------------------------------------------------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------- |
| 1 | iam.proto | `GetViewports` / `GetEffectivePermissions` / `Logout` / `GetPublicKey`JWKS | teacher-bff / student-bff / parent-bff | **P2 补全**iam 在 proto 补 4 个 RPCREST 已实现 |
| 2 | iam.proto | `GetChildrenByParent` / `GetParentsByStudent`(家长-学生关联) | **parent-bff P0 阻塞** | **P4 前必须补全**iam 新增 `ParentStudentService` 或扩展 `IamService`parent-bff 核心场景依赖 |
| 3 | iam.proto | `GetEffectiveDataScope` | data-anaDataScope 解析) | **P4 补全**iam 新增 RPCdata-ana gRPC 调用 |
| 4 | content.proto | `ChapterService` / `QuestionService` 域 | student-bff / content 自身 | **P4 补全**content 新增 2 个 service |
| 5 | core_edu.proto | `AttendanceService`(出勤) | parent-bff / core-edu | **P3 补全**core-edu 新增 service |
| 6 | events.proto | `NotificationEvent` / `AIUsageEvent` / `UserEvent` / `RoleEvent` | msg / ai / iam | **P2-P5 分阶段补全**events.proto 按事件类型补 message |
| 7 | buf.gen.yaml | 缺 gRPC 插件 | 全部 | **P3 补全**coord 在 buf.gen.yaml 加 `grpc-node` / `grpc-python` / `grpc-go` 插件 |
### 2.3 gRPC 启用时机P1 高优)
**现状**:所有 6 个业务服务 proto 已定义 gRPC service但全部仅实现 HTTP RESTgRPC server 未落地。004 §4.1 明确"BFF → 业务服务走 gRPC",但 teacher-bff 实际用 REST fetch。
**裁决**
| 阶段 | gRPC 启用范围 | 理由 |
| ---- | --------------------------------- | ----------------------------------------- |
| P2 | 不启用 | teacher-bff REST 已跑通,无阻塞 |
| P3 | iam + core-edu 启用 gRPC server | student-bff / parent-bff 将依赖,需先就绪 |
| P4 | content + data-ana 启用 | ai07 student-portal / parent-portal 依赖 |
| P5 | ai 启用(含 StreamChat 流式 RPC | teacher-portal AI 辅助出题依赖 |
**整改**004 §4.1 补充"gRPC 启用阶段矩阵"小节。
### 2.4 前端与后端端点不一致P1 高优)
| # | 前端文档声明 | 后端实际端点 | 冲突类型 | 裁决 |
| --- | ------------------------------------------ | ----------------------------------------------------- | ----------------- | --------------------------------------------------- |
| 1 | `GET /api/v1/ai/generate-questions`SSE | `POST /ai/chat/stream` + `POST /ai/generate/question` | 路径 + 方法不一致 | **以 ai 服务为准**ai07 修正 teacher-portal README |
| 2 | `GET /iam/effective-permissions` | `GET /iam/permissions/effective` | 路径不一致 | **以 iam 为准**ai07 修正 |
| 3 | `GET /iam/rbac/...` | `GET /iam/viewports` / `/iam/roles` 等 | 路径不一致 | **以 iam 为准**ai07 修正 |
| 4 | `POST /parent/switch-child` | `POST /parent/children/:childId/select` | 路径不一致 | **以 parent-bff 为准**ai07 修正 |
### 2.5 BFF API 风格REST vs GraphQLP1 高优)
**现状**004 §11.3 提到 BFF GraphQL Yoga + DataLoader但 teacher-bff 实际是 REST fetch。
**裁决****P2-P3 用 RESTP4 起若 BFF 切 GraphQL 再引入 urql**。004 §11.3 标注为"目标态",当前阶段以 REST 为准。
---
## 3. Kafka Topic 一致性审查
### 3.1 core-edu 教学事件 topic 命名双轨P0 最严重)
| 004 §7.2 规范 | core-edu 代码实际 | 消费方文档 | 冲突 |
| ----------------------------- | ----------------- | ------------------------------------------------- | ---------------------------------------------------- |
| `edu.teaching.exam.published` | `edu.exam.events` | msg 按规范消费student-bff/parent-bff 按代码消费 | **契约破裂**msg 订阅不上 core-edu 实际发布的 topic |
**裁决****统一为 `edu.teaching.<aggregate>.<action>` 风格**(遵循 004 §7.2。core-edu 修改 `TOPIC_MAP`student-bff / parent-bff 修改订阅 topic 名。
**整改清单**
- core-edu `shared/outbox/outbox.publisher.ts``edu.exam.events``edu.teaching.exam.published` 等 4 个 topic
- student-bff / parent-bff 文档:同步更新订阅 topic 名
- msg 文档:已按规范,无需修改
### 3.2 004 §7.2 需补登的 topicP1
| Topic | 发布方 | 消费方 | 裁决 |
| -------------------------------------------- | -------- | ----------------------------- | ------------------------------------------------ |
| `edu.identity.user.deleted` | iam | core-edu / msg / push-gateway | ✅ 补登 |
| `edu.identity.user.role_changed` | iam | 自身缓存 / msg | ✅ 补登 |
| `edu.identity.role.created` | iam | msg | ✅ 补登 |
| `edu.identity.role.updated` | iam | 自身缓存 / msg | ✅ 补登 |
| `edu.notification.events` | msg | push-gateway | ✅ 补登msg 必须明确发布此 topic |
| `edu.insight.ai.usage` | ai | data-ana | ✅ 补登 + events.proto 补 `AIUsageEvent` message |
| `edu-cdc.next_edu_cloud.*`5 个 CDC topic | Debezium | data-ana | ✅ 补登 CDC topic 命名规范段 |
### 3.3 Python 服务 Outbox 豁免P1
**现状**004 §12.2 禁止直接 Kafka producer但 data-ana / ai 是 Python 服务无 MySQL 写事务Outbox 不适用。
**裁决****派生数据事件(非业务事务写)允许直接 producer**。data-ana 的 `MasteryUpdated`、ai 的 `AIUsageRecorded` 属于派生数据,豁免 Outbox 约束。
**整改**004 §12.2 补充"派生数据事件豁免条款"。
### 3.4 content Outbox 缺失P1
**现状**004 §7.2 列 content 发 `edu.content.question.published`,但 content 骨架无 Outbox / Kafka 实现。
**裁决****ai05 在 P4 阶段 2 设计中补全 content Outbox**。
### 3.5 NotificationRequested 事件发布方未明确P1
**现状**push-gateway 消费 `edu.notification.events`,但 msg 文档未明确发布此 topic。
**裁决****msg 服务为 `edu.notification.events` 的唯一发布方**,使用 Outbox 模式msg 有 MySQL 写事务)。
---
## 4. 端口冲突审查
### 4.1 严重前后端端口冲突P0
| 端口 | 前端占用 | 后端占用 | 冲突性质 |
| ---- | -------------- | ------------------------------------- | --------------- |
| 3001 | student-portal | classeslegacyP3 合并入 core-edu | dev server 冲突 |
| 3002 | parent-portal | iam | dev server 冲突 |
| 3003 | admin-portal | teacher-bff | dev server 冲突 |
**裁决****前端 4 端改用 4000-4003 端口区间**。理由:后端 3001-3010 已成事实基线api-gateway 路由表 + 各服务自声明),前端迁移成本更低。
**整改清单**
- ai07 修正 `apps/teacher-portal/README.md` §9.1 端口矩阵3000→4000teacher-portal、3001→4001student-portal、3002→4002parent-portal、3003→4003admin-portal
- ai07 修正 §9.1 备注"3001-3003 已被避让"的错误描述
- ai07 修正 MF 配置示例中的 remoteEntry.js URL 端口
### 4.2 端口缺口P1
| 服务 | 缺失项 | 裁决 |
| ----------------------------- | ----------------------------------------- | ------------------------------------------------ |
| push-gateway | docs/01 + docs/02 未声明端口(实际 8081 | ai01 补充端口声明 |
| core-edu | gRPC 端口未正式声明 | ai03 声明为 50053 |
| content / msg / data-ana / ai | gRPC 端口未声明 | 各 AI 在 gRPC 启用阶段补充 |
| 004 §1.2 | 完全未声明端口 | **coord 在 §1.2 新增 HTTP 端口 + gRPC 端口两列** |
### 4.3 全局端口矩阵coord 裁决基线,已同步至 004 §1.2
| 端口 | 服务 | 用途 | 阶段 |
| ----- | -------------- | ------------------------------------ | ---- |
| 4000 | teacher-portal | HTTPShell | P2 |
| 4001 | student-portal | HTTPRemote | P3 |
| 4002 | parent-portal | HTTPRemote | P4 |
| 4003 | admin-portal | HTTPRemote | P6 |
| 8080 | api-gateway | HTTP + /healthz + /readyz + /metrics | P1 |
| 8081 | push-gateway | HTTP + WebSocket | P5 |
| 3002 | iam | HTTP/REST | P2 |
| 50052 | iam | gRPC | P3 |
| 3003 | teacher-bff | HTTP | P2 |
| 3009 | student-bff | HTTP | P3 |
| 3010 | parent-bff | HTTP | P4 |
| 3004 | core-edu | HTTP | P3 |
| 50053 | core-edu | gRPC | P3 |
| 3005 | content | HTTP | P4 |
| 50054 | content | gRPC待声明 | P4 |
| 3006 | data-ana | HTTP | P4 |
| 50055 | data-ana | gRPC待声明 | P4 |
| 3007 | msg | HTTP | P5 |
| 50056 | msg | gRPC待声明 | P5 |
| 3008 | ai | HTTP | P5 |
| 50057 | ai | gRPC待声明 | P5 |
---
## 5. 错误码前缀审查
### 5.1 前缀不重叠审查结果
**当前已声明业务前缀互不重叠**(无两个服务声明相同前缀):
`IAM_` / `CORE_EDU_` / `CLASSES_` / `CONTENT_` / `MSG_` / `AI_` / `DATA_ANA_` / `STUDENT_BFF_` / `PARENT_BFF_` / `PUSH_`
### 5.2 P0 问题teacher-bff 无自有前缀
**现状**teacher-bff 用 `BAD_GATEWAY`(无前缀),与 student-bff`STUDENT_BFF_`/ parent-bff`PARENT_BFF_`)不一致,且与前端期望 `BFF_TEACHER_` 冲突。
**裁决****3 个 BFF 统一为 `BFF_XXX_` 风格**BFF 在前,符合前端期望):
- teacher-bff`BFF_TEACHER_*`
- student-bff`BFF_STUDENT_*`(从 `STUDENT_BFF_` 迁移)
- parent-bff`BFF_PARENT_*`(从 `PARENT_BFF_` 迁移)
**整改**ai03 / ai04 / ai07 同步更新文档与代码。
### 5.3 P0 问题Python 服务信封偏离 ActionState
**现状**data-ana / ai 用 `{success, data, degraded}` 而非 `{success, error:{code, message}}`,错误时无 `error.code`,前端无法用统一前缀路由 i18n。
**裁决****Python 服务统一为 ActionState 信封**
- 成功:`{success: true, data: T}`
- 失败:`{success: false, error: {code, message, details?}}`
- 降级:`degraded` 作为 `details` 子字段(`details: {degraded: true}`)而非顶层字段
**整改**ai06 修正 data-ana / ai 的 02-architecture-design.md §6.2 错误响应信封定义。
### 5.4 P0 问题:前端 `GW_` 期望与 api-gateway 无前缀冲突
**现状**:前端 README §9.4 声明 `GW_` → api-gateway"ai01 已用"),但 api-gateway 文档明确"无业务错误码前缀"。
**裁决****api-gateway 加 `GW_` 前缀**。理由:前端 i18n 路由需要统一前缀匹配,`UNAUTHORIZED` 等纯语义码改为 `GW_UNAUTHORIZED` 等。
**整改**ai01 修正 api-gateway 01/02 文档错误码清单,加 `GW_` 前缀。
### 5.5 P1 问题core-edu 子模块前缀
**现状**core-edu 主体用 `CORE_EDU_*`classes 子模块用 `CLASSES_*`(黄金模板历史遗留)。前端期望 `EXAMS_` / `HOMEWORK_` / `GRADES_` 分前缀。
**裁决****core-edu 统一用 `CORE_EDU_*`**(含 exams/homework/grades 子域classes 模块保留 `CLASSES_*`黄金模板历史遗留P3 合并入 core-edu 后仍保留)。前端删除 `EXAMS_` / `HOMEWORK_` / `GRADES_` 期望。
**整改**ai07 修正 teacher-portal README §9.4 前缀期望表。
### 5.6 P1 问题push-gateway 01/02 前缀不一致
**现状**01 用 `UNAUTHORIZED` / `PUSH_FAILED`混用02 统一 `PUSH_*`
**裁决****以 02 的 `PUSH_*` 为准**ai01 修正 01 文档。
### 5.7 P2 问题:错误信封结构不一致
| 服务 | 信封结构 | 裁决 |
| ------------- | ----------------------------------------------------------- | ---------------------------------------- |
| iam | `{success:false, error:{code, message, details?, traceId}}` | ✅ 基准 |
| api-gateway | `{success:false, error:{code, message}}` | 补 `traceId` / `details` |
| push-gateway | 无信封定义 | 明确为 ActionState 对齐 |
| data-ana / ai | `{success, data, degraded}` | 改为 ActionState见 §5.3 |
| msg | ZodError 走默认 500 | 补 `ZodError` 分支返回 400 + ActionState |
---
## 6. 裁决整改清单汇总
| # | 优先级 | 整改项 | 责任方 | 涉及文件 |
| --- | ------ | -------------------------------------------------------------------------- | --------- | ------------------------------------------------------------ |
| 1 | P0 | core-edu topic 命名统一为 `edu.teaching.*` | ai03 | core-edu `outbox.publisher.ts` + student-bff/parent-bff 文档 |
| 2 | P0 | 前端 4 端端口改用 4000-4003 | ai07 | teacher-portal README §9.1 + MF 配置 |
| 3 | P0 | teacher-bff 补 `BFF_TEACHER_` 前缀 + student/parent-bff 迁移为 `BFF_XXX_` | ai03/ai04 | 3 BFF 文档 + 代码 |
| 4 | P0 | Python 服务信封改为 ActionState | ai06 | data-ana/ai 02 文档 + 代码 |
| 5 | P0 | api-gateway 加 `GW_` 前缀 | ai01 | api-gateway 01/02 文档 + 代码 |
| 6 | P0 | iam 补 `GetChildrenByParent` / `GetParentsByStudent` proto RPC | ai02 | iam.proto + iam 02 文档 |
| 7 | P1 | 004 §7.2 补登 6 个 topic + CDC 命名规范 | coord | 004 §7.2 |
| 8 | P1 | 004 §1.2 新增 HTTP/gRPC 端口两列 | coord | 004 §1.2 |
| 9 | P1 | 004 §4.1 补充 gRPC 启用阶段矩阵 | coord | 004 §4.1 |
| 10 | P1 | 004 §12.2 补充派生数据事件 Outbox 豁免条款 | coord | 004 §12.2 |
| 11 | P1 | project_rules §5 包名规范改为 `next_edu_cloud.*` | coord | project_rules §5 |
| 12 | P1 | iam.proto 补 4 个 RPCViewport/EffectivePermissions/Logout/GetPublicKey | ai02 | iam.proto + iam 02 文档 |
| 13 | P1 | content.proto 补 Chapter/Question 域 | ai05 | content.proto + content 02 文档 |
| 14 | P1 | core_edu.proto 补 Attendance 域 | ai03 | core_edu.proto + core-edu 02 文档 |
| 15 | P1 | events.proto 补 NotificationEvent/AIUsageEvent/UserEvent/RoleEvent | coord | events.proto |
| 16 | P1 | buf.gen.yaml 补 gRPC 插件 | coord | buf.gen.yaml |
| 17 | P1 | ai07 修正前端 4 处端点不一致 | ai07 | teacher-portal README §1.3.1 + §3.5 |
| 18 | P1 | content 补 Outbox 实现 | ai05 | content 代码 + 02 文档 |
| 19 | P1 | msg 明确发布 `edu.notification.events` topic | ai05 | msg 02 文档 + 代码 |
| 20 | P2 | api-gateway 信封补 traceId/details | ai01 | api-gateway 02 文档 |
| 21 | P2 | push-gateway 定义 ActionState 信封 | ai01 | push-gateway 02 文档 |
| 22 | P2 | msg ZodError 走 GlobalErrorFilter 返回 400 | ai05 | msg 代码 |
| 23 | P2 | core-edu 完整错误码清单文档化 | ai03 | core-edu 02 文档 |
| 24 | P2 | 建立 `infra/port-allocation.md` 全局端口表 | coord | infra/port-allocation.md |
---
## 7. 裁决生效说明
- 本章节裁决自发布之日起生效,各 AI 在下一阶段实施时必须遵循
- **裁决的设计意图已沉淀到 [004 架构影响地图](./004_architecture_impact_map.md) 对应章节**§1.2 端口矩阵、§4.2 gRPC 启用阶段矩阵、§7.2 topic 补登、§11.2 包名规范、§11.4 错误码前缀矩阵、§12.2 Outbox 豁免条款)
- 整改清单中标注"coord"的责任项由协调 AI 执行,标注具体 AI 的由对应开发 AI 执行
- 整改完成后各 AI 需在 `docs/troubleshooting/known-issues.md` 工作经验日志区追加记录
- 若整改涉及源码修改,必须运行 `pnpm run arch:scan` 更新 arch.db
---
## 8. 总裁裁决落实记录2026-07-09
> 本节记录总裁最终裁决([president-final-rulings.md](./president-final-rulings.md))对本审查报告裁决的落实情况。
### 8.1 已落实项
| 审查章节 | 裁决内容 | 落实状态 |
| --------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| §2.3 gRPC 启用时机 | iam gRPC server 50052 从 P3 前移到 P2I1 裁决) | ✅ 已同步至 004 §4.2 + port-allocation.md §5 |
| §3.2 topic 补登 | 新增 `edu.iam.audit.created` + notification 4 个具体动作 topic + warning.triggered 复用 mastery topic | ✅ 已同步至 004 §7.2 |
| §3.5 NotificationRequested 发布方 | 归 msg 发布topic `edu.notification.requested` | ✅ 已同步至 004 §7.2 |
| §6 整改清单 | content QuestionService 从 P5 前移到 P4N3 裁决) | ✅ 已同步至 004 §16.7.4/§16.7.5 |
### 8.2 批次 0 产出(本日完成)
| 产出项 | 文件 | 状态 |
| ----------------------- | ------------------------------------------------------------------ | -------------------------------------------------------- |
| iam.proto 8 RPC 补全 | `packages/shared-proto/proto/iam.proto` | ✅ 12 RPC |
| content.proto 补全 | `packages/shared-proto/proto/content.proto` | ✅ 4 service / 22 RPC |
| msg.proto 补全 | `packages/shared-proto/proto/msg.proto` | ✅ 3 service / 13 RPC |
| analytics.proto 扩展 | `packages/shared-proto/proto/analytics.proto` | ✅ 12 RPC含 Stream |
| core_edu.proto 补全 | `packages/shared-proto/proto/core_edu.proto` | ✅ 5 service+ClassService +AttendanceService |
| ai.proto 补全 | `packages/shared-proto/proto/ai.proto` | ✅ 6 RPC+GenerateLessonPlan +StreamGenerateQuestion |
| events.proto AuditEvent | `packages/shared-proto/proto/events.proto` | ✅ 9 message+AuditEvent |
| buf.gen.yaml gRPC 插件 | `packages/shared-proto/buf.gen.yaml` | ✅ go + python gRPC 插件 |
| shared-ts Outbox 工具包 | `packages/shared-ts/src/outbox/` | ✅ 6 文件module/service/publisher/types/schema/index |
| shared-go 包骨架 | `packages/shared-go/` | ✅ 4 模块tracer/logger/jwks/env |
| packages UI 骨架 | `packages/ui-tokens` + `packages/ui-components` + `packages/hooks` | ✅ 3 包 / 20 文件 |
| arch.db 更新 | `arch.db` | ✅ TS 14 模块 / Go 2 模块 / Proto 297 契约 |
### 8.3 未完事项(移交批次 1+
- shared-go `go mod tidy` 需在 Go 环境就绪后执行(补 otel/jwt 依赖)
- `buf generate` 需在 buf CLI 就绪后执行(生成 3 语言 gRPC stub
- packages `pnpm install` 已执行shared-ts subagent 已验证 typecheck/lint 零错误)