Files
magistr/docs/BUSINESS_LOGIC.md

10 KiB
Raw Blame History

📋 Бизнес-логика

Ролевая модель

Система поддерживает три роли пользователей:

Роль Enum Возможности
Администратор (Деканат) ADMIN Полный доступ: CRUD пользователей, групп, аудиторий, дисциплин, расписания. Управление тенантами (БД).
Преподаватель TEACHER Просмотр своего расписания. В перспективе — подача заявок на перенос.
Студент STUDENT Только просмотр расписания (Read-only).

После авторизации пользователь перенаправляется на свой интерфейс:

  • ADMIN/admin/
  • TEACHER/teacher/
  • STUDENT/student/

Управление ресурсами

Кафедры (Departments)

Организационные единицы университета. К кафедре привязываются пользователи, группы и дисциплины.

  • Имеют уникальный числовой code
  • Предзаполнены: «Кафедра ИБ», «Кафедра ВТ», «Кафедра КТ»

Специальности (Specialties)

Учебные направления с кодом по ФГОС.

  • Примеры: «Информационная безопасность» (10.03.01), «Программная инженерия» (09.03.04)

Формы обучения (Education Forms)

Уровни/формы обучения для привязки к группам.

  • Предзаполнены: Бакалавриат, Магистратура, Специалитет
  • Нельзя удалить форму обучения, если к ней привязаны группы

Учебные группы (Student Groups)

  • Поля: Название (уникальное), численность, форма обучения, кафедра, специальность, год начала обучения
  • Курс: вычисляется относительно учебного года: год начала учебного года - year_start_study + 1
  • Подгруппы: Возможно деление группы на подгруппы (таблица subgroups)

Аудитории (Classrooms)

  • Поля: Название (уникальное), вместимость (> 0), корпус, этаж, доступность
  • Оборудование: К каждой аудитории привязывается список оборудования (Many-to-Many) с указанием количества
  • Статус: Флаг is_available для блокирования назначения пар

Оборудование (Equipments)

Каталог оборудования для привязки к аудиториям.

  • Предзаполнены: Проектор, ПК, Лаборатория, Интерактивная доска, Документ-камера, Аудиосистема
  • Уникальность по названию

Дисциплины (Subjects)

  • Поля: Название (уникальное), код, кафедра, описание
  • Привязка преподавателей через teacher_subjects (Many-to-Many)

Логика расписания

Динамическая модель расписания

Основная модель расписания строится из правил, а не из отдельных статических пар.

Компонент Назначение
academic_years / semesters Учебные годы и семестры. Неделя 1 считается от semesters.start_date
holidays Даты, когда занятия не проводятся и часы не списываются
academic_calendar_matrix Тип недели для курса и специальности: теория, сессия, каникулы, практика
time_slots Настраиваемая сетка пар для тенанта
schedule_rules Лимит часов дисциплины в семестре
schedule_rule_groups Группы правила, включая потоковые лекции
schedule_rule_slots День, чётность, слот, преподаватель, аудитория, тип и формат занятия

Генератор ScheduleGeneratorService рендерит расписание по запросу:

  1. Определяет семестр для каждой даты диапазона.
  2. Вычисляет номер недели и чётность.
  3. Проверяет праздники и матрицу учебного графика.
  4. Загружает правила группы или преподавателя.
  5. Симулирует уже проведённые занятия от active_from_date.
  6. Останавливает вывод правила, когда достигнут total_academic_hours.

Праздник считается пропуском: занятие не переносится и не списывает академические часы.

Временная старая сущность «Занятие» (Lesson)

lessons пока физически остаётся в схеме до удаления старого кода, но базовая миграция больше не заполняет её тестовыми данными. Новые экраны просмотра используют GET /api/schedule.

Каждая запись в расписании содержит:

Поле Описание Пример
teacher_id Преподаватель 2
group_id Учебная группа 1
subject_id Дисциплина 3
lesson_format Формат проведения Очно, Онлайн
type_lesson Тип занятия Лекция, Практическая работа, Лабораторная работа
classroom_id Аудитория 1
day День недели Понедельник ... Суббота
week Чётность недели Верхняя, Нижняя, Обе
time Временной слот 8:00 - 9:30

Временны́е слоты

Сетка пар хранится в time_slots и настраивается для каждого тенанта. При миграции создаются базовые слоты:

Время
1 08:00 09:30
2 09:40 11:10
3 11:40 13:10
4 13:30 15:00
5 15:00 16:30
6 16:40 18:10
7 18:30 20:00

Валидация при создании/обновлении

  • Дни: только Понедельник Суббота (DayAndWeekValidator)
  • Недели: только Верхняя, Нижняя, Обе
  • Формат: только Очно, Онлайн (TypeAndFormatLessonValidator)
  • Тип: только Лекция, Практическая работа, Лабораторная работа
  • Все ID (преподаватель, группа, дисциплина, аудитория) обязательны и не могут быть 0

Временные старые данные к составлению расписания (Schedule Data)

Таблица schedule_data пока физически остаётся в схеме до удаления старого кода. Новая базовая миграция создаёт schedule_rules и schedule_rule_groups напрямую, без ETL из schedule_data.

Поле Описание
department_id Кафедра
semester Номер семестра
group_id Учебная группа
subjects_id Дисциплина
lesson_type_id Тип занятия
number_of_hours Количество часов
is_division Деление на подгруппы
teacher_id Преподаватель
semester_type Тип семестра (Весенний / Осенний)
period Учебный год (напр. 2024/2025)

Привязка преподаватель ↔ дисциплина

Связь Many-to-Many через таблицу teacher_subjects:

  • Указывается, какие дисциплины может вести конкретный преподаватель
  • Дополнительные поля: qualification_level, experience_years

Дополнительная связь через teacher_lesson_types:

  • Определяет, какие типы занятий (лекция, практика, лаба) может вести преподаватель по конкретной дисциплине

Бизнес-правила (планируемые)

Примечание: Следующие правила описаны в требованиях, но пока не полностью реализованы в коде.

Проверка конфликтов

  • Критический конфликт: Преподаватель не может одновременно находиться в двух разных аудиториях
  • Исключение: Преподаватель может вести несколько пар одновременно (потоковая лекция), если все группы в одной аудитории
  • Вместимость: Суммарная численность всех групп в слоте не должна превышать вместимость аудитории

Управление инцидентами

  • Регистрация отсутствия преподавателя (болезнь, командировка) с указанием периода
  • Автоматическая подсветка конфликтующих пар (Red Zone)
  • Resolution Wizard: предложение замены преподавателя или переноса занятия