151 lines
4.2 KiB
SQL
151 lines
4.2 KiB
SQL
-- Sequential order for programs, courses, modules, and lessons (1 = first in each scope).
|
|
-- Progress tables mark completion; API enforces prerequisites for learners (STUDENT role).
|
|
|
|
ALTER TABLE programs
|
|
ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
|
|
ALTER TABLE courses
|
|
ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
|
|
ALTER TABLE modules
|
|
ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
|
|
ALTER TABLE lessons
|
|
ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
|
|
|
|
-- Program order (one global sequence): Beginner -> Intermediate -> Advanced; others by id
|
|
UPDATE programs
|
|
SET sort_order = v.so
|
|
FROM (
|
|
VALUES
|
|
('Beginner', 1),
|
|
('Intermediate', 2),
|
|
('Advanced', 3)
|
|
) AS v (name, so)
|
|
WHERE programs.name = v.name;
|
|
|
|
UPDATE programs
|
|
SET sort_order = 1000 + r.rn
|
|
FROM (
|
|
SELECT
|
|
id,
|
|
row_number() OVER (
|
|
ORDER BY id
|
|
) AS rn
|
|
FROM programs
|
|
WHERE
|
|
sort_order = 0
|
|
) AS r
|
|
WHERE
|
|
programs.id = r.id;
|
|
|
|
-- CEFR courses: A1..C2; remaining courses in each program: stable order
|
|
UPDATE courses
|
|
SET sort_order = CASE name
|
|
WHEN 'A1' THEN
|
|
1
|
|
WHEN 'A2' THEN
|
|
2
|
|
WHEN 'B1' THEN
|
|
3
|
|
WHEN 'B2' THEN
|
|
4
|
|
WHEN 'C1' THEN
|
|
5
|
|
WHEN 'C2' THEN
|
|
6
|
|
ELSE
|
|
0
|
|
END
|
|
WHERE
|
|
name IN ('A1', 'A2', 'B1', 'B2', 'C1', 'C2');
|
|
|
|
UPDATE courses c
|
|
SET sort_order = 2000 + s.rn
|
|
FROM (
|
|
SELECT
|
|
id,
|
|
row_number() OVER (
|
|
PARTITION BY program_id
|
|
ORDER BY
|
|
id
|
|
) AS rn
|
|
FROM courses
|
|
WHERE
|
|
sort_order = 0
|
|
) AS s
|
|
WHERE
|
|
c.id = s.id;
|
|
|
|
UPDATE modules m
|
|
SET sort_order = r.rn
|
|
FROM (
|
|
SELECT
|
|
id,
|
|
row_number() OVER (
|
|
PARTITION BY course_id
|
|
ORDER BY
|
|
id
|
|
) AS rn
|
|
FROM modules
|
|
) AS r
|
|
WHERE
|
|
m.id = r.id;
|
|
|
|
UPDATE lessons l
|
|
SET sort_order = r.rn
|
|
FROM (
|
|
SELECT
|
|
id,
|
|
row_number() OVER (
|
|
PARTITION BY module_id
|
|
ORDER BY
|
|
id
|
|
) AS rn
|
|
FROM lessons
|
|
) AS r
|
|
WHERE
|
|
l.id = r.id;
|
|
|
|
CREATE UNIQUE INDEX uq_programs_sort_order ON programs (sort_order);
|
|
CREATE UNIQUE INDEX uq_courses_program_sort ON courses (program_id, sort_order);
|
|
CREATE UNIQUE INDEX uq_modules_course_sort ON modules (course_id, sort_order);
|
|
CREATE UNIQUE INDEX uq_lessons_module_sort ON lessons (module_id, sort_order);
|
|
|
|
CREATE TABLE lms_user_lesson_progress (
|
|
user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
lesson_id BIGINT NOT NULL REFERENCES lessons (id) ON DELETE CASCADE,
|
|
completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id, lesson_id)
|
|
);
|
|
|
|
CREATE INDEX idx_lms_user_lesson_progress_user ON lms_user_lesson_progress (user_id);
|
|
CREATE INDEX idx_lms_user_lesson_progress_lesson ON lms_user_lesson_progress (lesson_id);
|
|
|
|
CREATE TABLE lms_user_module_progress (
|
|
user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
module_id BIGINT NOT NULL REFERENCES modules (id) ON DELETE CASCADE,
|
|
completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id, module_id)
|
|
);
|
|
|
|
CREATE INDEX idx_lms_user_module_progress_user ON lms_user_module_progress (user_id);
|
|
CREATE INDEX idx_lms_user_module_progress_module ON lms_user_module_progress (module_id);
|
|
|
|
CREATE TABLE lms_user_course_progress (
|
|
user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
course_id BIGINT NOT NULL REFERENCES courses (id) ON DELETE CASCADE,
|
|
completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id, course_id)
|
|
);
|
|
|
|
CREATE INDEX idx_lms_user_course_progress_user ON lms_user_course_progress (user_id);
|
|
CREATE INDEX idx_lms_user_course_progress_course ON lms_user_course_progress (course_id);
|
|
|
|
CREATE TABLE lms_user_program_progress (
|
|
user_id BIGINT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
program_id BIGINT NOT NULL REFERENCES programs (id) ON DELETE CASCADE,
|
|
completed_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (user_id, program_id)
|
|
);
|
|
|
|
CREATE INDEX idx_lms_user_program_progress_user ON lms_user_program_progress (user_id);
|
|
CREATE INDEX idx_lms_user_program_progress_program ON lms_user_program_progress (program_id);
|