Fix LMS sequential gating when sort_order has gaps.
Resolve the immediate predecessor by sort_order (and id) instead of requiring sort_order - 1, so learners cannot skip locked programs, courses, or modules when ordering numbers are non-consecutive. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
fbad083ca4
commit
c00ab684c5
|
|
@ -1,11 +1,23 @@
|
|||
-- name: GetPreviousProgram :one
|
||||
-- Immediate predecessor by sort_order within the same category (gaps in sort_order are allowed).
|
||||
SELECT
|
||||
p2.*
|
||||
FROM
|
||||
programs AS p1
|
||||
INNER JOIN programs AS p2 ON p2.sort_order = p1.sort_order - 1
|
||||
INNER JOIN programs AS p2 ON p2.category = p1.category
|
||||
AND (
|
||||
p2.sort_order < p1.sort_order
|
||||
OR (
|
||||
p2.sort_order = p1.sort_order
|
||||
AND p2.id < p1.id
|
||||
)
|
||||
)
|
||||
WHERE
|
||||
p1.id = $1;
|
||||
p1.id = $1
|
||||
ORDER BY
|
||||
p2.sort_order DESC,
|
||||
p2.id DESC
|
||||
LIMIT 1;
|
||||
|
||||
-- name: GetPreviousCourseInProgram :one
|
||||
SELECT
|
||||
|
|
@ -13,9 +25,19 @@ SELECT
|
|||
FROM
|
||||
courses AS c1
|
||||
INNER JOIN courses AS c2 ON c2.program_id = c1.program_id
|
||||
AND c2.sort_order = c1.sort_order - 1
|
||||
AND (
|
||||
c2.sort_order < c1.sort_order
|
||||
OR (
|
||||
c2.sort_order = c1.sort_order
|
||||
AND c2.id < c1.id
|
||||
)
|
||||
)
|
||||
WHERE
|
||||
c1.id = $1;
|
||||
c1.id = $1
|
||||
ORDER BY
|
||||
c2.sort_order DESC,
|
||||
c2.id DESC
|
||||
LIMIT 1;
|
||||
|
||||
-- name: GetPreviousModuleInCourse :one
|
||||
SELECT
|
||||
|
|
@ -23,9 +45,19 @@ SELECT
|
|||
FROM
|
||||
modules AS m1
|
||||
INNER JOIN modules AS m2 ON m2.course_id = m1.course_id
|
||||
AND m2.sort_order = m1.sort_order - 1
|
||||
AND (
|
||||
m2.sort_order < m1.sort_order
|
||||
OR (
|
||||
m2.sort_order = m1.sort_order
|
||||
AND m2.id < m1.id
|
||||
)
|
||||
)
|
||||
WHERE
|
||||
m1.id = $1;
|
||||
m1.id = $1
|
||||
ORDER BY
|
||||
m2.sort_order DESC,
|
||||
m2.id DESC
|
||||
LIMIT 1;
|
||||
|
||||
-- name: GetPreviousLessonInModule :one
|
||||
SELECT
|
||||
|
|
|
|||
|
|
@ -647,9 +647,19 @@ SELECT
|
|||
FROM
|
||||
courses AS c1
|
||||
INNER JOIN courses AS c2 ON c2.program_id = c1.program_id
|
||||
AND c2.sort_order = c1.sort_order - 1
|
||||
AND (
|
||||
c2.sort_order < c1.sort_order
|
||||
OR (
|
||||
c2.sort_order = c1.sort_order
|
||||
AND c2.id < c1.id
|
||||
)
|
||||
)
|
||||
WHERE
|
||||
c1.id = $1
|
||||
ORDER BY
|
||||
c2.sort_order DESC,
|
||||
c2.id DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetPreviousCourseInProgram(ctx context.Context, id int64) (Course, error) {
|
||||
|
|
@ -715,9 +725,19 @@ SELECT
|
|||
FROM
|
||||
modules AS m1
|
||||
INNER JOIN modules AS m2 ON m2.course_id = m1.course_id
|
||||
AND m2.sort_order = m1.sort_order - 1
|
||||
AND (
|
||||
m2.sort_order < m1.sort_order
|
||||
OR (
|
||||
m2.sort_order = m1.sort_order
|
||||
AND m2.id < m1.id
|
||||
)
|
||||
)
|
||||
WHERE
|
||||
m1.id = $1
|
||||
ORDER BY
|
||||
m2.sort_order DESC,
|
||||
m2.id DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetPreviousModuleInCourse(ctx context.Context, id int64) (Module, error) {
|
||||
|
|
@ -742,11 +762,23 @@ SELECT
|
|||
p2.id, p2.name, p2.description, p2.thumbnail, p2.created_at, p2.updated_at, p2.sort_order, p2.category
|
||||
FROM
|
||||
programs AS p1
|
||||
INNER JOIN programs AS p2 ON p2.sort_order = p1.sort_order - 1
|
||||
INNER JOIN programs AS p2 ON p2.category = p1.category
|
||||
AND (
|
||||
p2.sort_order < p1.sort_order
|
||||
OR (
|
||||
p2.sort_order = p1.sort_order
|
||||
AND p2.id < p1.id
|
||||
)
|
||||
)
|
||||
WHERE
|
||||
p1.id = $1
|
||||
ORDER BY
|
||||
p2.sort_order DESC,
|
||||
p2.id DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
// Immediate predecessor by sort_order within the same category (gaps in sort_order are allowed).
|
||||
func (q *Queries) GetPreviousProgram(ctx context.Context, id int64) (Program, error) {
|
||||
row := q.db.QueryRow(ctx, GetPreviousProgram, id)
|
||||
var i Program
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user