feat(student-bff): extended queries/mutations resolvers + Dockerfile + nextstep 文档

This commit is contained in:
SpecialX
2026-07-14 16:01:20 +08:00
parent 895a060491
commit 422b55f901
6 changed files with 2547 additions and 18 deletions

View File

@@ -0,0 +1,199 @@
# student-bff 下游工作清单Next Steps
> 负责人ai04
> 更新日期2026-07-13
> 关联:[student-portal_contract.md](../../docs/architecture/issues/contracts/student-portal_contract.md)、[student-portal_workline.md](../../docs/architecture/issues/worklines/student-portal_workline.md)
---
## 1. 概述
student-bff 已完成全部 35 Query + 23 Mutation + 1 Subscription 的 schema 与 resolver 实现Docker 镜像本地构建与运行验证通过(`MOCK_UPSTREAM=false`)。下游 gRPC 服务未启动时BFF 进入降级模式(方案 B返回 `degraded: true` + `degradedReason` + `degradedFields`
**本地 Docker 测试结果2026-07-13**
- ✅ 镜像构建成功(`edu/student-bff:test`
- ✅ 容器启动正常(端口 3009NestFactory + GraphQL Yoga 初始化完成)
-`/healthz` 返回 200
-`MOCK_UPSTREAM=false`,下游未启动时进入降级模式
-`serverTime` Query 返回本地时间(无下游依赖)
-`myProfile` Query 返回 `degraded=true`,原因为 `DOWNSTREAM_FAILURE: iam.GetUserProfile failed after 3 attempts`
-`mySchedule` Query 返回空 items + `degraded=true`
-`markAsRead` Mutation 返回 `success=false` + `error.code=BFF_STUDENT_BAD_GATEWAY`
-`createLeaveRequest` Mutation 返回 `success=false` + `error.code=BFF_STUDENT_BAD_GATEWAY`
- ✅ B4 越权防御生效:无 `x-user-id` header 时返回 401 UnauthorizedError
- ✅ Kafka 软失败(不影响服务启动,仅 EventSubscriber 不工作)
---
## 2. 上游依赖api-gateway 路由)
### 2.1 api-gatewayai01 负责)
**阻塞级别P0必须完成才能端到端联调**
| # | 工作项 | 详情 |
| --- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| 1 | 新增 `/api/v1/student/graphql` 路由 | 当前 api-gateway 无此路由。需新增 POST `/api/v1/student/graphql` 代理到 student-bff :3009/graphqlARB-019 §21 |
| 2 | JWT 校验 + 用户身份注入 | api-gateway 校验 JWT 后,注入 `x-user-id` / `x-user-roles` / `x-request-id` header 到 student-bff |
| 3 | 学生角色校验 | `/api/v1/student/*` 路由组上添加 `student` 角色门禁,拒绝非 student 角色访问 |
| 4 | 限流配置 | student-bff 路由组配置 IP 级令牌桶限流 |
| 5 | 熔断/重试 | 对 student-bff 后端配置熔断器opossum 已在 student-bff 内部启用gateway 层可加外层熔断) |
**相关文件:**
- `services/api-gateway/main.go`(路由注册)
- `services/api-gateway/internal/middleware/auth.go`JWT 校验)
- `services/api-gateway/internal/proxy/proxy.go`(反向代理)
- `services/api-gateway/internal/config/config.go`(路由配置)
---
## 3. 下游依赖gRPC 微服务)
### 3.1 iam 服务ai06 负责)
**阻塞级别P0影响用户身份相关功能**
| # | gRPC 方法 | 用途 | 当前状态 |
| --- | ---------------- | ------------------------- | -------- |
| 1 | `GetUserProfile` | `myProfile` Query | ❌ 缺失 |
| 2 | `UpdateProfile` | `updateProfile` Mutation | ❌ 缺失 |
| 3 | `ChangePassword` | `changePassword` Mutation | ❌ 缺失 |
**proto 位置:** `packages/shared-proto/proto/iam/v1/iam.proto`
### 3.2 core-edu 服务ai08 负责)
**阻塞级别P0影响学生核心学习功能**
| # | gRPC 方法 | 用途 | 当前状态 |
| --- | ---------------------------- | ------------------------------ | -------- |
| 1 | `GetExam` | `examDetail` Query | ❌ 缺失 |
| 2 | `SubmitExam` | `submitExam` Mutation | ❌ 缺失 |
| 3 | `SaveExamDraft` | `saveExamDraft` Mutation | ❌ 缺失 |
| 4 | `RecordExamViolation` | `recordExamViolation` Mutation | ❌ 缺失 |
| 5 | `GetHomework` | `homeworkDetail` Query | ❌ 缺失 |
| 6 | `GetScheduleByStudent` | `mySchedule` Query | ❌ 缺失 |
| 7 | `ListLeaveRequestsByStudent` | `myLeaveRequests` Query | ❌ 缺失 |
| 8 | `CreateLeaveRequest` | `createLeaveRequest` Mutation | ❌ 缺失 |
| 9 | `CancelLeaveRequest` | `cancelLeaveRequest` Mutation | ❌ 缺失 |
| 10 | `GetReportCard` | `myReportCard` Query | ❌ 缺失 |
**proto 位置:** `packages/shared-proto/proto/core_edu/v1/core_edu.proto`
### 3.3 content 服务ai09 负责)
**阻塞级别P0影响学生内容浏览功能**
| # | gRPC 方法 | 用途 | 当前状态 |
| --- | --------------------------------- | -------------------------------- | -------- |
| 1 | `ListElectiveSelectionsByStudent` | `myElectiveSelections` Query | ❌ 缺失 |
| 2 | `ListAvailableElectiveCourses` | `availableElectiveCourses` Query | ❌ 缺失 |
| 3 | `SelectCourse` | `selectElectiveCourse` Mutation | ❌ 缺失 |
| 4 | `DropCourse` | `dropElectiveCourse` Mutation | ❌ 缺失 |
| 5 | `ListLessonPlansByStudent` | `myLessonPlans` Query | ❌ 缺失 |
| 6 | `GetLessonPlan` | `lessonPlanDetail` Query | ❌ 缺失 |
| 7 | `ListCoursePlansByStudent` | `myCoursePlans` Query | ❌ 缺失 |
| 8 | `GetCoursePlan` | `coursePlanDetail` Query | ❌ 缺失 |
**proto 位置:** `packages/shared-proto/proto/content/v1/content.proto`
### 3.4 data-ana 服务ai12 负责)
**阻塞级别P0影响学生学情分析功能**
| # | gRPC 方法 | 用途 | 当前状态 |
| --- | ------------------------------- | ------------------------------- | -------- |
| 1 | `GetStudentGrowth` | `studentGrowth` Query | ❌ 缺失 |
| 2 | `GetAssignmentAnalysis` | `assignmentAnalysis` Query | ❌ 缺失 |
| 3 | `GetMasterySummary` | `myMasterySummary` Query | ❌ 缺失 |
| 4 | `ListDiagnosticReports` | `myDiagnosticReports` Query | ❌ 缺失 |
| 5 | `ListErrorBookItems` | `myErrorBook` Query | ❌ 缺失 |
| 6 | `ListPracticeSessionsByStudent` | `myPracticeSessions` Query | ❌ 缺失 |
| 7 | `StartPracticeSession` | `startPracticeSession` Query | ❌ 缺失 |
| 8 | `SubmitPracticeAnswer` | `submitPracticeAnswer` Mutation | ❌ 缺失 |
**proto 位置:** `packages/shared-proto/proto/data_ana/v1/data_ana.proto`
### 3.5 msg 服务ai10 负责)
**阻塞级别P0影响学生通知与公告功能**
| # | gRPC 方法 | 用途 | 当前状态 |
| --- | ------------------------------ | --------------------------------------- | -------- |
| 1 | `ListAnnouncements` | `announcements` Query | ❌ 缺失 |
| 2 | `GetAnnouncement` | `announcementDetail` Query | ❌ 缺失 |
| 3 | `MarkNotificationAsRead` | `markAsRead` Mutation | ❌ 缺失 |
| 4 | `MarkAllNotificationsAsRead` | `markAllAsRead` Mutation | ❌ 缺失 |
| 5 | `UpdateNotificationPreference` | `updateNotificationPreference` Mutation | ❌ 缺失 |
| 6 | `MarkAnnouncementRead` | `markAnnouncementRead` Mutation | ❌ 缺失 |
**proto 位置:** `packages/shared-proto/proto/msg/v1/msg.proto`
### 3.6 ai 服务ai11 负责)
**阻塞级别P1影响 AI 辅助功能,可降级)**
| # | gRPC 方法 | 用途 | 当前状态 |
| --- | -------------- | ----------------------- | -------- |
| 1 | `StreamAIChat` | `aiStream` Subscription | ❌ 缺失 |
**proto 位置:** `packages/shared-proto/proto/ai/v1/ai.proto`
### 3.7 push-gatewayai13 负责)
**阻塞级别P1影响实时推送**
| # | 工作项 | 详情 |
| --- | ------------------ | ---------------------------------------------------------------- |
| 1 | WebSocket 推送端点 | student-bff EventSubscriber 接收 Kafka 事件后转发到 push-gateway |
| 2 | Kafka topic 对齐 | student-bff 订阅 `student.notification.*` 等 topic |
---
## 4. student-bff 已完成项汇总
| 工作项 | 状态 | 验证方式 |
| ------------------------------------------- | ---- | ------------------------------------------- |
| Schema 扩展13Q+2M → 35Q+23M+1S | ✅ | `pnpm typecheck` + GraphQL Playground 校验 |
| 22 个扩展 Query Resolver | ✅ | Docker 容器 GraphQL 请求测试 |
| 21 个扩展 Mutation Resolver | ✅ | Docker 容器 GraphQL 请求测试 |
| Zod 输入校验21 个 Mutation Input Schema | ✅ | typecheck + 运行时校验 |
| B4 越权防御assertOwnData | ✅ | 无 `x-user-id` 返回 401 |
| 降级模式(方案 B | ✅ | 下游不可用时返回 `degraded=true` + 原因 |
| Redis 缓存B6 5-30s TTL | ✅ | CacheService 已注入TTL 预设已配置 |
| Kafka EventSubscriber软失败 | ✅ | Kafka 不可用时不阻塞启动 |
| DataLoader 批量加载 | ✅ | createDataLoaders 已注入 context |
| Dockerfile 多阶段构建 | ✅ | `edu/student-bff:test` 构建成功 |
| Docker 本地测试MOCK_UPSTREAM=false | ✅ | healthz + GraphQL Query/Mutation 全部按预期 |
---
## 5. 联调顺序建议
1. **ai06** 完成 iam gRPCGetUserProfile / UpdateProfile / ChangePassword
2. **ai08** 完成 core-edu gRPCGetExam / SubmitExam / GetHomework / GetScheduleByStudent 等 10 个)
3. **ai09** 完成 content gRPC8 个选修/教案/课程计划相关)
4. **ai12** 完成 data-ana gRPC8 个学情分析相关)
5. **ai10** 完成 msg gRPC6 个通知/公告相关)
6. **ai01** 完成 api-gateway `/api/v1/student/graphql` 路由 + JWT 注入
7. **ai11** 完成 ai gRPC StreamAIChatP1
8. **ai13** 完成 push-gateway WebSocketP1
9. 端到端联调student-portal → api-gateway → student-bff → 6 个下游 gRPC 服务)
---
## 6. 已知限制
| # | 限制 | 说明 |
| --- | ------------------------------------- | ------------------------------------------------------------------------------------------ |
| 1 | Kafka 未启动时 EventSubscriber 软失败 | 服务正常启动,但实时事件推送(通知/AI 流式响应)不工作 |
| 2 | 下游 gRPC 未就绪时进入降级模式 | 所有 Query 返回 `degraded=true` + 空数据;所有 Mutation 返回 `success=false` + BAD_GATEWAY |
| 3 | DEV_MODE=true 时跳过 B4 越权校验 | 生产环境必须 `DEV_MODE=false`,由 api-gateway 注入 `x-user-id` header |
| 4 | pino-pretty 仅 devDependencies | 生产环境 `NODE_ENV=production` 时不启用 pino-pretty transport输出结构化 JSON |
| 5 | OTEL_EXPORTER_OTLP_ENDPOINT 未配置 | Tracer 被禁用,需配置 OTLP endpoint 启用全链路追踪 |
---
**本文件由 ai04 维护,下游工作项请各负责 AI 完成后通知 ai04 更新状态。**