This commit is contained in:
@@ -263,30 +263,44 @@ Bearer-токен проверяется на backend. Frontend-скрытие
|
||||
Учебный отдел может создать изменение конкретной пары:
|
||||
|
||||
- `CANCEL` — отменить пару;
|
||||
- `MOVE` — перенести пару на другой фактический интервал или в другую аудиторию;
|
||||
- `REPLACE` — заменить преподавателя, аудиторию или формат.
|
||||
- `MOVE` — перенести пару на другую учебную дату того же семестра или другой фактический интервал;
|
||||
- `REPLACE` — без изменения даты и времени заменить преподавателя, аудиторию или формат.
|
||||
|
||||
`CANCEL` не принимает новые ресурсы. Для `MOVE` обязателен новый временной слот или
|
||||
аудитория, для `REPLACE` — преподаватель, аудитория или формат. Дополнительные изменения
|
||||
можно объединять в одном payload, но основное действие должно фактически менять свою
|
||||
часть пары. Формат ограничен значениями `Очно` и `Онлайн`.
|
||||
`CANCEL` не принимает целевую дату и новые ресурсы. Для `MOVE` обязателен новый временной
|
||||
слот, для `REPLACE` — преподаватель, аудитория или формат. Перенос даты требует явно
|
||||
выбранного слота эффективной сетки целевого дня. Дополнительные изменения преподавателя,
|
||||
аудитории и формата можно объединить с `MOVE`, но основное действие должно фактически
|
||||
менять свою часть пары. Формат ограничен значениями `Очно` и `Онлайн`; дисциплина и тип
|
||||
занятия не изменяются.
|
||||
|
||||
Изменения не переписывают базовое правило, а накладываются поверх сгенерированного
|
||||
расписания на конкретную дату. Перед записью `ScheduleOverrideService`:
|
||||
расписания. Исходная пара всегда идентифицируется как `baseRuleSlotId + lessonDate`, а
|
||||
`targetLessonDate` хранит только новую дату единственного занятия. Перед записью
|
||||
`ScheduleOverrideService`:
|
||||
|
||||
1. захватывает transaction advisory lock PostgreSQL для tenant-БД и даты;
|
||||
1. захватывает transaction advisory lock PostgreSQL для исходных и целевых дат в стабильном порядке;
|
||||
2. строит базовый день для всех групп без интерактивного лимита широкого поиска;
|
||||
3. доказывает существование исходной пары с учётом семестра, календарного графика,
|
||||
чётности, недели начала, лимита часов и lifecycle;
|
||||
4. применяет сохранённые overrides и кандидат общей логикой `ScheduleQueryService`;
|
||||
5. проверяет полуоткрытые временные интервалы `[start, end)` и итоговые ресурсы;
|
||||
6. сохраняет изменение только при отсутствии конфликта.
|
||||
4. для новой даты проверяет границы того же семестра, активность правила и дисциплины,
|
||||
учебный день всех затронутых групп и эффективную сетку времени;
|
||||
5. проверяет lifecycle итоговых преподавателя и аудитории на целевую дату;
|
||||
6. применяет сохранённые overrides и кандидат общей логикой `ScheduleQueryService`;
|
||||
7. проверяет полуоткрытые временные интервалы `[start, end)` и итоговые ресурсы целевого дня;
|
||||
8. сохраняет изменение только при отсутствии конфликта.
|
||||
|
||||
В поиске `MOVE` удаляет исходное вхождение и добавляет занятие в целевой день, включая
|
||||
случай, когда в запрос попала только целевая дата. День недели, номер недели и чётность
|
||||
вычисляются заново по семестру, а расход академических часов остаётся у исходной пары.
|
||||
`CANCEL` скрывает занятие. Удаление override возвращает текущий вариант, который снова
|
||||
формируется базовым правилом.
|
||||
|
||||
Совпадение преподавателя или аудитории в пересекающееся время всегда является конфликтом.
|
||||
Для общей учебной группы занятие целой группы конфликтует с любой её подгруппой; разные
|
||||
подгруппы одной группы могут идти параллельно при свободных преподавателях и аудиториях.
|
||||
Конфликт возвращается как `409 Conflict` с русским сообщением. Блокировка PostgreSQL общая
|
||||
для backend-pod, поэтому два конкурентных изменения одной даты проверяются последовательно.
|
||||
для backend-pod, поэтому два конкурентных переноса с разных исходных дат на одну целевую
|
||||
дату и одинаковые ресурсы проверяются последовательно.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user