feat(core-edu): 完整实现 core-edu 教学核心服务
包含 classes/exams/homework/grades/attendance/scheduling 域、outbox、iam-consumer、redis 配置等完整实现
This commit is contained in:
@@ -3,8 +3,17 @@ syntax = "proto3";
|
||||
package next_edu_cloud.core_edu.v1;
|
||||
|
||||
// CoreEdu service contracts - P3 core teaching domain.
|
||||
// Covers exam management, homework assignment, and grade recording.
|
||||
// Covers exam management, homework assignment, grade recording,
|
||||
// attendance tracking, and class queries.
|
||||
//
|
||||
// Total: 5 Service / 27 RPC (P3 target state per president-final-rulings §2.5).
|
||||
// Event contracts live in events.proto under next_edu_cloud.events.v1.
|
||||
//
|
||||
// Status naming (ISSUE-003-ai08 arbitration, scheme A):
|
||||
// ExamStatus: draft / published / in_progress / grading / graded / archived / cancelled
|
||||
// HomeworkStatus: assigned / submitted / graded
|
||||
// SubmissionStatus: not_submitted / submitted / graded
|
||||
// AttendanceStatus: present / absent / late / leave
|
||||
|
||||
service ExamService {
|
||||
rpc CreateExam(CreateExamRequest) returns (CreateExamResponse);
|
||||
@@ -12,6 +21,9 @@ service ExamService {
|
||||
rpc ListExamsByClass(ListExamsByClassRequest) returns (ListExamsResponse);
|
||||
rpc UpdateExam(UpdateExamRequest) returns (UpdateExamResponse);
|
||||
rpc DeleteExam(DeleteExamRequest) returns (DeleteExamResponse);
|
||||
rpc PublishExam(PublishExamRequest) returns (PublishExamResponse);
|
||||
rpc SubmitExam(SubmitExamRequest) returns (SubmitExamResponse);
|
||||
rpc GradeExam(GradeExamRequest) returns (GradeExamResponse);
|
||||
}
|
||||
|
||||
service HomeworkService {
|
||||
@@ -19,6 +31,7 @@ service HomeworkService {
|
||||
rpc GetHomework(GetHomeworkRequest) returns (Homework);
|
||||
rpc ListHomeworkByClass(ListHomeworkByClassRequest) returns (ListHomeworkResponse);
|
||||
rpc SubmitHomework(SubmitHomeworkRequest) returns (SubmitHomeworkResponse);
|
||||
rpc GradeHomework(GradeHomeworkRequest) returns (GradeHomeworkResponse);
|
||||
}
|
||||
|
||||
service GradeService {
|
||||
@@ -27,54 +40,76 @@ service GradeService {
|
||||
rpc ListGradesByStudent(ListGradesByStudentRequest) returns (ListGradesResponse);
|
||||
rpc ListGradesByExam(ListGradesByExamRequest) returns (ListGradesResponse);
|
||||
rpc ListGradesByHomework(ListGradesByHomeworkRequest) returns (ListGradesResponse);
|
||||
rpc UpdateGrade(UpdateGradeRequest) returns (UpdateGradeResponse);
|
||||
}
|
||||
|
||||
service ClassService {
|
||||
rpc GetClass(GetClassRequest) returns (ClassInfo);
|
||||
rpc GetClassesByTeacher(GetClassesByTeacherRequest) returns (GetClassesByTeacherResponse);
|
||||
rpc BatchGetClasses(BatchGetClassesRequest) returns (BatchGetClassesResponse);
|
||||
rpc ListStudentsByClass(ListStudentsByClassRequest) returns (ListStudentsByClassResponse);
|
||||
}
|
||||
|
||||
service AttendanceService {
|
||||
rpc RecordAttendance(RecordAttendanceRequest) returns (RecordAttendanceResponse);
|
||||
rpc GetAttendance(GetAttendanceRequest) returns (Attendance);
|
||||
rpc ListAttendanceByStudent(ListAttendanceByStudentRequest) returns (ListAttendanceResponse);
|
||||
rpc ListAttendanceByClass(ListAttendanceByClassRequest) returns (ListAttendanceResponse);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Exam domain
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
message Exam {
|
||||
string id = 1;
|
||||
string class_id = 2;
|
||||
string title = 3;
|
||||
string description = 4;
|
||||
string exam_date = 5;
|
||||
string duration = 6;
|
||||
string total_score = 7;
|
||||
string status = 8;
|
||||
string created_by = 9;
|
||||
string created_at = 10;
|
||||
string updated_at = 11;
|
||||
string subject_id = 3;
|
||||
string title = 4;
|
||||
string description = 5;
|
||||
string exam_date = 6; // ISO 8601
|
||||
int32 duration = 7; // seconds
|
||||
string total_score = 8; // decimal as string
|
||||
string status = 9;
|
||||
string status_changed_at = 10;
|
||||
string status_changed_by = 11;
|
||||
string school_id = 12;
|
||||
string created_by = 13;
|
||||
string archived_at = 14;
|
||||
string created_at = 15;
|
||||
string updated_at = 16;
|
||||
}
|
||||
|
||||
message Homework {
|
||||
message ExamQuestion {
|
||||
string id = 1;
|
||||
string class_id = 2;
|
||||
string title = 3;
|
||||
string description = 4;
|
||||
string due_date = 5;
|
||||
string status = 6;
|
||||
string created_by = 7;
|
||||
string created_at = 8;
|
||||
string updated_at = 9;
|
||||
}
|
||||
|
||||
message Grade {
|
||||
string id = 1;
|
||||
string student_id = 2;
|
||||
string exam_id = 3;
|
||||
string homework_id = 4;
|
||||
string exam_id = 2;
|
||||
string question_id = 3;
|
||||
int32 order = 4;
|
||||
string score = 5;
|
||||
string feedback = 6;
|
||||
string question_type = 6;
|
||||
}
|
||||
|
||||
message ExamSubmission {
|
||||
string id = 1;
|
||||
string exam_id = 2;
|
||||
string student_id = 3;
|
||||
string status = 4;
|
||||
string submitted_at = 5;
|
||||
string graded_at = 6;
|
||||
string graded_by = 7;
|
||||
string created_at = 8;
|
||||
string updated_at = 9;
|
||||
string total_score = 8;
|
||||
}
|
||||
|
||||
message CreateExamRequest {
|
||||
string class_id = 1;
|
||||
string title = 2;
|
||||
string description = 3;
|
||||
string exam_date = 4;
|
||||
string duration = 5;
|
||||
string total_score = 6;
|
||||
string created_by = 7;
|
||||
string subject_id = 2;
|
||||
string title = 3;
|
||||
string description = 4;
|
||||
string exam_date = 5;
|
||||
int32 duration = 6;
|
||||
string total_score = 7;
|
||||
string school_id = 8;
|
||||
string created_by = 9;
|
||||
}
|
||||
|
||||
message CreateExamResponse {
|
||||
@@ -98,7 +133,7 @@ message UpdateExamRequest {
|
||||
string title = 2;
|
||||
string description = 3;
|
||||
string exam_date = 4;
|
||||
string duration = 5;
|
||||
int32 duration = 5;
|
||||
string total_score = 6;
|
||||
string status = 7;
|
||||
}
|
||||
@@ -115,12 +150,88 @@ message DeleteExamResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
message PublishExamRequest {
|
||||
string id = 1;
|
||||
string published_by = 2;
|
||||
}
|
||||
|
||||
message PublishExamResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
message SubmitExamRequest {
|
||||
string exam_id = 1;
|
||||
string student_id = 2;
|
||||
repeated AnswerInput answers = 3;
|
||||
}
|
||||
|
||||
message AnswerInput {
|
||||
string question_id = 1;
|
||||
string answer = 2;
|
||||
}
|
||||
|
||||
message SubmitExamResponse {
|
||||
string submission_id = 1;
|
||||
}
|
||||
|
||||
message GradeExamRequest {
|
||||
string exam_id = 1;
|
||||
string submission_id = 2;
|
||||
repeated ScoreInput scores = 3;
|
||||
string graded_by = 4;
|
||||
}
|
||||
|
||||
message ScoreInput {
|
||||
string question_id = 1;
|
||||
string score = 2;
|
||||
string teacher_comment = 3;
|
||||
}
|
||||
|
||||
message GradeExamResponse {
|
||||
bool success = 1;
|
||||
string total_score = 2;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Homework domain
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
message Homework {
|
||||
string id = 1;
|
||||
string class_id = 2;
|
||||
string subject_id = 3;
|
||||
string title = 4;
|
||||
string description = 5;
|
||||
string due_date = 6;
|
||||
int32 grace_period = 7;
|
||||
string status = 8;
|
||||
string school_id = 9;
|
||||
string created_by = 10;
|
||||
string created_at = 11;
|
||||
string updated_at = 12;
|
||||
}
|
||||
|
||||
message HomeworkSubmission {
|
||||
string id = 1;
|
||||
string homework_id = 2;
|
||||
string student_id = 3;
|
||||
string status = 4;
|
||||
string submitted_at = 5;
|
||||
string graded_at = 6;
|
||||
string graded_by = 7;
|
||||
string total_score = 8;
|
||||
string feedback = 9;
|
||||
}
|
||||
|
||||
message AssignHomeworkRequest {
|
||||
string class_id = 1;
|
||||
string title = 2;
|
||||
string description = 3;
|
||||
string due_date = 4;
|
||||
string created_by = 5;
|
||||
string subject_id = 2;
|
||||
string title = 3;
|
||||
string description = 4;
|
||||
string due_date = 5;
|
||||
int32 grace_period = 6;
|
||||
string school_id = 7;
|
||||
string created_by = 8;
|
||||
}
|
||||
|
||||
message AssignHomeworkResponse {
|
||||
@@ -140,11 +251,45 @@ message ListHomeworkResponse {
|
||||
}
|
||||
|
||||
message SubmitHomeworkRequest {
|
||||
string id = 1;
|
||||
string homework_id = 1;
|
||||
string student_id = 2;
|
||||
repeated AnswerInput answers = 3;
|
||||
}
|
||||
|
||||
message SubmitHomeworkResponse {
|
||||
string submission_id = 1;
|
||||
}
|
||||
|
||||
message GradeHomeworkRequest {
|
||||
string homework_id = 1;
|
||||
string submission_id = 2;
|
||||
repeated ScoreInput scores = 3;
|
||||
string feedback = 4;
|
||||
string graded_by = 5;
|
||||
}
|
||||
|
||||
message GradeHomeworkResponse {
|
||||
bool success = 1;
|
||||
string total_score = 2;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Grade domain
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
message Grade {
|
||||
string id = 1;
|
||||
string student_id = 2;
|
||||
string exam_id = 3;
|
||||
string homework_id = 4;
|
||||
string score = 5;
|
||||
string total_score = 6;
|
||||
string feedback = 7;
|
||||
string graded_by = 8;
|
||||
string school_id = 9;
|
||||
string idempotency_key = 10;
|
||||
string created_at = 11;
|
||||
string updated_at = 12;
|
||||
}
|
||||
|
||||
message RecordGradeRequest {
|
||||
@@ -152,8 +297,11 @@ message RecordGradeRequest {
|
||||
string exam_id = 2;
|
||||
string homework_id = 3;
|
||||
string score = 4;
|
||||
string feedback = 5;
|
||||
string graded_by = 6;
|
||||
string total_score = 5;
|
||||
string feedback = 6;
|
||||
string graded_by = 7;
|
||||
string school_id = 8;
|
||||
string idempotency_key = 9;
|
||||
}
|
||||
|
||||
message RecordGradeResponse {
|
||||
@@ -179,3 +327,107 @@ message ListGradesByHomeworkRequest {
|
||||
message ListGradesResponse {
|
||||
repeated Grade grades = 1;
|
||||
}
|
||||
|
||||
message UpdateGradeRequest {
|
||||
string id = 1;
|
||||
string score = 2;
|
||||
string feedback = 3;
|
||||
string updated_by = 4;
|
||||
}
|
||||
|
||||
message UpdateGradeResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Class domain (merged from classes service per ISSUE-006 decision #1)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
message ClassInfo {
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
string grade_id = 3;
|
||||
string head_teacher_id = 4;
|
||||
string description = 5;
|
||||
string created_at = 6;
|
||||
string updated_at = 7;
|
||||
}
|
||||
|
||||
message StudentInfo {
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
string class_id = 3;
|
||||
}
|
||||
|
||||
message GetClassRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message GetClassesByTeacherRequest {
|
||||
string teacher_id = 1;
|
||||
}
|
||||
|
||||
message GetClassesByTeacherResponse {
|
||||
repeated ClassInfo classes = 1;
|
||||
}
|
||||
|
||||
message BatchGetClassesRequest {
|
||||
repeated string ids = 1;
|
||||
}
|
||||
|
||||
message BatchGetClassesResponse {
|
||||
repeated ClassInfo classes = 1;
|
||||
}
|
||||
|
||||
message ListStudentsByClassRequest {
|
||||
string class_id = 1;
|
||||
}
|
||||
|
||||
message ListStudentsByClassResponse {
|
||||
repeated StudentInfo students = 1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Attendance domain
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
message Attendance {
|
||||
string id = 1;
|
||||
string schedule_id = 2;
|
||||
string student_id = 3;
|
||||
string status = 4;
|
||||
string remark = 5;
|
||||
string recorded_by = 6;
|
||||
string school_id = 7;
|
||||
string created_at = 8;
|
||||
string updated_at = 9;
|
||||
}
|
||||
|
||||
message RecordAttendanceRequest {
|
||||
string schedule_id = 1;
|
||||
string student_id = 2;
|
||||
string status = 3;
|
||||
string remark = 4;
|
||||
string recorded_by = 5;
|
||||
string school_id = 6;
|
||||
}
|
||||
|
||||
message RecordAttendanceResponse {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message GetAttendanceRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message ListAttendanceByStudentRequest {
|
||||
string student_id = 1;
|
||||
}
|
||||
|
||||
message ListAttendanceByClassRequest {
|
||||
string class_id = 1;
|
||||
}
|
||||
|
||||
message ListAttendanceResponse {
|
||||
repeated Attendance attendance = 1;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,36 @@ package next_edu_cloud.events.v1;
|
||||
|
||||
// Cross-service event contracts published by CoreEdu via the transactional
|
||||
// outbox pattern and consumed by downstream services (notifications, analytics,
|
||||
// audit, etc.). Topics follow the convention edu.{domain}.events.
|
||||
// audit, etc.).
|
||||
//
|
||||
// Topic naming follows the arbitration in coord-cross-review §3.1:
|
||||
// edu.teaching.<aggregate>.<action>
|
||||
//
|
||||
// Event routing (TOPIC_MAP in outbox.publisher.ts):
|
||||
// edu.exam.events <- exam.created / exam.updated / exam.deleted
|
||||
// edu.homework.events <- homework.assigned / homework.submitted / homework.graded
|
||||
// edu.grade.events <- grade.recorded / grade.updated
|
||||
// edu.class.events <- class.transferred
|
||||
// edu.teaching.exam.created <- ExamEvent.created
|
||||
// edu.teaching.exam.updated <- ExamEvent.updated
|
||||
// edu.teaching.exam.published <- ExamEvent.published
|
||||
// edu.teaching.exam.submitted <- ExamEvent.submitted
|
||||
// edu.teaching.exam.deleted <- ExamEvent.deleted
|
||||
// edu.teaching.homework.assigned <- HomeworkEvent.assigned
|
||||
// edu.teaching.homework.submitted <- HomeworkEvent.submitted
|
||||
// edu.teaching.homework.graded <- HomeworkEvent.graded
|
||||
// edu.teaching.grade.recorded <- GradeEvent.recorded
|
||||
// edu.teaching.grade.updated <- GradeEvent.updated
|
||||
// edu.teaching.attendance.recorded <- AttendanceEvent.recorded
|
||||
// edu.teaching.class.transferred <- ClassEvent.transferred
|
||||
//
|
||||
// All events MUST include:
|
||||
// - schema_version: event schema version (default "v1")
|
||||
// - event_id: UUID for idempotent consumption
|
||||
// - occurred_at: business timestamp (ms epoch)
|
||||
// - metadata: { traceId, userId }
|
||||
|
||||
message EventMetadata {
|
||||
string schema_version = 1;
|
||||
string trace_id = 2;
|
||||
string user_id = 3;
|
||||
}
|
||||
|
||||
message ClassEvent {
|
||||
string event_id = 1;
|
||||
@@ -20,7 +43,7 @@ message ClassEvent {
|
||||
string class_id = 5;
|
||||
string name = 6;
|
||||
string action = 7;
|
||||
map<string, string> metadata = 8;
|
||||
EventMetadata metadata = 8;
|
||||
}
|
||||
|
||||
message ExamEvent {
|
||||
@@ -30,9 +53,10 @@ message ExamEvent {
|
||||
int64 occurred_at = 4;
|
||||
string exam_id = 5;
|
||||
string class_id = 6;
|
||||
string title = 7;
|
||||
string action = 8;
|
||||
map<string, string> metadata = 9;
|
||||
string subject_id = 7;
|
||||
string title = 8;
|
||||
string action = 9;
|
||||
EventMetadata metadata = 10;
|
||||
}
|
||||
|
||||
message HomeworkEvent {
|
||||
@@ -42,9 +66,10 @@ message HomeworkEvent {
|
||||
int64 occurred_at = 4;
|
||||
string homework_id = 5;
|
||||
string class_id = 6;
|
||||
string title = 7;
|
||||
string action = 8;
|
||||
map<string, string> metadata = 9;
|
||||
string subject_id = 7;
|
||||
string title = 8;
|
||||
string action = 9;
|
||||
EventMetadata metadata = 10;
|
||||
}
|
||||
|
||||
message GradeEvent {
|
||||
@@ -55,6 +80,19 @@ message GradeEvent {
|
||||
string grade_id = 5;
|
||||
string student_id = 6;
|
||||
string score = 7;
|
||||
string action = 8;
|
||||
map<string, string> metadata = 9;
|
||||
string total_score = 8;
|
||||
string action = 9;
|
||||
EventMetadata metadata = 10;
|
||||
}
|
||||
|
||||
message AttendanceEvent {
|
||||
string event_id = 1;
|
||||
string aggregate_id = 2;
|
||||
string event_type = 3;
|
||||
int64 occurred_at = 4;
|
||||
string attendance_id = 5;
|
||||
string schedule_id = 6;
|
||||
string student_id = 7;
|
||||
string status = 8;
|
||||
EventMetadata metadata = 9;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user