51 lines
5.2 KiB
Markdown
51 lines
5.2 KiB
Markdown
# Концепция динамической генерации расписания
|
||
|
||
Документ фиксирует актуальную концепцию после внедрения календарных учебных графиков. Подробная продуктовая модель описана в [`docs/ACADEMIC_CALENDAR.md`](docs/ACADEMIC_CALENDAR.md), REST API — в [`docs/API.md`](docs/API.md), схема БД — в [`docs/DATABASE.md`](docs/DATABASE.md).
|
||
|
||
## Базовая идея
|
||
|
||
Фактические занятия не хранятся отдельными строками на каждую дату. Система хранит:
|
||
|
||
- календарный учебный график по специальности, профилю, форме обучения и учебному году;
|
||
- правила расписания дисциплин;
|
||
- слоты правил: день недели, чётность, пара, преподаватель, аудитория, тип занятия, формат и опциональные подгруппы для лабораторных;
|
||
- назначение конкретного календарного графика учебной группе на учебный год.
|
||
|
||
При запросе `GET /api/schedule` backend рендерит расписание на диапазон дат. Если дата не является днём теоретического обучения по назначенному группе графику, обычные пары не выводятся и академические часы не списываются.
|
||
|
||
## Слои модели
|
||
|
||
### Календарный слой
|
||
|
||
- `academic_years` и `semesters` задают границы учебного года и семестров.
|
||
- `specialties` и `specialty_profiles` определяют образовательную программу группы.
|
||
- `academic_calendars` хранит график профиля и формы обучения.
|
||
- `academic_calendar_activity_types` хранит коды из Excel-графика: `Т`, `Э`, `К`, `У`, `П`, `Пд`, `Н`, `Г`, `Д`, `ПА`, `С`, `*`, `=`.
|
||
- `academic_calendar_days` хранит дневную сетку по курсу и дате.
|
||
- `student_group_calendar_assignments` выбирает график для группы на учебный год.
|
||
|
||
### Слой правил расписания
|
||
|
||
- `time_slots` задаёт сетку пар для тенанта.
|
||
- `schedule_rules` хранит дисциплину, семестр, отдельные лимиты часов и стартовые недели для лекций, лабораторных и практик.
|
||
- `schedule_rule_groups` связывает правило с одной или несколькими группами.
|
||
- `schedule_rule_slots` хранит шаблонные занятия правила, а `schedule_rule_slot_subgroups` связывает лабораторный слот с одной или несколькими подгруппами.
|
||
|
||
## Алгоритм генерации
|
||
|
||
1. Для даты определяется семестр.
|
||
2. Для группы находится назначенный календарный учебный график.
|
||
3. По году начала обучения вычисляется текущий курс группы.
|
||
4. По курсу и дате находится код активности.
|
||
5. Обычные пары генерируются только для кода, где `allow_schedule = true`; в seed-данных это `Т`.
|
||
6. Для разрешённого дня выбираются активные правила и слоты.
|
||
7. Лимит часов считается только по реально проведённым занятиям; для лабораторных подгрупп счётчик ведётся отдельно по каждой подгруппе.
|
||
|
||
Лекции и практики нельзя делить на подгруппы. Если лабораторный слот привязан к нескольким подгруппам разных групп, он выводится как совместное занятие этих групп, а часы списываются отдельно по каждой подгруппе.
|
||
|
||
Если назначение графика отсутствует, расписание группы возвращается пустым списком без ошибки.
|
||
|
||
## Административный сценарий
|
||
|
||
Администратор создаёт специальность и профиль, затем создаёт группу с этой связкой. В разделе расписания он создаёт учебный год, семестры и календарный график, заполняет дневную сетку кодами активностей и назначает график группе. После сохранения графика или назначения кэш генератора очищается, поэтому следующие запросы расписания используют новые правила сразу.
|