Files
Edu/docs/architecture/issues/objections/msg_issue.md
SpecialX c179af64a6 docs(docs): coord 完成 15 模块 issue 仲裁与基础设施同步
coord.md 新增 ARB-019/020/021 三章仲裁章节,修正 ARB-001。

- coord.md: 新增 ARB-019/020/021(student/parent/admin-portal 24 项)
- coord.md: 修正 ARB-001(admin P2 预留/schema 文件名/classes 数据源)
- 004 §4: 依赖图加 PBFF→DataAna+Msg
- 004 §7.2: push-gateway→Redis 软失败标注
- 004 §11.4: 错误码前缀矩阵(11 服务+i18n key)
- 004 §11.5: ActionState 信封规范(降级模式方案 B)
- matrix §1: 依赖矩阵加 PBFF 边
- matrix §2: 移除 api-gateway 为 iam gRPC 消费方
- matrix §4: admin-portal→teacher-bff
- matrix §5: 移除 /sse+鉴权头统一
- matrix §6: 错误码表补 i18n key 列
- 15 个 issue.md: 仲裁结论回写
- push-gateway_contract: 移除 /sse+鉴权头改 X-Internal-Token
- packages/contracts: 新建包 ADMIN_* 权限点常量

AI: coord
2026-07-10 16:30:51 +08:00

