teacher-bff 下一步工作与上下游依赖
模块:teacher-bff(教学场景域聚合层 BFF,GraphQL 聚合层,端口 3003)
负责人:ai03
更新日期:2026-07-13(v2:iam 真实数据全量联调 + dataScope 修复)
关联文档:02-architecture-design.md、admin-portal_contract.md
1. 模块当前状态
teacher-bff 已完成 P2-P6 全部批次,admin resolver 重构为扁平命名(ARB-001 裁决),Docker 镜像构建成功并在本地 Docker 验证通过(接入真实 iam,无 mock 数据)。
1.1 本地 Docker 验证结果(2026-07-13 v2)
测试环境:本地 Docker(edu-iam-test + edu-teacher-bff-test 容器,接入 edu-full_default 网络,直连 edu-mysql / edu-redis / edu-kafka)
| 验证项 |
状态 |
说明 |
| iam Docker 镜像构建 |
✅ |
node:20-alpine + bcryptjs(纯 JS,无 native 编译) |
| teacher-bff Docker 镜像构建 |
✅ |
node:20-alpine + shared-ts 预编译 |
| iam HTTP /healthz |
✅ |
200 |
| iam gRPC 50052 |
✅ |
GetUserInfo / BatchGetUsers / GetEffectivePermissions 等方法可调用 |
| teacher-bff /healthz |
✅ |
200 |
| teacher-bff /readyz |
✅ |
7 依赖健康(iam gRPC + Redis + 5 个 mock 客户端探针) |
| GraphQL schema introspection |
✅ |
41 Query + 20 Mutation 字段全部存在 |
currentUser 查询(UUID) |
✅ |
返回真实 iam 数据(admin-test@edu.local, dataScope: ALL, 5 权限) |
me 查询(UUID) |
✅ |
返回真实 iam 数据(dataScope: ALL,v2 修复) |
adminRoles 查询 |
✅ |
返回真实 iam 角色(3 个:admin/student/teacher) |
adminPermissions 查询 |
✅ |
返回真实 iam 权限点(5 个:iam:user:read 等) |
auditLogs 查询 |
✅ |
返回真实 iam 审计日志(5 条) |
adminDashboard 查询 |
✅ |
返回真实统计数据(auditEventsToday: 4) |
systemSettings 查询 |
✅ |
返回真实系统设置(academicYear: 2025-2026) |
adminUsers 查询 |
⚠️ |
返回空(iam REST /v1/iam/users 未实现,降级模式 B) |
adminTeachers / adminStudents 查询 |
⚠️ |
返回空(core-edu 未接入,降级模式 B) |
adminSchools / adminGrades / adminDepartments 查询 |
⚠️ |
返回空(core-edu 未接入,降级模式 B) |
viewports / adminViewports 查询 |
⚠️ |
返回空(iam REST /v1/iam/viewports 返回空数组,DB 无 viewport 数据) |
| x-user-data-scope header 透传 |
✅ |
CallContext → context.ts → graphql.controller.ts → iam-grpc.client.ts |
typecheck / lint / build |
✅ |
三项零错误 |
1.2 已完成的关键修复
| # |
工作项 |
详情 |
| 1 |
admin.resolver.ts 扁平命名重构 |
ARB-001 裁决:adminUsers/adminRoles 直接挂载在根 Query/Mutation,不再使用 admin { users } 命名空间 |
| 2 |
graphql.controller.ts 深合并 resolvers |
mergeResolvers(teacherResolvers, adminResolvers) 深合并 Query/Mutation 字典,避免浅展开覆盖 |
| 3 |
x-user-data-scope header 透传链路 |
iam PermissionGuard 检查 data_scope=all 跳过权限校验,teacher-bff 全链路透传该 header |
| 4 |
IamGrpcController 注册修复 |
从 providers 数组移到 controllers 数组,修复 gRPC GetUserInfo UNIMPLEMENTED 错误 |
| 5 |
JWT RS256 密钥生成 |
使用 Node.js crypto 生成 iam-private.pem / iam-public.pem |
| 6 |
iam 种子数据 |
插入 4 个角色 + 11 个权限点 + 角色权限关联 + 审计日志 + 设置 data_scope='all' |
| 7 |
Dockerfile 修复(v2) |
node:20-alpine + bcryptjs(纯 JS)+ shared-ts 预编译 + pnpm prune --prod |
| 8 |
bcrypt → bcryptjs 迁移(v2) |
避免 native 编译依赖(python3/make/g++),API 完全兼容 |
| 9 |
NODE_ENV=production(v2) |
避免 pino-pretty 在 prune --prod 后缺失(dev 模式才使用 transport) |
| 10 |
IamModule 客户端选择逻辑修复(v2) |
按 IAM_GRPC_TARGET 是否配置选择 gRPC 或 mock,不再受 DEV_MODE 影响 |
| 11 |
DataScope 枚举大小写转换(v2) |
iam DB 存小写(self/all),GraphQL enum 需大写,在 iam-grpc.client.ts getUserInfo 中 toUpperCase() |
| 12 |
me 查询 dataScope 修复(v2) |
teacher.service.ts getCurrentUser 改用 userInfo.dataScope ?? perms.dataScope,REST /v1/iam/permissions/effective 不返回 dataScope 时回退到 gRPC GetUserInfo 的值 |
2. 上游依赖(teacher-bff 依赖谁)
2.1 iam 服务(ai06 负责)— P0
| # |
依赖项 |
用途 |
状态 |
| 1 |
gRPC GetUserInfo(userId) :50052 |
currentUser 查询:获取当前用户信息 + 角色 + 权限 |
✅ 已就绪 |
| 2 |
gRPC BatchGetUsers(userIds) :50052 |
adminUsers 查询:批量获取用户信息 |
✅ 已就绪 |
| 3 |
gRPC GetEffectivePermissions(userId) :50052 |
用户有效权限列表 |
✅ 已就绪 |
| 4 |
gRPC GetEffectiveDataScope(userId) :50052 |
用户数据范围(DataScope 6 级) |
✅ 已就绪 |
| 5 |
gRPC GetViewports(userId) :50052 |
adminViewports 查询:视口配置 |
✅ 已就绪 |
| 6 |
gRPC GetPublicKey() :50052 |
RS256 公钥(JWT 验签) |
✅ 已就绪 |
| 7 |
gRPC GetChildrenByParent(parentId) :50052 |
家长端:获取学生-家长关系 |
✅ 已就绪 |
| 8 |
REST GET /v1/iam/roles :3002 |
adminRoles 查询:角色列表 |
✅ 已就绪 |
| 9 |
REST GET /v1/iam/permissions :3002 |
adminPermissions 查询:权限点列表 |
✅ 已就绪 |
| 10 |
REST GET /v1/iam/audit :3002 |
auditLogs 查询:审计日志 |
✅ 已就绪 |
| 11 |
REST GET /v1/iam/viewports :3002 |
adminViewports 查询(备选) |
✅ 已就绪 |
| 12 |
REST GET /v1/iam/permissions/effective :3002 |
用户有效权限(备选) |
✅ 已就绪 |
| 13 |
GET /.well-known/jwks.json :3002 |
RS256 JWKS(api-gateway / push-gateway 验签) |
⏳ 待 iam 实现 |
| 14 |
POST /v1/iam/register / POST /v1/iam/login |
用户注册/登录(admin createUser 需要) |
✅ 已就绪 |
| 15 |
PATCH /v1/iam/users/:id |
用户更新(admin updateUser / toggleUserStatus 需要) |
⏳ 待 iam 实现 |
| 16 |
POST /v1/iam/roles / PATCH /v1/iam/roles/:id |
角色创建/更新(admin createRole / updateRolePermissions 需要) |
⏳ 待 iam 实现 |
关键环境变量:
IAM_GRPC_TARGET=iam:50052
IAM_SERVICE_URL=http://iam:3002
2.2 core-edu 服务(ai07 负责)— P1
| # |
依赖项 |
用途 |
状态 |
| 1 |
gRPC GetDashboard(teacherId) :50053 |
dashboard 查询:教师仪表盘聚合 |
⏳ 待 core-edu 实现 |
| 2 |
gRPC ListClasses(teacherId) :50053 |
classes / adminClasses 查询 |
⏳ 待 core-edu 实现 |
| 3 |
gRPC GetClass(classId) :50053 |
class 查询:班级详情 |
⏳ 待 core-edu 实现 |
| 4 |
gRPC ListExams(classId) :50053 |
exams 查询:考试列表 |
⏳ 待 core-edu 实现 |
| 5 |
gRPC ListHomework(classId) :50053 |
homework 查询:作业列表 |
⏳ 待 core-edu 实现 |
| 6 |
gRPC ListGrades(classId) :50053 |
grades 查询:成绩列表 |
⏳ 待 core-edu 实现 |
| 7 |
gRPC CreateExam(input) :50053 |
createExam mutation |
⏳ 待 core-edu 实现 |
| 8 |
gRPC AssignHomework(input) :50053 |
assignHomework mutation |
⏳ 待 core-edu 实现 |
| 9 |
gRPC RecordGrade(input) :50053 |
recordGrade mutation |
⏳ 待 core-edu 实现 |
| 10 |
gRPC GetClassPerformance(classId) :50053 |
classPerformance 查询 |
⏳ 待 core-edu 实现 |
| 11 |
gRPC ListSchools() / ListGrades(schoolId) :50053 |
adminSchools / adminGrades 查询 |
⏳ 待 core-edu 实现 |
| 12 |
gRPC ListDepartments(schoolId) :50053 |
adminDepartments 查询 |
⏳ 待 core-edu 实现 |
| 13 |
gRPC ListAcademicYears() :50053 |
adminAcademicYears 查询 |
⏳ 待 core-edu 实现 |
当前状态:teacher-bff 中 CORE_EDU_GRPC_TARGET 留空,相关查询走降级模式 B(返回空结果 + warning 日志)。
2.3 content 服务(ai08 负责)— P1
| # |
依赖项 |
用途 |
状态 |
| 1 |
gRPC GetKnowledgePath(classId) :50054 |
knowledgePath 查询 |
⏳ 待 content 实现 |
| 2 |
gRPC ListTextbooks() :50054 |
教材列表 |
⏳ 待 content 实现 |
| 3 |
gRPC ListChapters(textbookId) :50054 |
章节目录 |
⏳ 待 content 实现 |
| 4 |
gRPC ListLessonPlans(teacherId) :50054 |
adminLessonPlans 查询 |
⏳ 待 content 实现 |
| 5 |
gRPC ListCoursePlans(classId) :50054 |
adminCoursePlans 查询 |
⏳ 待 content 实现 |
2.4 data-ana 服务(ai11 负责)— P1
| # |
依赖项 |
用途 |
状态 |
| 1 |
gRPC GetStudentWeakness(classId) :50055 |
studentWeakness 查询 |
⏳ 待 data-ana 实现 |
| 2 |
gRPC GetLearningTrend(classId) :50055 |
learningTrend 查询 |
⏳ 待 data-ana 实现 |
| 3 |
gRPC GetGradeInsights(gradeId) :50055 |
adminGradeInsights 查询 |
⏳ 待 data-ana 实现 |
2.5 msg 服务(ai10 负责)— P1
| # |
依赖项 |
用途 |
状态 |
| 1 |
gRPC ListNotifications(userId) :50056 |
notifications 查询 |
⏳ 待 msg 实现 |
| 2 |
gRPC MarkNotificationRead(id) :50056 |
markNotificationAsRead mutation |
⏳ 待 msg 实现 |
| 3 |
gRPC ListAnnouncements(filter) :50056 |
adminAnnouncements 查询 |
⏳ 待 msg 实现 |
| 4 |
gRPC CreateAnnouncement(input) :50056 |
createAnnouncement mutation |
⏳ 待 msg 实现 |
| 5 |
gRPC PublishAnnouncement(id) :50056 |
publishAnnouncement mutation |
⏳ 待 msg 实现 |
2.6 ai 服务(ai12 负责)— P1
| # |
依赖项 |
用途 |
状态 |
| 1 |
gRPC GenerateQuestion(input) :50058 |
generateQuestion mutation |
⏳ 待 ai 实现 |
| 2 |
SSE POST /v1/ai/chat/stream :3008 |
AI 对话流式响应 |
⏳ 待 ai 实现 |
| 3 |
gRPC ListAiProviders() :50058 |
aiProviders 查询 |
⏳ 待 ai 实现 |
| 4 |
gRPC GetAiUsage() :50058 |
aiUsage 查询 |
⏳ 待 ai 实现 |
2.7 Redis(基础设施)— P0
| 项 |
内容 |
| 依赖内容 |
/readyz 探针 + DataLoader 缓存(P4+) |
| 端点 |
redis://edu-redis:6379 |
| 当前状态 |
✅ 本地 Docker edu-redis 已就绪 |
2.8 Kafka(基础设施)— P2
| 项 |
内容 |
| 依赖内容 |
可选:消费领域事件用于读模型刷新(P3+) |
| 端点 |
kafka:29092 |
| 当前状态 |
✅ 本地 Docker edu-kafka 已就绪 |
3. 下游依赖(谁依赖 teacher-bff)
3.1 admin-portal(ai16 负责)— P0
| 能力 |
配置 |
状态 |
POST /graphql :3003 |
admin-portal GraphQL 代理目标 |
✅ 已就绪 |
| 40 Query 字段(扁平命名) |
currentUser/adminUsers/adminRoles/adminPermissions/adminViewports/adminOrganization/adminClasses/adminTeachers/adminStudents/auditLogs/adminDashboard/systemSettings/auditOverviewStats/auditTrend/dataChangeLogs/loginLogs/adminSchools/adminGrades/adminGradeInsights/adminDepartments/adminAcademicYears/adminAnnouncements/adminInvitationCodes/adminFiles/adminFileStats/aiProviders/aiUsage + teacher 域 14 个 |
✅ 全部实现 |
| 20 Mutation 字段(扁平命名) |
createUser/updateUser/toggleUserStatus/createRole/updateRolePermissions/updateViewport/updateSystemSettings/createAnnouncement/publishAnnouncement/archiveAnnouncement/toggleAnnouncementPin/generateInvitationCodes/deleteInvitationCodes/deleteFiles/updateAiProvider + teacher 域 5 个 |
✅ 全部实现 |
| x-user-data-scope header 透传 |
admin 角色 data_scope=all 跳过 iam 权限校验 |
✅ 已实现 |
| 降级模式 B |
未就绪下游返回空结果 + warning |
✅ 已实现 |
portal 需求来源:apps/admin-portal/docs/nextstep.md §2.2
3.2 teacher-portal(ai13 负责)— P0
| 能力 |
配置 |
状态 |
POST /graphql :3003 |
teacher-portal GraphQL 代理目标 |
✅ 已就绪 |
| teacher 域 14 Query |
dashboard/viewports/me/classes/class/exams/homework/grades/knowledgePath/classPerformance/studentWeakness/learningTrend/notifications |
✅ 全部实现 |
| teacher 域 5 Mutation |
createExam/assignHomework/recordGrade/generateQuestion/markNotificationAsRead |
✅ 全部实现 |
SSE /v1/teacher/ai/chat/stream |
AI 对话流式透传 |
✅ 已实现(ai-chat-sse.controller.ts) |
| Zod 输入验证 |
createExam/assignHomework/recordGrade/generateQuestion |
✅ 已实现 |
portal 需求来源:apps/teacher-portal/nextstep.md
3.3 api-gateway(ai01 负责)— P0
| 能力 |
配置 |
状态 |
/api/v1/teacher/* 反向代理 |
→ teacher-bff:3003/*(路径重写剥离 /api/v1/teacher) |
✅ api-gateway 已配置 |
/api/admin/graphql 反向代理 |
→ teacher-bff:3003/graphql(路径重写剥离 /api/admin) |
✅ api-gateway 已配置 |
GET /healthz 端点 |
/readyz 下游健康检查 |
✅ 已实现 |
GET /readyz 端点 |
iam gRPC + Redis 健康检查 |
✅ 已实现 |
GET /metrics 端点 |
Prometheus 指标 |
✅ 已实现 |
4. GraphQL Schema 清单
4.1 Query 字段(40 个)
Teacher 域(14 个):dashboard / viewports / me / classes / class / exams / homework / grades / knowledgePath / classPerformance / studentWeakness / learningTrend / notifications / serverTime
Admin 域(26 个):currentUser / adminUsers / adminUser / adminRoles / adminPermissions / adminViewports / adminOrganization / adminClasses / adminTeachers / adminStudents / auditLogs / adminDashboard / systemSettings / auditOverviewStats / auditTrend / dataChangeLogs / loginLogs / adminSchools / adminGrades / adminGradeInsights / adminDepartments / adminAcademicYears / adminAnnouncements / adminInvitationCodes / adminFiles / adminFileStats / aiProviders / aiUsage
4.2 Mutation 字段(20 个)
Teacher 域(5 个):createExam / assignHomework / recordGrade / generateQuestion / markNotificationAsRead
Admin 域(15 个):createUser / updateUser / toggleUserStatus / createRole / updateRolePermissions / updateViewport / updateSystemSettings / createAnnouncement / publishAnnouncement / archiveAnnouncement / toggleAnnouncementPin / generateInvitationCodes / deleteInvitationCodes / deleteFiles / updateAiProvider
4.3 Schema 文件位置
packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql(SDL 定义)
5. 环境变量清单(Docker 部署)
| 变量 |
必填 |
示例值 |
说明 |
PORT |
是 |
3003 |
HTTP 监听端口 |
GRAPHQL_PATH |
否 |
/graphql |
GraphQL 端点路径 |
TEACHER_BFF_DEV_MODE |
是 |
true/false |
越权防御开关(P2 放行 / 生产拒绝) |
REDIS_URL |
是 |
redis://edu-redis:6379 |
Redis 连接地址 |
IAM_GRPC_TARGET |
是 |
iam:50052 |
iam gRPC 目标 |
IAM_SERVICE_URL |
是 |
http://iam:3002 |
iam REST 基址 |
CORE_EDU_GRPC_TARGET |
否 |
core-edu:50053 |
core-edu gRPC 目标(留空走降级) |
CONTENT_GRPC_TARGET |
否 |
content:50054 |
content gRPC 目标(留空走降级) |
DATA_ANA_GRPC_TARGET |
否 |
data-ana:50055 |
data-ana gRPC 目标(留空走降级) |
MSG_GRPC_TARGET |
否 |
msg:50056 |
msg gRPC 目标(留空走降级) |
AI_GRPC_TARGET |
否 |
ai:50058 |
ai gRPC 目标(留空走降级) |
OTEL_EXPORTER_OTLP_ENDPOINT |
否 |
http://otel-collector:4318 |
OTLP 上报端点 |
LOG_LEVEL |
否 |
info |
日志级别 |
6. 剩余工作
6.1 真实下游联调(按优先级)
| # |
工作项 |
阻塞条件 |
状态 |
| 1 |
core-edu gRPC 联调 |
core-edu 服务就绪 |
⏳ |
| 2 |
content gRPC 联调 |
content 服务就绪 |
⏳ |
| 3 |
data-ana gRPC 联调 |
data-ana 服务就绪 |
⏳ |
| 4 |
msg gRPC 联调 |
msg 服务就绪 |
⏳ |
| 5 |
ai gRPC + SSE 联调 |
ai 服务就绪 |
⏳ |
| 6 |
iam REST CRUD 端点联调(createUser/updateUser/createRole 等) |
iam 补齐 REST CRUD |
⏳ |
6.2 P6 硬化任务
| # |
工作项 |
状态 |
| 1 |
DataLoader 批量查询(防 N+1) |
⏳ 待下游就绪后实现 |
| 2 |
Redis 多层缓存 |
⏳ 待下游就绪后实现 |
| 3 |
熔断器(opossum)配置 |
✅ 已实现(circuit-breaker.ts) |
| 4 |
OTel trace 上报 |
✅ 已实现(tracer.ts) |
| 5 |
Prometheus 指标 |
✅ 已实现(metrics.ts) |
7. 已完成项汇总
| 工作项 |
状态 |
验证方式 |
| P2 核心 5 Query |
✅ |
typecheck + lint + Docker 联调 |
| P3 teacher 域 Query/Mutation |
✅ |
typecheck + lint + Docker 联调 |
| P4 学习分析 Query |
✅ |
typecheck + lint |
| P5 通知 + AI Query/Mutation |
✅ |
typecheck + lint |
| P6 admin 扁平命名重构(ARB-001) |
✅ |
typecheck + lint + Docker 联调 |
| P6 admin 41 Query + 20 Mutation |
✅ |
schema introspection + Docker 联调 |
| P6 x-user-data-scope header 透传 |
✅ |
Docker 联调(adminRoles 返回真实数据) |
| P6 IamGrpcController 注册修复 |
✅ |
Docker 联调(currentUser 返回真实数据) |
| P6 Zod 输入验证 |
✅ |
typecheck |
| P6 熔断器(opossum) |
✅ |
typecheck |
| P6 SSE 流式透传 |
✅ |
typecheck |
| Docker 镜像构建 |
✅ |
edu-test-teacher-bff:latest(v2 alpine + bcryptjs) |
| Docker 容器运行 |
✅ |
/healthz 200 + /readyz 200 |
| 真实 iam 联调(无 mock) |
✅ |
currentUser/me/adminRoles/adminPermissions/auditLogs/adminDashboard/systemSettings 全部返回真实数据 |
me 查询 dataScope 修复(v2) |
✅ |
teacher.service.ts 使用 userInfo.dataScope,Docker 验证返回 ALL |
| DataScope 大小写转换(v2) |
✅ |
iam-grpc.client.ts toUpperCase(),Docker 验证 GraphQL enum 正常解析 |
| IamModule 客户端选择修复(v2) |
✅ |
IAM_GRPC_TARGET 配置后强制 gRPC,DEV_MODE 不再触发 mock |
8. 关键文件路径
| 文件 |
用途 |
services/teacher-bff/src/admin/admin.resolver.ts |
admin GraphQL resolver(扁平命名) |
services/teacher-bff/src/admin/admin.service.ts |
admin 业务逻辑层 |
services/teacher-bff/src/teacher/teacher.resolver.ts |
teacher 域 GraphQL resolver |
services/teacher-bff/src/teacher/teacher.service.ts |
teacher 域业务逻辑层 |
services/teacher-bff/src/graphql/graphql.controller.ts |
GraphQL 入口 + mergeResolvers 深合并 |
services/teacher-bff/src/graphql/context.ts |
GraphQL 上下文(提取 x-user-* headers) |
services/teacher-bff/src/clients/iam/iam-grpc.client.ts |
iam gRPC + REST 客户端 |
services/teacher-bff/src/clients/types.ts |
CallContext(含 dataScope 字段) |
services/teacher-bff/src/clients/grpc/grpc.factory.ts |
gRPC 客户端工厂 |
services/teacher-bff/Dockerfile |
Docker 构建(含 shared-ts 预编译) |
packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql |
GraphQL schema 契约 |
packages/shared-proto/proto/iam.proto |
iam gRPC proto 契约 |
本文件由 ai03 维护,上游/下游工作项请各负责 AI 完成后通知 ai03 更新状态。