assets and tier plans revamp

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-08-01 17:44:25 +08:00
parent 39c3c4566b
commit cae958b5d5
41 changed files with 1271 additions and 165 deletions
+41
View File
@@ -41,6 +41,7 @@ const CompletionRequirement = require("../../models/courses/completion_requireme
const { VALID_ENTITY_TYPES } = require("../../utils/courses/completion_requirements.registry");
const mdl_Users = require("../../models/users/users.mdl");
const { mdl_PlanUnits, mdl_TierPlans } = require("../../models/tiers/tier.associations");
const notDeleted = { deletedAt: null };
const onlyDeleted = { deletedAt: { [Op.not]: null } };
@@ -160,6 +161,46 @@ exports.getUnitsFlat = async (req, res) => {
}
};
// Bundle picker (Tier Plan wizard) — mirrors getCoursesBySubscription in
// controllers/admin/courses.controller.js.
exports.getUnitsBySubscription = async (req, res) => {
try {
const { slug } = req.query;
if (!slug) return R.error(res, 'slug query param is required.', 400);
const rows = await Unit.findAll({
where: { ...notDeleted, subscription: slug },
attributes: ['unit_id', 'title', 'description', 'subscription'],
include: [{
model: mdl_PlanUnits,
as: 'planUnit',
required: false,
attributes: ['plan_id'],
include: [{
model: mdl_TierPlans,
as: 'plan',
attributes: ['plan_id', 'label'],
}],
}],
order: [['title', 'ASC']],
});
// Flatten so the frontend can just check `assigned_plan` — a unit belongs
// to at most one plan (UNIQUE constraint on plan_units.unit_id).
const data = rows.map((u) => {
const plain = u.toJSON();
const assigned_plan = plain.planUnit?.plan ?? null;
delete plain.planUnit;
return { ...plain, assigned_plan };
});
return R.success(res, 'Units retrieved.', data);
} catch (err) {
console.error('[UNIT LIB][BY SUBSCRIPTION]', err);
return R.error(res, 'Could not retrieve units.', 500);
}
};
exports.getUnit = async (req, res) => {
try {
const { unitId } = req.params;