-- Sub-course prerequisite links (admin-defined course flow) CREATE TABLE IF NOT EXISTS sub_course_prerequisites ( id BIGSERIAL PRIMARY KEY, sub_course_id BIGINT NOT NULL REFERENCES sub_courses(id) ON DELETE CASCADE, prerequisite_sub_course_id BIGINT NOT NULL REFERENCES sub_courses(id) ON DELETE CASCADE, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE(sub_course_id, prerequisite_sub_course_id), CHECK(sub_course_id != prerequisite_sub_course_id) ); CREATE INDEX IF NOT EXISTS idx_sub_course_prerequisites_sub_course_id ON sub_course_prerequisites(sub_course_id); CREATE INDEX IF NOT EXISTS idx_sub_course_prerequisites_prerequisite_id ON sub_course_prerequisites(prerequisite_sub_course_id); -- User progress per sub-course CREATE TABLE IF NOT EXISTS user_sub_course_progress ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, sub_course_id BIGINT NOT NULL REFERENCES sub_courses(id) ON DELETE CASCADE, status VARCHAR(20) NOT NULL DEFAULT 'IN_PROGRESS' CHECK ( status IN ('IN_PROGRESS', 'COMPLETED') ), progress_percentage SMALLINT NOT NULL DEFAULT 0 CHECK ( progress_percentage BETWEEN 0 AND 100 ), started_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, completed_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ, UNIQUE(user_id, sub_course_id) ); CREATE INDEX IF NOT EXISTS idx_user_sub_course_progress_user_id ON user_sub_course_progress(user_id); CREATE INDEX IF NOT EXISTS idx_user_sub_course_progress_sub_course_id ON user_sub_course_progress(sub_course_id); CREATE INDEX IF NOT EXISTS idx_user_sub_course_progress_status ON user_sub_course_progress(user_id, status);