# Календарный учебный график ## Назначение Календарный учебный график хранит правила учебного года в той же логике, что и исходные Excel-таблицы: для каждого курса и каждой даты указывается код активности. Динамическое расписание использует этот график как фильтр: обычные пары выводятся только в дни теоретического обучения. График нужен, чтобы разные образовательные программы могли иметь разные периоды теории, экзаменов, практики, каникул и нерабочих дней. Несколько групп могут использовать один и тот же график, если они учатся по одной календарной модели. ## Связи данных Основная цепочка выглядит так: ```text специальность -> профиль обучения -> календарный учебный график -> назначение группе ``` - `specialties` хранит код и название специальности, например `09.03.04`. - `specialty_profiles` хранит профили внутри специальности. У одной специальности может быть несколько профилей. - `academic_calendars` хранит график профиля, формы обучения и учебного года. - Форма обучения графика берётся из общего справочника `education_forms`; отдельной таблицы форм для календаря нет. - `academic_calendar_days` хранит дневную сетку графика по курсу и дате. - `academic_calendar_subjects` хранит дисциплины графика по номерам учебных семестров; дисциплины выбираются из справочника `subjects`. - `student_groups` связана со специальностью, профилем и той же таблицей форм обучения. - `student_group_calendar_assignments` назначает группе конкретный график на учебный год. Группа выбирает не код активности напрямую, а календарный график. Поэтому один график можно назначить нескольким группам. ## Коды активностей | Код | Значение | Обычные пары | |-----|----------|--------------| | `Т` | Теоретическое обучение | Да | | `Э` | Экзаменационная сессия | Нет | | `К` | Каникулы | Нет | | `У` | Учебная практика | Нет | | `П` | Производственная практика | Нет | | `Пд` | Преддипломная практика | Нет | | `Н` | Научно-исследовательская работа | Нет | | `Г` | Государственная итоговая аттестация | Нет | | `Д` | Подготовка выпускной квалификационной работы | Нет | | `ПА` | Промежуточная аттестация | Нет | | `С` | Самостоятельная работа или специальный период | Нет | | `*` | Праздничный или нерабочий день | Нет | | `=` | День вне учебного года или пустая ячейка графика | Нет | Технически разрешение генерации задаётся полем `academic_calendar_activity_types.allow_schedule`. В seed-данных `true` установлен только для `Т`. ## Правило генерации расписания `ScheduleGeneratorService` при запросе `GET /api/schedule` проверяет календарный график до вывода занятия: 1. Определяется учебный год и семестр даты. 2. Для группы находится назначение графика на этот учебный год. 3. По году начала обучения группы вычисляется текущий курс. 4. В `academic_calendar_days` ищется ячейка для курса и даты. 5. Если код ячейки разрешает обычные пары, применяются правила `schedule_rules`. 6. Если код не разрешает пары, день пропускается и академические часы не списываются. Если график группе не назначен, расписание группы возвращается пустым списком без ошибки. Это сделано намеренно: отсутствие календаря означает, что нет разрешённых дат для генерации. ## Работа администратора 1. В разделе кафедр и специальностей администратор создаёт специальность и её профили. 2. В разделе групп администратор создаёт группу, выбирая специальность и профиль обучения. 3. В разделе календарного графика администратор создаёт учебный год и семестры. 4. Там же создаётся календарный учебный график: название, учебный год, специальность, профиль, форма обучения из общего справочника и количество курсов. 5. Администратор открывает сетку графика, заполняет дни вручную или массово через диапазон дат. 6. На вкладке дисциплин графика администратор вручную привязывает дисциплины к учебным семестрам: например, для четырёх курсов доступны семестры `1..8`. 7. В разделе групп администратор назначает календарный график группе на нужный учебный год; вместе с назначением виден список дисциплин по семестрам. После сохранения графика или назначения группы кэш динамического расписания сбрасывается. Следующий запрос `GET /api/schedule` сразу использует новые правила календаря. ## Особенности модели - Старый отдельный механизм праздников не используется: праздник хранится кодом `*` в дневной сетке. - Дни вне учебного года или пустые периоды Excel хранятся кодом `=`. - График привязан к профилю обучения, а не только к коду специальности. - Форма обучения графика должна совпадать с формой обучения группы при назначении графика. - Название группы не является уникальным ключом; идентичные названия допустимы, если различаются другие параметры. - Excel-импорт в первой реализации не предусмотрен: редактор заполняет данные через сайт.