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 }