feat(db): миграции групп, курсов, статусов и профиля

This commit is contained in:
2026-10-26 15:47:11 +03:00
parent cde04487e8
commit de9535d35c
14 changed files with 460 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
-- Курс-дисциплина, назначения преподавателей и привязка групп.
CREATE TABLE courses (
id uuid PRIMARY KEY DEFAULT uuidv7(),
course_no bigint GENERATED ALWAYS AS IDENTITY UNIQUE NOT NULL,
title varchar(200) NOT NULL,
owner_account_id uuid NOT NULL,
status varchar(16) NOT NULL DEFAULT 'ACTIVE',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
CONSTRAINT courses_status_check CHECK (status IN ('ACTIVE', 'ARCHIVED'))
);
CREATE INDEX courses_status_idx ON courses (status);
CREATE TABLE course_teachers (
id uuid PRIMARY KEY DEFAULT uuidv7(),
course_id uuid NOT NULL REFERENCES courses (id) ON DELETE CASCADE,
account_id uuid NOT NULL,
assigned_at timestamptz NOT NULL DEFAULT now(),
removed_at timestamptz
);
CREATE UNIQUE INDEX course_teachers_active_uidx
ON course_teachers (course_id, account_id)
WHERE removed_at IS NULL;
CREATE INDEX course_teachers_account_idx ON course_teachers (account_id)
WHERE removed_at IS NULL;
CREATE TABLE course_groups (
id uuid PRIMARY KEY DEFAULT uuidv7(),
course_id uuid NOT NULL REFERENCES courses (id) ON DELETE CASCADE,
group_id uuid NOT NULL,
added_at timestamptz NOT NULL DEFAULT now(),
removed_at timestamptz
);
CREATE UNIQUE INDEX course_groups_active_uidx
ON course_groups (course_id, group_id)
WHERE removed_at IS NULL;
CREATE INDEX course_groups_group_idx ON course_groups (group_id)
WHERE removed_at IS NULL;

View File

@@ -0,0 +1,12 @@
-- Лабораторные привязываются к курсу. Nullable-фаза: курс C создаёт
-- bootstrap после первого входа админа, затем выполняется post-bootstrap
-- миграция с SET NOT NULL.
ALTER TABLE labs ADD COLUMN course_id uuid REFERENCES courses (id) ON DELETE RESTRICT;
ALTER TABLE labs DROP CONSTRAINT IF EXISTS labs_number_semester_unique;
-- Для лаб курса номер уникален в рамках курса. NULL-курс (до bootstrap)
-- не участвует в уникальности, поэтому старые дубли по семестрам не мешают
-- миграции; preflight показывает их до привязки.
CREATE UNIQUE INDEX labs_number_course_uidx ON labs (number, course_id);
CREATE INDEX labs_course_idx ON labs (course_id);

View File

@@ -0,0 +1,18 @@
-- Материалы: глава может принадлежать курсу или быть глобальной с аудиторией.
ALTER TABLE chapters ADD COLUMN course_id uuid REFERENCES courses (id) ON DELETE CASCADE;
ALTER TABLE chapters ADD COLUMN audience varchar(16);
ALTER TABLE chapters
ADD CONSTRAINT chapters_audience_check CHECK (
audience IS NULL OR audience IN ('ALL', 'STUDENTS', 'TEACHERS')
),
ADD CONSTRAINT chapters_course_audience_check CHECK (
course_id IS NULL OR audience IS NULL
);
-- slug уникален глобально только среди глобальных глав и внутри курса —
-- среди курсовых.
ALTER TABLE chapters DROP CONSTRAINT IF EXISTS chapters_slug_key;
CREATE UNIQUE INDEX chapters_slug_global_uidx ON chapters (slug) WHERE course_id IS NULL;
CREATE UNIQUE INDEX chapters_slug_course_uidx ON chapters (course_id, slug) WHERE course_id IS NOT NULL;
CREATE INDEX chapters_course_idx ON chapters (course_id);

View File

@@ -0,0 +1,2 @@
-- Активы уже связаны со статьёй, но выборка по статье не индексирована.
CREATE INDEX article_assets_article_idx ON article_assets (article_id);