# Student Portal — 下游依赖工作（Next Steps）

> 生成时间：2026-07-13
> 生成者：ai14（student-portal）
> 最近更新：2026-07-13（添加 Docker 测试验证结果）

## 0. Docker 构建验证（已完成）

student-portal Docker 镜像已在本地 Docker Desktop 验证通过：

- **镜像名**：`edu/student-portal:test`
- **构建命令**：`docker build -t edu/student-portal:test -f apps/student-portal/Dockerfile --build-arg NEXT_PUBLIC_API_MOCKING=disabled .`
- **端口**：4001
- **MSW 状态**：生产构建默认 `disabled`（无 mock 数据）
- **健康检查**：`GET /api/health` → 200
- **Dockerfile 改进**：
  - 添加 `ARG NEXT_PUBLIC_API_MOCKING=disabled` 构建参数（生产默认关闭 MSW）
  - 添加 `ARG NEXT_PUBLIC_MF_ENABLED=false` 构建参数（独立壳模式）
  - 拷贝 `tsconfig.base.json`（TypeScript 配置基线）
  - 拷贝 `packages/` 下 5 个 workspace 共享包源码（contracts/hooks/ui-components/ui-tokens/shared-ts）

### Docker 测试结果

| 验证项 | 状态 |
|--------|------|
| `pnpm typecheck` | ✅ 0 errors |
| `pnpm lint` | ✅ 0 errors |
| `pnpm test` | ✅ 481/481 passed |
| `pnpm build`（本地） | ✅ 31 routes generated |
| `docker build` | ✅ 镜像构建成功 |
| `docker run` + healthcheck | ✅ /api/health 返回 200 |

### 无 mock 数据运行说明

生产镜像中 MSW 已禁用，所有 GraphQL 请求将走真实 API。在后端（student-bff）未就绪前：
- 页面能正常渲染（SSR + 客户端 hydration）
- API 调用将失败并显示错误状态（ActionState fail 信封）
- 健康检查端点 `/api/health` 正常工作

## 1. student-bff 后端实现（ai04）

student-portal 前端已实现 57 个 GraphQL 操作（35 查询 + 22 变更），需要 student-bff 后端逐一实现对应 resolver。

### 必须实现的 GraphQL 操作清单

#### P3 核心（必须先完成）
| 操作 | 类型 | 说明 |
|------|------|------|
| currentUser | query | 当前学生信息 + 权限 + 视口 |
| myClasses | query | 我的班级列表 |
| myExams | query | 我的考试列表 |
| examDetail | query | 考试详情（含题目） |
| myHomework | query | 我的作业列表 |
| homeworkDetail | query | 作业详情 |
| myGrades | query | 我的成绩列表 |
| myAttendance | query | 我的考勤 |
| studentDashboard | query | 学生仪表盘聚合 |
| serverTime | query | 服务器时间（倒计时校正） |
| submitHomework | mutation | 提交作业 |
| submitExam | mutation | 提交考试（含幂等 key） |
| saveExamDraft | mutation | 保存考试草稿 |
| recordExamViolation | mutation | 记录防作弊违规 |
| recordPasteEvent | mutation | 记录粘贴事件 |

#### P3 扩展
| mySchedule | query | 我的课表（周视图） |
| studentGrowth | query | 成长曲线（vs 班级平均） |
| assignmentAnalysis | query | 作业分析 |
| myProfile | query | 个人资料 |
| updateProfile | mutation | 更新个人资料 |
| changePassword | mutation | 修改密码 |
| requestExtension | mutation | 作业延期申请 |
| joinClass | mutation | 加入班级 |
| leaveClass | mutation | 退出班级 |

#### P4 学习
| textbooks | query | 教材列表 |
| chapters | query | 章节目录 |
| learningPath | query | 学习路径 |
| myWeakness | query | 薄弱知识点 |
| myTrend | query | 学习趋势 |
| myMasterySummary | query | 掌握度概览 |
| myDiagnosticReports | query | 诊断报告 |
| myErrorBook | query | 错题本 |
| addErrorBookItem | mutation | 添加错题 |
| updateErrorBookItem | mutation | 更新错题 |
| deleteErrorBookItem | mutation | 删除错题 |

#### P5 校园生活
| myNotifications | query | 通知列表 |
| markAsRead | mutation | 标记已读 |
| markAllAsRead | mutation | 全部已读 |
| updateNotificationPreference | mutation | 更新通知偏好 |
| announcements | query | 公告列表 |
| announcementDetail | query | 公告详情 |
| markAnnouncementRead | mutation | 标记公告已读 |
| myLeaveRequests | query | 请假记录 |
| createLeaveRequest | mutation | 创建请假 |
| cancelLeaveRequest | mutation | 取消请假 |
| myElectiveSelections | query | 我的选课 |
| availableElectiveCourses | query | 可选课程 |
| selectElectiveCourse | mutation | 选课 |
| dropElectiveCourse | mutation | 退选 |
| myLessonPlans | query | 课案列表 |
| lessonPlanDetail | query | 课案详情 |
| myCoursePlans | query | 课程计划列表 |
| coursePlanDetail | query | 课程计划详情 |
| myReportCard | query | 成绩报告卡 |
| myPracticeSessions | query | 练习会话列表 |
| startPracticeSession | query | 启动练习 |
| submitPracticeAnswer | mutation | 提交练习答案 |

### 关键约束
- 所有 Query 不接受 `studentId` 参数，由 Resolver 从 JWT `x-user-id` 提取（ARB-019 §21.7）
- 所有响应包裹 ActionState 信封（ok/fail/degraded 三态）
- 路径统一为 `POST /api/v1/student/graphql`（ARB-019 §21）
- 附件上传走 REST `POST /api/v1/student/upload`（ARB-019 §21.5 方案 A）

## 2. api-gateway 路由配置（ai01）

- `/api/v1/student/*` → `student-bff:3009/*`（ARB-019 §21 已裁决）
- `/api/v1/student/upload` → 对象存储 + signed URL

## 3. push-gateway WebSocket 事件（ai10）

- `ExamExtended`：教师延长考试（ARB-019 §21.6 已确认）
- `ExamForceSubmitted`：教师强制收卷（ARB-019 §21.6 已确认）
- `ExamQuestionReordered`：教师调整题目顺序（P4 评估）

## 4. 共享 schema 文件（ai04）

- `packages/shared-ts/contracts/graphql/student-bff.graphql` 需创建（ARB-019 §21 已裁决）
- 包含全部 57 个操作的 schema 定义

## 5. Module Federation Shell 集成（ai02）

- teacher-portal 作为 Shell 需注入 GraphQL client（`@edu/hooks` 的 `useGraphQLClient`）
- student-portal 通过 `tryLoadShellClient` 运行时探测，Shell 未就绪时降级为独立 client
- 当前降级路径已就绪，但 Shell 注入尚未实现

## 6. 数据库 Schema（ai04）

student-bff 需要的数据库表（基于 Drizzle ORM）：
- users（学生信息）
- classes / class_members（班级/成员）
- exams / exam_questions / exam_submissions（考试/题目/提交）
- homework / homework_submissions（作业/提交）
- grade_records（成绩）
- attendance_records（考勤）
- notifications（通知）
- announcements（公告）
- error_book_items（错题本）
- leave_requests（请假）
- elective_courses / elective_selections（选课）
- practice_sessions / practice_answers（自适应练习）
- lesson_plans（课案）
- course_plans（课程计划）
- schedule（课表）
- textbooks / textbook_chapters（教材/章节）
