Files
Edu/docs/architecture/issues/worklines/student-bff_workline.md

18 KiB
Raw Blame History

student-bff 工作排期

负责人ai04 关联:workline.mdcoord.mdcontracts/student-bff_contract.mdobjections/student-bff_issue.md 模式:全并行(各 AI 一口气完成 P2-P6 全部代码,开发期间用 mock最后统一集成测试 裁决依据:coord-final-decisions.md §2 B1-B8、president-final-rulings.md §2.2/§3.4/§6.1


§1 总览

student-bff 为学生端提供 GraphQL 聚合 APIB1 裁决P2 起直接 GraphQL + DataLoader下游通过 gRPC 调用业务服务B2 裁决:首次实现即 gRPC复用 teacher-bff 产出的 DownstreamClient 抽象B8 裁决)。

  • 阶段归属P3 核心教学阶段(批次 2
  • 端口3009HTTP GraphQL endpoint
  • 路由前缀/studentapi-gateway 代理 /api/v1/student/* → student-bff:3009
  • schema 存放packages/shared-ts/contracts/graphql/student-bff.schema.graphqlpresident §2.2
  • 核心场景:学生 Dashboard 聚合 + 考试作答 + 作业提交 + 成绩查看

1.1 关键裁决对齐

裁决 结论 对齐方式
B1 API 风格 P2 起直接 GraphQLYoga + DataLoader P3 首次实现即 GraphQL禁止 REST
B2 下游通信 首次实现即 gRPC @grpc/grpc-js + @bufbuild/protobuf禁止 HTTP fetch
B3 权限装饰器 BFF 豁免 @RequirePermission 仅校验 x-user-id 存在,权限交下游
B4 越权防御 全部 BFF 强制 AuthorizationGuard 强制 userId 比对
B5 错误码前缀 BFF_STUDENT_ 统一 BFF_ 前缀
B6 缓存策略 Redis 5-30s 短缓存 CacheInterceptor + Redis
B7 Kafka 订阅 P2-P4 不订阅P5 后订阅 P3/P4 纯同步聚合P5 引入 EventSubscriber
B8 DownstreamClient 回写 teacher-bff3 BFF 统一 复用 ai03 P2 产出的抽象

§2 全阶段甘特图(批次 1 等待期 + 批次 2-5

gantt
    title ai04 student-bff 全阶段排期(对齐总裁 §6.1 批次时间线)
    dateFormat YYYY-MM-DD
    axisFormat %m-%d

    section 批次1等待期
    W0.1 GraphQL schema 第一版起草 :crit, w1, 2026-07-10, 3d
    W0.2 01/02 文档回写(B1/B2/B5/B8) :crit, w2, after w1, 3d
    W0.3 schema 提交 coord 仲裁 :milestone, w3, after w2, 0d

    section 批次2 P3 核心
    P3.1 NestJS+GraphQL Yoga 骨架 :crit, p1, after w3, 2d
    P3.2 DownstreamClient+gRPC client(iam+core-edu) :crit, p2, after p1, 3d
    P3.3 核心 Query Resolver(dashboard/homework/grades/exams) :crit, p3, after p2, 3d
    P3.4 Mutation(submitHomework)+AuthorizationGuard(B4) :crit, p4, after p3, 2d
    P3.5 DataLoader+N+1防御 :p5, after p4, 1d
    P3.6 Redis缓存(B6)+ActionState信封 :p6, after p4, 1d
    P3.7 /healthz+/readyz探针(iam+core-edu) :p7, after p6, 1d
    P3.8 横切关注点(logger/metrics/tracer/error filter) :p8, after p6, 2d
    P3.9 单元测试(覆盖率≥80%) :p9, after p8, 2d

    section 批次3 P4 扩展
    P4.1 content gRPC client(textbooks/chapters/questions) :p10, after p9, 3d
    P4.2 data-ana gRPC client(weakness/trend) :p11, after p10, 2d
    P4.3 Query 扩展(myTextbooks/myWeakness/myTrend) :p12, after p11, 2d
    P4.4 /readyz 扩展探针(content+data-ana) :p13, after p12, 1d
    P4.5 Dashboard Resolver 字段扩展 :p14, after p12, 1d

    section 批次4 P5 扩展
    P5.1 msg gRPC client(notifications) :p15, after p14, 2d
    P5.2 ai gRPC client(chat/streamChat SSE) :p16, after p15, 3d
    P5.3 Query/Mutation 扩展(myNotifications/markAsRead/aiChat) :p17, after p16, 2d
    P5.4 Kafka EventSubscriber(B7 P5订阅) :p18, after p17, 2d
    P5.5 push-gateway 推送通道 :p19, after p18, 2d
    P5.6 /readyz 扩展探针(msg+ai) :p20, after p19, 1d

    section 批次5 P6 硬化
    P6.1 熔断器(opossum)完善 :p21, after p20, 2d
    P6.2 HPA+全链路可观测 :p22, after p21, 2d
    P6.3 灾备演练+99.9%可用性 :p23, after p22, 3d

关键路径critschema 起草 → 文档回写 → P3 骨架 → gRPC client → Query Resolver → Mutation+Guard 总时间线:批次 1 等待期 6 天 + 批次 2 P3 约 17 天 + 批次 3 P4 约 9 天 + 批次 4 P5 约 12 天 + 批次 5 P6 约 7 天


§3 详细任务

3.1 批次 1 等待期2026-07-10 起,约 6 天)

W0.1 GraphQL schema 第一版起草

  • 负责人ai04
  • 依赖president §2.2 裁决 ai04 在批次 1 等待期起草)
  • 交付物
    • packages/shared-ts/contracts/graphql/student-bff.schema.graphql 第一版
    • 包含 Query/Mutation 清单 + 类型定义 + 权限点标注(# @permission:+ DataScope 标注(# @dataScope: SELF
    • 分页采用 Relay Cursor Connections 规范president §2.2 #5
    • 错误格式GraphQL errors 数组 + extensions.code + extensions.traceIdpresident §2.2 #3
  • 验收标准
    • P3 核心 QuerystudentDashboard / myHomework / myGrades / myExams / myClasses / currentUser
    • P3 核心 MutationsubmitHomework
    • 提交 coord 仲裁president §2.2coord 在批次 2 启动前仲裁第一版)
  • 状态 待办(见 objections ISSUE-STU-004

W0.2 01/02 文档回写

  • 负责人ai04
  • 依赖:无
  • 交付物
    • services/student-bff/docs/01-understanding.md 回写ISSUE-STU-001
      • §3.2 REST 端点 → GraphQL Query/Mutation 清单
      • §3.1/§4 HTTP fetch → gRPC 下游调用
      • §3.3/§6 错误码 STUDENT_BFF_BFF_STUDENT_
      • §7.2 删除已裁决的"待仲裁"项
    • services/student-bff/docs/02-architecture-design.md 回写ISSUE-028-ai04
      • §4 21 个 REST 端点 → GraphQL Schema 设计
      • §9.2 删除 REST→GraphQL 演进,改为 GraphQL 即起点
      • §9.3 删除 HTTP→gRPC 演进,改为 gRPC 首次实现即用
      • §8.3 删除 8 项已裁决的"待仲裁"标注ISSUE-STU-003
      • 修正 §11.4/§11.5 错误引用ISSUE-STU-002
      • 补充 GraphQL Schema / DataLoader / gRPC client / AuthorizationGuard 设计
  • 验收标准:与 coord-final-decisions §2 B1-B8 + president §2.2 完全一致
  • 状态 待办

3.2 批次 2 P3 核心教学(约 17 天)

P3.1 NestJS + GraphQL Yoga 骨架

  • 负责人ai04
  • 依赖:批次 1 完成iam gRPC 50052 + ai03 DownstreamClient 抽象就绪president §6.1
  • 交付物
    • services/student-bff/ 服务骨架(克隆 teacher-bff 结构B8 复用 shared/
    • src/app.module.ts + src/main.ts(端口 3009
    • GraphQL Yoga endpointPOST /graphql+ Playground开发环境
    • package.json@edu/student-bff+ tsconfig.jsonNodeNext ESM+ nest-cli.json
    • Dockerfile多阶段构建EXPOSE 3009
  • 验收标准POST /graphql 返回 200 + schema 内省可用
  • 状态 待办

P3.2 DownstreamClient + gRPC clientiam + core-edu

  • 负责人ai04
  • 依赖P3.1 + ai03 teacher-bff P2 产出的 DownstreamClient 抽象B8
  • 交付物
    • src/shared/downstream/downstream-client.ts(复用 teacher-bff 抽象B8
    • gRPC client 配置iam:50052 + core-edu:50053
    • src/config/env.tsIamGrpcUrl + CoreEduGrpcUrl + 超时/重试参数
    • gRPC interceptortraceId 透传 + 错误归一化
  • 验收标准:可调用 iam.GetUserInfo + core-edu.HomeworkService.ListHomeworkByClass
  • 状态 待办

P3.3 核心 Query Resolver

  • 负责人ai04
  • 依赖P3.2 + coord 仲裁的 schema 第一版
  • 交付物
    • src/student/resolvers/dashboard.resolver.tsstudentDashboard聚合 iam + core-edu
    • src/student/resolvers/homework.resolver.tsmyHomeworkcore-edu
    • src/student/resolvers/grades.resolver.tsmyGradescore-eduB4 强制 userId 比对)
    • src/student/resolvers/exams.resolver.tsmyExamscore-edu
    • src/student/resolvers/classes.resolver.tsmyClassescore-edu
    • src/student/resolvers/auth.resolver.tscurrentUser聚合 iam.GetUserInfo + GetEffectivePermissions + GetViewports
    • 并行编排Promise.allSettled + 部分降级president §2.6 方案 Bdata 内 degraded 字段)
  • 验收标准5 个核心 Query 可执行,返回 ActionState 信封
  • 状态 待办

P3.4 MutationsubmitHomework+ AuthorizationGuardB4

  • 负责人ai04
  • 依赖P3.3
  • 交付物
    • src/student/resolvers/homework.mutation.resolver.tssubmitHomework Mutation
    • src/student/guards/authorization.guard.tsB4 自我越权防御
      • 接口:canAccessOwnData(userId, requestedStudentId): Promise<boolean>
      • P3 实现:强制 studentId === userId(学生只能操作自己数据)
      • 参照 teacher-bff ISSUE-033-ai03 的 AuthorizationGuard 模式president §2.9
    • Zod 输入校验SubmitHomeworkInput schema
  • 验收标准submitHomework 可提交越权请求studentId ≠ userId返回 BFF_STUDENT_FORBIDDEN
  • 状态 待办

P3.5 DataLoader + N+1 防御

  • 负责人ai04
  • 依赖P3.3
  • 交付物
    • src/student/dataloaders/homework.loader.ts:批量加载作业
    • src/student/dataloaders/grades.loader.ts:批量加载成绩
    • Dashboard 内多学生场景用 DataLoader 批量去重004 §11.3
  • 验收标准N+1 查询场景下下游 gRPC 调用数 ≤ 2
  • 状态 待办

P3.6 Redis 缓存B6+ ActionState 信封

  • 负责人ai04
  • 依赖P3.3
  • 交付物
    • src/shared/cache/cache.module.tsRedis CacheInterceptor
    • 缓存 Key 规范:student:dashboard:{userId}TTL 5-30sB6
    • ActionState 信封:{success, data, meta?} / {success: false, error: {code, message, details?, traceId?}}
    • 降级模式:data.degraded = true + data.degradedReasonpresident §2.6 方案 B
  • 验收标准:缓存命中时 P50 < 100ms降级响应符合方案 B
  • 状态 待办

P3.7 /healthz + /readyz 探针

  • 负责人ai04
  • 依赖P3.2
  • 交付物
    • src/shared/health/health.controller.ts/healthzliveness+ /readyzreadiness
    • P3 /readyz 探针iam gRPC 50052 + core-edu gRPC 500532 项president §2.4
    • 必需依赖失败返回 503可选依赖软失败返回 200 + degraded
  • 验收标准/readyz 返回 2 项探针状态
  • 状态 待办

P3.8 横切关注点

  • 负责人ai04
  • 依赖P3.1
  • 交付物
    • src/shared/observability/logger.tspinoservice: 'student-bff'
    • src/shared/observability/metrics.tsprom-client11 个 student_bff_* 指标)
    • src/shared/observability/tracer.tsOTelserviceName: 'student-bff'
    • src/shared/errors/global-error.filter.ts@Catch()BFF_STUDENT_* 错误码)
    • src/shared/errors/application-error.ts(错误类层次)
    • 优雅关闭SIGTERM → app.close() → shutdownTracer()
  • 验收标准/metrics 可访问GlobalErrorFilter 捕获所有异常
  • 状态 待办

P3.9 单元测试

  • 负责人ai04
  • 依赖P3.3-P3.8
  • 交付物
    • test/unit/resolvers/*.test.tsResolver 聚合逻辑mock gRPC 下游)
    • test/unit/guards/*.test.tsAuthorizationGuard 越权防御
    • test/unit/dataloaders/*.test.tsDataLoader 批量逻辑
    • vitest.config.ts(对齐 classes 测试框架)
  • 验收标准:覆盖率 ≥ 80%
  • 状态 待办

3.3 批次 3 P4 内容分析扩展(约 9 天)

P4.1-P4.2 content + data-ana gRPC client

  • 负责人ai04
  • 依赖:批次 3 启动content gRPC 50054 + data-ana gRPC 50055 就绪)
  • 交付物
    • content gRPC clientTextbookService + ChapterService + QuestionService + KnowledgeGraphService
    • data-ana gRPC clientAnalyticsService.GetStudentWeakness + GetLearningTrend
  • 验收标准:可调用 content + data-ana gRPC RPC
  • 状态 待办(属"跨阶段扩展例外"president §2.3 允许新增下游 gRPC 调用)

P4.3-P4.5 Query 扩展 + 探针扩展 + Dashboard 字段扩展

  • 交付物
    • Query 扩展myTextbooks / myChapters / myQuestions / myLearningPath / myWeakness / myTrend
    • /readyz 扩展探针:+ content 50054 + data-ana 50055共 4 项)
    • Dashboard Resolver 字段扩展null 字段 → 真实 data-ana 数据president §2.3 #4 允许)
  • 状态 待办

3.4 批次 4 P5 沟通 AI 扩展(约 12 天)

P5.1-P5.3 msg + ai gRPC client + Query/Mutation 扩展

  • 交付物
    • msg gRPC clientNotificationService.ListNotifications + MarkAsRead
    • ai gRPC clientAiService.Chat + StreamChatSSE 流式透传)
    • Query/Mutation 扩展myNotifications / markAsRead Mutation / aiChat / aiStreamChat
  • 状态 待办

P5.4-P5.6 Kafka EventSubscriber + push-gateway + 探针扩展

  • 交付物
    • src/student/events/event-subscriber.tsKafka 消费者组B7 P5 才订阅)
    • 订阅 topicedu.homework.events / edu.exam.events / edu.grade.events / edu.identity.user.role_changed
    • 幂等性Redis SETNX event_id 去重
    • push-gateway 推送通道POST /push/user/:userId
    • /readyz 扩展探针:+ msg 50056 + ai 50058共 6 项)
  • 状态 待办

3.5 批次 5 P6 硬化(约 7 天)

P6.1-P6.3 熔断器 + HPA + 灾备

  • 交付物
    • 熔断器opossum完善每个下游 gRPC client 独立熔断器
    • HPA 自动扩缩容配置
    • 全链路 trace + Grafana 仪表盘
    • 灾备演练 + 99.9% 可用性压测
  • 状态 待办

§4 依赖与就绪信号

4.1 我依赖的上游就绪标志

依赖项 提供 AI 就绪信号 阻塞阶段 状态
core_edu.proto 补全AttendanceService / GetClassesByTeacher coordpresident §2.5 proto message + RPC 签名定义 批次 2 P3
buf.gen.yaml gRPC 插件 coord批次 0.9 grpc/node 插件配置 批次 2 P3
ai03 DownstreamClient 抽象 ai03B8 裁决) teacher-bff P2 产出可复用抽象 批次 2 P3
iam gRPC 50052 + 12 RPC ai06I1 裁决) HealthService.Check = SERVING 批次 2 P3
core-edu gRPC 50053 + 22 RPC ai08C2 裁决) HealthService.Check = SERVING 批次 2 P3
content gRPC 50054 + 18 RPC ai09 HealthService.Check = SERVING 批次 3 P4
data-ana gRPC 50055 + 12 RPC ai11 HealthService.Check = SERVING 批次 3 P4
msg gRPC 50056 + 13 RPC ai10 HealthService.Check = SERVING 批次 4 P5
ai gRPC 50058 + 6 RPC ai12 HealthService.Check = SERVING 批次 4 P5
coord 仲裁 student-bff schema 第一版 coordpresident §2.2 schema 第一版裁定 批次 2 P3
api-gateway /student 路由 ai01 /api/v1/student/* 可代理 批次 2 P3

4.2 我的就绪标志(供下游消费)

就绪标志 验证方式 消费方
student-bff GraphQL :3009 启用 GET /healthz 返回 200 k8s / 监控
/readyz 返回 200含下游 gRPC 连通性) GET /readyz 返回 200 + checks k8s / 监控
GraphQL schema 可内省 POST /graphql 返回 schema ai14student-portal
核心 Query 可执行 studentDashboard / myHomework / myGrades / myClasses / currentUser ai14
核心 Mutation 可执行 submitHomework ai14
/metrics 可访问 GET /metrics 返回 prometheus 格式 Prometheus

§5 Mock 策略(全并行开发期间)

5.1 我提供的 mock供 ai14 student-portal

在 student-bff 真实就绪前,为 ai14 提供 GraphQL mock

  • 方式MSW 拦截 POST /graphql + 固定 response
  • mock 数据
    • currentUser 返回固定学生id="student-001", name="李同学", roles=["student"]
    • studentDashboard 返回固定仪表盘pendingHomework=3, upcomingExams=2, unreadNotifications=5
    • myHomework 返回固定 3 个作业1 个待提交)
    • myGrades 返回固定 5 个成绩
    • myExams 返回固定 2 个考试
    • myClasses 返回固定 1 个班级

5.2 我消费的 mock上游未就绪前

上游 mock 方式 切换真实时机
iam gRPC grpc-mock 拦截 + 固定 UserInfo/Permissions/Viewports iam 就绪信号
core-edu gRPC grpc-mock 拦截 + 固定 Homework/Exam/Grade/Class core-edu 就绪信号
content gRPC grpc-mock 拦截 + 固定 Textbook/Chapter/Question content 就绪信号
data-ana gRPC grpc-mock 拦截 + 固定 Weakness/Trend data-ana 就绪信号
msg gRPC grpc-mock 拦截 + 固定 Notification msg 就绪信号
ai gRPC grpc-mock 拦截 + 固定 Chat response ai 就绪信号

所有上游 mock 通过 gRPC client 拦截器实现,上游就绪后移除拦截器切换真实调用(对齐 matrix.md §7 全并行 Mock 策略)。


§6 风险与缓解

风险 概率 影响 缓解措施
schema 仲裁延迟阻塞 P3 启动 ai04 批次 1 等待期优先产出 schema 草案W0.1
ai03 DownstreamClient 抽象未就绪 ISSUE-007 已识别coord 验收批次 1 时检查
core_edu.proto 补全延迟 president §2.5 已明确 coord 负责 proto 定义
GraphQL + gRPC 首次实现复杂度高 复用 teacher-bff P2 模式B8 DownstreamClient + Yoga endpoint
下游 gRPC mock 与真实行为不一致 集成测试阶段统一验证matrix.md §9