diff --git a/db/init/init.sql b/db/init/init.sql index 575e117..87f4c46 100644 --- a/db/init/init.sql +++ b/db/init/init.sql @@ -184,118 +184,13 @@ CREATE TABLE IF NOT EXISTS teacher_lesson_types ( CREATE TABLE IF NOT EXISTS lessons ( id BIGSERIAL PRIMARY KEY, teacher_id BIGINT NOT NULL REFERENCES users(id), - subject_id BIGINT NOT NULL REFERENCES subjects(id), - lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id), - classroom_id BIGINT NOT NULL REFERENCES classrooms(id), group_id BIGINT NOT NULL REFERENCES student_groups(id), - subgroup_id BIGINT REFERENCES subgroups(id), - - day_of_week INT NOT NULL CHECK (day_of_week BETWEEN 1 AND 7), - is_even_week BOOLEAN NOT NULL, - start_time TIME NOT NULL, - end_time TIME NOT NULL, - - -- Дополнительные поля - semester INT CHECK (semester BETWEEN 1 AND 12), - academic_year VARCHAR(9), -- например: '2023-2024' - is_active BOOLEAN DEFAULT TRUE, - notes TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - - -- Проверки - CHECK (end_time > start_time), - CHECK (end_time <= start_time + INTERVAL '4 hours') -- Максимальная длина занятия 4 часа + lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id), + day VARCHAR(255) NOT NULL, + week VARCHAR(255) NOT NULL, + time VARCHAR(255) NOT NULL ); --- Индексы для эффективного поиска -CREATE INDEX IF NOT EXISTS idx_lessons_teacher ON lessons(teacher_id, day_of_week, is_even_week); -CREATE INDEX IF NOT EXISTS idx_lessons_group ON lessons(group_id, day_of_week, is_even_week); -CREATE INDEX IF NOT EXISTS idx_lessons_classroom ON lessons(classroom_id, day_of_week, is_even_week, start_time); -CREATE INDEX IF NOT EXISTS idx_lessons_datetime ON lessons(day_of_week, start_time, end_time); -CREATE INDEX IF NOT EXISTS idx_lessons_active ON lessons(is_active); - --- ========================================== --- Таблица для отслеживания замен и изменений в расписании --- ========================================== -CREATE TABLE IF NOT EXISTS schedule_changes ( - id BIGSERIAL PRIMARY KEY, - original_lesson_id BIGINT REFERENCES lessons(id) ON DELETE SET NULL, - new_teacher_id BIGINT REFERENCES users(id), - new_classroom_id BIGINT REFERENCES classrooms(id), - new_start_time TIME, - new_end_time TIME, - change_reason TEXT NOT NULL, - changed_by BIGINT REFERENCES users(id), - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - effective_date DATE NOT NULL -); - --- ========================================== --- Функция для проверки пересечений расписания --- ========================================== -CREATE OR REPLACE FUNCTION check_schedule_conflict() -RETURNS TRIGGER AS $$ -BEGIN - -- Проверка пересечений для преподавателя - IF EXISTS ( - SELECT 1 FROM lessons - WHERE teacher_id = NEW.teacher_id - AND day_of_week = NEW.day_of_week - AND is_even_week = NEW.is_even_week - AND id != COALESCE(NEW.id, -1) - AND ( - (start_time <= NEW.start_time AND end_time > NEW.start_time) - OR (start_time < NEW.end_time AND end_time >= NEW.end_time) - OR (start_time >= NEW.start_time AND end_time <= NEW.end_time) - ) - ) THEN - RAISE EXCEPTION 'Конфликт расписания для преподавателя'; - END IF; - - -- Проверка пересечений для аудитории - IF EXISTS ( - SELECT 1 FROM lessons - WHERE classroom_id = NEW.classroom_id - AND day_of_week = NEW.day_of_week - AND is_even_week = NEW.is_even_week - AND id != COALESCE(NEW.id, -1) - AND ( - (start_time <= NEW.start_time AND end_time > NEW.start_time) - OR (start_time < NEW.end_time AND end_time >= NEW.end_time) - OR (start_time >= NEW.start_time AND end_time <= NEW.end_time) - ) - ) THEN - RAISE EXCEPTION 'Конфликт расписания для аудитории'; - END IF; - - -- Проверка пересечений для группы - IF EXISTS ( - SELECT 1 FROM lessons - WHERE group_id = NEW.group_id - AND day_of_week = NEW.day_of_week - AND is_even_week = NEW.is_even_week - AND id != COALESCE(NEW.id, -1) - AND ( - (start_time <= NEW.start_time AND end_time > NEW.start_time) - OR (start_time < NEW.end_time AND end_time >= NEW.end_time) - OR (start_time >= NEW.start_time AND end_time <= NEW.end_time) - ) - ) THEN - RAISE EXCEPTION 'Конфликт расписания для группы'; - END IF; - - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - --- Триггер для проверки конфликтов при вставке/обновлении -DROP TRIGGER IF EXISTS check_lesson_conflict ON lessons; -CREATE TRIGGER check_lesson_conflict - BEFORE INSERT OR UPDATE ON lessons - FOR EACH ROW - EXECUTE FUNCTION check_schedule_conflict(); - -- ========================================== -- Функция обновления timestamp -- ========================================== @@ -313,16 +208,8 @@ CREATE TRIGGER update_users_updated_at FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -CREATE TRIGGER update_lessons_updated_at - BEFORE UPDATE ON lessons - FOR EACH ROW - EXECUTE FUNCTION update_updated_at_column(); - -- ========================================== -- Комментарии к таблицам и полям (для документации) -- ========================================== COMMENT ON TABLE users IS 'Пользователи системы (студенты, преподаватели, администраторы)'; -COMMENT ON TABLE lessons IS 'Основное расписание занятий'; -COMMENT ON COLUMN lessons.day_of_week IS 'День недели (1-Пн, 2-Вт, 3-Ср, 4-Чт, 5-Пт, 6-Сб, 7-Вс)'; -COMMENT ON COLUMN lessons.is_even_week IS 'true - четная неделя, false - нечетная'; -COMMENT ON TABLE schedule_changes IS 'История изменений и замен в расписании'; \ No newline at end of file +COMMENT ON TABLE lessons IS 'Основное расписание занятий'; \ No newline at end of file