Files
Edu/apps/student-portal/docs/nextstep-v2.md

407 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Student Portal — 下游依赖工作 V2Next Steps v2
> 生成时间2026-07-14
> 最近更新2026-07-14二次核查§9
> 生成者ai14student-portal
> 基于版本v1nextstep.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 个未装配操作清单
**未装配的 Query22 个)**
examDetail, homeworkDetail, serverTime, mySchedule, studentGrowth, assignmentAnalysis, myProfile, myMasterySummary, myDiagnosticReports, myErrorBook, announcements, announcementDetail, myLeaveRequests, myElectiveSelections, availableElectiveCourses, myLessonPlans, lessonPlanDetail, myCoursePlans, coursePlanDetail, myReportCard, myPracticeSessions, startPracticeSession
**未装配的 Mutation20 个)**
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 只能通过 `<GraphQLProvider client={shellClient}>` 显式注入,不能运行时动态加载。当前独立壳模式(`NEXT_PUBLIC_MF_ENABLED=false`)完全可用,无需修复。
## 6. shared-ts GraphQL Schemaai04 修复)
### 核查结果:⚠️ 文件存在但不完整
- 文件路径:`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 passed12 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 | 命名不一致,非阻断 |
---
## 9. 二次核查结果2026-07-14
> 用户通知"所有下游服务已经完成 nextstep.md 工作"后,对 main 分支最新代码(含未提交工作区)进行二次核查。
### 9.1 核查总结
| 下游服务 | 负责人 | 首次核查§0 | 二次核查结果 | 变化 |
| ---------------------- | ------ | --------------------- | ----------------------------- | ---------------------------------- |
| student-bff | ai04 | ❌ 42/57 未装配 | ❌ **仍未装配** | 无变化P0 未修复) |
| shared-ts schema | ai04 | ⚠️ 仅 15Q+2M | ⚠️ **仍仅 15Q+2M+1S** | 无变化P0 未修复) |
| docker-compose | SRE | ❌ 缺失 | ❌ **仍缺失** | 无变化P0 未修复) |
| api-gateway deploy.yml | SRE | ⚠️ 缺 STUDENT_BFF_URL | ⚠️ **仍缺** | 无变化P0 未修复) |
| api-gateway 路由 | ai01 | ✅ 已注册 | ✅ **已注册 + 路径重写修复** | ✅ 改善registerBffProxy |
| core-edu gRPC | ai08 | ❌ RPC 缺失 | ✅ **40 RPC 全部就绪** | ✅ 改善24/24 smoke test |
| iam gRPC | ai06 | 未核查 | ✅ **15 RPC 全部就绪** | ✅ 新发现(含 GetUserProfile 等) |
| msg gRPC + REST | ai10 | 未核查 | ✅ **13 RPC + REST 全部就绪** | ✅ 新发现(含 announcements REST |
| push-gateway | ai10 | ✅ 已验证 | ✅ **已验证** | 无变化 |
| MF Shell | ai02 | ⚠️ 限制 | ⚠️ **限制仍在** | 无变化(非阻断) |
| core-edu 事件发布 | ai08 | ❌ 未实现 | ❌ **仍未实现** | 无变化P1 未修复) |
### 9.2 student-bff 装配缺口仍未修复P0
**二次核查结果:❌ 未修复**
- `services/student-bff/src/student/resolvers/extended-queries.resolver.ts`:✅ 存在22 个 Query 已实现
- `services/student-bff/src/student/resolvers/extended-mutations.resolver.ts`:✅ 存在21 个 Mutation 已实现
- `services/student-bff/src/student/resolvers/index.ts`:❌ **仍未导入** extended-queries 和 extended-mutations
ai04 的 nextstep.md§4声称"22 个扩展 Query Resolver ✅"和"21 个扩展 Mutation Resolver ✅"Docker 测试也声称通过。但 index.ts 未装配这些 resolver意味着 GraphQL schema 实际不会注册这 43 个操作。
**修复方法ai04 执行):**
在 `services/student-bff/src/student/resolvers/index.ts` 追加:
```typescript
import { extendedQueriesResolvers } from "./extended-queries.resolver.js";
import { extendedMutationsResolvers } from "./extended-mutations.resolver.js";
export const studentBffResolvers = {
Query: {
// ... 现有 11 个基础 resolver ...
...(extendedQueriesResolvers.Query ?? {}),
},
Mutation: {
// ... 现有 2 个基础 mutation ...
...(extendedMutationsResolvers.Mutation ?? {}),
},
Subscription: {
...(aiStreamResolvers.Subscription ?? {}),
},
};
```
### 9.3 shared-ts schema 仍未补全P0
**二次核查结果:❌ 未修复**
- 文件:`packages/shared-ts/contracts/graphql/student-bff.schema.graphql`822 行)
- 当前定义15 Query + 2 Mutation + 1 Subscription = 18 操作
- 缺失43 个操作的 SDL type/field/input 定义
- 需补全的 43 个操作清单与 §1 一致
### 9.4 docker-compose 仍缺失 student-bff + student-portalP0
**二次核查结果:❌ 未修复**
`infra/docker-compose.deploy.yml` 中仍无 student-bff 和 student-portal 服务定义api-gateway 的 environment 仍缺 `STUDENT_BFF_URL`。需新增的服务定义见 §2。
### 9.5 core-edu gRPC 已全部就绪(✅ 改善)
**二次核查结果:✅ 全部就绪**
ai08 完成了 P3.13 下游缺失 RPC 补全:
- 9 Service / 40 RPC 全部实现
- 24/24 gRPC smoke test 通过
- student-bff 需要的 10 个 RPC 全部就绪:
- `ExamService.GetExam` ✅examDetail
- `ExamService.SubmitExam` ✅submitExam
- `ExamService.SaveExamDraft` ✅saveExamDraft
- `ExamService.RecordExamViolation` ✅recordExamViolation
- `HomeworkService.GetHomework` ✅homeworkDetail
- `HomeworkService.SubmitHomework` ✅submitHomework
- `GradeService.ListGradesByStudent` ✅myGrades
- `GradeService.GetReportCard` ✅myReportCard
- `ScheduleService.GetScheduleByStudent` ✅mySchedule
- `AttendanceService.ListAttendanceByStudent` ✅myAttendance
- `LeaveRequestService` 3 RPC ✅myLeaveRequests/createLeaveRequest/cancelLeaveRequest
### 9.6 iam gRPC 已全部就绪(✅ 新发现)
**二次核查结果:✅ 全部就绪**
ai06 实现了 15 个 gRPC RPC包含 student-bff 需要的全部方法:
- `GetUserProfile` ✅myProfile
- `UpdateProfile` ✅updateProfile
- `ChangePassword` ✅changePassword
- `GetUserInfo` ✅currentUser
- `GetEffectivePermissions` ✅currentUser permissions
- `GetViewports` ✅currentUser viewport
- `GetChildrenByParent` ✅(家长端,非学生端)
> 注ai04 的 nextstep.md §3.1 将 iam 三个 RPC 标记为"❌ 缺失",但实际 iam 已全部实现。ai04 需更新其 nextstep.md 状态。
### 9.7 msg gRPC + REST 已就绪(✅ 新发现)
**二次核查结果:✅ 就绪gRPC + REST 混合)**
ai10 实现了 13 个 gRPC RPC + 完整 REST API
- `NotificationService.ListNotifications` ✅ gRPCmyNotifications
- `NotificationService.MarkAsRead` ✅ gRPCmarkAsRead
- `NotificationPreferenceService.GetPreferences` ✅ gRPC
- `NotificationPreferenceService.UpdatePreferences` ✅ gRPCupdateNotificationPreference
- 公告REST `/announcements` + `/announcements/:id/read` ✅
> 注ai04 的 nextstep.md §3.5 将 msg 6 个 RPC 标记为"❌ 缺失",但 msg 已实现核心 RPC。公告相关方法通过 REST 提供ai04 需确认是否需补 gRPC 或改用 REST 调用。
### 9.8 api-gateway 路由已修复(✅ 改善)
**二次核查结果:✅ 已修复**
ai01 新增 `registerBffProxy` 函数,对 BFF 路由teacher/student/parent正确剥离前缀
- `/api/v1/student/graphql` → `student-bff:3009/graphql` ✅(不再 404
- JWT 鉴权 + x-user-id/x-user-roles 注入 ✅
### 9.9 core-edu 事件发布仍未实现P1
**二次核查结果:❌ 未修复**
`ExamExtended`、`ExamForceSubmitted`、`ExamQuestionReordered` 事件字面量在 core-edu 源码中仍未找到。这三个事件由教师端触发(延长考试/强制收卷/调整题目),需 core-edu 在相应业务操作中通过 Outbox 发布到 Kafka。
### 9.10 更新后的优先级排序
| 优先级 | 任务 | 负责人 | 阻断原因 | 状态变化 |
| ------ | -------------------------------------------------- | -------- | ------------------------ | ------------------ |
| **P0** | student-bff index.ts 装配 extended resolvers | ai04 | 43 个操作不可用 | ❌ 未修复 |
| **P0** | shared-ts schema 补全 43 个操作 SDL | ai04 | GraphQL schema 不完整 | ❌ 未修复 |
| **P0** | docker-compose 新增 student-bff + student-portal | SRE | 无法部署 | ❌ 未修复 |
| **P0** | api-gateway deploy.yml 补充 STUDENT_BFF_URL | SRE | 路由无法到达 student-bff | ❌ 未修复 |
| P1 | core-edu 发布 ExamExtended/ExamForceSubmitted 事件 | ai08 | 考试实时推送不可用 | ❌ 未修复 |
| P2 | MF Shell 运行时 client 注入 | ai02 | MF 模式限制(非阻断) | 无变化 |
| ~~P1~~ | ~~实现 myAttendance resolver~~ | ~~ai04~~ | ~~考勤不可用~~ | ✅ core-edu 已就绪 |
### 9.11 student-portal 自身状态(✅ 确认完成)
二次核查确认 student-portal 自身全部通过:
| 验证项 | 结果 |
| ------------------ | ---------------------------------- |
| `pnpm typecheck` | ✅ 0 errors |
| `pnpm lint` | ✅ 0 errors, 0 warnings |
| `pnpm test` | ✅ 481/481 passed12 test files |
| 57 个 GraphQL 操作 | ✅ operations.ts 完整定义 |
| Docker 构建 | ✅ 镜像构建成功nextstep.md §0 |
### 9.12 联调就绪状态
当前联调就绪状态student-portal → api-gateway → student-bff → 下游 gRPC
```
student-portal ──✅──> api-gateway ──✅──> student-bff ──❌──> [43 个操作未装配]
├──✅──> core-edu (40 RPC 就绪)
├──✅──> iam (15 RPC 就绪)
├──✅──> msg (13 RPC + REST 就绪)
└──❌──> docker-compose 未配置
```
**结论:** student-portal 自身已完全就绪。4 个 P0 问题全部集中在下游服务ai04 装配 + SRE 部署),需 ai04 和 SRE AI 修复后方可端到端联调。core-edu / iam / msg 下游 gRPC 已全部就绪,一旦 student-bff 装配完成即可联调。