Expose publish_status on create/update, filter learner-facing lists and gates, and add migration 000060. Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
2.0 KiB
Go
52 lines
2.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"Yimaru-Backend/internal/domain"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
func (h *Handler) canManageLMSPractices(c *fiber.Ctx) bool {
|
|
rn := string(c.Locals("role").(domain.Role))
|
|
return h.rbacSvc.HasPermission(rn, "practices.create") || h.rbacSvc.HasPermission(rn, "practices.update")
|
|
}
|
|
|
|
func (h *Handler) canManageExamPrepPractices(c *fiber.Ctx) bool {
|
|
rn := string(c.Locals("role").(domain.Role))
|
|
return h.rbacSvc.HasPermission(rn, "exam_prep.practices.create") || h.rbacSvc.HasPermission(rn, "exam_prep.practices.update")
|
|
}
|
|
|
|
// forbidIfLinkedPracticeDraftForSubscriber returns 404 for draft LMS/exam-prep shells when the caller cannot manage content.
|
|
func (h *Handler) forbidIfLinkedPracticeDraftForSubscriber(c *fiber.Ctx, questionSetID int64) error {
|
|
if lp, ok, err := h.practiceSvc.TryGetByQuestionSetID(c.Context(), questionSetID); err != nil {
|
|
return err
|
|
} else if ok && !lp.VisibleToLearners() && !h.canManageLMSPractices(c) {
|
|
return fiber.NewError(fiber.StatusNotFound, "Practice not found")
|
|
}
|
|
|
|
if ep, ok, err := h.examPrepSvc.TryGetExamPrepPracticeByQuestionSetID(c.Context(), questionSetID); err != nil {
|
|
return err
|
|
} else if ok && !ep.VisibleToLearners() && !h.canManageExamPrepPractices(c) {
|
|
return fiber.NewError(fiber.StatusNotFound, "Practice not found")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// forbidCompletingDraftPractice blocks completion when an LMS/exam-prep shell is still in draft (learners/students path).
|
|
func (h *Handler) forbidCompletingDraftPractice(c *fiber.Ctx, questionSetID int64) error {
|
|
if lp, ok, err := h.practiceSvc.TryGetByQuestionSetID(c.Context(), questionSetID); err != nil {
|
|
return err
|
|
} else if ok && !lp.VisibleToLearners() {
|
|
return fiber.NewError(fiber.StatusForbidden, "Only published practices can be completed")
|
|
}
|
|
|
|
if ep, ok, err := h.examPrepSvc.TryGetExamPrepPracticeByQuestionSetID(c.Context(), questionSetID); err != nil {
|
|
return err
|
|
} else if ok && !ep.VisibleToLearners() {
|
|
return fiber.NewError(fiber.StatusForbidden, "Only published practices can be completed")
|
|
}
|
|
|
|
return nil
|
|
}
|