Merge worktree branch merge-15-modules-to-main-5ug5xJ

This commit is contained in:
SpecialX
2026-07-10 15:28:20 +08:00
parent 60d7173545
commit df62ffc176
51 changed files with 11559 additions and 1908 deletions

View File

@@ -1,7 +1,8 @@
# teacher-bff 对接契约
> 负责人ai03
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[core_edu.proto](../../../packages/shared-proto/proto/core_edu.proto)、[content.proto](../../../packages/shared-proto/proto/content.proto)、[analytics.proto](../../../packages/shared-proto/proto/analytics.proto)、[msg.proto](../../../packages/shared-proto/proto/msg.proto)、[ai.proto](../../../packages/shared-proto/proto/ai.proto)
> 版本v22026-07-10对齐 president §2.7/§2.17/§5.1 + coord B5/B8 + port-allocation §5
> 关联:[matrix.md](../matrix.md)、[iam.proto](../../../../packages/shared-proto/proto/iam.proto)、[core_edu.proto](../../../../packages/shared-proto/proto/core_edu.proto)、[content.proto](../../../../packages/shared-proto/proto/content.proto)、[analytics.proto](../../../../packages/shared-proto/proto/analytics.proto)、[msg.proto](../../../../packages/shared-proto/proto/msg.proto)、[ai.proto](../../../../packages/shared-proto/proto/ai.proto)、[coord-final-decisions.md §2 B1-B8](../../coord-final-decisions.md)、[president-final-rulings.md §2.7/§2.17/§5.1](../../president-final-rulings.md)
---
@@ -9,42 +10,77 @@
### 1.1 gRPC 接口(如有)
无对外 gRPC。teacher-bff 是 GraphQL 聚合层。
无对外 gRPC。teacher-bff 是 GraphQL 聚合层B1 裁决P2 起直接 GraphQL
### 1.2 HTTP 端点(如有)
| Method | Path | 用途 | 认证 |
| ------ | -------- | ----------------------------------------- | ----------------------- |
| POST | /graphql | 教师 BFF GraphQL 端点 | JWT 必需 + teacher 角色 |
| GET | /graphql | GraphQL Playground开发环境 | 开发环境公开 |
| GET | /healthz | 健康检查liveness | 公开 |
| GET | /readyz | 就绪检查readiness含下游 gRPC 连通性 | 公开 |
| Method | Path | 用途 | 认证 | 裁决依据 |
| ------ | -------- | ----------------------------------------- | ----------------------- | -------- |
| POST | /graphql | 教师 BFF GraphQL 端点 | JWT 必需 + teacher 角色 | B1 |
| GET | /graphql | GraphQL Playground开发环境,生产关闭 | 开发环境公开 | ARB-001 |
| GET | /healthz | 健康检查liveness | 公开 | G3 |
| GET | /readyz | 就绪检查readiness按阶段扩展下游探针 | 公开 | G2 + §2.4 |
### 1.3 GraphQL schema如 BFF
GraphQL schema 文件路径:`apps/teacher-bff/src/schema/*.graphql`(端口 :3003
**SDL-first**president §2.17 裁决schema 文件路径:
```
packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql
```
> 文件命名遵循 president §2.17 统一规范 `<bff-name>.schema.graphql`,由 ai03 起草、coord 在批次 1 启动前仲裁第一版。
> 前端 AIai13/ai16通过 graphql-codegen 生成 TS 类型消费。
核心 Query / Mutation 域:
- **auth**currentUser聚合 iam.GetUserInfo + GetEffectivePermissions + GetViewports
- **classes**myClasses聚合 core-edu.ClassService.GetClassesByTeacher
- **students**classStudents聚合 core-edu.ClassService.ListStudentsByClass + iam.BatchGetUsers 补用户名)
- **exams**classExams / createExam / updateExam聚合 core-edu.ExamService
- **homework**classHomework / assignHomework聚合 core-edu.HomeworkService
- **grades**studentGrades / recordGrade聚合 core-edu.GradeService
- **attendance**classAttendance / recordAttendance聚合 core-edu.AttendanceService
- **content**textbooks / chapters / knowledgePoints / questions聚合 content 4 个 Service
- **dashboard**teacherDashboard聚合 data-ana.AnalyticsService.GetTeacherDashboard
- **notifications**myNotifications / markAsRead聚合 msg.NotificationService
- **ai**aiChat / generateQuestion / generateLessonPlan聚合 ai.AiService
| 域 | Query / Mutation | 聚合下游 | 阶段 |
| -------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------ |
| **auth** | currentUser | iam.GetUserInfo + GetEffectivePermissions + GetViewports | P2 |
| **dashboard** | teacherDashboard | P2: iam gRPC用户基础信息下游字段返 null + extensions.warning<br>P3+: data-ana.GetTeacherDashboard | P2 null → P4 真实 |
| **classes** | myClasses | P2: iam gRPC按 president §3.5P2 班级列表来自 iam 数据)<br>P3+: core-edu.ClassService.GetClassesByTeacher | P2 iam → P3 core-edu |
| **students** | classStudents | core-edu.ClassService.ListStudentsByClass + iam.BatchGetUsers | P3+ |
| **exams** | classExams / createExam / updateExam / deleteExam | core-edu.ExamService | P3+ |
| **homework** | classHomework / assignHomework | core-edu.HomeworkService | P3+ |
| **grades** | studentGrades / recordGrade | core-edu.GradeService | P3+ |
| **attendance** | classAttendance / recordAttendance | core-edu.AttendanceServiceC4 裁决 P3 补全) | P3+ |
| **content** | textbooks / chapters / knowledgePoints / questions | content 4 个 Service | P4+ |
| **notifications** | myNotifications / markAsRead | msg.NotificationService | P5+ |
| **ai** | aiChat / generateQuestion / generateLessonPlan | ai.AiServiceA4 裁决 P5 补全 GenerateLessonPlan | P5+ |
| **admin.\*** | admin.schoolStats / admin.listClasses / admin.listTeachers 等 | admin 命名空间,复用 teacher-bff endpointpresident §5.1 | P2 预留 schema / P6 实现 |
**admin 命名空间预留**president §5.1 + §7.3 强制):
- **P2 预留**schema 文件中预留 `admin.*` Query/Mutation 命名空间占位(含类型定义但 Resolver 返 null
- **P6 实现**ai16 admin-portal 复用 teacher-bff GraphQL endpointai03 在 P6 实现 admin Resolver 真实数据
- **理由**admin 操作低 QPS无需独立 admin-bff 服务;减少 ai16 工作量
### 1.4 Kafka 事件发布(如有)
无。teacher-bff 不发布事件,仅做 gRPC 聚合。
无。teacher-bff 不发布事件,仅做 gRPC 聚合B7 裁决P2-P4 不订阅 KafkaP5 push-gateway 落地后再订阅)
### 1.5 错误码前缀
`BFF_TEACHER_`如 BFF_TEACHER_UPSTREAM_UNAVAILABLE、BFF_TEACHER_AGGREGATION_FAILED、BFF_TEACHER_FORBIDDEN
`BFF_TEACHER_`B5 + G14 裁决,统一 BFF_ 前缀)。
**BFF 越权防御 3 类错误码**president §2.7 裁决):
| 错误码 | HTTP | 场景 | i18n key |
| -------------------------------- | ---- | ---------------------------------------------------- | ------------------------------------- |
| `BFF_TEACHER_UNAUTHORIZED` | 401 | x-user-id 缺失或无效 | `error.bffTeacher.unauthorized` |
| `BFF_TEACHER_FORBIDDEN_RESOURCE` | 403 | teacherId 与资源无归属关系(场景 A | `error.bffTeacher.forbidden_resource` |
| `BFF_TEACHER_IDENTITY_MISMATCH` | 403 | JWT teacherId 与请求 body teacherId 不一致(场景 B | `error.bffTeacher.identity_mismatch` |
**其他 BFF_TEACHER_ 错误码**(聚合层):
| 错误码 | HTTP | 场景 |
| ------------------------------------- | ---- | -------------------------------------- |
| `BFF_TEACHER_UPSTREAM_UNAVAILABLE` | 502 | 下游 gRPC 不可达 |
| `BFF_TEACHER_AGGREGATION_FAILED` | 500 | 聚合多下游时部分失败且无降级数据 |
| `BFF_TEACHER_VALIDATION_FAILED` | 400 | 输入参数校验失败 |
| `BFF_TEACHER_INTERNAL_ERROR` | 500 | 兜底内部错误 |
**B3 裁决澄清**BFF 豁免 `@RequirePermission` 指不做"功能权限决策",但必须做"数据权限防御"B4 越权防御,见 §3.3)。
---
@@ -52,38 +88,115 @@ GraphQL schema 文件路径:`apps/teacher-bff/src/schema/*.graphql`(端口 :
### 2.1 gRPC 调用(同步)
| 被调用方 | Service.RPC | 用途 | mock 策略 |
| --------------- | ------------------------------------- | ---------------- | ----------------------------------------------- |
| iam (ai06) | IamService.GetUserInfo | 获取当前教师信息 | iam 就绪前返回固定 UserInfoteacher 角色) |
| iam (ai06) | IamService.BatchGetUsers | 批量补全学生姓名 | iam 就绪前返回固定用户名("学生001"~"学生030" |
| iam (ai06) | IamService.GetEffectivePermissions | 权限校验 | iam 就绪前返回全权限(放行) |
| iam (ai06) | IamService.GetViewports | 教师导航菜单 | iam 就绪前返回固定视口列表 |
| core-edu (ai08) | ClassService.GetClassesByTeacher | 教师班级列表 | core-edu 就绪前返回固定 3 个 ClassInfo |
| core-edu (ai08) | ClassService.ListStudentsByClass | 班级学生名单 | core-edu 就绪前返回固定 30 个 StudentInfo |
| core-edu (ai08) | ExamService.* | 考试管理 | core-edu 就绪前返回固定考试数据 |
| core-edu (ai08) | HomeworkService.* | 作业管理 | core-edu 就绪前返回固定作业数据 |
| core-edu (ai08) | GradeService.* | 成绩管理 | core-edu 就绪前返回固定成绩数据 |
| core-edu (ai08) | AttendanceService.* | 考勤管理 | core-edu 就绪前返回固定考勤数据 |
| content (ai09) | TextbookService.ListTextbooks | 教材列表 | content 就绪前返回固定 5 个教材 |
| content (ai09) | ChapterService.ListChapters | 章节列表 | content 就绪前返回固定章节树 |
| content (ai09) | KnowledgeGraphService.* | 知识图谱 | content 就绪前返回固定知识点 |
| content (ai09) | QuestionService.SearchQuestions | 题库检索 | content 就绪前返回固定 20 题 |
| data-ana (ai11) | AnalyticsService.GetTeacherDashboard | 教师仪表盘 | data-ana 就绪前返回固定仪表盘数据 |
| data-ana (ai11) | AnalyticsService.GetClassPerformance | 班级成绩分析 | data-ana 就绪前返回固定分析数据 |
| data-ana (ai11) | AnalyticsService.GetWarningList | 预警列表 | data-ana 就绪前返回固定 5 条预警 |
| msg (ai10) | NotificationService.ListNotifications | 教师通知列表 | msg 就绪前返回固定 10 条通知 |
| msg (ai10) | NotificationService.MarkAsRead | 标记已读 | msg 就绪前返回 success=true |
| ai (ai12) | AiService.Chat | AI 对话 | ai 就绪前返回固定回复 |
| ai (ai12) | AiService.GenerateQuestion | AI 出题 | ai 就绪前返回固定题目 |
| ai (ai12) | AiService.GenerateLessonPlan | AI 备课 | ai 就绪前返回固定教案 |
**B2 裁决**:首次实现即 gRPC 调用下游,禁止 REST fetch 过渡。
**B8 裁决**:通过 `DownstreamClient` 抽象统一封装BFF 模式 v2 标准抽象3 个 BFF 共用)。
> **RPC 现状标注说明**
> - ✅ = proto 中已定义(按 packages/shared-proto/proto/ 现状核对)
> - ❌ = proto 中未定义,待 coord 补全(已在裁决中明确补全时机)
#### 2.1.1 iam (ai06) — gRPC 50052
| Service.RPC | 用途 | 现状 | 阶段 | mock 策略 |
| --------------------------------- | ---------------- | ---- | ---- | ------------------------------------------- |
| IamService.GetUserInfo | 获取当前教师信息 | ✅ | P2 | 返回固定 UserInfoteacher 角色) |
| IamService.GetViewports | 教师导航菜单 | ❌ | P2 | 返回固定视口列表(待 coord 补 proto |
| IamService.GetEffectivePermissions | 权限校验 | ❌ | P2 | 返回全权限(放行) |
| IamService.BatchGetUsers | 批量补全学生姓名 | ❌ | P3+ | 返回固定用户名("学生001"~"学生030" |
| IamService.GetEffectiveDataScope | 数据范围校验 | ❌ | P3+ | 返回 OWN 范围 |
| IamService.GetChildrenByParent | parent-bff 用)| ❌ | P4 | teacher-bff 不调用 |
> iam.proto 现状仅 4 RPCRegister/Login/RefreshToken/GetUserInfomatrix.md §2 标称 12 RPC待 ai06 + coord 按 I1-I8 裁决补全。
#### 2.1.2 core-edu (ai08) — gRPC 50053
| Service.RPC | 用途 | 现状 | 阶段 | mock 策略 |
| ------------------------------------ | -------------- | ---- | ---- | ---------------------------------- |
| ExamService.CreateExam | 创建考试 | ✅ | P3 | 返回固定 examId |
| ExamService.GetExam | 获取考试详情 | ✅ | P3 | 返回固定考试数据 |
| ExamService.ListExamsByClass | 按班级列考试 | ✅ | P3 | 返回固定 5 场考试 |
| ExamService.UpdateExam | 更新考试 | ✅ | P3 | 返回 success=true |
| ExamService.DeleteExam | 删除考试 | ✅ | P3 | 返回 success=true |
| HomeworkService.AssignHomework | 布置作业 | ✅ | P3 | 返回固定 homeworkId |
| HomeworkService.GetHomework | 获取作业详情 | ✅ | P3 | 返回固定作业数据 |
| HomeworkService.ListHomeworkByClass | 按班级列作业 | ✅ | P3 | 返回固定 5 份作业 |
| HomeworkService.SubmitHomework | 提交作业 | ✅ | P3 | 返回 success=truestudent-bff 用)|
| GradeService.RecordGrade | 录入成绩 | ✅ | P3 | 返回 success=true |
| GradeService.GetGrade | 获取成绩 | ✅ | P3 | 返回固定成绩数据 |
| GradeService.ListGradesByStudent | 按学生列成绩 | ✅ | P3 | 返回固定 10 条成绩 |
| GradeService.ListGradesByExam | 按考试列成绩 | ✅ | P3 | 返回固定 30 条成绩 |
| GradeService.ListGradesByHomework | 按作业列成绩 | ✅ | P3 | 返回固定 30 条成绩 |
| ClassService.GetClassesByTeacher | 教师班级列表 | ❌ | P3 | 返回固定 3 个 ClassInfo |
| ClassService.ListStudentsByClass | 班级学生名单 | ❌ | P3 | 返回固定 30 个 StudentInfo |
| ClassService.BatchGetClasses | 批量获取班级 | ❌ | P3 | 返回固定班级数据 |
| AttendanceService.RecordAttendance | 记录考勤 | ❌ | P3 | 返回 success=trueC4 裁决补全) |
| AttendanceService.GetClassAttendance | 查询考勤 | ❌ | P3 | 返回固定考勤数据C4 裁决补全) |
> core_edu.proto 现状 14 RPCExamService 5 + HomeworkService 4 + GradeService 5matrix.md §2 标称 22 RPC 5 Service待 coord 按 C4/C5 裁决补 AttendanceService + ClassServiceGetClassesByTeacher / ListStudentsByClass / BatchGetClasses
#### 2.1.3 content (ai09) — gRPC 50054
| Service.RPC | 用途 | 现状 | 阶段 | mock 策略 |
| ------------------------------------ | ------------ | ---- | ---- | ------------------------------- |
| TextbookService.ListTextbooks | 教材列表 | ✅ | P4 | 返回固定 5 个教材 |
| TextbookService.GetTextbook | 获取教材详情 | ✅ | P4 | 返回固定教材数据 |
| TextbookService.CreateTextbook | 创建教材 | ✅ | P4 | 返回固定 textbookId |
| KnowledgeGraphService.GetPrerequisites | 知识点前置 | ✅ | P4 | 返回固定知识点依赖 |
| KnowledgeGraphService.GetLearningPath | 学习路径 | ✅ | P4 | 返回固定学习路径 |
| ChapterService.ListChapters | 章节列表 | ❌ | P4 | 返回固定章节树N5 裁决补全) |
| ChapterService.GetChapter | 章节详情 | ❌ | P4 | 返回固定章节N5 裁决补全) |
| QuestionService.SearchQuestions | 题库检索 | ❌ | P4 | 返回固定 20 题N3 裁决补全) |
> content.proto 现状 5 RPCTextbookService 3 + KnowledgeGraphService 2matrix.md §2 标称 18 RPC 4 Service待 coord 按 N3/N5 裁决补 ChapterService + QuestionService。
#### 2.1.4 data-ana (ai11) — gRPC 50055
| Service.RPC | 用途 | 现状 | 阶段 | mock 策略 |
| ------------------------------------ | -------------- | ---- | ---- | ---------------------------------- |
| AnalyticsService.GetClassPerformance | 班级成绩分析 | ✅ | P4 | 返回固定分析数据 |
| AnalyticsService.GetStudentWeakness | 学生薄弱点 | ✅ | P4 | 返回固定 3 个薄弱知识点 |
| AnalyticsService.GetLearningTrend | 学习趋势 | ✅ | P4 | 返回固定 12 个月趋势 |
| AnalyticsService.GetTeacherDashboard | 教师仪表盘 | ❌ | P4 | 返回固定仪表盘数据D4 裁决补全) |
| AnalyticsService.GetWarningList | 预警列表 | ❌ | P4 | 返回固定 5 条预警D4 裁决补全) |
| AnalyticsService.GetMasteryDistribution | 知识掌握分布 | ❌ | P4 | 返回固定分布数据D4 裁决补全) |
| AnalyticsService.SubscribeMasteryUpdate (stream) | 掌握度订阅 | ❌ | P5+ | 流式 mockD4 裁决补全) |
> analytics.proto 现状 3 RPCmatrix.md §2 标称 12 RPC待 coord 按 D4 裁决补全 4 端 Dashboard + Warning + MasteryDistribution + SubscribeMasteryUpdate Stream RPC。
#### 2.1.5 msg (ai10) — gRPC 50056
| Service.RPC | 用途 | 现状 | 阶段 | mock 策略 |
| ---------------------------------------- | ------------ | ---- | ---- | ---------------------------------- |
| NotificationService.SendNotification | 发送通知 | ✅ | P5 | 返回固定 notificationId |
| NotificationService.ListNotifications | 教师通知列表 | ✅ | P5 | 返回固定 10 条通知 |
| NotificationService.MarkAsRead | 标记已读 | ✅ | P5 | 返回 success=true |
| NotificationService.SearchNotifications | 搜索通知 | ✅ | P5 | 返回固定搜索结果 |
| NotificationPreferenceService.* | 通知偏好 | ❌ | P5 | 返回默认偏好(待 coord 补 proto |
| NotificationTemplateService.* | 通知模板 | ❌ | P5 | 返回固定模板(待 coord 补 proto |
> msg.proto 现状 4 RPCNotificationServicematrix.md §2 标称 13 RPC 3 Service待 coord 补 NotificationPreferenceService + NotificationTemplateService。
#### 2.1.6 ai (ai12) — gRPC 50058
| Service.RPC | 用途 | 现状 | 阶段 | mock 策略 |
| --------------------------------- | -------- | ---- | ---- | ------------------------------- |
| AiService.Chat | AI 对话 | ✅ | P5 | 返回固定回复 |
| AiService.StreamChat (stream) | 流式对话 | ✅ | P5 | 流式 mockSSE |
| AiService.GenerateQuestion | AI 出题 | ✅ | P5 | 返回固定题目 |
| AiService.OptimizeExpression | 表达优化 | ✅ | P5 | 返回固定优化结果 |
| AiService.GenerateLessonPlan | AI 备课 | ❌ | P5 | 返回固定教案A4 裁决补全) |
| AiService.StreamGenerateQuestion (stream) | 流式出题 | ❌ | P5 | 流式 mockA4 裁决补全) |
> ai.proto 现状 4 RPCmatrix.md §2 标称 6 RPC待 coord 按 A4 裁决补 GenerateLessonPlan + StreamGenerateQuestion。
> **端口说明**ai 服务端口为 **50058**port-allocation.md §5 最终值push-gateway 50057 豁免释放后 50058 让给 ai
### 2.2 Kafka 事件订阅(异步)
无。teacher-bff 不订阅 Kafka 事件,仅同步 gRPC 聚合。
无。teacher-bff 不订阅 Kafka 事件B7 裁决P2-P4 不订阅,仅同步聚合P5 push-gateway 落地后再订阅,届时评估订阅 edu.notification.* 用于实时通知推送)
### 2.3 HTTP 调用(如有)
无。
无。B2 裁决:首次实现即 gRPC禁止 REST fetch。
---
@@ -91,21 +204,53 @@ GraphQL schema 文件路径:`apps/teacher-bff/src/schema/*.graphql`(端口 :
### 3.1 我依赖的上游就绪标志
- [ ] iam gRPC 50052 启用ai06
- [ ] core-edu gRPC 50053 启用ai08
- [ ] content gRPC 50054 启用ai09
- [ ] data-ana gRPC 50055 启用ai11
- [ ] msg gRPC 50056 启用ai10
- [ ] ai gRPC 50057 启用ai12
| 上游 | AI | 就绪信号 | 阶段 |
| ---------- | ---- | ------------------------------------------------ | ---- |
| iam | ai06 | gRPC 50052 + 12 RPC + HealthService SERVING | P2 |
| core-edu | ai08 | gRPC 50053 + 22 RPC + HealthService SERVING | P3 |
| content | ai09 | gRPC 50054 + 18 RPC + HealthService SERVING | P4 |
| data-ana | ai11 | gRPC 50055 + 12 RPC + HealthService SERVING | P4 |
| msg | ai10 | gRPC 50056 + 13 RPC + HealthService SERVING | P5 |
| ai | ai12 | gRPC 50058 + 6 RPC + HealthService SERVING | P5 |
| coord | coord | shared-ts DownstreamClient 抽象包就绪B8 裁决)| P2 启动前 |
| coord | coord | teacher-bff.schema.graphql 第一版仲裁完成(含 admin namespace| P2 启动前 |
### 3.2 我的就绪标志(供下游消费)
- [ ] teacher-bff GraphQL :3003 启用(/healthz 返回 200
- [ ] /readyz 返回 200含 6 个下游 gRPC 连通性检查)
- [ ] GraphQL schema 可内省POST /graphql 返回 schema
- [ ] 核心 Query 可执行currentUser / myClasses / teacherDashboard
- [ ] 核心 Mutation 可执行createExam / assignHomework / recordGrade
- [ ] admin namespace 可用(供 admin-portal 消费)
| 信号 | 阶段 | 消费方 |
| --------------------------------------------- | ---- | ------------------- |
| teacher-bff GraphQL :3003 启用(/healthz 200| P2 | teacher-portal |
| /readyz 返回 200按阶段扩展探针见 §3.3 | P2+ | api-gateway |
| GraphQL schema 可内省POST /graphql | P2 | teacher-portal / admin-portal |
| 核心 Query 可执行currentUser / myClasses / teacherDashboard | P2 | teacher-portal |
| 核心 Mutation 可执行createExam / assignHomework / recordGrade | P3 | teacher-portal |
| admin namespace 预留schema 含 admin.* 类型P6 实现 Resolver| P2 预留 / P6 实现 | admin-portal |
| DownstreamClient 抽象落地3 BFF 共用B8 | P2 | student-bff / parent-bff |
### 3.3 /readyz 探针按阶段扩展president §2.4 + G2
**DownstreamHealthCheck 注册表模式**,每个下游注册独立探针,按阶段启用:
| 阶段 | 探针列表 | 项数 |
| ---- | --------------------------------------------------------------------- | ---- |
| P2 | Redis PING + iam gRPC 50052 | 2 |
| P3 | + core-edu gRPC 50053 | 3 |
| P4 | + content gRPC 50054 + data-ana gRPC 50055 | 5 |
| P5 | + ai gRPC 50058 + msg gRPC 50056 | 7 |
> 总裁裁决 §2.4:探针列表扩展属"跨阶段扩展例外"president §2.3),允许新增探针但禁止修改已有探针检查项。
> **软失败规则**必需依赖Redis / 已启用 gRPC 下游)失败返 503可选依赖Kafka 消费 / 未启用 gRPC 下游)失败仅告警返 200 + `degraded: true`。
### 3.4 越权防御B4 + president §2.9
**AuthorizationGuard** 实现 teacherId 与资源归属校验:
| 阶段 | 实现方式 | 裁决依据 |
| ---- | --------------------------------------------------------------------- | -------- |
| P2 | DEV_MODE 放行(环境变量 TEACHER_BFF_DEV_MODE=true+ 日志告警 | §2.9 |
| P3+ | 接入 core-edu gRPC 真实校验GetClassesByTeacher 比对 teacherId | §2.9 |
> B3 裁决澄清BFF 豁免 `@RequirePermission` 不做"功能权限决策",但必须做"数据权限防御"B4。错误码见 §1.5。
---
@@ -124,7 +269,7 @@ GraphQL schema 文件路径:`apps/teacher-bff/src/schema/*.graphql`(端口 :
### 4.2 我消费的 mock
在真实上游就绪前teacher-bff 使用以下 mock详见 §2.1 mock 策略列):
在真实上游就绪前teacher-bff 使用以下 mock详见 §2.1 各表的 mock 策略列):
- **iam mock**:固定 UserInfo + 全权限 + 固定视口
- **core-edu mock**:固定班级/学生/考试/作业/成绩/考勤数据
@@ -133,4 +278,4 @@ GraphQL schema 文件路径:`apps/teacher-bff/src/schema/*.graphql`(端口 :
- **msg mock**:固定通知列表 + MarkAsRead success
- **ai mock**:固定 AI 回复/题目/教案
> 所有上游 mock 通过 gRPC client 拦截器实现,上游就绪后移除拦截器切换真实调用。
> 所有上游 mock 通过 gRPC client 拦截器实现DownstreamClient 抽象内置 mock 开关B8 裁决),上游就绪后移除拦截器切换真实调用。