From c711df68b9ef0fc1c57768aa9e3d34d3089af4da Mon Sep 17 00:00:00 2001 From: Yared Yemane Date: Tue, 12 May 2026 02:57:05 -0700 Subject: [PATCH] Fix practice completion lookup for progress endpoint. Accept either question-set IDs or LMS practice IDs and recognize LMS owner types so valid practice completions no longer return practice-not-found responses. Co-authored-by: Cursor --- internal/web_server/handlers/questions.go | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/internal/web_server/handlers/questions.go b/internal/web_server/handlers/questions.go index a7f115f..876021a 100644 --- a/internal/web_server/handlers/questions.go +++ b/internal/web_server/handlers/questions.go @@ -731,7 +731,7 @@ func isSequenceGatedPractice(set domain.QuestionSet) bool { return false } ot := strings.ToUpper(strings.TrimSpace(*set.OwnerType)) - return ot == "SUB_COURSE" || ot == "SUB_MODULE" + return ot == "SUB_COURSE" || ot == "SUB_MODULE" || ot == "COURSE" || ot == "MODULE" || ot == "LESSON" } func (h *Handler) enforcePracticeSequenceForStudent(c *fiber.Ctx, set domain.QuestionSet) error { @@ -1539,7 +1539,7 @@ func (h *Handler) CompletePractice(c *fiber.Ctx) error { } userID := c.Locals("user_id").(int64) - setID, err := strconv.ParseInt(c.Params("id"), 10, 64) + id, err := strconv.ParseInt(c.Params("id"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid practice ID", @@ -1547,12 +1547,23 @@ func (h *Handler) CompletePractice(c *fiber.Ctx) error { }) } - set, err := h.questionsSvc.GetQuestionSetByID(c.Context(), setID) + set, err := h.questionsSvc.GetQuestionSetByID(c.Context(), id) if err != nil { - return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{ - Message: "Practice not found", - Error: err.Error(), - }) + // Backward/UX compatibility: accept either question_set.id or lms_practices.id. + practice, practiceErr := h.practiceSvc.GetByID(c.Context(), id) + if practiceErr != nil { + return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{ + Message: "Practice not found", + Error: err.Error(), + }) + } + set, err = h.questionsSvc.GetQuestionSetByID(c.Context(), practice.QuestionSetID) + if err != nil { + return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{ + Message: "Practice not found", + Error: err.Error(), + }) + } } if !isSequenceGatedPractice(set) || !strings.EqualFold(set.Status, "PUBLISHED") { return c.Status(fiber.StatusNotFound).JSON(domain.ErrorResponse{