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 by CourseOccurrence.occurrence_date (YYYY-MM-DD).

  • end_date: filter end date by CourseOccurrence.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.weekday is a string enum: MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY.

  • sessions includes id, occurrence_date, weekday, sections, start_time, end_time, classroom, classroom_id, status, source_type, and remark.

  • sessions returns only occurrences that are not cancelled (status != cancelled).

  • When start_date / end_date is provided, only courses with occurrences in that date range are returned, and sessions is 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-6 integer 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 / secretary only.

  • 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 UC are 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 UC and 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 remark column 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_date to end_date).

  • target_week in 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
  }
}