# parent-portal 对接契约

> 负责人：ai15
> 关联：[matrix.md](./matrix.md)

---

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

### 1.1 gRPC 接口（如有）

无。parent-portal 是前端微前端 Remote。

### 1.2 HTTP 端点（如有）

| Method | Path                  | 用途         | 认证                                  |
| ------ | --------------------- | ------------ | ------------------------------------- |
| GET    | /                     | 家长门户首页 | JWT 必需（前端路由守卫）              |
| GET    | /children             | 我的孩子列表 | JWT 必需                              |
| GET    | /child/:id/summary    | 孩子概况     | JWT 必需 + 数据范围校验（仅自己孩子） |
| GET    | /child/:id/grades     | 孩子成绩     | JWT 必需 + 数据范围校验               |
| GET    | /child/:id/attendance | 孩子考勤     | JWT 必需 + 数据范围校验               |
| GET    | /child/:id/homework   | 孩子作业     | JWT 必需 + 数据范围校验               |
| GET    | /child/:id/weakness   | 孩子薄弱点   | JWT 必需 + 数据范围校验               |
| GET    | /notifications        | 通知中心     | JWT 必需                              |

### 1.3 GraphQL schema（如 BFF）

不适用。parent-portal 消费 parent-bff GraphQL，自身不提供 schema。

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

无。

### 1.5 错误码前缀

无（前端不定义错误码前缀，透传 BFF 错误码）。

### 1.6 微前端架构（补充）

| 角色                   | 说明                                             |
| ---------------------- | ------------------------------------------------ |
| MF Remote              | 家长门户是微前端远程模块                         |
| 暴露的 remote 模块     | ParentApp（家长端完整应用）、shared 家长端组件   |
| module federation 配置 | `apps/parent-portal/module-federation.config.ts` |

---

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

### 2.1 gRPC 调用（同步）

无。前端不直接调 gRPC。

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

无。前端不直接订阅 Kafka。

### 2.3 HTTP 调用（如有）

| 被调用方            | Method.Path              | 用途                                         | mock 策略                                                        |
| ------------------- | ------------------------ | -------------------------------------------- | ---------------------------------------------------------------- |
| api-gateway (ai01)  | POST /api/parent/graphql | 家长 GraphQL 查询（经网关代理到 parent-bff） | api-gateway/parent-bff 就绪前使用 MSW 拦截返回 mock GraphQL 响应 |
| api-gateway (ai01)  | POST /api/auth/login     | 家长登录                                     | api-gateway 就绪前使用 MSW 返回固定 JWT                          |
| push-gateway (ai02) | GET /ws                  | WebSocket 实时通知                           | push-gateway 就绪前使用 mock-socket 模拟 WS 推送                 |

### 2.4 GraphQL 查询域（经 api-gateway 代理到 parent-bff）

| Query/Mutation               | 用途                 | mock 策略                     |
| ---------------------------- | -------------------- | ----------------------------- |
| currentUser                  | 当前家长信息         | MSW 返回固定家长              |
| myChildren                   | 我的孩子列表（核心） | MSW 返回固定 2 个孩子         |
| childSummary                 | 孩子概况             | MSW 返回固定仪表盘            |
| childGrades                  | 孩子成绩             | MSW 返回固定 5 个成绩         |
| childAttendance              | 孩子考勤             | MSW 返回固定 10 条考勤        |
| childHomework                | 孩子作业             | MSW 返回固定 3 个作业         |
| childWeakness                | 孩子薄弱点           | MSW 返回固定 3 个 weak_points |
| childTrend                   | 孩子学习趋势         | MSW 返回固定趋势数据          |
| myNotifications / markAsRead | 通知中心             | MSW 返回固定通知              |

---

## §3 就绪信号

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

- [ ] api-gateway HTTP :8080 启用（ai01）—— 前端请求入口
- [ ] parent-bff GraphQL :3010 启用（ai05）—— 数据来源
- [ ] push-gateway WebSocket :8081/ws 启用（ai02）—— 实时通知

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

- [ ] parent-portal dev server :4002 启用
- [ ] MF Remote 可被 AppShell 加载（暴露 ParentApp 模块）
- [ ] 独立壳渲染（首页 + 导航 + 路由守卫）
- [ ] 登录流程可用（POST /api/auth/login 获取 JWT 存入 cookie）
- [ ] GraphQL 查询可执行（currentUser / myChildren / childSummary 返回数据）
- [ ] 数据范围校验生效（前端路由守卫校验 child:id 是否在 myChildren 返回列表中）
- [ ] WebSocket 通知可接收

---

## §4 Mock 策略

### 4.1 我提供的 mock

parent-portal 是前端，无下游消费方。但对开发体验提供：

- **Storybook**：各组件独立 story
- **MSW handlers**：`apps/parent-portal/src/mocks/handlers.ts`，拦截所有 GraphQL/HTTP 请求

### 4.2 我消费的 mock

在真实上游就绪前，parent-portal 使用以下 mock：

- **HTTP/GraphQL mock**：使用 MSW 拦截所有请求
  - POST /api/auth/login → 返回固定 JWT + UserInfo（parent 角色）
  - POST /api/parent/graphql → 根据 operationName 返回对应 mock 响应（与 parent-bff mock 数据一致）
  - myChildren mock 必须返回固定 2 个孩子（id="student-001" + "student-002"），与其他 child* 查询的 student_id 一致
  - 所有 mock 响应定义在 `apps/parent-portal/src/mocks/fixtures/*.json`
- **WebSocket mock**：使用 mock-socket 库
  - 连接后每 30 秒推送 1 条 mock 通知
- **JWT mock**：使用固定 mock JWT，存入 httpOnly cookie
- **环境切换**：通过 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制，上游就绪后设为 `disabled`
