Yimaru-BackEnd/internal/web_server/handlers/content_access_gate.go
Yared Yemane 4f873fe9de chore: temporarily disable exam-prep subscription enforcement
Add ExamPrepSubscriptionGateDisabled so learners can access exam-prep content without an IELTS or Duolingo plan. LMS subscription gating is unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 04:44:18 -07:00

124 lines
4.6 KiB
Go

package handlers
import (
"Yimaru-Backend/internal/domain"
"fmt"
"github.com/gofiber/fiber/v2"
)
func (h *Handler) learnerHasLearnEnglishSubscription(c *fiber.Ctx) (bool, error) {
return h.learnerHasSubscriptionCategory(c, domain.SubscriptionCategoryLearnEnglish)
}
func (h *Handler) ensureLearnerPremiumContentAccess(c *fiber.Ctx, effectiveTier domain.ContentAccessTier, category domain.SubscriptionCategory) error {
role, _ := c.Locals("role").(domain.Role)
if !role.IsCustomerLearnerRole() || domain.CategorySubscriptionGateDisabled {
return nil
}
if !effectiveTier.RequiresSubscription() {
return nil
}
active, err := h.learnerHasSubscriptionCategory(c, category)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
Message: fmt.Sprintf("Failed to verify %s subscription", category),
Error: err.Error(),
})
}
if !active {
return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{
Message: fmt.Sprintf("An active %s subscription is required", humanizeSubscriptionCategory(category)),
})
}
return nil
}
func applyProgramEffectiveAccessTier(p *domain.Program) {
p.EffectiveAccessTier = p.AccessTier
}
func applyCourseEffectiveAccessTier(course *domain.Course, program domain.Program) {
course.EffectiveAccessTier = domain.EffectiveContentAccessTier(program.AccessTier, course.AccessTier)
}
func applyModuleEffectiveAccessTier(module *domain.Module, program domain.Program, course domain.Course) {
module.EffectiveAccessTier = domain.EffectiveContentAccessTier(program.AccessTier, course.AccessTier, module.AccessTier)
}
func applyLessonEffectiveAccessTier(lesson *domain.Lesson, program domain.Program, course domain.Course, module domain.Module) {
lesson.EffectiveAccessTier = domain.EffectiveContentAccessTier(program.AccessTier, course.AccessTier, module.AccessTier, lesson.AccessTier)
}
func applyExamPrepCatalogCourseEffectiveAccessTier(cc *domain.ExamPrepCatalogCourse) {
cc.EffectiveAccessTier = cc.AccessTier
}
func applyExamPrepUnitEffectiveAccessTier(unit *domain.ExamPrepUnit, catalogCourse domain.ExamPrepCatalogCourse) {
unit.EffectiveAccessTier = domain.EffectiveContentAccessTier(catalogCourse.AccessTier, unit.AccessTier)
}
func applyExamPrepModuleEffectiveAccessTier(module *domain.ExamPrepModule, catalogCourse domain.ExamPrepCatalogCourse, unit domain.ExamPrepUnit) {
module.EffectiveAccessTier = domain.EffectiveContentAccessTier(catalogCourse.AccessTier, unit.AccessTier, module.AccessTier)
}
func applyExamPrepLessonEffectiveAccessTier(lesson *domain.ExamPrepLesson, catalogCourse domain.ExamPrepCatalogCourse, unit domain.ExamPrepUnit, module domain.ExamPrepModule) {
lesson.EffectiveAccessTier = domain.EffectiveContentAccessTier(catalogCourse.AccessTier, unit.AccessTier, module.AccessTier, lesson.AccessTier)
}
func learnerCanViewEffectiveTier(hasSubscription bool, effectiveTier domain.ContentAccessTier) bool {
return !effectiveTier.RequiresSubscription() || hasSubscription
}
func filterProgramsForLearner(items []domain.Program, hasLearnEnglish bool) []domain.Program {
filtered := make([]domain.Program, 0, len(items))
for _, item := range items {
applyProgramEffectiveAccessTier(&item)
if learnerCanViewEffectiveTier(hasLearnEnglish, item.EffectiveAccessTier) {
filtered = append(filtered, item)
}
}
return filtered
}
func filterCoursesForLearner(items []domain.Course, program domain.Program, hasLearnEnglish bool) []domain.Course {
filtered := make([]domain.Course, 0, len(items))
for i := range items {
applyCourseEffectiveAccessTier(&items[i], program)
if learnerCanViewEffectiveTier(hasLearnEnglish, items[i].EffectiveAccessTier) {
filtered = append(filtered, items[i])
}
}
return filtered
}
func filterExamPrepCatalogCoursesForLearner(items []domain.ExamPrepCatalogCourse, hasIELTS, hasDuolingo bool) []domain.ExamPrepCatalogCourse {
if domain.ExamPrepSubscriptionGateDisabled {
out := make([]domain.ExamPrepCatalogCourse, 0, len(items))
for _, item := range items {
applyExamPrepCatalogCourseEffectiveAccessTier(&item)
out = append(out, item)
}
return out
}
filtered := make([]domain.ExamPrepCatalogCourse, 0, len(items))
for _, item := range items {
applyExamPrepCatalogCourseEffectiveAccessTier(&item)
if !item.EffectiveAccessTier.RequiresSubscription() {
filtered = append(filtered, item)
continue
}
switch domain.SubscriptionCategory(item.Category) {
case domain.SubscriptionCategoryIELTS:
if hasIELTS {
filtered = append(filtered, item)
}
case domain.SubscriptionCategoryDuolingo:
if hasDuolingo {
filtered = append(filtered, item)
}
}
}
return filtered
}