# student-portal 对接契约

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

---

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

### 1.1 gRPC 接口（如有）

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

### 1.2 HTTP 端点（如有）

| Method | Path           | 用途         | 认证                     |
| ------ | -------------- | ------------ | ------------------------ |
| GET    | /              | 学生门户首页 | JWT 必需（前端路由守卫） |
| GET    | /my-classes    | 我的班级     | JWT 必需                 |
| GET    | /my-exams      | 我的考试     | JWT 必需                 |
| GET    | /my-homework   | 我的作业     | JWT 必需                 |
| GET    | /my-grades     | 我的成绩     | JWT 必需                 |
| GET    | /my-attendance | 我的考勤     | JWT 必需                 |
| GET    | /learning-path | 学习路径     | JWT 必需                 |
| GET    | /dashboard     | 学生仪表盘   | JWT 必需                 |
| GET    | /notifications | 通知中心     | JWT 必需                 |

### 1.3 GraphQL schema（如 BFF）

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

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

无。

### 1.5 错误码前缀

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

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

| 角色                   | 说明                                                              |
| ---------------------- | ----------------------------------------------------------------- |
| MF Remote              | 学生门户是微前端远程模块，由 teacher-portal AppShell 或独立壳加载 |
| 暴露的 remote 模块     | StudentApp（学生端完整应用）、shared 学生端组件                   |
| module federation 配置 | `apps/student-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/student/graphql | 学生 GraphQL 查询（经网关代理到 student-bff） | api-gateway/student-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 代理到 student-bff）

| Query/Mutation                      | 用途            | mock 策略                                          |
| ----------------------------------- | --------------- | -------------------------------------------------- |
| currentUser                         | 当前学生信息    | MSW 返回固定学生                                   |
| myClasses                           | 我的班级        | MSW 返回固定 1 个班级                              |
| myExams                             | 我的考试        | MSW 返回固定 2 个考试                              |
| myHomework / submitHomework         | 我的作业 + 提交 | MSW 返回固定作业 + submitHomework success          |
| myGrades                            | 我的成绩        | MSW 返回固定 5 个成绩                              |
| myAttendance                        | 我的考勤        | MSW 返回固定 10 条考勤                             |
| textbooks / chapters / learningPath | 学习内容        | MSW 返回固定内容 + 学习路径                        |
| studentDashboard                    | 学生仪表盘      | MSW 返回固定仪表盘（avg_score=85.0, class_rank=5） |
| myWeakness                          | 我的薄弱点      | MSW 返回固定 3 个 weak_points                      |
| myTrend                             | 学习趋势        | MSW 返回固定趋势数据                               |
| myNotifications / markAsRead        | 通知中心        | MSW 返回固定通知                                   |

---

## §3 就绪信号

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

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

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

- [ ] student-portal dev server :4001 启用
- [ ] MF Remote 可被 AppShell 加载（暴露 StudentApp 模块）
- [ ] 独立壳渲染（首页 + 导航 + 路由守卫）
- [ ] 登录流程可用（POST /api/auth/login 获取 JWT 存入 cookie）
- [ ] GraphQL 查询可执行（currentUser / myClasses / studentDashboard 返回数据）
- [ ] WebSocket 通知可接收

---

## §4 Mock 策略

### 4.1 我提供的 mock

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

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

### 4.2 我消费的 mock

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

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