.. SPDX-License-Identifier: GPL-3.0-or-later ============================ Courses & Seasonal Schedules ============================ Author: Zhenyu Yang , Sixu Wei Last updated: Apr 24, 2026 Corresponding API docs: `Course API <../../api/courses.rst>`__ ``courses`` Code Entry ---------------------- - ``backend/apps/courses/models/__init__.py`` - ``backend/apps/courses/views.py`` - ``backend/apps/courses/services/__init__.py`` ``courses`` Core Data --------------------- ``Course`` ~~~~~~~~~~ The course master record, storing basic course information, teacher, class, course number, semester range, and raw import fields. ``CourseOccurrence`` ~~~~~~~~~~~~~~~~~~~~ A single class session instance, storing: - ``occurrence_date`` - ``classroom`` - ``sections`` - ``schedule_key`` - ``status`` - ``source_type`` - ``remark`` At runtime, ``CourseOccurrence`` serves as the source of truth for scheduled classes; the system no longer derives actual classes from an independent periodic schedule table. Query Model ----------- - ``CourseViewSet`` is a read-only ViewSet. - Supported filters: - ``teacher_id`` - ``class_name`` - ``start_date`` - ``end_date`` - Queries prefetch occurrences with ``status in (scheduled, rescheduled)``. - When a date range is provided: - The course set only includes courses that have occurrences within the range. - ``sessions`` are also trimmed accordingly. Import, Export & Template ------------------------- Import Template ~~~~~~~~~~~~~~~ - Entry: ``GET /courses/import-template`` - ``superadmin`` / ``secretary`` only. - The template is dynamically generated by the backend. Excel Import ~~~~~~~~~~~~ - Entry: ``POST /courses/import`` - ``superadmin`` / ``secretary`` only. - File format: ``.xlsx`` / ``.xls``, max 50MB. - Business rules are governed by ``CourseImportService``; the current implementation retains the following key constraints: - Import must include ``semester_start_date``. - Records where the administrative class column (``行政班``) contains ``UC`` are imported directly. - Other records are only imported for the 2nd and 3rd floors of Building 5. - Physical education courses have a special branch. - When the number of successfully processed records is greater than 0, ``semester_start_date`` is written back to ``SystemConfig``. Export ~~~~~~ - Entry: ``GET /courses/export`` - ``superadmin`` / ``secretary`` only. - Export data re-aggregates occurrences by pattern for generating an Excel weekly view. Rescheduling ------------ - Entry: ``POST /courses/sessions/{session_id}/reschedule`` - Permissions: - The current course teacher - ``superadmin`` - ``secretary`` - ``assistant`` - The current implementation requires the new time range to fully match a standard class period; cross-day rescheduling is not supported. - The rescheduling date must fall within the course’s ``start_date`` to ``end_date``. Seasonal Schedules ------------------ - Class period times are not hardcoded in models; they are dynamically resolved by ``SeasonConfigService``. - At runtime, the system switches between winter and summer schedules based on ``SystemConfig.season``. - Changing the season setting clears the course time cache. ``courses`` and Other Modules ----------------------------- - ``classrooms.schedule`` and ``signage.schedule`` both depend on expanded course instance results. - ``borrowings`` course conflict detection depends on course instances. - ``checkins`` uses ``CourseOccurrence`` to create check-in sessions.