Files
magistr/SCHEDULE_TASKS.md

14 KiB
Raw Permalink Blame History

📋 Задачи: Динамическая генерация расписания

Декомпозиция SCHEDULE_PROPOSAL.md на подзадачи для доски планирования. Категории: Backend, Frontend, DevOps/DB


DevOps / Database

Flyway-миграция: Временные слоты

  • Создать миграцию: таблица time_slots (id, order_number, start_time, end_time, duration_minutes)
  • Добавить CHECK-ограничения (start_time < end_time, duration_minutes > 0, order_number > 0)

Flyway-миграция: Учебные годы и семестры

  • Создать миграцию: таблица academic_years (id, title, start_date, end_date)
  • Создать миграцию: таблица semesters (id, academic_year_id FK, semester_type ENUM, start_date, end_date)
  • Добавить CHECK-ограничения и индексы

Flyway-миграция: Праздники

  • Создать миграцию: таблица holidays (id, date, academic_year_id FK, description)
  • Добавить уникальный индекс на (date, academic_year_id)

Flyway-миграция: Матрица учебного графика

  • Создать миграцию: таблица academic_calendar_matrix (id, semester_id FK, course_number, specialty_id FK, week_number, activity_type ENUM)
  • Добавить ENUM: THEORY, EXAM, VACATION, PRACTICE
  • Добавить уникальный индекс на (semester_id, course_number, specialty_id, week_number)

Flyway-миграция: Правила расписания

  • Создать миграцию: таблица schedule_rules (id, subject_id FK, semester_id FK, active_from_date, total_academic_hours)
  • Создать миграцию: связующая таблица schedule_rule_groups (schedule_rule_id FK, group_id FK, PK составной)
  • Создать миграцию: таблица schedule_rule_slots (id, schedule_rule_id FK, day_of_week, parity ENUM, time_slot_id FK, subgroup_id FK NULL, teacher_id FK, classroom_id FK, lesson_type_id FK, lesson_format)
  • Добавить CHECK на day_of_week (17)
  • Добавить ENUM: BOTH, EVEN, ODD

ETL-миграция данных

  • Написать SQL/Java скрипт миграции schedule_dataschedule_rules + schedule_rule_groups
    • Маппинг number_of_hourstotal_academic_hours
    • Маппинг привязок групп
  • Написать SQL/Java скрипт миграции lessonsschedule_rule_slots
    • Трансформация day (строка) → day_of_week (INT 16)
    • Трансформация time (строка) → time_slot_id (FK)
    • Трансформация week (строка) → parity (ENUM)
    • Группировка записей с одинаковым (subject_id, group_id) в одно правило
  • Верификация мигрированных данных (количество записей, целостность FK)
  • Создать миграцию на удаление устаревших таблиц lessons и schedule_data (после верификации)

Backend (Java + Spring Boot)

JPA-сущности (Model)

  • Создать Entity: TimeSlot
  • Создать Entity: AcademicYear
  • Создать Entity: Semester (связь ManyToOne → AcademicYear)
  • Создать Entity: Holiday (связь ManyToOne → AcademicYear)
  • Создать Entity: AcademicCalendarMatrix (связи на Semester, Specialty)
  • Создать Entity: ScheduleRule (связи на Subject, Semester)
  • Создать Entity: ScheduleRuleSlot (связи на ScheduleRule, TimeSlot, Teacher, Classroom, LessonType)
  • Настроить ManyToMany-связь ScheduleRule ↔ StudentGroup через schedule_rule_groups

DTO

  • Создать DTO: TimeSlotDto
  • Создать DTO: AcademicYearDto, SemesterDto
  • Создать DTO: HolidayDto
  • Создать DTO: AcademicCalendarMatrixDto
  • Создать DTO: ScheduleRuleDto, ScheduleRuleSlotDto
  • Создать DTO: RenderedLessonDto (ответ генератора расписания)

Repository

  • Создать TimeSlotRepository
  • Создать AcademicYearRepository
  • Создать SemesterRepository (метод findByDateRange)
  • Создать HolidayRepository (метод findByAcademicYearId)
  • Создать AcademicCalendarMatrixRepository (метод findBySemesterAndCourseAndSpecialty)
  • Создать ScheduleRuleRepository с JOIN FETCH (решение N+1 проблемы)
    • Метод: findByGroupIdAndSemesterId (через schedule_rule_groups)
    • Метод: findByTeacherIdAndSemesterId (через schedule_rule_slots.teacher_id)

Сервис: AcademicDateService

  • Метод: перевод произвольной даты → номер недели семестра
  • Метод: определение чётности недели с учётом настройки тенанта
  • Метод: проверка попадания даты в справочник holidays
  • Метод: вычисление текущего курса группы (текущий_учебный_год - year_start_study + 1)
  • Метод: определение семестра по дате
  • Написать юнит-тесты для AcademicDateService

