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
+47 -4
View File
@@ -37,6 +37,7 @@ const {
} = require("../../models/courses/courses.associations");
const mdl_Users = require("../../models/users/users.mdl");
const { mdl_PlanLessons, mdl_TierPlans } = require("../../models/tiers/tier.associations");
const notDeleted = { deletedAt: null };
const onlyDeleted = { deletedAt: { [Op.not]: null } };
@@ -155,6 +156,46 @@ exports.getLessonsFlat = async (req, res) => {
}
};
// Bundle picker (Tier Plan wizard) — mirrors getCoursesBySubscription in
// controllers/admin/courses.controller.js.
exports.getLessonsBySubscription = async (req, res) => {
try {
const { slug } = req.query;
if (!slug) return R.error(res, 'slug query param is required.', 400);
const rows = await Lesson.findAll({
where: { ...notDeleted, subscription: slug },
attributes: ['lesson_id', 'title', 'description', 'subscription'],
include: [{
model: mdl_PlanLessons,
as: 'planLesson',
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 lesson
// belongs to at most one plan (UNIQUE constraint on plan_lessons.lesson_id).
const data = rows.map((l) => {
const plain = l.toJSON();
const assigned_plan = plain.planLesson?.plan ?? null;
delete plain.planLesson;
return { ...plain, assigned_plan };
});
return R.success(res, 'Lessons retrieved.', data);
} catch (err) {
console.error('[LESSON LIB][BY SUBSCRIPTION]', err);
return R.error(res, 'Could not retrieve lessons.', 500);
}
};
exports.getLesson = async (req, res) => {
try {
const { lessonId } = req.params;
@@ -179,11 +220,12 @@ exports.getLesson = async (req, res) => {
exports.createLesson = async (req, res) => {
const t = await sequelize.transaction();
try {
const { title, description, unit_id, order, objectives = [], createdBy } = req.body;
const { title, description, subscription, unit_id, order, objectives = [], createdBy } = req.body;
if (!title) return R.error(res, "Title is required.", 400);
const lesson = await Lesson.create({
title,
subscription: subscription || null,
description: description ?? null,
duration_seconds: 0,
createdBy: createdBy ?? req.user?.user_id ?? null,
@@ -231,10 +273,11 @@ exports.updateLesson = async (req, res) => {
const lesson = await Lesson.findOne({ where: { lesson_id: lessonId, ...notDeleted } });
if (!lesson) return R.error(res, "Lesson not found.", 404);
const { title, description, objectives, updatedBy } = req.body;
const { title, description, subscription, objectives, updatedBy } = req.body;
if (title !== undefined) lesson.title = title;
if (description !== undefined) lesson.description = description;
if (title !== undefined) lesson.title = title;
if (description !== undefined) lesson.description = description;
if (subscription !== undefined) lesson.subscription = subscription || null;
lesson.updatedBy = updatedBy ?? req.user?.user_id ?? null;
await lesson.save({ transaction: t });