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 项联调待办。
This commit is contained in:
SpecialX
2026-07-14 17:54:37 +08:00
parent abde336876
commit 78e406b317
32 changed files with 2086 additions and 13 deletions

View File

@@ -23,6 +23,7 @@ service ChapterService {
service KnowledgeGraphService {
rpc GetPrerequisites(GetPrerequisitesRequest) returns (KnowledgePointsResponse);
rpc GetLearningPath(GetLearningPathRequest) returns (LearningPath);
rpc GetKnowledgePath(GetKnowledgePathRequest) returns (LearningPath);
rpc AddPrerequisite(AddPrerequisiteRequest) returns (Empty);
rpc RemovePrerequisite(RemovePrerequisiteRequest) returns (Empty);
}
@@ -38,6 +39,24 @@ service QuestionService {
rpc SearchQuestions(SearchQuestionsRequest) returns (SearchQuestionsResponse);
}
service ElectiveService {
rpc ListAvailableElectiveCourses(ListAvailableElectiveCoursesRequest) returns (ListElectiveCoursesResponse);
rpc ListElectiveSelectionsByStudent(ListElectiveSelectionsByStudentRequest) returns (ListElectiveSelectionsResponse);
rpc SelectCourse(SelectCourseRequest) returns (ElectiveSelection);
rpc DropCourse(DropCourseRequest) returns (Empty);
}
service LessonPlanService {
rpc ListLessonPlansByTeacher(ListLessonPlansByTeacherRequest) returns (ListLessonPlansResponse);
rpc ListLessonPlansByStudent(ListLessonPlansByStudentRequest) returns (ListLessonPlansResponse);
rpc GetLessonPlan(GetLessonPlanRequest) returns (LessonPlan);
}
service CoursePlanService {
rpc ListCoursePlansByStudent(ListCoursePlansByStudentRequest) returns (ListCoursePlansResponse);
rpc GetCoursePlan(GetCoursePlanRequest) returns (CoursePlan);
}
message Empty {}
message Textbook {
@@ -272,3 +291,124 @@ message SearchQuestionsResponse {
int32 total = 2;
string next_page_token = 3;
}
// KnowledgeGraphService: GetKnowledgePath (按班级查询学习路径)
message GetKnowledgePathRequest {
string class_id = 1;
string subject_id = 2;
}
// ElectiveService messages
message ElectiveCourse {
string id = 1;
string title = 2;
string subject_id = 3;
string teacher_id = 4;
int32 capacity = 5;
int32 enrolled_count = 6;
string status = 7;
string description = 8;
int64 created_at = 9;
int64 updated_at = 10;
}
message ElectiveSelection {
string id = 1;
string student_id = 2;
string course_id = 3;
string status = 4;
int64 selected_at = 5;
int64 dropped_at = 6;
}
message ListAvailableElectiveCoursesRequest {
string subject_id = 1;
int32 page_size = 2;
string page_token = 3;
}
message ListElectiveCoursesResponse {
repeated ElectiveCourse courses = 1;
string next_page_token = 2;
}
message ListElectiveSelectionsByStudentRequest {
string student_id = 1;
string status = 2;
}
message ListElectiveSelectionsResponse {
repeated ElectiveSelection selections = 1;
}
message SelectCourseRequest {
string student_id = 1;
string course_id = 2;
}
message DropCourseRequest {
string student_id = 1;
string course_id = 2;
}
// LessonPlanService messages
message LessonPlan {
string id = 1;
string teacher_id = 2;
string class_id = 3;
string subject_id = 4;
string title = 5;
string content = 6;
string status = 7;
google.protobuf.Struct metadata = 8;
int64 created_at = 9;
int64 updated_at = 10;
}
message ListLessonPlansByTeacherRequest {
string teacher_id = 1;
string class_id = 2;
string subject_id = 3;
}
message ListLessonPlansByStudentRequest {
string student_id = 1;
string class_id = 2;
}
message ListLessonPlansResponse {
repeated LessonPlan lesson_plans = 1;
}
message GetLessonPlanRequest {
string id = 1;
}
// CoursePlanService messages
message CoursePlan {
string id = 1;
string student_id = 2;
string class_id = 3;
string subject_id = 4;
string title = 5;
string plan_type = 6;
string content = 7;
string status = 8;
google.protobuf.Struct metadata = 9;
int64 created_at = 10;
int64 updated_at = 11;
}
message ListCoursePlansByStudentRequest {
string student_id = 1;
string class_id = 2;
string plan_type = 3;
}
message ListCoursePlansResponse {
repeated CoursePlan course_plans = 1;
}
message GetCoursePlanRequest {
string id = 1;
}