Files
Edu/packages/shared-proto/proto/core_edu.proto

730 lines
18 KiB
Protocol Buffer

syntax = "proto3";
package next_edu_cloud.core_edu.v1;
// CoreEdu service contracts - P3 core teaching domain.
// Covers exam management, homework assignment, grade recording,
// attendance tracking, and class queries.
//
// Total: 9 Service / 40 RPC (P3.13 expanded state per downstream 9-module analysis).
// - ExamService: 10 RPC (8 original + SaveExamDraft + RecordExamViolation)
// - HomeworkService: 5 RPC
// - GradeService: 7 RPC (6 original + GetReportCard)
// - ClassService: 4 RPC
// - AttendanceService: 4 RPC
// - ScheduleService: 1 RPC (GetScheduleByStudent)
// - LeaveRequestService: 3 RPC
// - DashboardService: 2 RPC
// - AdminService: 4 RPC (aggregation stubs)
// 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
// LeaveRequestStatus: pending / approved / rejected / cancelled
service ExamService {
rpc CreateExam(CreateExamRequest) returns (CreateExamResponse);
rpc GetExam(GetExamRequest) returns (Exam);
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);
rpc SaveExamDraft(SaveExamDraftRequest) returns (SaveExamDraftResponse);
rpc RecordExamViolation(RecordExamViolationRequest) returns (RecordExamViolationResponse);
}
service HomeworkService {
rpc AssignHomework(AssignHomeworkRequest) returns (AssignHomeworkResponse);
rpc GetHomework(GetHomeworkRequest) returns (Homework);
rpc ListHomeworkByClass(ListHomeworkByClassRequest) returns (ListHomeworkResponse);
rpc SubmitHomework(SubmitHomeworkRequest) returns (SubmitHomeworkResponse);
rpc GradeHomework(GradeHomeworkRequest) returns (GradeHomeworkResponse);
}
service GradeService {
rpc RecordGrade(RecordGradeRequest) returns (RecordGradeResponse);
rpc GetGrade(GetGradeRequest) returns (Grade);
rpc ListGradesByStudent(ListGradesByStudentRequest) returns (ListGradesResponse);
rpc ListGradesByExam(ListGradesByExamRequest) returns (ListGradesResponse);
rpc ListGradesByHomework(ListGradesByHomeworkRequest) returns (ListGradesResponse);
rpc UpdateGrade(UpdateGradeRequest) returns (UpdateGradeResponse);
rpc GetReportCard(GetReportCardRequest) returns (ReportCard);
}
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);
}
service ScheduleService {
rpc GetScheduleByStudent(GetScheduleByStudentRequest) returns (GetScheduleByStudentResponse);
}
service LeaveRequestService {
rpc ListLeaveRequestsByStudent(ListLeaveRequestsByStudentRequest) returns (ListLeaveRequestsResponse);
rpc CreateLeaveRequest(CreateLeaveRequestRequest) returns (CreateLeaveRequestResponse);
rpc CancelLeaveRequest(CancelLeaveRequestRequest) returns (CancelLeaveRequestResponse);
}
service DashboardService {
rpc GetDashboard(GetDashboardRequest) returns (DashboardData);
rpc GetClassPerformance(GetClassPerformanceRequest) returns (ClassPerformance);
}
service AdminService {
rpc ListSchools(ListSchoolsRequest) returns (ListSchoolsResponse);
rpc ListGradeLevels(ListGradeLevelsRequest) returns (ListGradeLevelsResponse);
rpc ListDepartments(ListDepartmentsRequest) returns (ListDepartmentsResponse);
rpc ListAcademicYears(ListAcademicYearsRequest) returns (ListAcademicYearsResponse);
}
// ----------------------------------------------------------------------------
// Exam domain
// ----------------------------------------------------------------------------
message Exam {
string id = 1;
string class_id = 2;
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 ExamQuestion {
string id = 1;
string exam_id = 2;
string question_id = 3;
int32 order = 4;
string score = 5;
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 total_score = 8;
}
message CreateExamRequest {
string class_id = 1;
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 {
string id = 1;
}
message GetExamRequest {
string id = 1;
}
message ListExamsByClassRequest {
string class_id = 1;
}
message ListExamsResponse {
repeated Exam exams = 1;
}
message UpdateExamRequest {
string id = 1;
string title = 2;
string description = 3;
string exam_date = 4;
int32 duration = 5;
string total_score = 6;
string status = 7;
}
message UpdateExamResponse {
bool success = 1;
}
message DeleteExamRequest {
string id = 1;
}
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 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 {
string id = 1;
}
message GetHomeworkRequest {
string id = 1;
}
message ListHomeworkByClassRequest {
string class_id = 1;
}
message ListHomeworkResponse {
repeated Homework homework = 1;
}
message SubmitHomeworkRequest {
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 {
string student_id = 1;
string exam_id = 2;
string homework_id = 3;
string score = 4;
string total_score = 5;
string feedback = 6;
string graded_by = 7;
string school_id = 8;
string idempotency_key = 9;
}
message RecordGradeResponse {
string id = 1;
}
message GetGradeRequest {
string id = 1;
}
message ListGradesByStudentRequest {
string student_id = 1;
}
message ListGradesByExamRequest {
string exam_id = 1;
}
message ListGradesByHomeworkRequest {
string homework_id = 1;
}
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;
}
// ----------------------------------------------------------------------------
// Exam domain extensions (P3.13)
// ----------------------------------------------------------------------------
message SaveExamDraftRequest {
string exam_id = 1;
string student_id = 2;
repeated AnswerInput answers = 3;
}
message SaveExamDraftResponse {
string draft_id = 1;
}
message RecordExamViolationRequest {
string exam_id = 1;
string student_id = 2;
string violation_type = 3; // tab_switch / window_blur / copy_paste / fullscreen_exit / browser_devtools
string detail = 4;
int32 severity = 5; // 1=info, 2=warning, 3=critical
}
message RecordExamViolationResponse {
string violation_id = 1;
}
// ----------------------------------------------------------------------------
// Grade domain extensions (P3.13)
// ----------------------------------------------------------------------------
message GetReportCardRequest {
string student_id = 1;
string term_id = 2; // optional: filter by academic term
}
message ReportCard {
string student_id = 1;
string term_id = 2;
repeated ReportCardEntry entries = 3;
string overall_grade = 4;
string class_rank = 5;
string created_at = 6;
}
message ReportCardEntry {
string subject_id = 1;
string subject_name = 2;
string exam_score = 3;
string exam_total = 4;
string homework_score = 5;
string homework_total = 6;
string final_score = 7;
string grade_level = 8; // A / B / C / D / F
string teacher_comment = 9;
}
// ----------------------------------------------------------------------------
// Schedule domain extensions (P3.13)
// ----------------------------------------------------------------------------
message GetScheduleByStudentRequest {
string student_id = 1;
string week_start = 2; // ISO 8601 date, optional
}
message GetScheduleByStudentResponse {
repeated ScheduleSlotInfo slots = 1;
}
message ScheduleSlotInfo {
string id = 1;
string course_id = 2;
string course_name = 3;
string teacher_id = 4;
string class_id = 5;
string room_id = 6;
string start_time = 7; // ISO 8601
string end_time = 8; // ISO 8601
string subject_id = 9;
}
// ----------------------------------------------------------------------------
// LeaveRequest domain (P3.13)
// ----------------------------------------------------------------------------
message LeaveRequest {
string id = 1;
string student_id = 2;
string class_id = 3;
string leave_type = 4; // sick / personal / family / activity / other
string start_date = 5; // ISO 8601
string end_date = 6; // ISO 8601
string reason = 7;
string status = 8; // pending / approved / rejected / cancelled
string submitted_by = 9;
string reviewed_by = 10;
string review_comment = 11;
string school_id = 12;
string created_at = 13;
string updated_at = 14;
}
message ListLeaveRequestsByStudentRequest {
string student_id = 1;
string status = 2; // optional filter
}
message ListLeaveRequestsResponse {
repeated LeaveRequest leave_requests = 1;
}
message CreateLeaveRequestRequest {
string student_id = 1;
string class_id = 2;
string leave_type = 3;
string start_date = 4;
string end_date = 5;
string reason = 6;
string submitted_by = 7;
string school_id = 8;
}
message CreateLeaveRequestResponse {
string id = 1;
}
message CancelLeaveRequestRequest {
string id = 1;
string cancelled_by = 2;
}
message CancelLeaveRequestResponse {
bool success = 1;
}
// ----------------------------------------------------------------------------
// Dashboard domain (P3.13)
// ----------------------------------------------------------------------------
message GetDashboardRequest {
string teacher_id = 1;
}
message DashboardData {
string teacher_id = 1;
int32 total_classes = 2;
int32 total_students = 3;
int32 pending_homework = 4;
int32 upcoming_exams = 5;
int32 ungraded_submissions = 6;
repeated DashboardClassCard classes = 7;
repeated DashboardExamCard upcoming_exam_list = 8;
string generated_at = 9;
}
message DashboardClassCard {
string class_id = 1;
string class_name = 2;
int32 student_count = 3;
}
message DashboardExamCard {
string exam_id = 1;
string title = 2;
string exam_date = 3;
string class_id = 4;
string class_name = 5;
}
message GetClassPerformanceRequest {
string class_id = 1;
string subject_id = 2; // optional
}
message ClassPerformance {
string class_id = 1;
string class_name = 2;
int32 student_count = 3;
string average_score = 4;
string highest_score = 5;
string lowest_score = 6;
string median_score = 7;
repeated ClassPerformanceSubject subjects = 8;
string generated_at = 9;
}
message ClassPerformanceSubject {
string subject_id = 1;
string subject_name = 2;
string average_score = 3;
int32 student_count = 4;
}
// ----------------------------------------------------------------------------
// Admin aggregation domain (P3.13 stubs)
// ----------------------------------------------------------------------------
message ListSchoolsRequest {
// no params - returns all schools (admin scope)
}
message ListSchoolsResponse {
repeated SchoolInfo schools = 1;
}
message SchoolInfo {
string id = 1;
string name = 2;
string address = 3;
string principal_id = 4;
string created_at = 5;
}
message ListGradeLevelsRequest {
string school_id = 1;
}
message ListGradeLevelsResponse {
repeated GradeLevelInfo grade_levels = 1;
}
message GradeLevelInfo {
string id = 1;
string name = 2; // 如 "7年级"
string school_id = 3;
int32 order = 4;
}
message ListDepartmentsRequest {
string school_id = 1;
}
message ListDepartmentsResponse {
repeated DepartmentInfo departments = 1;
}
message DepartmentInfo {
string id = 1;
string name = 2;
string school_id = 3;
string head_id = 4;
string created_at = 5;
}
message ListAcademicYearsRequest {
string school_id = 1; // optional
}
message ListAcademicYearsResponse {
repeated AcademicYearInfo academic_years = 1;
}
message AcademicYearInfo {
string id = 1;
string name = 2; // 如 "2025-2026 第一学期"
string school_id = 3;
string start_date = 4;
string end_date = 5;
bool is_current = 6;
}