Expose publish_status on create/update, filter learner-facing lists and gates, and add migration 000060. Co-authored-by: Cursor <cursoragent@cursor.com>
206 lines
6.8 KiB
SQL
206 lines
6.8 KiB
SQL
-- Aggregated LMS learning activity for admin: completed lessons and completed practices
|
|
-- (rollup tables + lesson/practice completion are the persisted signals in this schema).
|
|
|
|
-- name: ListUserLMSFlatLearningActivityByUser :many
|
|
SELECT
|
|
x.activity_kind,
|
|
x.program_id,
|
|
x.program_name,
|
|
x.program_sort_order,
|
|
x.program_completed_at,
|
|
x.course_id,
|
|
x.course_name,
|
|
x.course_sort_order,
|
|
x.course_completed_at,
|
|
COALESCE(x.module_id, 0)::BIGINT AS module_id,
|
|
COALESCE(x.module_name, '')::TEXT AS module_name,
|
|
COALESCE(x.module_sort_order, 0)::INT AS module_sort_order,
|
|
x.module_completed_at,
|
|
COALESCE(x.lesson_id, 0)::BIGINT AS lesson_id,
|
|
COALESCE(x.lesson_title, '')::TEXT AS lesson_title,
|
|
COALESCE(x.lesson_sort_order, 0)::INT AS lesson_sort_order,
|
|
x.lesson_completed_at,
|
|
COALESCE(x.lms_practice_id, 0)::BIGINT AS lms_practice_id,
|
|
COALESCE(x.practice_title, '')::TEXT AS practice_title,
|
|
x.activity_at
|
|
FROM (
|
|
SELECT
|
|
'lesson'::TEXT AS activity_kind,
|
|
p.id AS program_id,
|
|
p.name AS program_name,
|
|
p.sort_order AS program_sort_order,
|
|
prf.completed_at AS program_completed_at,
|
|
c.id AS course_id,
|
|
c.name AS course_name,
|
|
c.sort_order AS course_sort_order,
|
|
crf.completed_at AS course_completed_at,
|
|
m.id AS module_id,
|
|
m.name AS module_name,
|
|
m.sort_order AS module_sort_order,
|
|
mrf.completed_at AS module_completed_at,
|
|
l.id AS lesson_id,
|
|
l.title AS lesson_title,
|
|
l.sort_order AS lesson_sort_order,
|
|
ulp.completed_at AS lesson_completed_at,
|
|
NULL::BIGINT AS lms_practice_id,
|
|
NULL::VARCHAR AS practice_title,
|
|
ulp.completed_at AS activity_at
|
|
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
|
|
AND c.program_id = m.program_id
|
|
INNER JOIN programs p ON p.id = c.program_id
|
|
LEFT JOIN lms_user_program_progress prf ON prf.user_id = ulp.user_id
|
|
AND prf.program_id = p.id
|
|
LEFT JOIN lms_user_course_progress crf ON crf.user_id = ulp.user_id
|
|
AND crf.course_id = c.id
|
|
LEFT JOIN lms_user_module_progress mrf ON mrf.user_id = ulp.user_id
|
|
AND mrf.module_id = m.id
|
|
WHERE
|
|
ulp.user_id = $1
|
|
UNION ALL
|
|
SELECT
|
|
'practice'::TEXT,
|
|
p.id,
|
|
p.name,
|
|
p.sort_order,
|
|
prf.completed_at,
|
|
c.id,
|
|
c.name,
|
|
c.sort_order,
|
|
crf.completed_at,
|
|
m.id,
|
|
m.name,
|
|
m.sort_order,
|
|
mrf.completed_at,
|
|
l.id,
|
|
l.title,
|
|
l.sort_order,
|
|
lucomp.completed_at,
|
|
lp.id,
|
|
lp.title,
|
|
upp.completed_at
|
|
FROM
|
|
user_practice_progress upp
|
|
INNER JOIN lms_practices lp ON lp.question_set_id = upp.question_set_id
|
|
AND lp.lesson_id IS NOT NULL
|
|
AND lp.publish_status = 'PUBLISHED'
|
|
INNER JOIN question_sets qs ON qs.id = upp.question_set_id
|
|
AND qs.set_type = 'PRACTICE'
|
|
AND qs.status = 'PUBLISHED'
|
|
INNER JOIN lessons l ON l.id = lp.lesson_id
|
|
INNER JOIN modules m ON m.id = l.module_id
|
|
INNER JOIN courses c ON c.id = m.course_id
|
|
AND c.program_id = m.program_id
|
|
INNER JOIN programs p ON p.id = c.program_id
|
|
LEFT JOIN lms_user_program_progress prf ON prf.user_id = upp.user_id
|
|
AND prf.program_id = p.id
|
|
LEFT JOIN lms_user_course_progress crf ON crf.user_id = upp.user_id
|
|
AND crf.course_id = c.id
|
|
LEFT JOIN lms_user_module_progress mrf ON mrf.user_id = upp.user_id
|
|
AND mrf.module_id = m.id
|
|
LEFT JOIN lms_user_lesson_progress lucomp ON lucomp.user_id = upp.user_id
|
|
AND lucomp.lesson_id = l.id
|
|
WHERE
|
|
upp.user_id = $1
|
|
AND upp.completed_at IS NOT NULL
|
|
UNION ALL
|
|
SELECT
|
|
'practice'::TEXT,
|
|
p.id,
|
|
p.name,
|
|
p.sort_order,
|
|
prf.completed_at,
|
|
c.id,
|
|
c.name,
|
|
c.sort_order,
|
|
crf.completed_at,
|
|
m.id,
|
|
m.name,
|
|
m.sort_order,
|
|
mrf.completed_at,
|
|
NULL::BIGINT,
|
|
NULL::VARCHAR,
|
|
NULL::INT,
|
|
NULL::TIMESTAMPTZ,
|
|
lp.id,
|
|
lp.title,
|
|
upp.completed_at
|
|
FROM
|
|
user_practice_progress upp
|
|
INNER JOIN lms_practices lp ON lp.question_set_id = upp.question_set_id
|
|
AND lp.module_id IS NOT NULL
|
|
AND lp.lesson_id IS NULL
|
|
AND lp.publish_status = 'PUBLISHED'
|
|
INNER JOIN question_sets qs ON qs.id = upp.question_set_id
|
|
AND qs.set_type = 'PRACTICE'
|
|
AND qs.status = 'PUBLISHED'
|
|
INNER JOIN modules m ON m.id = lp.module_id
|
|
INNER JOIN courses c ON c.id = m.course_id
|
|
AND c.program_id = m.program_id
|
|
INNER JOIN programs p ON p.id = c.program_id
|
|
LEFT JOIN lms_user_program_progress prf ON prf.user_id = upp.user_id
|
|
AND prf.program_id = p.id
|
|
LEFT JOIN lms_user_course_progress crf ON crf.user_id = upp.user_id
|
|
AND crf.course_id = c.id
|
|
LEFT JOIN lms_user_module_progress mrf ON mrf.user_id = upp.user_id
|
|
AND mrf.module_id = m.id
|
|
WHERE
|
|
upp.user_id = $1
|
|
AND upp.completed_at IS NOT NULL
|
|
UNION ALL
|
|
SELECT
|
|
'practice'::TEXT,
|
|
p.id,
|
|
p.name,
|
|
p.sort_order,
|
|
prf.completed_at,
|
|
c.id,
|
|
c.name,
|
|
c.sort_order,
|
|
crf.completed_at,
|
|
NULL::BIGINT,
|
|
NULL::VARCHAR,
|
|
NULL::INT,
|
|
NULL::TIMESTAMPTZ,
|
|
NULL::BIGINT,
|
|
NULL::VARCHAR,
|
|
NULL::INT,
|
|
NULL::TIMESTAMPTZ,
|
|
lp.id,
|
|
lp.title,
|
|
upp.completed_at
|
|
FROM
|
|
user_practice_progress upp
|
|
INNER JOIN lms_practices lp ON lp.question_set_id = upp.question_set_id
|
|
AND lp.course_id IS NOT NULL
|
|
AND lp.module_id IS NULL
|
|
AND lp.lesson_id IS NULL
|
|
AND lp.publish_status = 'PUBLISHED'
|
|
INNER JOIN question_sets qs ON qs.id = upp.question_set_id
|
|
AND qs.set_type = 'PRACTICE'
|
|
AND qs.status = 'PUBLISHED'
|
|
INNER JOIN courses c ON c.id = lp.course_id
|
|
INNER JOIN programs p ON p.id = c.program_id
|
|
LEFT JOIN lms_user_program_progress prf ON prf.user_id = upp.user_id
|
|
AND prf.program_id = p.id
|
|
LEFT JOIN lms_user_course_progress crf ON crf.user_id = upp.user_id
|
|
AND crf.course_id = c.id
|
|
WHERE
|
|
upp.user_id = $1
|
|
AND upp.completed_at IS NOT NULL
|
|
) AS x
|
|
ORDER BY
|
|
x.program_sort_order,
|
|
x.program_id,
|
|
x.course_sort_order,
|
|
x.course_id,
|
|
x.module_sort_order NULLS LAST,
|
|
x.module_id NULLS LAST,
|
|
x.lesson_sort_order NULLS LAST,
|
|
x.lesson_id NULLS LAST,
|
|
x.activity_kind,
|
|
x.activity_at;
|