Yimaru-BackEnd/internal/web_server/handlers/practice_publish_gate.go
Yared Yemane bd1767d2a6 Add LMS lesson draft and publish visibility.
Migration 000062 adds lessons.publish_status (DRAFT default for new rows; existing rows published). Editors see all lessons; learners see published-only lists and GET by id. Sequential prerequisites and completion counts ignore drafts. Course lesson_count counts published lessons only. Swagger documents publish_status on create/update bodies.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 02:16:42 -07:00

57 lines
2.2 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) canManageLessons(c *fiber.Ctx) bool {
rn := string(c.Locals("role").(domain.Role))
return h.rbacSvc.HasPermission(rn, "lessons.create") || h.rbacSvc.HasPermission(rn, "lessons.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
}