Courses API¶
1. Course List (Authenticated)¶
GET /api/v1/courses
Query (optional):
teacher_id: teachers query their own courses.class_name: students query courses by class.start_date: filter start date byCourseOccurrence.occurrence_date(YYYY-MM-DD).end_date: filter end date byCourseOccurrence.occurrence_date(YYYY-MM-DD).
Returns: basic course information plus sessions.
sessions is always the per-occurrence CourseOccurrence detail
list and is no longer grouped by schedule_key.
Notes:
sessions.weekdayis a string enum:MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY.sessionsincludesid,occurrence_date,weekday,sections,start_time,end_time,classroom,classroom_id,status,source_type, andremark.sessionsreturns only occurrences that are not cancelled (status != cancelled).When
start_date/end_dateis provided, only courses with occurrences in that date range are returned, andsessionsis also trimmed to that range.API callers such as web and Mini Program clients should make decisions based on this enum value and must not depend on the backend database’s internal integer encoding.
The legacy
0-6integer weekday protocol is not supported.
2. Import Timetable from Excel (superadmin / secretary)¶
POST /api/v1/courses/import
Content-Type: multipart/form-data
Fields:
file: Excel file (.xlsx/.xls).semester_start_date: semester start date (YYYY-MM-DD).
Notes:
Permission:
superadmin/secretaryonly.File format:
.xlsx/.xls; maximum size 50 MB.The template is generated by the backend. Column order: course name, teacher name, weekday, sections, week range, remarks, classroom, administrative class, grade, teaching building, classroom type, floor, course sequence number, course code, administrative class count, teacher staff ID, classroom capacity.
The weekday column in Excel follows the academic affairs import format:
1-7(1=Monday,7=Sunday). Text values such as Monday are also supported.The import template must contain the course sequence number column. Import fails immediately if it is missing.
Import filtering rules:
Records whose administrative class contains
UCare imported directly, case-insensitively.Other records are imported only for classrooms on floors 2 and 3 of Teaching Building 5.
Special handling for physical education courses: when the administrative class contains
UCand the course name contains physical education, teacher and classroom association is optional, and the course record is imported directly.The classroom capacity column and enrollment count column can both be used for course enrollment.
The remarks column or
remarkcolumn is written to the backend course remark.At most 100 errors are returned in the error list. If there are more,
error_report_available = true.
Download the import template:
GET /api/v1/courses/import-template/
The template is generated by the backend.
The classroom column uses the full classroom string, for example
Teaching Building 5 C317.
Example response:
{
"code": 0,
"message": "Import completed: 85 succeeded, 10 skipped",
"data": {
"total_rows": 100,
"processed": 85,
"skipped": 10,
"created": 50,
"updated": 35,
"failed": 5,
"errors": [],
"error_rows": [],
"error_count": 5,
"error_report_available": false,
"details_truncated": false
}
}
3. Export Timetable (superadmin / secretary)¶
GET /api/v1/courses/export
Query (optional):
classroom_id: filter by classroom.
Returns: Excel file download. The week range is exported by semester week number.
4. Reschedule a Course Session¶
Move a course session to a new time or classroom.
POST /api/v1/courses/sessions/{session_id}/reschedule
Permission: the course teacher, or superadmin / secretary /
assistant.
Body:
{
"classroom_id": 121,
"start_time": "2026-01-20T08:00:00+08:00",
"end_time": "2026-01-20T09:50:00+08:00"
}
Notes:
The rescheduled date must be within the course validity period (
start_datetoend_date).target_weekin the response is the semester week number.The selected time range must match standard class sections.
Cross-day rescheduling is not supported.
Response:
{
"code": 0,
"message": "Course reschedule submitted successfully",
"data": {
"session_id": 123,
"target_session_id": 456,
"target_week": 5,
"occurrence_id": 789
}
}