9.4 KiB
Student Portal — 下游依赖工作 V2(Next Steps v2)
生成时间:2026-07-14 生成者:ai14(student-portal) 基于版本:v1(nextstep.md)核查后的更新 核查方法:拉取 main 最新代码,逐项核查下游服务源码实现状态
0. 核查总结
| 下游服务 | 负责人 | v1 状态 | v2 核查结果 | 阻断级别 |
|---|---|---|---|---|
| student-bff | ai04 | 声称已完成 | ❌ 42/57 resolver 未装配 | P0 严重 |
| api-gateway | ai01 | 声称已完成 | ⚠️ 路由已注册,deploy.yml 缺 STUDENT_BFF_URL | P1 |
| push-gateway | ai10 | 声称已完成 | ✅ 三事件透传已验证 | 无 |
| MF Shell (teacher-portal) | ai02 | 声称已完成 | ⚠️ Shell 已暴露 client,但 student-portal tryLoadShellClient 无效 | P2 |
| shared-ts schema | ai04 | 声称已完成 | ⚠️ schema 文件存在但仅定义 15 Query + 2 Mutation | P0 |
| docker-compose | SRE AI | 未完成 | ❌ student-bff + student-portal 均缺失 | P0 |
| core-edu 事件发布 | ai08 | 未完成 | ❌ ExamExtended/ExamForceSubmitted 未实现 | P1 |
1. student-bff 严重装配缺口(ai04 修复)
问题描述
student-bff 的 src/student/resolvers/index.ts 只装配了 11 个基础 resolver 文件,未导入 extended-queries.resolver.ts(22 个 Query)和 extended-mutations.resolver.ts(21 个 Mutation)。
影响范围
57 个 GraphQL 操作中:
- ✅ 14 个可用(基础 resolver 已装配)
- ⚠️ 42 个已实现但未生效(代码写在 extended-*.ts 中,但 index.ts 未装配 + schema 未声明)
- ❌ 1 个完全缺失(myAttendance,需 core-edu AttendanceService)
42 个未装配操作清单
未装配的 Query(22 个): examDetail, homeworkDetail, serverTime, mySchedule, studentGrowth, assignmentAnalysis, myProfile, myMasterySummary, myDiagnosticReports, myErrorBook, announcements, announcementDetail, myLeaveRequests, myElectiveSelections, availableElectiveCourses, myLessonPlans, lessonPlanDetail, myCoursePlans, coursePlanDetail, myReportCard, myPracticeSessions, startPracticeSession
未装配的 Mutation(20 个): submitExam, saveExamDraft, recordExamViolation, recordPasteEvent, markAsRead, markAllAsRead, updateNotificationPreference, updateProfile, changePassword, requestExtension, joinClass, leaveClass, addErrorBookItem, updateErrorBookItem, deleteErrorBookItem, markAnnouncementRead, createLeaveRequest, cancelLeaveRequest, selectElectiveCourse, dropElectiveCourse, submitPracticeAnswer
修复方法(ai04 执行)
-
在
services/student-bff/src/student/resolvers/index.ts追加:import { extendedQueriesResolvers } from "./extended-queries.resolver"; import { extendedMutationsResolvers } from "./extended-mutations.resolver"; // 在 studentBffResolvers 中合并 Query: { ...extendedQueriesResolvers.Query }, Mutation: { ...extendedMutationsResolvers.Mutation }, -
在
packages/shared-ts/contracts/graphql/student-bff.schema.graphql补全 43 个操作的 SDL 定义 -
实现 myAttendance resolver(调用 core-edu ListAttendanceByStudent)
-
修正 startPracticeSession 类型不一致(v1 列为 mutation,代码实现为 query)
2. docker-compose 部署缺失(SRE AI 修复)
问题描述
infra/docker-compose.deploy.yml 中完全缺失 student-bff 和 student-portal 服务定义,且 api-gateway 的 environment 缺少 STUDENT_BFF_URL。
需要新增的服务
student-bff:
build:
context: ./repo
dockerfile: services/student-bff/Dockerfile
container_name: edu-student-bff
restart: unless-stopped
environment:
NODE_ENV: production
PORT: 3009
# 下游服务 URL
IAM_SERVICE_URL: http://iam:3002
CORE_EDU_SERVICE_URL: http://core-edu:3004
CONTENT_SERVICE_URL: http://content:3005
DATA_ANA_SERVICE_URL: http://data-ana:3006
MSG_SERVICE_URL: http://msg:3007
ports:
- "${STUDENT_BFF_PORT:-3009}:3009"
depends_on:
iam:
condition: service_healthy
core-edu:
condition: service_healthy
networks:
- edu-net
- edu-shared
student-portal:
build:
context: ./repo
dockerfile: apps/student-portal/Dockerfile
args:
NEXT_PUBLIC_API_MOCKING: "disabled"
container_name: edu-student-portal
restart: unless-stopped
environment:
NODE_ENV: production
PORT: 4001
API_GATEWAY_URL: http://api-gateway:8080
NEXT_PUBLIC_API_MOCKING: "disabled"
NEXT_PUBLIC_MF_ENABLED: "false"
NEXT_PUBLIC_GRAPHQL_ENDPOINT: /api/v1/student/graphql
NEXT_PUBLIC_PUSH_GATEWAY_URL: ws://push-gateway:8081
ports:
- "${STUDENT_PORTAL_PORT:-4001}:4001"
depends_on:
api-gateway:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--quiet", "--spider", "http://localhost:4001/api/health"]
interval: 30s
timeout: 5s
start_period: 20s
retries: 3
networks:
- edu-net
- edu-shared
api-gateway 环境变量补充
在 api-gateway 的 environment 块中追加:
STUDENT_BFF_URL: http://student-bff:3009
3. api-gateway 路由(ai01 已完成)
核查结果:✅ 路由已注册
services/api-gateway/main.go:84—registerProxy(api, "student", cfg.StudentBffURL)services/api-gateway/internal/config/config.go:81—StudentBffURL: getEnv("STUDENT_BFF_URL", "http://localhost:3009")- 路径前缀改写:
/api/v1/student/*→/v1/student/*(proxy.go:24)
待修复
deploy.yml 中 api-gateway 的 environment 缺少 STUDENT_BFF_URL,会回退到 http://localhost:3009,容器内无法访问。
4. push-gateway 事件(ai10 已完成)
核查结果:✅ 全部就绪
push-gateway 采用通用事件透传机制,不硬编码事件类型。Kafka 消息中的 event_type 字段被原样作为 WebSocket 消息的 event 字段投递。
三个事件均已 Docker 验证通过:
ExamExtended✅ExamForceSubmitted✅ExamQuestionReordered✅
上游事件生产缺失(ai08 修复)
core-edu 源码中尚未实现发布 ExamExtended/ExamForceSubmitted 事件到 Kafka topic edu.exam.events(仲裁文档 coord.md §21.11 ai08 执行项)。事件名仅存在于文档中,未在任何 .ts/.go/.py 源码或 .proto 中找到字面量定义。
5. MF Shell 集成(ai02 已完成,有限制)
核查结果:⚠️ Shell 已暴露,但运行时探测无效
Shell 侧(teacher-portal):✅ 已暴露
next.config.js暴露./GraphQLProvider和./useGraphQLClient- 所有共享包设为
singleton: true
student-portal 侧:⚠️ tryLoadShellClient 实际无效
provider.tsx:51-67定义了tryLoadShellClient,但函数注释明确说明useGraphQLClient是 React Hook,无法在异步上下文调用- 该函数永远返回 null
- 降级逻辑完整:MF 模式下初始用独立 client,
useEffect异步探测 Shell 失败后保持独立 client
修复建议
MF 模式下复用 Shell client 只能通过 <GraphQLProvider client={shellClient}> 显式注入,不能运行时动态加载。当前独立壳模式(NEXT_PUBLIC_MF_ENABLED=false)完全可用,无需修复。
6. shared-ts GraphQL Schema(ai04 修复)
核查结果:⚠️ 文件存在但不完整
- 文件路径:
packages/shared-ts/contracts/graphql/student-bff.schema.graphql(822 行) - 与 v1 约定路径不一致(v1 写的是
student-bff.graphql,实际是student-bff.schema.graphql) - schema 仅定义 15 Query + 2 Mutation + 1 Subscription,缺少 43 个操作的 SDL 定义
待修复
- 补全 43 个操作的 type/field/input SDL 定义
- 统一命名规则(与 parent-bff.graphql / teacher-bff.schema.graphql 对齐)
7. student-portal 自身状态(ai14 已完成)
✅ 已完成项
| 项目 | 状态 | 说明 |
|---|---|---|
| 57 个 GraphQL 操作 | ✅ | operations.ts 定义完整(35 Query + 22 Mutation) |
| 15+ 个 Hook | ✅ | hooks.ts 全部实现 |
| 37 个页面 | ✅ | 全部页面路由就绪 |
| Vitest 测试 | ✅ | 481/481 passed(12 test files) |
| typecheck + lint | ✅ | 0 errors |
| Docker 构建 | ✅ | 镜像构建成功,容器运行正常 |
| MSW 禁用 | ✅ | Dockerfile build-arg 默认 disabled |
| 401 处理 | ✅ | client.ts 自动跳转 /login |
| 降级模式处理 | ✅ | client.ts 检测 degraded 标记并 console.warn |
| nextstep.md v1 | ✅ | 完整下游依赖清单 |
⚠️ 待下游就绪后验证
- 切换
NEXT_PUBLIC_API_MOCKING=disabled后真实 API 调用 - 端到端 Docker Compose 联调(需 student-bff + api-gateway + 下游微服务全部就绪)
- MF Shell 模式联调(需 teacher-portal MF 启用)
8. 优先级排序
| 优先级 | 任务 | 负责人 | 阻断原因 |
|---|---|---|---|
| P0 | 装配 extended resolvers + 补全 schema | ai04 | 42/57 操作不可用 |
| P0 | docker-compose 新增 student-bff + student-portal | SRE AI | 无法部署 |
| P0 | api-gateway environment 补充 STUDENT_BFF_URL | SRE AI | 路由无法到达 student-bff |
| P1 | 实现 myAttendance resolver | ai04 | 考勤功能不可用 |
| P1 | core-edu 发布 ExamExtended/ExamForceSubmitted 事件 | ai08 | 考试实时推送不可用 |
| P2 | MF Shell 运行时 client 注入 | ai02 | MF 模式下无法复用 Shell client |
| P2 | 统一 schema 文件命名 | ai04 | 命名不一致,非阻断 |