215 lines
14 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.
# msg 问题记录
> 负责人ai10
> 关联:[coord.md](../coord.md)、[contracts/msg_contract.md](../contracts/msg_contract.md)
> 规则AI 遇到问题时在此追加条目coord 仲裁后更新状态
---
## §0 已有仲裁核查ai10 复核)
> 本节核查 01-understanding.md / 02-architecture-design.md 中引用的已有仲裁,对照源码/proto 验证准确性。
### ISSUE-001-ai10M8 ZodError 已修复 — 核查通过
- **提请方**ai10
- **日期**2026-07-10
- **类型**:仲裁核查
- **描述**01-understanding.md M8 称"GlobalErrorFilter 已识别 ZodError 返回 400"。核查 [global-error.filter.ts](../../../services/msg/src/shared/errors/global-error.filter.ts) L32-42`else if (exception instanceof ZodError) { statusCode = 400; ... }`,确实已处理,返回 `MSG_VALIDATION_ERROR` + 400。
- **核查结论**:✅ 仲裁准确M8 标记"已修复"无误
- **状态**:已裁决(核查通过,无需处理)
### ISSUE-002-ai10M12 proto 包名规范 — 核查通过
- **提请方**ai10
- **日期**2026-07-10
- **类型**:仲裁核查
- **描述**01-understanding.md M12 称"实际 `next_edu_cloud.msg.v1` 符合规范"。核查 [msg.proto](../../../packages/shared-proto/proto/msg.proto) L3`package next_edu_cloud.msg.v1;`,与 01-understanding.md 描述一致。
- **核查结论**:✅ 仲裁准确,但存在规则冲突(见 ISSUE-007
- **状态**:已裁决(核查通过)
### ISSUE-003-ai10M2 msg 必须有 Outbox — 核查通过
- **提请方**ai10
- **日期**2026-07-10
- **类型**:仲裁核查
- **描述**01-understanding.md M2 称"004 §7.2 明确 msg 生产 `edu.notification.events`msg 必须有 Outbox"。核查 004 §7.3 L638 `NotificationRequested` 事件Msg 投递通知到多渠道)+ known-issues §msg L346"Outbox 强制"。
- **核查结论**:✅ 仲裁准确msg 必须实现 OutboxP5 强制)
- **状态**:已裁决(核查通过)
### ISSUE-004-ai10core-edu 事件 topic 命名统一 — 核查部分通过
- **提请方**ai10
- **日期**2026-07-10
- **类型**:仲裁核查
- **描述**02-architecture-design.md §7.2 P11 称"coord 已仲裁采用 `edu.teaching.*` 新约定"。核查:
- 004 §7.2 L623-625 使用 `edu.teaching.assignment.submitted` / `edu.teaching.exam.published` / `edu.teaching.grade.recorded`(新约定)✅
- [events.proto](../../../packages/shared-proto/proto/events.proto) L9-13 注释仍用 `edu.exam.events` / `edu.homework.events`(旧约定)❌ 未同步
- [matrix.md](../matrix.md) §4 L112-115 使用 `edu.exam.events` / `edu.homework.events`(旧约定)❌ 未同步
- **核查结论**:⚠️ 仲裁已作出但未全量同步events.proto 注释与 matrix.md 仍用旧约定,需 coord 统一更新
- **状态**:待 coord 同步(见 ISSUE-008
### ISSUE-005-ai10Push Gateway 调用方向歧义 — 核查通过
- **提请方**ai10
- **日期**2026-07-10
- **类型**:仲裁核查
- **描述**02-architecture-design.md §7.2 P10 称"004 §4.1 写 PushGW→Msg实际是 Msg→PushGW"。核查 004 §4.1 L413`push-gateway → Msg | gRPC | 推送通道建立`,方向确实反了。实际流程是 msg 调 push-gateway 的 gRPC PushService.Push见 [notifications.service.ts](../../../services/msg/src/notifications/notifications.service.ts) L179 fetch POST /internal/push 降级实现)。
- **核查结论**:✅ 歧义确认,建议 coord 修正 004 §4.1 表述为"Msg → push-gateway (gRPC)"
- **状态**:待 coord 修正 004
---
## §1 新发现问题ai10 提请)
### ISSUE-006-ai10events.proto P9 字段描述不准确
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**02-architecture-design.md §7.2 P9 称"events.proto ExamEvent / HomeworkEvent / GradeEvent 需补 `class_id` / `student_ids[]` 字段"。核查 events.proto
- `ExamEvent` L32 **已有** `class_id` 字段 ✅
- `HomeworkEvent` L45 **已有** `class_id` 字段 ✅
- `GradeEvent` L50-59 **无** `class_id`(仅有 `student_id`)❌
- 三者均**无** `student_ids[]`(复数,用于 fan-out 广播)❌
- **建议方案**:修正 P9 表述为"`GradeEvent` 需补 `class_id`;全部事件需补 `student_ids[]` 字段msg fan-out 广播通知需要)"
- **状态**:待 coord 仲裁
### ISSUE-007-ai10proto 包名规则冲突project_rules vs 实际)
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**[project_rules §5](../../../.trae/rules/project_rules.md) 规定"包名规范:`edu.<domain>.v1`(如 `edu.iam.v1``edu.core_edu.v1`",但实际所有 proto 文件使用 `next_edu_cloud.<domain>.v1`(如 msg.proto L3 `next_edu_cloud.msg.v1`、events.proto L3 `next_edu_cloud.events.v1`。01-understanding.md 称"coord 已裁决采用 `next_edu_cloud.*`",但 project_rules §5 未同步更新,仍写 `edu.<domain>.v1`
- **建议方案**coord 统一裁决,二选一:
- 方案 A更新 project_rules §5 为 `next_edu_cloud.<domain>.v1`(与实际 proto 一致)
- 方案 B重命名所有 proto package 为 `edu.<domain>.v1`(与规则一致,但改动大)
- **状态**:待 coord 仲裁
### ISSUE-008-ai10Kafka topic 命名三套约定并存
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**msg 相关的 Kafka topic 命名存在三套约定:
- **约定 A004 §7.2per-event topic**`edu.identity.user.created` / `edu.teaching.exam.published` / `edu.notification.sent`
- **约定 Bmatrix.md §4 + events.proto 注释aggregate topic**`edu.iam.user.events` / `edu.exam.events` / `edu.notification.requested`
- **约定 Cmsg_contract.md §1.4aggregate topic + action 字段)**`edu.msg.notification.events`action: sent/read/recalled/failed
- 02-architecture-design.md §5.1/§5.2 采用约定 Amsg_contract.md §1.4 采用约定 Cmatrix.md 采用约定 B。known-issues §全局 L182 已标记此冲突。
- **建议方案**coord 统一为一套约定。ai10 倾向约定 Aper-event topic理由
- 004 §7.2 已采用,是架构设计意图唯一源
- per-event topic 便于消费者按需订阅,避免反序列化无关事件
- 与 NotificationSent / NotificationRead 等事件命名PascalCase对齐
- **状态**:待 coord 仲裁
### ISSUE-009-ai10RPC 数量超预算17 vs 13
- **提请方**ai10
- **日期**2026-07-10
- **类型**:工作量超批
- **描述**[ai-allocation.md §3.2](../../ai-allocation.md) L112 与 [matrix.md](../matrix.md) §2 L90 均规定 msg 为"3 Service 13 RPC"。但 02-architecture-design.md §4.2 列出 17 RPC
- NotificationService 9 RPCSendNotification / BatchSendNotification / ListNotifications / GetUnreadCount / MarkAsRead / BatchMarkAsRead / MarkAllAsRead / SearchNotifications / RecallNotification
- NotificationPreferenceService 2 RPCGetPreferences / UpdatePreferences
- NotificationTemplateService 6 RPCCreateTemplate / GetTemplate / ListTemplates / UpdateTemplate / DeleteTemplate / RenderTemplate
- 而 msg_contract.md §1.1 列出 13 RPC分布不同5+4+4两文档互相不一致
- **建议方案**coord 裁决 RPC 范围,二选一:
- 方案 A维持 13 RPC 预算02-architecture-design.md 裁剪至 13移除 BatchSendNotification / GetUnreadCount / BatchMarkAsRead / MarkAllAsRead / UpdateTemplate / DeleteTemplate降级为 REST only 或合并)
- 方案 B放宽至 17 RPC同步更新 ai-allocation.md + matrix.md + msg_contract.md
- **状态**:待 coord 仲裁
### ISSUE-010-ai10markAsRead 权限点与设计不一致
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**[notifications.controller.ts](../../../services/msg/src/notifications/notifications.controller.ts) L74 markAsRead 使用 `MSG_NOTIFICATION_MANAGE` 权限,但 02-architecture-design.md §6.1 L730 规定 markAsRead 应使用 `MSG_NOTIFICATION_READ`。MANAGE 权限通常给管理员,学生标记自己通知已读不应需要 MANAGE 权限。
- **建议方案**:以 02-architecture-design.md §6.1 为准READP5 实现时修正 controller 权限点
- **状态**:待 coord 确认
### ISSUE-011-ai10DB→ES 降级方向与 ai-allocation §5 相反
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**
- [ai-allocation.md §5](../../ai-allocation.md) ai10 设计重点要求"ES 降级查询策略(**DB 不可用时走 ES 索引**"——即 DB 故障时 ES 作为读模型兜底
- 02-architecture-design.md §3.2.2 / §3.4 描述"**ES 不可用时降级到 MySQL LIKE 查询**"——即 ES 故障时 DB 兜底
- 01-understanding.md M16 称"无 DB→ES 降级读路径"
- 三处描述方向相反,需统一
- **建议方案**ai10 倾向双向降级(两种故障场景都覆盖):
- ES 故障 → DB LIKE 查询(设计文档已覆盖)
- DB 故障 → ES 只读模式ai-allocation 要求,设计文档需补充)
- 但 DB 故障时写操作无法降级(必须等 DB 恢复),仅读操作可走 ES
- **状态**:待 coord 仲裁
### ISSUE-012-ai10设计文档缺 DLQ 与三层幂等防线
- **提请方**ai10
- **日期**2026-07-10
- **类型**:前置依赖缺失
- **描述**[known-issues §msg](../../../docs/troubleshooting/known-issues.md) L344 / L356 已记录两项 ai10 设计点,但 02-architecture-design.md 未覆盖:
- **三层幂等防线**L344L1 Redis SETNX / L2 msg_idempotency 表 / L3 notifications.source_event_id 唯一索引。设计文档 §5.5 仅描述两层Redis + DB UNIQUE缺中间层 msg_idempotency 表
- **死信队列**L356消费失败超 3 次投递 `edu.notification.dlq`。设计文档 §5 完全未提及 DLQ 设计
- **建议方案**02-architecture-design.md 补充:
- §3.1 补 `msg_idempotency` 表 schema中间层
- §5.5 改为三层幂等防线
- §5 补 DLQ 设计(重试 3 次后投递 `edu.notification.dlq` + 告警)
- **状态**:待 coord 确认非阻塞ai10 自行补充设计文档即可)
### ISSUE-013-ai10events.proto 缺 4 类 message 阻塞 msg 消费
- **提请方**ai10
- **日期**2026-07-10
- **类型**:前置依赖缺失
- **描述**[events.proto](../../../packages/shared-proto/proto/events.proto) 仅有 ClassEvent / ExamEvent / HomeworkEvent / GradeEvent 4 个 message。msg 消费还需要:
- `UserEvent`iam 发布 user.created/updated/deleted/role_changed— 阻塞欢迎通知/角色变更通知
- `RoleEvent`iam 发布 role.created/updated— 阻塞角色变更通知
- `MasteryEvent`data-ana 发布 mastery.updated— 阻塞学情预警通知
- `NotificationEvent`msg 发布 notification.sent/read/recalled/failed— 阻塞 push-gateway 消费 msg 事件
- **建议方案**coord 维护 shared-proto在 P5 启动前补齐这 4 个 message。msg 在 proto 补齐前用通用 JSON payload 解析A6 假设)
- **状态**:待 coord 仲裁(🔴 阻塞 P5 消费链路)
### ISSUE-014-ai10msg_contract.md 与 02-architecture-design.md RPC 清单不一致
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**:两文档 RPC 清单存在差异:
- msg_contract.md 独有02 缺GetPreferenceByChannel、ListPreferences
- 02-architecture-design.md 独有contract 缺BatchSendNotification、GetUnreadCount、BatchMarkAsRead、MarkAllAsRead、UpdateTemplate、DeleteTemplate
- 即使忽略 ISSUE-009 的数量问题,两文档的 RPC 组合也不同
- **建议方案**:待 ISSUE-009 仲裁后,统一两文档 RPC 清单
- **状态**:待 coord 仲裁(依赖 ISSUE-009
### ISSUE-015-ai10msg_contract.md Kafka 发布事件与设计文档不一致
- **提请方**ai10
- **日期**2026-07-10
- **类型**:契约不明确
- **描述**
- msg_contract.md §1.4`edu.msg.notification.events` topic单一 NotificationEvent 含 action 字段
- 02-architecture-design.md §5.24 个 per-event topic`edu.notification.sent` / `edu.notification.read` / `edu.notification.recalled` / `edu.notification.failed`
- matrix.md §4 L118`edu.notification.requested`(第三种命名)
- **建议方案**:待 ISSUE-008 仲裁 topic 命名约定后统一
- **状态**:待 coord 仲裁(依赖 ISSUE-008
---
## §2 仲裁结论2026-07-10 coord
> 详见 [coord.md §10 ARB-008](../coord.md#10-arb-008msg-模块-15-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ------- | ------------------------------------------------------------------------------------------------------------- | ------------ |
| 001~005 | ✅ 核查通过001/002/003004 待 coord 同步 events.protoARB-006005 待 coord 修正 004 §4.1 PushGW 方向 | coord |
| 006 | ✅ coord 补全 GradeEvent class_id + 全部事件 student_ids[]ARB-011 | coord |
| 007 | ✅ 统一 `next_edu_cloud.<domain>.v1`ARB-011 | coord |
| 008 | ✅ msg 采用具体动作 topicARB-013 | coord |
| 009 | ✅ 维持 13 RPC裁剪 4 RPC 降级 REST | ai10 |
| 010 | ✅ markAsRead 权限改为 `MSG_NOTIFICATION_READ` | ai10 |
| 011 | ✅ 双向降级ES 故障→DB LIKEDB 故障→ES 只读) | ai10 |
| 012 | ✅ 非阻塞ai10 补 DLQ + 三层幂等设计文档 | ai10 |
| 013 | ✅ coord 补全 events.protoARB-011NotificationEvent + MasteryEvent | coord |
| 014 | ✅ 统一 13 RPC两文档对齐 | ai10 |
| 015 | ✅ 统一 topic 命名ARB-013 | ai10 + coord |