This commit is contained in:
84
docs/API.md
84
docs/API.md
@@ -416,6 +416,25 @@ GET /api/schedule?groupId=1&startDate=2026-04-27&endDate=2026-05-03
|
||||
]
|
||||
```
|
||||
|
||||
### `GET /api/schedule/semesters`
|
||||
|
||||
Доступный только для чтения список семестров для фильтров просмотра расписания. Доступен всем ролям,
|
||||
которые могут просматривать расписание, включая `DEPARTMENT` и `SCHEDULE_VIEWER`.
|
||||
Семестры возвращаются от новых к старым.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 2,
|
||||
"academicYearId": 1,
|
||||
"academicYearTitle": "2025/2026",
|
||||
"semesterType": "spring",
|
||||
"startDate": "2026-02-09",
|
||||
"endDate": "2026-06-30"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### `GET /api/admin/time-slots`
|
||||
|
||||
Список временных слотов занятий. Слот принадлежит конкретной сетке времени: базовой, автоматической субботней или ручной.
|
||||
@@ -737,45 +756,82 @@ GET /api/schedule/search?classroomId=1&startDate=2026-05-20&endDate=2026-05-27
|
||||
```
|
||||
|
||||
Ответ совпадает со структурой `RenderedLessonDto` из `GET /api/schedule`.
|
||||
Для занятия, к которому применено разовое изменение, дополнительно заполнены:
|
||||
|
||||
- `scheduleOverrideId` — идентификатор изменения;
|
||||
- `overrideAction` — `MOVE` или `REPLACE` (`CANCEL` в выдачу не попадает);
|
||||
- `originalLessonDate` — исходная дата занятия из базового правила.
|
||||
|
||||
Перенос удаляет занятие из исходного дня и добавляет его в целевой. Поиск учитывает
|
||||
изменение, если в запрошенный диапазон попала исходная **или** целевая дата, поэтому
|
||||
входящий перенос находится даже запросом только по целевому диапазону. Для целевой даты
|
||||
пересчитываются день недели, номер недели и чётность; учёт академических часов остаётся
|
||||
привязан к исходному занятию.
|
||||
|
||||
### Точечные изменения расписания учебного отдела
|
||||
|
||||
| Метод | URL | Назначение |
|
||||
|-------|-----|------------|
|
||||
| `GET` | `/api/edu-office/schedule/overrides` | Список точечных изменений |
|
||||
| `GET` | `/api/edu-office/schedule/overrides?startDate=&endDate=` | Список изменений; диапазон проверяется по исходной или целевой дате |
|
||||
| `GET` | `/api/edu-office/schedule/overrides/availability?baseRuleSlotId=&lessonDate=` | Границы семестра и допустимые учебные даты для конкретного занятия |
|
||||
| `POST` | `/api/edu-office/schedule/overrides` | Создать перенос, отмену или замену |
|
||||
| `PUT` | `/api/edu-office/schedule/overrides/{id}` | Обновить изменение |
|
||||
| `DELETE` | `/api/edu-office/schedule/overrides/{id}` | Удалить изменение |
|
||||
| `DELETE` | `/api/edu-office/schedule/overrides/{id}` | Удалить изменение и вернуть актуальный вариант из правила |
|
||||
|
||||
`startDate` и `endDate` у списка передаются только парой, включительно; максимальный
|
||||
диапазон — 120 дней. Ответ реестра содержит исходные дату, время, преподавателя,
|
||||
аудиторию, формат, дисциплину, тип занятия, группы и границы семестра, поэтому отменённую
|
||||
или перенесённую пару можно открыть без присутствия в текущей выдаче расписания.
|
||||
|
||||
```json
|
||||
{
|
||||
"baseRuleSlotId": 31,
|
||||
"lessonDate": "2026-05-21",
|
||||
"action": "REPLACE",
|
||||
"targetLessonDate": "2026-05-27",
|
||||
"action": "MOVE",
|
||||
"newTimeSlotId": 4,
|
||||
"newClassroomId": 2,
|
||||
"newTeacherId": 5,
|
||||
"comment": "Замена аудитории и преподавателя"
|
||||
"newLessonFormat": "Онлайн",
|
||||
"comment": "Перенос конкретного занятия"
|
||||
}
|
||||
```
|
||||
|
||||
`lessonDate` всегда обозначает исходное занятие из правила. `targetLessonDate` передаётся
|
||||
только при переносе на другой день и не заменяет идентификатор исходной пары
|
||||
`baseRuleSlotId + lessonDate`.
|
||||
|
||||
Правила payload:
|
||||
|
||||
- `CANCEL` отменяет конкретную пару; поля `newTimeSlotId`, `newClassroomId`,
|
||||
`newTeacherId` и `newLessonFormat` должны отсутствовать;
|
||||
- `MOVE` требует новый временной слот или аудиторию; преподавателя и формат можно изменить
|
||||
в том же запросе;
|
||||
- `REPLACE` требует нового преподавателя, аудиторию или формат; временной слот можно
|
||||
изменить в том же запросе;
|
||||
- `CANCEL` отменяет конкретную пару; `targetLessonDate` и все поля `new*` должны отсутствовать;
|
||||
- `MOVE` требует новый временной слот; при переносе даты слот выбирается из эффективной
|
||||
сетки целевого дня, а преподавателя, аудиторию и формат можно изменить тем же запросом;
|
||||
- `REPLACE` используется только без изменения даты и времени и требует нового
|
||||
преподавателя, аудиторию или формат;
|
||||
- формат принимает только `Очно` или `Онлайн`;
|
||||
- `MOVE` и `REPLACE` должны фактически менять основные параметры действия. Другой ID
|
||||
временного слота с тем же интервалом не считается переносом.
|
||||
|
||||
До сохранения backend строит базовую пару на `lessonDate` по тем же правилам, что и обычное
|
||||
расписание: семестр, календарный график, чётность, активность сущностей и остаток часов.
|
||||
Если пара не формируется или нарушена матрица действия, API возвращает `400` с русским
|
||||
сообщением. Если результирующее время пересекается с занятым преподавателем, аудиторией,
|
||||
группой или той же подгруппой, API возвращает `409 Conflict`; соседние интервалы и разные
|
||||
подгруппы одной группы не конфликтуют.
|
||||
При переносе даты backend дополнительно проверяет тот же семестр, действие правила и
|
||||
дисциплины, lifecycle итоговых ресурсов, учебный календарь всех затронутых групп и
|
||||
принадлежность времени эффективной сетке целевого дня. Если пара не формируется или
|
||||
нарушена матрица действия, API возвращает `400` с русским сообщением. Если результирующее
|
||||
время пересекается с занятым преподавателем, аудиторией, группой или той же подгруппой,
|
||||
API возвращает `409 Conflict`; соседние интервалы и разные подгруппы одной группы не
|
||||
конфликтуют.
|
||||
|
||||
Пример ответа availability:
|
||||
|
||||
```json
|
||||
{
|
||||
"semesterId": 3,
|
||||
"semesterStartDate": "2026-02-09",
|
||||
"semesterEndDate": "2026-06-30",
|
||||
"availableDates": ["2026-05-21", "2026-05-22", "2026-05-25"]
|
||||
}
|
||||
```
|
||||
|
||||
## Загруженность
|
||||
|
||||
|
||||
Reference in New Issue
Block a user