Yimaru-BackEnd/db/query/lms_progress.sql
Yared Yemane 12ad59c409 Add draft vs published status for LMS and exam-prep practices.
Expose publish_status on create/update, filter learner-facing lists and gates, and add migration 000060.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 03:57:43 -07:00

346 lines
7.6 KiB
SQL

-- name: GetPreviousProgram :one
SELECT
p2.*
FROM
programs AS p1
INNER JOIN programs AS p2 ON p2.sort_order = p1.sort_order - 1
WHERE
p1.id = $1;
-- name: GetPreviousCourseInProgram :one
SELECT
c2.*
FROM
courses AS c1
INNER JOIN courses AS c2 ON c2.program_id = c1.program_id
AND c2.sort_order = c1.sort_order - 1
WHERE
c1.id = $1;
-- name: GetPreviousModuleInCourse :one
SELECT
m2.*
FROM
modules AS m1
INNER JOIN modules AS m2 ON m2.course_id = m1.course_id
AND m2.sort_order = m1.sort_order - 1
WHERE
m1.id = $1;
-- name: GetPreviousLessonInModule :one
SELECT
l2.*
FROM
lessons AS l1
INNER JOIN lessons AS l2 ON l2.module_id = l1.module_id
AND l2.sort_order = l1.sort_order - 1
WHERE
l1.id = $1;
-- name: UserHasProgramProgress :one
SELECT
EXISTS (
SELECT
1
FROM
lms_user_program_progress
WHERE
user_id = $1
AND program_id = $2) AS v;
-- name: UserHasCourseProgress :one
SELECT
EXISTS (
SELECT
1
FROM
lms_user_course_progress
WHERE
user_id = $1
AND course_id = $2) AS v;
-- name: UserHasModuleProgress :one
SELECT
EXISTS (
SELECT
1
FROM
lms_user_module_progress
WHERE
user_id = $1
AND module_id = $2) AS v;
-- name: UserHasLessonProgress :one
SELECT
EXISTS (
SELECT
1
FROM
lms_user_lesson_progress
WHERE
user_id = $1
AND lesson_id = $2) AS v;
-- name: InsertUserLessonProgress :exec
INSERT INTO lms_user_lesson_progress (user_id, lesson_id)
VALUES ($1, $2)
ON CONFLICT (user_id, lesson_id)
DO NOTHING;
-- name: InsertUserModuleProgress :exec
INSERT INTO lms_user_module_progress (user_id, module_id)
VALUES ($1, $2)
ON CONFLICT (user_id, module_id)
DO NOTHING;
-- name: InsertUserCourseProgress :exec
INSERT INTO lms_user_course_progress (user_id, course_id)
VALUES ($1, $2)
ON CONFLICT (user_id, course_id)
DO NOTHING;
-- name: InsertUserProgramProgress :exec
INSERT INTO lms_user_program_progress (user_id, program_id)
VALUES ($1, $2)
ON CONFLICT (user_id, program_id)
DO NOTHING;
-- name: CountLessonsInModule :one
SELECT
count(*)::int AS n
FROM
lessons
WHERE
module_id = $1;
-- name: CountUserCompletedLessonsInModule :one
SELECT
count(*)::int AS n
FROM
lms_user_lesson_progress ulp
INNER JOIN lessons l ON l.id = ulp.lesson_id
WHERE
l.module_id = $1
AND ulp.user_id = $2;
-- name: CountModulesInCourse :one
SELECT
count(*)::int AS n
FROM
modules
WHERE
course_id = $1;
-- name: CountUserCompletedModulesInCourse :one
SELECT
count(*)::int AS n
FROM
lms_user_module_progress ump
INNER JOIN modules m ON m.id = ump.module_id
WHERE
m.course_id = $1
AND ump.user_id = $2;
-- name: CountCoursesInProgram :one
SELECT
count(*)::int AS n
FROM
courses
WHERE
program_id = $1;
-- name: CountUserCompletedCoursesInProgram :one
SELECT
count(*)::int AS n
FROM
lms_user_course_progress ucp
INNER JOIN courses c ON c.id = ucp.course_id
WHERE
c.program_id = $1
AND ucp.user_id = $2;
-- name: ListLMSCompletedLessonIDsByUser :many
SELECT
ulp.lesson_id
FROM
lms_user_lesson_progress AS ulp
WHERE
ulp.user_id = $1
ORDER BY
ulp.completed_at ASC,
ulp.lesson_id ASC;
-- name: ListLMSCompletedModuleIDsByUser :many
SELECT
ump.module_id
FROM
lms_user_module_progress AS ump
WHERE
ump.user_id = $1
ORDER BY
ump.completed_at ASC,
ump.module_id ASC;
-- name: ListLMSCompletedCourseIDsByUser :many
SELECT
ucp.course_id
FROM
lms_user_course_progress AS ucp
WHERE
ucp.user_id = $1
ORDER BY
ucp.completed_at ASC,
ucp.course_id ASC;
-- name: ListLMSCompletedProgramIDsByUser :many
SELECT
upp.program_id
FROM
lms_user_program_progress AS upp
WHERE
upp.user_id = $1
ORDER BY
upp.completed_at ASC,
upp.program_id ASC;
-- Lesson-based progress within a course (all modules).
-- name: CountLessonsInCourse :one
SELECT
count(*)::int AS n
FROM
lessons l
INNER JOIN modules m ON m.id = l.module_id
WHERE
m.course_id = $1;
-- name: CountUserCompletedLessonsInCourse :one
SELECT
count(*)::int AS n
FROM
lms_user_lesson_progress ulp
INNER JOIN lessons l ON l.id = ulp.lesson_id
INNER JOIN modules m ON m.id = l.module_id
WHERE
m.course_id = $1
AND ulp.user_id = $2;
-- Lesson-based progress within a program (all courses).
-- name: CountLessonsInProgram :one
SELECT
count(*)::int AS n
FROM
lessons l
INNER JOIN modules m ON m.id = l.module_id
INNER JOIN courses c ON c.id = m.course_id
WHERE
c.program_id = $1;
-- name: CountUserCompletedLessonsInProgram :one
SELECT
count(*)::int AS n
FROM
lms_user_lesson_progress ulp
INNER JOIN lessons l ON l.id = ulp.lesson_id
INNER JOIN modules m ON m.id = l.module_id
INNER JOIN courses c ON c.id = m.course_id
WHERE
c.program_id = $1
AND ulp.user_id = $2;
-- Published practices in a module (module-level and lesson-level practices should carry module_id).
-- name: CountPublishedPracticesInModule :one
SELECT
count(*)::int AS n
FROM
lms_practices lp
INNER JOIN question_sets qs ON qs.id = lp.question_set_id
WHERE
lp.module_id = $1
AND qs.set_type = 'PRACTICE'
AND qs.status = 'PUBLISHED'
AND lp.publish_status = 'PUBLISHED';
-- name: CountUserCompletedPublishedPracticesInModule :one
SELECT
count(*)::int AS n
FROM
lms_practices lp
INNER JOIN question_sets qs ON qs.id = lp.question_set_id
INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id
WHERE
lp.module_id = $1
AND upp.user_id = $2
AND upp.completed_at IS NOT NULL
AND qs.set_type = 'PRACTICE'
AND qs.status = 'PUBLISHED'
AND lp.publish_status = 'PUBLISHED';
-- name: CountPublishedPracticesInCourse :one
SELECT
count(*)::int AS n
FROM
lms_practices lp
INNER JOIN question_sets qs ON qs.id = lp.question_set_id
WHERE
lp.course_id = $1
AND qs.set_type = 'PRACTICE'
AND qs.status = 'PUBLISHED'
AND lp.publish_status = 'PUBLISHED';
-- name: CountUserCompletedPublishedPracticesInCourse :one
SELECT
count(*)::int AS n
FROM
lms_practices lp
INNER JOIN question_sets qs ON qs.id = lp.question_set_id
INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id
WHERE
lp.course_id = $1
AND upp.user_id = $2
AND upp.completed_at IS NOT NULL
AND qs.set_type = 'PRACTICE'
AND qs.status = 'PUBLISHED';
-- name: CountPublishedPracticesInProgram :one
SELECT
count(*)::int AS n
FROM
lms_practices lp
INNER JOIN courses c ON c.id = lp.course_id
INNER JOIN question_sets qs ON qs.id = lp.question_set_id
WHERE
c.program_id = $1
AND qs.set_type = 'PRACTICE'
AND qs.status = 'PUBLISHED'
AND lp.publish_status = 'PUBLISHED';
-- name: CountUserCompletedPublishedPracticesInProgram :one
SELECT
count(*)::int AS n
FROM
lms_practices lp
INNER JOIN courses c ON c.id = lp.course_id
INNER JOIN question_sets qs ON qs.id = lp.question_set_id
INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id
WHERE
c.program_id = $1
AND upp.user_id = $2
AND upp.completed_at IS NOT NULL
AND qs.set_type = 'PRACTICE'
AND qs.status = 'PUBLISHED'
AND lp.publish_status = 'PUBLISHED';
-- name: GetPracticeScopeByQuestionSetID :one
SELECT
id,
course_id,
module_id,
lesson_id
FROM
lms_practices
WHERE
question_set_id = $1
ORDER BY
id DESC
LIMIT 1;