Сервис: ScheduleGeneratorService

  • Метод: buildScheduleForGroup(groupId, startDate, endDate) — расписание группы
    • Определение семестра по диапазону дат
    • Вычисление номера недели и курса группы
    • Проверка типа деятельности через матрицу графика
    • Загрузка активных правил для группы
    • Симуляция прогона часов (подсчёт consumed_hours)
    • Пропуск праздников при подсчёте часов
    • Проекция слотов на запрошенную неделю с учётом чётности и подгрупп
  • Метод: buildScheduleForTeacher(teacherId, startDate, endDate) — расписание преподавателя
    • Поиск правил по teacher_id в слотах
    • Обогащение ответа списком групп из schedule_rule_groups
  • Написать юнит-тесты для ScheduleGeneratorService
  • Написать интеграционные тесты (полный цикл с тестовой БД)

Кеширование

  • Реализовать кеш списка праздников по учебному году
  • Реализовать кеш матрицы учебного графика по ключу (course, specialty_id, semester_id)
  • Реализовать кеш consumed_hours для каждого правила
  • Реализовать инвалидацию кеша праздников при CRUD-операциях с holidays
  • Реализовать инвалидацию кеша consumed_hours при изменении правил или праздников

Валидация

  • Адаптировать валидатор пересечения аудиторий (симуляция всего семестра при сохранении правила)
  • Валидация пересечения преподавателей (один преподаватель не может вести две пары одновременно)
  • Валидация пересечения групп (одна группа не может быть на двух занятиях одновременно, кроме подгрупп)

REST API: Контроллеры

  • GET /api/schedule — Новый эндпоинт расписания (параметры: groupId/teacherId + startDate + endDate)
  • Пометить GET /api/users/lessons как @Deprecated (обратная совместимость)
  • CRUD: POST/GET/PUT/DELETE /api/admin/time-slots
  • CRUD: POST/GET/PUT/DELETE /api/admin/calendar/years
  • CRUD: GET/PUT /api/admin/calendar/semesters (вложены в years)
  • CRUD: POST/GET/PUT/DELETE /api/admin/calendar/holidays
  • CRUD: GET/PUT /api/admin/calendar/matrix (массовое сохранение матрицы)
  • CRUD: POST/GET/PUT/DELETE /api/admin/schedule-rules
    • Включая вложенные слоты и привязку групп
  • Написать интеграционные тесты для API

Удаление устаревшего кода

  • Удалить/рефакторить старый LessonsController (после миграции фронтенда)
  • Удалить/рефакторить старый ScheduleDataController
  • Удалить старые Entity: Lesson, ScheduleData
  • Удалить старые Repository и Service для lessons/schedule_data

Frontend (Vanilla JS + HTML/CSS)

Просмотр расписания: Студенты

  • Реализовать переключатель дат (Date Picker / кнопки-стрелки по неделям)
  • Переключить API-запросы на новый GET /api/schedule?groupId=...&startDate=...&endDate=...
  • Рендеринг расписания по дням и временным слотам
  • Отображение статуса периода (Каникулы / Практика / Экзамены), если неделя не учебная
  • Отображение информации о подгруппах (два занятия рядом для разных подгрупп)

Просмотр расписания: Преподаватели

  • Реализовать переключатель дат (Date Picker / кнопки-стрелки по неделям)
  • Переключить API-запросы на новый GET /api/schedule?teacherId=...&startDate=...&endDate=...
  • Отображение всех групп, привязанных к каждому занятию
  • Отображение подгрупп, если преподаватель ведёт у подгруппы

Панель администратора: Вкладка «Временные слоты»

  • Создать UI-страницу настройки временных слотов
  • CRUD-интерфейс: добавление/редактирование/удаление пар
  • Отображение таблицы: номер пары → время начала → время окончания → длительность
  • Валидация на фронтенде (пересечение времён, корректность данных)

Панель администратора: Вкладка «Учебный график»

  • Создать UI: выбор учебного года и семестра
  • Создать UI: CRUD учебных годов и семестров
  • Создать UI: CRUD праздников (список дат с описанием)
  • Создать визуальную сетку-матрицу:
    • Горизонтальная ось — номера недель
    • Вертикальная ось — Курс + Специальность
    • Цветовая кодировка ячеек: Теория/Экзамены/Каникулы/Практика
    • Клик/драг для массового назначения статуса
  • Сохранение матрицы через API PUT /api/admin/calendar/matrix

Панель администратора: Вкладка «Конструктор Правил»

  • Создать UI: список существующих правил с фильтрацией (по группе, предмету, семестру)
  • Форма создания/редактирования правила:
    • Мультиселект групп (для потоковых лекций)
    • Выбор дисциплины (subject)
    • Выбор семестра
    • Ввод totalHours (академические часы)
    • Ввод даты начала (active_from_date)
  • Динамический массив слотов (кнопка «Добавить занятие»):
    • Select: День недели
    • Select: Временной слот (из таблицы time_slots)
    • Select: Чётность (Обе/Чётная/Нечётная)
    • Select: Подгруппа (опционально)
    • Select: Преподаватель
    • Select: Аудитория
    • Select: Тип занятия (Лекция/Практика/Лаба)
    • Select: Формат (Очно/Онлайн)
  • Визуальное предупреждение при конфликтах (аудитория/преподаватель уже заняты)
  • Удаление правила с подтверждением