33 lines
1.6 KiB
SQL
33 lines
1.6 KiB
SQL
-- A learning path is deliberately only a curated, ordered collection of
|
|
-- existing courses. Lessons remain owned by their courses, so a course edit
|
|
-- is reflected everywhere that course appears.
|
|
create table learning_paths (
|
|
id uuid primary key default gen_random_uuid(),
|
|
title text not null check (char_length(trim(title)) between 1 and 160),
|
|
description text not null default '',
|
|
cover_image_url text,
|
|
cover_image_zoom real not null default 1 check (cover_image_zoom between 1 and 2.5),
|
|
cover_image_position_x real not null default 50 check (cover_image_position_x between 0 and 100),
|
|
cover_image_position_y real not null default 50 check (cover_image_position_y between 0 and 100),
|
|
status course_status not null default 'draft',
|
|
published_at timestamptz,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
constraint learning_paths_published_at_check check (
|
|
(status = 'published' and published_at is not null) or status <> 'published'
|
|
)
|
|
);
|
|
|
|
create table learning_path_courses (
|
|
learning_path_id uuid not null references learning_paths(id) on delete cascade,
|
|
course_id uuid not null references courses(id) on delete restrict,
|
|
position integer not null check (position > 0),
|
|
primary key (learning_path_id, course_id),
|
|
unique (learning_path_id, position)
|
|
);
|
|
|
|
create index learning_paths_published_index on learning_paths (published_at desc) where status = 'published';
|
|
create index learning_path_courses_position_index on learning_path_courses (learning_path_id, position);
|
|
|
|
create trigger learning_paths_set_updated_at before update on learning_paths for each row execute function set_updated_at();
|