# msg 对接契约

> 负责人：ai10
> 关联：[matrix.md](./matrix.md)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)

---

## §1 我提供什么（对外接口）

### 1.1 gRPC 接口（如有）

| Service                       | RPC                    | 请求                          | 响应                        | 端口  |
| ----------------------------- | ---------------------- | ----------------------------- | --------------------------- | ----- |
| NotificationService           | SendNotification       | SendNotificationRequest       | Notification                | 50056 |
| NotificationService           | ListNotifications      | ListNotificationsRequest      | ListNotificationsResponse   | 50056 |
| NotificationService           | MarkAsRead             | MarkAsReadRequest             | MarkAsReadResponse          | 50056 |
| NotificationService           | SearchNotifications    | SearchNotificationsRequest    | SearchNotificationsResponse | 50056 |
| NotificationService           | RecallNotification     | RecallNotificationRequest     | RecallNotificationResponse  | 50056 |
| NotificationPreferenceService | GetPreference          | GetPreferenceRequest          | NotificationPreference      | 50056 |
| NotificationPreferenceService | UpdatePreference       | UpdatePreferenceRequest       | NotificationPreference      | 50056 |
| NotificationPreferenceService | GetPreferenceByChannel | GetPreferenceByChannelRequest | ChannelPreference           | 50056 |
| NotificationPreferenceService | ListPreferences        | ListPreferencesRequest        | ListPreferencesResponse     | 50056 |
| NotificationTemplateService   | CreateTemplate         | CreateTemplateRequest         | NotificationTemplate        | 50056 |
| NotificationTemplateService   | GetTemplate            | GetTemplateRequest            | NotificationTemplate        | 50056 |
| NotificationTemplateService   | ListTemplates          | ListTemplatesRequest          | ListTemplatesResponse       | 50056 |
| NotificationTemplateService   | RenderTemplate         | RenderTemplateRequest         | RenderedTemplate            | 50056 |

### 1.2 HTTP 端点（如有）

无对外 HTTP 端点，仅 gRPC。

### 1.3 GraphQL schema（如 BFF）

不适用。

### 1.4 Kafka 事件发布（如有）

| Topic                       | Event                                                  | 消费方                  |
| --------------------------- | ------------------------------------------------------ | ----------------------- |
| edu.msg.notification.events | NotificationEvent（action: sent/read/recalled/failed） | push-gateway / data-ana |

### 1.5 错误码前缀

`MSG_`（如 MSG_TEMPLATE_NOT_FOUND、MSG_CHANNEL_DISABLED、MSG_RATE_LIMITED）

---

## §2 我消费什么（依赖上游）

### 2.1 gRPC 调用（同步）

无主动 gRPC 调用上游。msg 通过 Kafka 事件被动接收业务事件后触发通知。

### 2.2 Kafka 事件订阅（异步）

| Topic                       | Event                                                     | 发布方          | mock 策略                                               |
| --------------------------- | --------------------------------------------------------- | --------------- | ------------------------------------------------------- |
| edu.iam.user.events         | UserEvent                                                 | iam (ai06)      | iam 就绪前使用本地用户偏好默认值                        |
| edu.exam.events             | ExamEvent（action: created/updated/deleted）              | core-edu (ai08) | core-edu 就绪前不订阅，使用本地 stub 事件触发 mock 通知 |
| edu.homework.events         | HomeworkEvent（action: assigned/submitted/graded）        | core-edu (ai08) | 同上                                                    |
| edu.grade.events            | GradeEvent（action: recorded/updated）                    | core-edu (ai08) | 同上                                                    |
| edu.class.events            | ClassEvent（action: transferred）                         | core-edu (ai08) | 同上                                                    |
| edu.data_ana.mastery.events | MasteryEvent（action: mastery.updated/warning.triggered） | data-ana (ai11) | data-ana 就绪前不订阅，预警通知使用本地 stub            |

### 2.3 HTTP 调用（如有）

无。

---

## §3 就绪信号

### 3.1 我依赖的上游就绪标志

- [ ] iam gRPC 50052 启用（ai06）—— 用于用户通知偏好查询（可选）
- [ ] core-edu gRPC 50053 启用（ai08）—— 业务事件来源
- [ ] edu.exam.events / edu.homework.events / edu.grade.events / edu.class.events topic 有事件发布（ai08）
- [ ] data-ana gRPC 50055 启用（ai11）—— 预警事件来源
- [ ] edu.data_ana.mastery.events topic 有事件发布（ai11）

### 3.2 我的就绪标志（供下游消费）

- [ ] msg gRPC 50056 启用（HealthService.Check 返回 SERVING）
- [ ] NotificationService 5 RPC 可调用
- [ ] NotificationPreferenceService 4 RPC 可调用
- [ ] NotificationTemplateService 4 RPC 可调用（含 RenderTemplate 模板渲染）
- [ ] edu.msg.notification.events topic 可发布（供 push-gateway 推送）

---

## §4 Mock 策略

### 4.1 我提供的 mock

在 msg 真实服务就绪前，为下游（teacher-bff / student-bff / parent-bff / push-gateway）提供以下 mock：

- **gRPC mock**：使用 grpc-mock 拦截 50056 端口
  - NotificationService.ListNotifications 返回固定 10 条未读通知
  - NotificationService.MarkAsRead 返回 success=true
  - NotificationPreferenceService.GetPreference 返回默认偏好（in_app+email 开启，sms+push 关闭）
  - NotificationTemplateService.RenderTemplate 返回固定 title+content
- **Kafka mock**：msg 就绪前不发布真实 NotificationEvent，push-gateway 使用本地 stub 推送

### 4.2 我消费的 mock

在真实上游就绪前，msg 使用以下 mock：

- 业务事件：core-edu/data-ana 就绪前，msg 内置定时器发布本地 stub 事件（ExamEvent/HomeworkEvent），触发 mock 通知流程
- 用户偏好：iam 就绪前使用默认偏好（所有用户 in_app 开启）
- 模板渲染：内置 5 个常用模板（exam.created / homework.assigned / grade.recorded / warning.triggered / system.notice）
