Files
Edu/services/content/docs/nextstep-v2.md
SpecialX 78e406b317 feat(content): v2 扩展 Elective/LessonPlan/CoursePlan 三业务域
新增 3 个业务域(10 RPC):
- ElectiveService: 选修课列表/学生选课记录/选课/退课(含容量与重复校验)
- LessonPlanService: 教师备课列表/学生备课列表(仅 published)/详情
- CoursePlanService: 学生课程计划列表/详情
- KnowledgeGraphService.GetKnowledgePath: 与 GetLearningPath 同实现

新增 4 张 MySQL 表(elective_courses/selections/lesson_plans/course_plans),含完整索引。

新增 11 个权限点,覆盖 admin/teacher/student/parent 四角色。

proto 由 4 Service/22 RPC 扩展至 7 Service/32 RPC,v1 全部 RPC 保持向后兼容。

修复 logger.ts pino 导入: default import 在 NodeNext ESM 下不可调用,
改用 named import(与 iam/msg/core-edu 对齐)。

Docker 本地测试全部通过(HTTP + gRPC 双协议),健康检查、
Elective/LessonPlan/CoursePlan CRUD、4 个新 gRPC Service 全部验证通过。

nextstep-v2.md 已创建,记录上下游依赖与 6 项联调待办。
2026-07-14 17:54:37 +08:00

