Fix LMS practice visibility and completion publish checks.
Require question_sets.status to be PUBLISHED for learner-visible practices and reject completion for non-published practice sets so learner progress reflects only publish-ready content. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
474bf3282a
commit
ffbb885d06
|
|
@ -34,10 +34,15 @@ SELECT
|
||||||
p.created_at,
|
p.created_at,
|
||||||
p.updated_at
|
p.updated_at
|
||||||
FROM lms_practices p
|
FROM lms_practices p
|
||||||
|
INNER JOIN question_sets qs ON qs.id = p.question_set_id
|
||||||
WHERE p.course_id = $1
|
WHERE p.course_id = $1
|
||||||
AND (
|
AND (
|
||||||
sqlc.arg('published_only')::boolean = FALSE
|
sqlc.arg('published_only')::boolean = FALSE
|
||||||
OR p.publish_status = 'PUBLISHED'::TEXT
|
OR (
|
||||||
|
p.publish_status = 'PUBLISHED'::TEXT
|
||||||
|
AND qs.set_type = 'PRACTICE'
|
||||||
|
AND qs.status = 'PUBLISHED'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
ORDER BY p.created_at DESC
|
ORDER BY p.created_at DESC
|
||||||
LIMIT $2 OFFSET $3;
|
LIMIT $2 OFFSET $3;
|
||||||
|
|
@ -59,10 +64,15 @@ SELECT
|
||||||
p.created_at,
|
p.created_at,
|
||||||
p.updated_at
|
p.updated_at
|
||||||
FROM lms_practices p
|
FROM lms_practices p
|
||||||
|
INNER JOIN question_sets qs ON qs.id = p.question_set_id
|
||||||
WHERE p.module_id = $1
|
WHERE p.module_id = $1
|
||||||
AND (
|
AND (
|
||||||
sqlc.arg('published_only')::boolean = FALSE
|
sqlc.arg('published_only')::boolean = FALSE
|
||||||
OR p.publish_status = 'PUBLISHED'::TEXT
|
OR (
|
||||||
|
p.publish_status = 'PUBLISHED'::TEXT
|
||||||
|
AND qs.set_type = 'PRACTICE'
|
||||||
|
AND qs.status = 'PUBLISHED'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
ORDER BY p.created_at DESC
|
ORDER BY p.created_at DESC
|
||||||
LIMIT $2 OFFSET $3;
|
LIMIT $2 OFFSET $3;
|
||||||
|
|
@ -84,10 +94,15 @@ SELECT
|
||||||
p.created_at,
|
p.created_at,
|
||||||
p.updated_at
|
p.updated_at
|
||||||
FROM lms_practices p
|
FROM lms_practices p
|
||||||
|
INNER JOIN question_sets qs ON qs.id = p.question_set_id
|
||||||
WHERE p.lesson_id = $1
|
WHERE p.lesson_id = $1
|
||||||
AND (
|
AND (
|
||||||
sqlc.arg('published_only')::boolean = FALSE
|
sqlc.arg('published_only')::boolean = FALSE
|
||||||
OR p.publish_status = 'PUBLISHED'::TEXT
|
OR (
|
||||||
|
p.publish_status = 'PUBLISHED'::TEXT
|
||||||
|
AND qs.set_type = 'PRACTICE'
|
||||||
|
AND qs.status = 'PUBLISHED'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
ORDER BY p.created_at DESC
|
ORDER BY p.created_at DESC
|
||||||
LIMIT $2 OFFSET $3;
|
LIMIT $2 OFFSET $3;
|
||||||
|
|
|
||||||
|
|
@ -147,10 +147,15 @@ SELECT
|
||||||
p.created_at,
|
p.created_at,
|
||||||
p.updated_at
|
p.updated_at
|
||||||
FROM lms_practices p
|
FROM lms_practices p
|
||||||
|
INNER JOIN question_sets qs ON qs.id = p.question_set_id
|
||||||
WHERE p.course_id = $1
|
WHERE p.course_id = $1
|
||||||
AND (
|
AND (
|
||||||
$4::boolean = FALSE
|
$4::boolean = FALSE
|
||||||
OR p.publish_status = 'PUBLISHED'::TEXT
|
OR (
|
||||||
|
p.publish_status = 'PUBLISHED'::TEXT
|
||||||
|
AND qs.set_type = 'PRACTICE'
|
||||||
|
AND qs.status = 'PUBLISHED'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
ORDER BY p.created_at DESC
|
ORDER BY p.created_at DESC
|
||||||
LIMIT $2 OFFSET $3
|
LIMIT $2 OFFSET $3
|
||||||
|
|
@ -237,10 +242,15 @@ SELECT
|
||||||
p.created_at,
|
p.created_at,
|
||||||
p.updated_at
|
p.updated_at
|
||||||
FROM lms_practices p
|
FROM lms_practices p
|
||||||
|
INNER JOIN question_sets qs ON qs.id = p.question_set_id
|
||||||
WHERE p.lesson_id = $1
|
WHERE p.lesson_id = $1
|
||||||
AND (
|
AND (
|
||||||
$4::boolean = FALSE
|
$4::boolean = FALSE
|
||||||
OR p.publish_status = 'PUBLISHED'::TEXT
|
OR (
|
||||||
|
p.publish_status = 'PUBLISHED'::TEXT
|
||||||
|
AND qs.set_type = 'PRACTICE'
|
||||||
|
AND qs.status = 'PUBLISHED'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
ORDER BY p.created_at DESC
|
ORDER BY p.created_at DESC
|
||||||
LIMIT $2 OFFSET $3
|
LIMIT $2 OFFSET $3
|
||||||
|
|
@ -327,10 +337,15 @@ SELECT
|
||||||
p.created_at,
|
p.created_at,
|
||||||
p.updated_at
|
p.updated_at
|
||||||
FROM lms_practices p
|
FROM lms_practices p
|
||||||
|
INNER JOIN question_sets qs ON qs.id = p.question_set_id
|
||||||
WHERE p.module_id = $1
|
WHERE p.module_id = $1
|
||||||
AND (
|
AND (
|
||||||
$4::boolean = FALSE
|
$4::boolean = FALSE
|
||||||
OR p.publish_status = 'PUBLISHED'::TEXT
|
OR (
|
||||||
|
p.publish_status = 'PUBLISHED'::TEXT
|
||||||
|
AND qs.set_type = 'PRACTICE'
|
||||||
|
AND qs.status = 'PUBLISHED'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
ORDER BY p.created_at DESC
|
ORDER BY p.created_at DESC
|
||||||
LIMIT $2 OFFSET $3
|
LIMIT $2 OFFSET $3
|
||||||
|
|
|
||||||
|
|
@ -1594,6 +1594,11 @@ func (h *Handler) CompletePractice(c *fiber.Ctx) error {
|
||||||
if !strings.EqualFold(set.SetType, string(domain.QuestionSetTypePractice)) {
|
if !strings.EqualFold(set.SetType, string(domain.QuestionSetTypePractice)) {
|
||||||
return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{Message: "Practice not found"})
|
return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{Message: "Practice not found"})
|
||||||
}
|
}
|
||||||
|
if !strings.EqualFold(set.Status, "PUBLISHED") {
|
||||||
|
return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{
|
||||||
|
Message: "Only published practices can be completed",
|
||||||
|
})
|
||||||
|
}
|
||||||
if practiceErr != nil {
|
if practiceErr != nil {
|
||||||
if err := h.forbidCompletingDraftPractice(c, set.ID); err != nil {
|
if err := h.forbidCompletingDraftPractice(c, set.ID); err != nil {
|
||||||
code := fiber.StatusInternalServerError
|
code := fiber.StatusInternalServerError
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user