From 21f2485749924d550223bc722567ab0a0b7efb8e Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Tue, 14 Jul 2026 08:36:02 +0800 Subject: [PATCH] =?UTF-8?q?docs(student-portal):=20nextstep-v2=20=E6=A0=B8?= =?UTF-8?q?=E6=9F=A5=E4=B8=8B=E6=B8=B8=E6=9C=8D=E5=8A=A1=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=8A=B6=E6=80=81+=E8=AE=B0=E5=BD=9542=E4=B8=AAresolver?= =?UTF-8?q?=E6=9C=AA=E8=A3=85=E9=85=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/student-portal/docs/nextstep-v2.md | 223 ++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 apps/student-portal/docs/nextstep-v2.md diff --git a/apps/student-portal/docs/nextstep-v2.md b/apps/student-portal/docs/nextstep-v2.md new file mode 100644 index 0000000..a0ef014 --- /dev/null +++ b/apps/student-portal/docs/nextstep-v2.md @@ -0,0 +1,223 @@ +# 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 执行) + +1. 在 `services/student-bff/src/student/resolvers/index.ts` 追加: + ```typescript + import { extendedQueriesResolvers } from "./extended-queries.resolver"; + import { extendedMutationsResolvers } from "./extended-mutations.resolver"; + + // 在 studentBffResolvers 中合并 + Query: { ...extendedQueriesResolvers.Query }, + Mutation: { ...extendedMutationsResolvers.Mutation }, + ``` + +2. 在 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql` 补全 43 个操作的 SDL 定义 + +3. 实现 myAttendance resolver(调用 core-edu ListAttendanceByStudent) + +4. 修正 startPracticeSession 类型不一致(v1 列为 mutation,代码实现为 query) + +## 2. docker-compose 部署缺失(SRE AI 修复) + +### 问题描述 + +`infra/docker-compose.deploy.yml` 中完全缺失 student-bff 和 student-portal 服务定义,且 api-gateway 的 environment 缺少 `STUDENT_BFF_URL`。 + +### 需要新增的服务 + +```yaml + 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 块中追加: +```yaml +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 只能通过 `` 显式注入,不能运行时动态加载。当前独立壳模式(`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 定义 + +### 待修复 + +1. 补全 43 个操作的 type/field/input SDL 定义 +2. 统一命名规则(与 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 | ✅ | 完整下游依赖清单 | + +### ⚠️ 待下游就绪后验证 + +1. 切换 `NEXT_PUBLIC_API_MOCKING=disabled` 后真实 API 调用 +2. 端到端 Docker Compose 联调(需 student-bff + api-gateway + 下游微服务全部就绪) +3. 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 | 命名不一致,非阻断 |