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
14 KiB
14 KiB
msg 问题记录
负责人:ai10 关联:coord.md、contracts/msg_contract.md 规则:AI 遇到问题时在此追加条目,coord 仲裁后更新状态
§0 已有仲裁核查(ai10 复核)
本节核查 01-understanding.md / 02-architecture-design.md 中引用的已有仲裁,对照源码/proto 验证准确性。
ISSUE-001-ai10:M8 ZodError 已修复 — 核查通过
- 提请方:ai10
- 日期:2026-07-10
- 类型:仲裁核查
- 描述:01-understanding.md M8 称"GlobalErrorFilter 已识别 ZodError 返回 400"。核查 global-error.filter.ts L32-42:
else if (exception instanceof ZodError) { statusCode = 400; ... },确实已处理,返回MSG_VALIDATION_ERROR+ 400。 - 核查结论:✅ 仲裁准确,M8 标记"已修复"无误
- 状态:已裁决(核查通过,无需处理)
ISSUE-002-ai10:M12 proto 包名规范 — 核查通过
- 提请方:ai10
- 日期:2026-07-10
- 类型:仲裁核查
- 描述:01-understanding.md M12 称"实际
next_edu_cloud.msg.v1符合规范"。核查 msg.proto L3:package next_edu_cloud.msg.v1;,与 01-understanding.md 描述一致。 - 核查结论:✅ 仲裁准确,但存在规则冲突(见 ISSUE-007)
- 状态:已裁决(核查通过)
ISSUE-003-ai10:M2 msg 必须有 Outbox — 核查通过
- 提请方:ai10
- 日期:2026-07-10
- 类型:仲裁核查
- 描述:01-understanding.md M2 称"004 §7.2 明确 msg 生产
edu.notification.events,msg 必须有 Outbox"。核查 004 §7.3 L638NotificationRequested事件(Msg 投递通知到多渠道)+ known-issues §msg L346"Outbox 强制"。 - 核查结论:✅ 仲裁准确,msg 必须实现 Outbox(P5 强制)
- 状态:已裁决(核查通过)
ISSUE-004-ai10:core-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 L9-13 注释仍用
edu.exam.events/edu.homework.events(旧约定)❌ 未同步 - matrix.md §4 L112-115 使用
edu.exam.events/edu.homework.events(旧约定)❌ 未同步
- 004 §7.2 L623-625 使用
- 核查结论:⚠️ 仲裁已作出但未全量同步,events.proto 注释与 matrix.md 仍用旧约定,需 coord 统一更新
- 状态:待 coord 同步(见 ISSUE-008)
ISSUE-005-ai10:Push 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 L179 fetch POST /internal/push 降级实现)。 - 核查结论:✅ 歧义确认,建议 coord 修正 004 §4.1 表述为"Msg → push-gateway (gRPC)"
- 状态:待 coord 修正 004
§1 新发现问题(ai10 提请)
ISSUE-006-ai10:events.proto P9 字段描述不准确
- 提请方:ai10
- 日期:2026-07-10
- 类型:契约不明确
- 描述:02-architecture-design.md §7.2 P9 称"events.proto ExamEvent / HomeworkEvent / GradeEvent 需补
class_id/student_ids[]字段"。核查 events.proto:ExamEventL32 已有class_id字段 ✅HomeworkEventL45 已有class_id字段 ✅GradeEventL50-59 无class_id(仅有student_id)❌- 三者均无
student_ids[](复数,用于 fan-out 广播)❌
- 建议方案:修正 P9 表述为"
GradeEvent需补class_id;全部事件需补student_ids[]字段(msg fan-out 广播通知需要)" - 状态:待 coord 仲裁
ISSUE-007-ai10:proto 包名规则冲突(project_rules vs 实际)
- 提请方:ai10
- 日期:2026-07-10
- 类型:契约不明确
- 描述:project_rules §5 规定"包名规范:
edu.<domain>.v1(如edu.iam.v1、edu.core_edu.v1)",但实际所有 proto 文件使用next_edu_cloud.<domain>.v1(如 msg.proto L3next_edu_cloud.msg.v1、events.proto L3next_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(与规则一致,但改动大)
- 方案 A:更新 project_rules §5 为
- 状态:待 coord 仲裁
ISSUE-008-ai10:Kafka topic 命名三套约定并存
- 提请方:ai10
- 日期:2026-07-10
- 类型:契约不明确
- 描述:msg 相关的 Kafka topic 命名存在三套约定:
- 约定 A(004 §7.2,per-event topic):
edu.identity.user.created/edu.teaching.exam.published/edu.notification.sent - 约定 B(matrix.md §4 + events.proto 注释,aggregate topic):
edu.iam.user.events/edu.exam.events/edu.notification.requested - 约定 C(msg_contract.md §1.4,aggregate topic + action 字段):
edu.msg.notification.events(action: sent/read/recalled/failed) - 02-architecture-design.md §5.1/§5.2 采用约定 A;msg_contract.md §1.4 采用约定 C;matrix.md 采用约定 B。known-issues §全局 L182 已标记此冲突。
- 约定 A(004 §7.2,per-event topic):
- 建议方案:coord 统一为一套约定。ai10 倾向约定 A(per-event topic),理由:
- 004 §7.2 已采用,是架构设计意图唯一源
- per-event topic 便于消费者按需订阅,避免反序列化无关事件
- 与 NotificationSent / NotificationRead 等事件命名(PascalCase)对齐
- 状态:待 coord 仲裁
ISSUE-009-ai10:RPC 数量超预算(17 vs 13)
- 提请方:ai10
- 日期:2026-07-10
- 类型:工作量超批
- 描述:ai-allocation.md §3.2 L112 与 matrix.md §2 L90 均规定 msg 为"3 Service 13 RPC"。但 02-architecture-design.md §4.2 列出 17 RPC:
- NotificationService 9 RPC(SendNotification / BatchSendNotification / ListNotifications / GetUnreadCount / MarkAsRead / BatchMarkAsRead / MarkAllAsRead / SearchNotifications / RecallNotification)
- NotificationPreferenceService 2 RPC(GetPreferences / UpdatePreferences)
- NotificationTemplateService 6 RPC(CreateTemplate / 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-ai10:markAsRead 权限点与设计不一致
- 提请方:ai10
- 日期:2026-07-10
- 类型:契约不明确
- 描述: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 为准(READ),P5 实现时修正 controller 权限点
- 状态:待 coord 确认
ISSUE-011-ai10:DB→ES 降级方向与 ai-allocation §5 相反
- 提请方:ai10
- 日期:2026-07-10
- 类型:契约不明确
- 描述:
- ai-allocation.md §5 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 L344 / L356 已记录两项 ai10 设计点,但 02-architecture-design.md 未覆盖:
- 三层幂等防线(L344):L1 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+ 告警)
- §3.1 补
- 状态:待 coord 确认(非阻塞,ai10 自行补充设计文档即可)
ISSUE-013-ai10:events.proto 缺 4 类 message 阻塞 msg 消费
- 提请方:ai10
- 日期:2026-07-10
- 类型:前置依赖缺失
- 描述: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-ai10:msg_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-ai10:msg_contract.md Kafka 发布事件与设计文档不一致
- 提请方:ai10
- 日期:2026-07-10
- 类型:契约不明确
- 描述:
- msg_contract.md §1.4:
edu.msg.notification.eventstopic,单一 NotificationEvent 含 action 字段 - 02-architecture-design.md §5.2:4 个 per-event topic(
edu.notification.sent/edu.notification.read/edu.notification.recalled/edu.notification.failed) - matrix.md §4 L118:
edu.notification.requested(第三种命名)
- msg_contract.md §1.4:
- 建议方案:待 ISSUE-008 仲裁 topic 命名约定后统一
- 状态:待 coord 仲裁(依赖 ISSUE-008)
§2 仲裁结论(2026-07-10 coord)
| ISSUE | 仲裁结论 | 执行方 |
|---|---|---|
| 001~005 | ✅ 核查通过(001/002/003);004 待 coord 同步 events.proto(ARB-006);005 待 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 采用具体动作 topic(ARB-013) | coord |
| 009 | ✅ 维持 13 RPC,裁剪 4 RPC 降级 REST | ai10 |
| 010 | ✅ markAsRead 权限改为 MSG_NOTIFICATION_READ |
ai10 |
| 011 | ✅ 双向降级(ES 故障→DB LIKE;DB 故障→ES 只读) | ai10 |
| 012 | ✅ 非阻塞,ai10 补 DLQ + 三层幂等设计文档 | ai10 |
| 013 | ✅ coord 补全 events.proto(ARB-011:NotificationEvent + MasteryEvent) | coord |
| 014 | ✅ 统一 13 RPC,两文档对齐 | ai10 |
| 015 | ✅ 统一 topic 命名(ARB-013) | ai10 + coord |