/*********************************************************************************************************************************************************************** * File Name: tierGrants.service.js * Type of Program: Service * Description: Snapshots a Tier Plan's current bundle contents (plan_courses/ * plan_units/plan_lessons — exactly one of the three per plan, * per the single-type bundle rule) into user_tier_grants for a * given user_tiers row. Shared by the client purchase-capture * flow (controllers/client/tiers.controller.js#captureOrder) and * the admin manual-grant flow (controllers/admin/tiers.controller.js#grantTier) * so both paths produce the same item-specific entitlement. * Author: Kenneth Obsequio (@lash0000) * Date Created: Aug. 4, 2026 ***********************************************************************************************************************************************************************/ 'use strict'; const { mdl_PlanCourses, mdl_PlanUnits, mdl_PlanLessons, mdl_UserTierGrants, } = require('../models/tiers/tier.associations'); // Replaces every grant row tied to this user_tiers purchase with a fresh // snapshot of the plan's current bundle — safe to call again on repeat // purchase/extension of the same plan (refreshes to whatever the plan // currently contains, in case an admin edited it since the first purchase). async function snapshotPlanGrants(userTierRow, planId) { await mdl_UserTierGrants.destroy({ where: { user_tier_id: userTierRow.tier_id } }); if (!planId) return; const [courseRows, unitRows, lessonRows] = await Promise.all([ mdl_PlanCourses.findAll({ where: { plan_id: planId }, attributes: ['course_id'] }), mdl_PlanUnits.findAll({ where: { plan_id: planId }, attributes: ['unit_id'] }), mdl_PlanLessons.findAll({ where: { plan_id: planId }, attributes: ['lesson_id'] }), ]); const grants = [ ...courseRows.map((r) => ({ item_type: 'course', item_id: r.course_id })), ...unitRows.map((r) => ({ item_type: 'unit', item_id: r.unit_id })), ...lessonRows.map((r) => ({ item_type: 'lesson', item_id: r.lesson_id })), ]; if (!grants.length) return; await mdl_UserTierGrants.bulkCreate( grants.map((g) => ({ user_tier_id: userTierRow.tier_id, user_id: userTierRow.user_id, plan_id: planId, item_type: g.item_type, item_id: g.item_id, granted_at: new Date(), })), ); } module.exports = { snapshotPlanGrants };