1 Задача
This commit is contained in:
@@ -334,6 +334,34 @@ erDiagram
|
||||
TEXT comment
|
||||
}
|
||||
|
||||
teacher_absences {
|
||||
BIGSERIAL id PK
|
||||
BIGINT teacher_id FK
|
||||
DATE start_date
|
||||
DATE end_date
|
||||
TEXT reason
|
||||
VARCHAR status
|
||||
BIGINT requested_by FK
|
||||
BIGINT reviewed_by FK
|
||||
TEXT review_comment
|
||||
TIMESTAMPTZ reviewed_at
|
||||
TIMESTAMPTZ created_at
|
||||
TIMESTAMPTZ updated_at
|
||||
}
|
||||
|
||||
teacher_absence_decisions {
|
||||
BIGSERIAL id PK
|
||||
BIGINT absence_id FK
|
||||
BIGINT base_rule_slot_id FK
|
||||
DATE lesson_date
|
||||
VARCHAR resolution
|
||||
VARCHAR decision_status
|
||||
BIGINT schedule_override_id FK
|
||||
TEXT comment
|
||||
BIGINT decided_by FK
|
||||
TIMESTAMPTZ decided_at
|
||||
}
|
||||
|
||||
schedule_rule_slot_subgroups {
|
||||
BIGINT schedule_rule_slot_id FK,PK
|
||||
BIGINT subgroup_id FK,PK
|
||||
@@ -385,6 +413,11 @@ erDiagram
|
||||
time_slots ||--o{ schedule_overrides : "new_time_slot_id"
|
||||
classrooms ||--o{ schedule_overrides : "new_classroom_id"
|
||||
users ||--o{ schedule_overrides : "new_teacher_id"
|
||||
users ||--o{ teacher_absences : "teacher_id/requested_by/reviewed_by"
|
||||
teacher_absences ||--o{ teacher_absence_decisions : "absence_id"
|
||||
schedule_rule_slots ||--o{ teacher_absence_decisions : "base_rule_slot_id"
|
||||
schedule_overrides ||--o{ teacher_absence_decisions : "schedule_override_id"
|
||||
users ||--o{ teacher_absence_decisions : "decided_by"
|
||||
time_slot_scopes ||--o{ time_slots : "time_slot_scope_id"
|
||||
time_slot_scopes ||--o{ time_slot_date_assignments : "time_slot_scope_id"
|
||||
time_slots ||--o{ schedule_rule_slots : "time_slot_id"
|
||||
@@ -905,6 +938,44 @@ V1 добавляет `uq_schedule_rule_slots_exact_payload`: в одном пр
|
||||
lifecycle ресурсов, эффективная сетка целевого дня, реальность изменения и ресурсные
|
||||
конфликты проверяются транзакционным сервисом, а не SQL CHECK.
|
||||
|
||||
#### `teacher_absences` — Отсутствия преподавателей
|
||||
|
||||
| Колонка | Тип | Описание |
|
||||
|---------|-----|----------|
|
||||
| `id` | BIGSERIAL PK | ID отсутствия |
|
||||
| `teacher_id` | BIGINT FK → users | Отсутствующий преподаватель |
|
||||
| `start_date`, `end_date` | DATE | Включительные границы периода |
|
||||
| `reason` | TEXT | Причина длиной 1–2000 символов |
|
||||
| `status` | VARCHAR(20) | `PENDING`, `APPROVED`, `REJECTED`, `RESOLVED`, `CANCELLED` |
|
||||
| `requested_by` | BIGINT FK → users | Автор регистрации или заявки |
|
||||
| `reviewed_by` | BIGINT FK → users | Подтвердивший или отклонивший сотрудник |
|
||||
| `review_comment` | TEXT | Комментарий согласования |
|
||||
| `reviewed_at` | TIMESTAMPTZ | Время согласования |
|
||||
| `created_at`, `updated_at` | TIMESTAMPTZ | Аудит жизненного цикла |
|
||||
|
||||
CHECK запрещает обратный период, пустую или слишком длинную причину и неизвестный статус.
|
||||
Индекс `(teacher_id, start_date, end_date)` ускоряет поиск пересекающихся отсутствий и
|
||||
проверку кандидатов мастера.
|
||||
|
||||
#### `teacher_absence_decisions` — Журнал мастера замены
|
||||
|
||||
| Колонка | Тип | Описание |
|
||||
|---------|-----|----------|
|
||||
| `id` | BIGSERIAL PK | ID записи журнала |
|
||||
| `absence_id` | BIGINT FK → teacher_absences | Инцидент отсутствия |
|
||||
| `base_rule_slot_id` | BIGINT FK → schedule_rule_slots | Базовый слот занятия |
|
||||
| `lesson_date` | DATE | Исходная дата занятия |
|
||||
| `resolution` | VARCHAR(30) | Замена, перенос, аудитория, отмена или отклонение |
|
||||
| `decision_status` | VARCHAR(20) | `APPLIED` либо `REJECTED` |
|
||||
| `schedule_override_id` | BIGINT FK → schedule_overrides | Созданная разовая правка, если есть |
|
||||
| `comment` | TEXT | Комментарий ответственного сотрудника |
|
||||
| `decided_by` | BIGINT FK → users | Автор решения |
|
||||
| `decided_at` | TIMESTAMPTZ | Время решения |
|
||||
|
||||
Уникальность `(absence_id, base_rule_slot_id, lesson_date)` не позволяет повторно обработать
|
||||
одно занятие одного инцидента. При удалении override ссылка обнуляется, но аудиторская запись
|
||||
сохраняется.
|
||||
|
||||
---
|
||||
|
||||
## Flyway миграции
|
||||
@@ -924,12 +995,15 @@ lifecycle ресурсов, эффективная сетка целевого
|
||||
| Файл | Описание |
|
||||
|------|----------|
|
||||
| `V1__init.sql` | Полная baseline-схема: справочники, роли, refresh-сессии JWT, PostgreSQL rate limit и аудит входа, lifecycle-поля, история кафедр, календарные графики с интервальным хранением активностей и нумерацией недель `понедельник–воскресенье`, динамическое расписание, точечные изменения с переносом даты, seed, CHECK/UNIQUE/GiST-ограничения, конкурентно безопасные триггеры и комментарии |
|
||||
| `V2__teacher_absences_and_replacement_wizard.sql` | Реестр отсутствий преподавателей, статусы согласования и журнал применённых/отклонённых решений со ссылками на обычные `schedule_overrides` |
|
||||
|
||||
### Этап разработки
|
||||
|
||||
По прямому решению владельца проекта разработческие миграции V2–V7 объединены в baseline
|
||||
`V1`. Интервальное хранение активностей и правильная нумерация недель календарного графика
|
||||
также входят непосредственно в V1.
|
||||
Исторические разработческие миграции V2–V7 по прямому решению владельца проекта были
|
||||
объединены в baseline `V1`. После фиксации baseline нумерация начата заново: текущая `V2`
|
||||
добавляет отсутствия и мастер замены, не изменяя контрольную сумму `V1`.
|
||||
Интервальное хранение активностей и правильная нумерация недель календарного графика входят
|
||||
непосредственно в V1.
|
||||
Перед применением этой редакции требуется полностью пустая tenant-схема.
|
||||
|
||||
### Полный сброс БД (локально)
|
||||
|
||||
Reference in New Issue
Block a user