задачи 2 и 8
This commit is contained in:
@@ -265,8 +265,32 @@ constraint. При чтении API разворачивает периоды о
|
||||
- **Жизненный цикл:** архивные преподаватели, аудитории, группы и дисциплины не принимаются в новых правилах.
|
||||
- **Правило расписания:** `status=ARCHIVED` или дата вне `valid_from` / `valid_to` исключают правило из генерации.
|
||||
- **Доступность аудитории:** `is_available=false` запрещает новые назначения, но не удаляет историю.
|
||||
- **Конфликты слотов:** сначала попарно проверяются слоты самого нового payload, включая точные дубли, затем — активные правила того же семестра. Конфликт возникает при пересечении дня, базового временного слота, чётности (`BOTH` пересекается с любой чётностью) и активных недель слота, если совпадает преподаватель, аудитория или учебная группа. `ODD` и `EVEN` между собой не конфликтуют. Активные недели считаются из лимита часов типа занятия, недели начала, чётности и порядка слотов внутри правила; например, занятие на 1-3 неделях не конфликтует с тем же ресурсом с 4 недели. Для лабораторных занятий разные подгруппы одной группы могут идти параллельно, но занятие для всей группы конфликтует с любой её подгруппой. Backend возвращает `409 Conflict`; `conflictRule` присутствует только для конфликта с сохранённым правилом, а внутренний конфликт описывается полями и русскими причинами без искусственной записи.
|
||||
- **Конкурентная запись:** публичные методы `ScheduleRuleService` являются транзакционными. Создание сначала блокирует строку семестра, а update блокирует правило и старый/новый семестры в стабильном порядке, поэтому два backend-pod не могут одновременно пройти проверку одного семестра по устаревшему снимку.
|
||||
- **Конфликты слотов:** сначала попарно проверяются слоты самого нового payload, включая точные дубли, затем — активные правила той же версии. Конфликт возникает при пересечении дня, базового временного слота, чётности (`BOTH` пересекается с любой чётностью) и активных недель слота, если совпадает преподаватель, аудитория или учебная группа. `ODD` и `EVEN` между собой не конфликтуют. Активные недели считаются из лимита часов типа занятия, недели начала, чётности и порядка слотов внутри правила; например, занятие на 1-3 неделях не конфликтует с тем же ресурсом с 4 недели. Для лабораторных занятий разные подгруппы одной группы могут идти параллельно, но занятие для всей группы конфликтует с любой её подгруппой. Backend возвращает `409 Conflict`; `conflictRule` присутствует только для конфликта с сохранённым правилом, а внутренний конфликт описывается полями и русскими причинами без искусственной записи.
|
||||
- **Конкурентная запись:** публичные методы `ScheduleRuleService` являются транзакционными. Создание блокирует строку семестра и выбранную версию, а update — правило, версию и старый/новый семестры в стабильном порядке. Публикация блокирует версию до завершения полной проверки, поэтому другой backend-pod не может дописать правило после валидации черновика.
|
||||
|
||||
### Черновики, версии и публикация
|
||||
|
||||
Правила каждого семестра принадлежат явной версии расписания. Жизненный цикл версии:
|
||||
|
||||
1. `DRAFT` создаётся пустым или как полная копия выбранной версии.
|
||||
2. Конструктор добавляет, изменяет и архивирует правила только в выбранном черновике.
|
||||
3. Полная проверка выявляет внутренние конфликты правил; diff сопоставляет правила по
|
||||
стабильному `version_group_id` и отдельно сравнивает сформированные занятия семестра.
|
||||
4. Публикация требует причины и в одной транзакции архивирует прежнюю публикацию, затем
|
||||
переводит проверенный черновик в `PUBLISHED`.
|
||||
5. Ранее опубликованная версия получает `ARCHIVED` и может быть восстановлена такой же
|
||||
атомарной операцией с обязательной причиной.
|
||||
|
||||
На уровне БД частичный уникальный индекс допускает только одну `PUBLISHED`-версию на
|
||||
семестр. Блокировки версии и набора версий семестра не позволяют публикации пересечься с
|
||||
редактированием черновика или конкурентной публикацией. Каждое создание, архивирование,
|
||||
публикация и восстановление записывается в неизменяемый журнал с автором, временем и
|
||||
причиной.
|
||||
|
||||
Обычная генерация для студентов, преподавателей и кабинетов просмотра всегда выбирает
|
||||
только опубликованные правила. Точечные изменения привязаны к слотам конкретной версии:
|
||||
после новой публикации overrides прежней версии сохраняются как аудит, но не влияют на
|
||||
актуальное расписание и не показываются в его операционном реестре.
|
||||
|
||||
### Точечные изменения расписания
|
||||
|
||||
@@ -386,6 +410,41 @@ constraint. При чтении API разворачивает периоды о
|
||||
отозвать только собственную ожидающую заявку. История содержит автора, время, статус и
|
||||
комментарий каждого перехода.
|
||||
|
||||
### Анализ качества и локальная оптимизация расписания
|
||||
|
||||
Анализатор качества работает без собственной таблицы и не меняет правила расписания.
|
||||
Пользователь выбирает конкретную версию семестра. Для `PUBLISHED` он строит фактические
|
||||
занятия через `ScheduleQueryService`, поэтому в расчёт входят переносы, замены и отмены из
|
||||
`schedule_overrides`. `DRAFT` и `ARCHIVED` генерируются напрямую по собственным правилам,
|
||||
без точечных изменений текущей публикации. Семестр загружается частями не более 120 дней,
|
||||
но оценка рассчитывается единообразно по всему периоду.
|
||||
|
||||
Итоговая оценка от 0 до 100 формируется из объяснимых штрафов:
|
||||
|
||||
- окна групп и преподавателей между занятиями одного дня;
|
||||
- пятая и последующие пары группы или преподавателя за день;
|
||||
- нехватка мест и заметно избыточная вместимость аудитории;
|
||||
- занятие в подтверждённый строго недоступный или нежелательный интервал;
|
||||
- занятие вне предпочтительного интервала преподавателя на выбранный день недели;
|
||||
- нарушение пожеланий `NO_GAPS` и `CONSECUTIVE`.
|
||||
|
||||
Неравномерность дневной нагрузки выводится отдельной диагностической метрикой в процентах
|
||||
и не добавляет скрытого штрафа к итоговой оценке.
|
||||
|
||||
В ответе сохраняются исходный штраф, вклад каждого критерия и конкретные проблемы с
|
||||
датой, занятием и затронутой сущностью. Это делает оценку воспроизводимой и позволяет
|
||||
фильтровать проблемы по типу и серьёзности.
|
||||
|
||||
Для проблемы опубликованной версии помощник перебирает другие слоты эффективной сетки того же дня и
|
||||
активные аудитории достаточной вместимости. Каждый вариант повторно проходит
|
||||
`ScheduleOverrideService`, затем анализатор моделирует его влияние на общую оценку и
|
||||
показывает улучшения и компромиссы. Занятия с ручным override считаются закреплёнными и не
|
||||
получают рекомендаций. Применение возможно только после подтверждения пользователя через
|
||||
обычный механизм `schedule_overrides`; автоматической публикации и полного solver в MVP
|
||||
нет. Для черновика доступны те же оценка, метрики и объяснимые проблемы, но рекомендации
|
||||
не создаются: пользователь исправляет правила в изолированном конструкторе и повторяет
|
||||
проверку до публикации. Архив анализируется только для чтения.
|
||||
|
||||
## Привязка преподаватель ↔ дисциплина
|
||||
|
||||
Связь Many-to-Many через таблицу `teacher_subjects`:
|
||||
|
||||
Reference in New Issue
Block a user