342 lines
21 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.
# content 下一步工作与上下游依赖v2
> 模块content内容域服务7 Service / 32 RPC端口 HTTP 3005 / gRPC 50054
> 更新日期2026-07-14v2 全部完成Docker 本地测试通过)
> 关联文档:[nextstep.md](./nextstep.md)、[02-architecture-design.md](./02-architecture-design.md)
---
## 1. v2 完成项
content 模块在 v1 基础上扩展了 3 个业务域Elective / LessonPlan / CoursePlan+ 1 个查询入口GetKnowledgePath新增 10 个 RPC、4 张 MySQL 表、11 个权限点HTTP + gRPC 双协议本地 Docker 全部测试通过。
### 1.1 v2 服务能力概览
| Service | RPC 数 | v1 已有 | v2 新增 | 核心能力 |
| --------------------- | ------ | ------- | ------- | ------------------------------------------------------ |
| TextbookService | 5 | 5 | 0 | 教材 CRUD、归档、版本 |
| ChapterService | 5 | 5 | 0 | 章节 CRUD、目录树 |
| KnowledgeGraphService | 5 | 4 | 1 | 知识图谱、学习路径、前置依赖、可视化、GetKnowledgePath |
| QuestionService | 8 | 8 | 0 | 题目 CRUD、ES 检索、审核状态机、AI 出题 |
| **ElectiveService** | 4 | 0 | 4 | 选修课列表 / 学生选课记录 / 选课 / 退课 |
| **LessonPlanService** | 3 | 0 | 3 | 教师备课列表 / 学生备课列表 / 详情 |
| **CoursePlanService** | 2 | 0 | 2 | 学生课程计划列表 / 详情 |
| **合计** | **32** | 22 | **10** | **7 Service** |
### 1.2 v2 新增 RPC 列表
| Service | RPC | 用途 |
| --------------------- | ------------------------------- | -------------------------------------------------------------------- |
| KnowledgeGraphService | GetKnowledgePath | 知识图谱路径查询(与 GetLearningPath 同实现,符合上游 BFF 命名约定) |
| ElectiveService | ListAvailableElectiveCourses | 列出可选选修课status=open 且有剩余容量) |
| ElectiveService | ListElectiveSelectionsByStudent | 查询学生已选选修课 |
| ElectiveService | SelectCourse | 学生选课(含容量校验 + 重复选课校验) |
| ElectiveService | DropCourse | 学生退课(同步 enrolled_count 减 1 |
| LessonPlanService | ListLessonPlansByTeacher | 教师视角备课列表 |
| LessonPlanService | ListLessonPlansByStudent | 学生视角备课列表(仅 status=published |
| LessonPlanService | GetLessonPlan | 备课详情 |
| CoursePlanService | ListCoursePlansByStudent | 学生课程计划列表 |
| CoursePlanService | GetCoursePlan | 课程计划详情 |
### 1.3 v2 新增数据表
| 表名 | 用途 | 索引 |
| --------------------------- | ------------ | ------------------------------------------ |
| content_elective_courses | 选修课主表 | subject_id / teacher_id / status |
| content_elective_selections | 学生选课记录 | student_id / course_id / status |
| content_lesson_plans | 教师备课计划 | teacher_id / class_id / status |
| content_course_plans | 学生课程计划 | student_id / class_id / plan_type / status |
迁移 SQL[v2-migration.sql](./v2-migration.sql)
### 1.4 v2 新增权限点
| 权限常量 | admin | teacher | student | parent |
| -------------------------- | ----- | ------- | ------- | ------ |
| CONTENT_ELECTIVE_CREATE | ✅ | ✅ | ❌ | ❌ |
| CONTENT_ELECTIVE_READ | ✅ | ✅ | ✅ | ✅ |
| CONTENT_ELECTIVE_SELECT | ❌ | ❌ | ✅ | ❌ |
| CONTENT_LESSON_PLAN_CREATE | ✅ | ✅ | ❌ | ❌ |
| CONTENT_LESSON_PLAN_READ | ✅ | ✅ | ✅ | ✅ |
| CONTENT_LESSON_PLAN_UPDATE | ✅ | ✅ | ❌ | ❌ |
| CONTENT_LESSON_PLAN_DELETE | ✅ | ✅ | ❌ | ❌ |
| CONTENT_COURSE_PLAN_CREATE | ✅ | ✅ | ❌ | ❌ |
| CONTENT_COURSE_PLAN_READ | ✅ | ✅ | ✅ | ✅ |
| CONTENT_COURSE_PLAN_UPDATE | ✅ | ✅ | ❌ | ❌ |
| CONTENT_COURSE_PLAN_DELETE | ✅ | ✅ | ❌ | ❌ |
### 1.5 v2 Docker 本地测试结果2026-07-14
测试环境:本地 Dockeredu-mysql + edu-neo4j + edu-es + edu-kafka + edu-redis + edu-content-test
```
镜像edu/content:test
容器edu-content-testDEV_MODE=trueHTTP 3105 / gRPC 51054
测试 1健康检查
GET /healthz → {"status":"ok"} ✅
GET /readyz → {"status":"ok","dependencies":[mysql:ok, neo4j:ok, kafka:ok, outbox:ok, elasticsearch:ok]} ✅
测试 2Elective CRUD全部通过
POST /electives/courses → 创建选修课 ✅ (id=rtssmkviljmmkpa04npvklq0)
GET /electives/courses → 列表 ✅ (count=1)
POST /electives/select → 学生选课 ✅ (id=js987vhi63xnnxyxov2yttbg)
GET /electives/selections → 学生选课记录 ✅ (count=1, status=selected)
POST /electives/drop → 退课 ✅
测试 3LessonPlan CRUD全部通过
POST /lesson-plans → 创建备课 ✅ (id=gxgozqgr059y4w0v9ndhm6mt, status=draft)
PUT /lesson-plans/:id → 发布备课 ✅ (status=published)
GET /lesson-plans?teacherId=.. → 教师列表 ✅ (count=1)
GET /lesson-plans?studentId=..&classId=.. → 学生列表(仅 published ✅ (count=1)
GET /lesson-plans/:id → 详情 ✅
DELETE /lesson-plans/:id → 删除 ✅
测试 4CoursePlan CRUD全部通过
POST /course-plans → 创建课程计划 ✅ (id=za9r3arn8hetr5nwjao9dgre, status=active)
GET /course-plans?studentId=.. → 学生列表 ✅ (count=1)
GET /course-plans/:id → 详情 ✅
PUT /course-plans/:id → 更新 ✅ (status=archived)
DELETE /course-plans/:id → 删除 ✅
测试 5gRPC 4 个新 Service全部通过
ElectiveService.ListAvailableElectiveCourses → ✅ 返回 1 个课程
LessonPlanService.ListLessonPlansByTeacher → ✅ 返回空(已删除测试数据)
CoursePlanService.ListCoursePlansByStudent → ✅ 返回空(已删除测试数据)
KnowledgeGraphService.GetKnowledgePath → ✅ 返回 1 个知识点
测试 6gRPC Controller 注册(启动日志验证)
7 个 gRPC controller 全部注册 ✅
8 个 HTTP controller 全部注册 ✅
Neo4jSyncWorker / EsSyncWorker / OutboxPublisher 全部启动 ✅
```
---
## 2. 上游需求满足情况content → 上游 BFF
content 已实现上游 3 个 BFF 在 nextstep-v2.md 中提出的全部 v2 依赖。
### 2.1 teacher-bffai03 负责)
| # | teacher-bff 依赖项 | content 实现 RPC | 状态 |
| --- | ---------------------------------------- | -------------------------------------------- | ---- |
| 1 | gRPC `GetKnowledgePath(classId)` :50054 | `KnowledgeGraphService.GetKnowledgePath` | ✅ |
| 2 | gRPC `ListTextbooks()` :50054 | `TextbookService.ListTextbooks`v1 已有) | ✅ |
| 3 | gRPC `ListLessonPlans(teacherId)` :50054 | `LessonPlanService.ListLessonPlansByTeacher` | ✅ |
### 2.2 student-bffai04 负责)
| # | student-bff 依赖项 | content 实现 RPC | 状态 |
| --- | ------------------------------------------------- | -------------------------------------------------- | ---- |
| 1 | `TextbookService.ListTextbooks` | `TextbookService.ListTextbooks`v1 已有) | ✅ |
| 2 | `ChapterService.ListChapters` | `ChapterService.ListChapters`v1 已有) | ✅ |
| 3 | `KnowledgeGraphService.GetLearningPath` | `KnowledgeGraphService.GetLearningPath`v1 已有) | ✅ |
| 4 | `ElectiveService.ListElectiveSelectionsByStudent` | `ElectiveService.ListElectiveSelectionsByStudent` | ✅ |
| 5 | `ElectiveService.ListAvailableElectiveCourses` | `ElectiveService.ListAvailableElectiveCourses` | ✅ |
| 6 | `ElectiveService.SelectCourse` | `ElectiveService.SelectCourse` | ✅ |
| 7 | `ElectiveService.DropCourse` | `ElectiveService.DropCourse` | ✅ |
| 8 | `LessonPlanService.ListLessonPlansByStudent` | `LessonPlanService.ListLessonPlansByStudent` | ✅ |
| 9 | `LessonPlanService.GetLessonPlan` | `LessonPlanService.GetLessonPlan` | ✅ |
| 10 | `CoursePlanService.ListCoursePlansByStudent` | `CoursePlanService.ListCoursePlansByStudent` | ✅ |
| 11 | `CoursePlanService.GetCoursePlan` | `CoursePlanService.GetCoursePlan` | ✅ |
### 2.3 parent-bffai05 负责)
| # | parent-bff 依赖项 | content 实现 RPC | 状态 |
| --- | ---------------------------- | -------------------------------------------------------------- | ---- |
| 1 | `CoursePlanService.List/Get` | `CoursePlanService.ListCoursePlansByStudent` + `GetCoursePlan` | ✅ |
| 2 | `LessonPlanService.List/Get` | `LessonPlanService.ListLessonPlansByStudent` + `GetLessonPlan` | ✅ |
| 3 | `ElectiveService.List` | `ElectiveService.ListElectiveSelectionsByStudent` | ✅ |
### 2.4 api-gatewayai01 负责)
| 路由 | 转发目标 | 状态 |
| ------------------------------- | ------------ | ------------------------------ |
| `/api/v1/textbooks/*` | content:3005 | ✅ v1 已配置 |
| `/api/v1/chapters/*` | content:3005 | ✅ v1 已配置 |
| `/api/v1/knowledge-points/*` | content:3005 | ✅ v1 已配置 |
| `/api/v1/questions/*` | content:3005 | ✅ v1 已配置 |
| **`/api/v1/electives/*`** | content:3005 | ⏳ 待 api-gateway 补充 v2 路由 |
| **`/api/v1/lesson-plans/*`** | content:3005 | ⏳ 待 api-gateway 补充 v2 路由 |
| **`/api/v1/course-plans/*`** | content:3005 | ⏳ 待 api-gateway 补充 v2 路由 |
| **`/api/v1/knowledge-graph/*`** | content:3005 | ⏳ 待 api-gateway 补充 v2 路由 |
---
## 3. 下游需求content 需要谁)
### 3.1 MySQL基础设施— ✅ 已就绪
v2 新增 4 张表已通过 `v2-migration.sql` 在本地 Docker MySQL 中创建。
### 3.2 Neo4j / Kafka / Elasticsearch / Redis — ✅ 已就绪
v2 复用 v1 基础设施,无新增依赖。
### 3.3 ai 服务ai12 负责)— ⏳ 待联调
| # | 依赖项 | 用途 | 状态 |
| --- | ------------------------------ | ----------------------------------- | ----------------- |
| 1 | gRPC `GenerateQuestion` :50058 | AI 批量出题QuestionService 联调) | ⏳ 待 ai 服务就绪 |
### 3.4 iam 服务ai06 负责)— ⏳ 待联调
| # | 依赖项 | 用途 | 状态 |
| --- | -------------------------------------------- | ------------------------------------------- | ------------------ |
| 1 | JWT 公钥 / JWKS 端点 | 生产模式 JWT 校验DEV_MODE=true 时已绕过) | ⏳ 待 iam 服务就绪 |
| 2 | 用户角色信息admin/teacher/student/parent | 权限守卫根据角色判断访问权限 | ⏳ 待 iam 服务就绪 |
### 3.5 core-edu 服务ai07 负责)— ⏳ 待联调v3+
| # | 依赖项 | 用途 | 状态 |
| --- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| 1 | 班级学生名单查询 | LessonPlan 学生视角:按 classId 过滤学生所在班级的备课计划。当前实现需前端在 query 中显式传 classId未来可由 core-edu 提供学生→班级映射后自动解析 | ⏳ v3+ |
| 2 | 教师任教科目查询 | LessonPlan/CoursePlan 按 subjectId 过滤时,前端需显式传参。未来可由 core-edu 提供教师→科目映射 | ⏳ v3+ |
---
## 4. 环境变量v2 无新增)
v2 沿用 v1 全部环境变量,详见 [nextstep.md §4](./nextstep.md#4-环境变量清单)。
---
## 5. 待上下游完成的工作
### 5.1 给 api-gatewayai01
**v2 路由补充**:在 `services/api-gateway` 的路由配置中新增以下 4 条反向代理规则,剥离 `/api` 前缀后转发到 `content:3005`
| 路由 | 转发目标 | 备注 |
| --------------------------- | ------------ | ---------------------------------------------------------------------------------------------------- |
| `/api/v1/electives/*` | content:3005 | 选修课管理(含 /electives/courses、/electives/selections、/electives/select、/electives/drop |
| `/api/v1/lesson-plans/*` | content:3005 | 备课计划管理 |
| `/api/v1/course-plans/*` | content:3005 | 课程计划管理 |
| `/api/v1/knowledge-graph/*` | content:3005 | 知识图谱可视化v1 已有路由 `/api/v1/knowledge-points`,但 `/knowledge-graph/visualization` 需补充) |
### 5.2 给 teacher-bffai03
**content gRPC 客户端联调**
1. 配置 `CONTENT_GRPC_TARGET=content:50054`(已配置)
2.`services/teacher-bff/src/clients/content/content-grpc.client.ts` 中确认 3 个 RPC 调用:
- `KnowledgeGraphService.GetKnowledgePath`request: `{ subject_id }`response: `LearningPath`
- `TextbookService.ListTextbooks`v1 已有)
- `LessonPlanService.ListLessonPlansByTeacher`request: `{ teacher_id }`response: `ListLessonPlansResponse`
3. 移除 mock 降级逻辑,切换到真实 gRPC 调用
### 5.3 给 student-bffai04
**content gRPC 客户端联调**
1. 配置 `CONTENT_GRPC_TARGET=content:50054`
2. 确认 11 个 content RPC 调用(详见 §2.2),重点验证 v2 新增 8 个 RPC
- ElectiveService4 个):`ListAvailableElectiveCourses` / `ListElectiveSelectionsByStudent` / `SelectCourse` / `DropCourse`
- LessonPlanService2 个):`ListLessonPlansByStudent` / `GetLessonPlan`
- CoursePlanService2 个):`ListCoursePlansByStudent` / `GetCoursePlan`
3. 移除 mock 降级逻辑,切换到真实 gRPC 调用
### 5.4 给 parent-bffai05
**content gRPC 客户端联调**
1. 配置 `CONTENT_GRPC_TARGET=content:50054`
2. 确认 6 个 content RPC 调用(详见 §2.3
- CoursePlanService.ListCoursePlansByStudent + GetCoursePlan
- LessonPlanService.ListLessonPlansByStudent + GetLessonPlan
- ElectiveService.ListElectiveSelectionsByStudent
3. 移除 mock 降级逻辑,切换到真实 gRPC 调用
### 5.5 给 iamai06
**生产 JWT 联调**
content 在生产模式下需要 iam 的 JWKS 端点校验 JWT。当前 `DEV_MODE=true` 已绕过校验使用预定义角色。iam 就绪后:
1. 提供 JWKS 端点 URL配置 `JWT_JWKS_URI`
2. JWT payload 中包含 `role` 字段admin/teacher/student/parent
3. content 的 `permission.guard.ts` 已支持上述 4 种角色 + 11 个 v2 权限点
### 5.6 给 ai 服务ai12
**AI 出题联调**
content 的 `QuestionService.BatchCreateQuestions` 已预留 AI 出题入口,需要 ai 服务实现:
1. gRPC `GenerateQuestion` :50058
2. 输入:知识点 ID + 题目数量 + 难度
3. 输出:题目数组(题干 + 选项 + 答案 + 解析)
4. content 配置 `AI_GRPC_TARGET=ai:50058`
---
## 6. 契约变更说明
### 6.1 proto 变更
**文件**`packages/shared-proto/proto/content.proto`
**v2 新增**
- 1 个 RPC`KnowledgeGraphService.GetKnowledgePath`
- 3 个 Service`ElectiveService` / `LessonPlanService` / `CoursePlanService`
- 9 个新 RPC
- 13 个新 messageElectiveCourse / ElectiveSelection / LessonPlan / CoursePlan 及其 Request/Response
**向后兼容**v1 全部 22 个 RPC 保持不变,无破坏性变更。
### 6.2 数据库变更
**文件**`infra/init-sql/02-all-services-schema.sql`(已更新 4.6-4.9 节)+ `services/content/docs/v2-migration.sql`
**v2 新增 4 张表**:见 §1.3。
### 6.3 权限变更
**文件**`services/content/src/middleware/permission.guard.ts`
**v2 新增 11 个权限点**:见 §1.4。
---
## 7. 关键文件路径
| 文件 | 用途 |
| -------------------------------------------------------------- | -------------------------------------- |
| `packages/shared-proto/proto/content.proto` | gRPC 契约v2: 32 RPC / 7 Service |
| `services/content/src/electives/` | 选修课模块schema/dto/repo/svc/ctrl |
| `services/content/src/lesson-plans/` | 备课计划模块 |
| `services/content/src/course-plans/` | 课程计划模块 |
| `services/content/src/grpc/elective.grpc.controller.ts` | 选修课 gRPC controller |
| `services/content/src/grpc/lesson-plan.grpc.controller.ts` | 备课计划 gRPC controller |
| `services/content/src/grpc/course-plan.grpc.controller.ts` | 课程计划 gRPC controller |
| `services/content/src/grpc/knowledge-graph.grpc.controller.ts` | 知识图谱 gRPC controllerv2 扩展) |
| `services/content/src/grpc/grpc-types.ts` | gRPC TypeScript 类型定义 |
| `services/content/src/middleware/permission.guard.ts` | 权限守卫v2 新增 11 权限) |
| `services/content/docs/v2-migration.sql` | v2 数据库迁移 SQL |
| `infra/init-sql/02-all-services-schema.sql` | 全量 schema含 v2 新表) |
---
## 8. 剩余工作
| # | 工作项 | 阶段 | 状态 |
| ------------------------------ | ------------------------------------------------------ | ------- | ---------------- |
| 1 | Elective / LessonPlan / CoursePlan 三业务域实现 | v2 | ✅ 完成 |
| 4 张新表 + 迁移 SQL | v2 | ✅ 完成 |
| 11 个新权限点 + 角色映射 | v2 | ✅ 完成 |
| GetKnowledgePath RPC | v2 | ✅ 完成 |
| HTTP + gRPC 双协议 Docker 测试 | v2 | ✅ 完成 |
| 2 | api-gateway 补充 4 条 v2 路由 | v2 联调 | ⏳ 待 ai01 |
| 3 | teacher-bff / student-bff / parent-bff 切换到真实 gRPC | v2 联调 | ⏳ 待 ai03/04/05 |
| 4 | iam 生产 JWT 联调 | v2 联调 | ⏳ 待 ai06 |
| 5 | ai 服务 AI 出题联调BatchCreateQuestions | 联调 | ⏳ 待 ai12 |
| 6 | core-edu 班级/科目映射(学生视角自动解析 classId | v3+ | ⏳ 待 ai07 |
content 模块 v2 自身功能已全部完成,剩余工作均为上下游联调。
---
**本文件由 content 模块维护,上下游工作项请各负责 AI 完成后通知更新状态。**