mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -30,12 +30,9 @@
|
||||
***********************************************************************************************************************************************************************/
|
||||
"use strict";
|
||||
|
||||
const { Op } = require("sequelize");
|
||||
const R = require("../../utils/response.util");
|
||||
const logActivity = require("../../utils/logActivity.util");
|
||||
const sequelize = require("../../config/db.config");
|
||||
const mdl_Product = require("../../models/courses/products.mdl");
|
||||
const mdl_CoursePurchase = require("../../models/courses/course_purchases.mdl");
|
||||
|
||||
const {
|
||||
Unit, Lesson,
|
||||
@@ -64,35 +61,6 @@ function sanitizeQuestions(questions = []) {
|
||||
});
|
||||
}
|
||||
|
||||
// Batch-fetch active product listings + this user's completed/unexpired
|
||||
// purchases for a set of standalone targets (unit or lesson), same shape as
|
||||
// the courses.controller.js equivalent — used by getUnits/getLessons below so
|
||||
// the browse-list Buy button has price data without an N+1 query per row.
|
||||
async function attachProducts(user_id, purchasable_type, ids) {
|
||||
if (!ids.length) return { productById: new Map(), purchasedIds: new Set() };
|
||||
|
||||
const products = await mdl_Product.findAll({
|
||||
where: { purchasable_type, purchasable_id: { [Op.in]: ids }, is_active: true },
|
||||
attributes: ["id", "name", "price", "currency", "access_days", "is_active", "purchasable_id"],
|
||||
});
|
||||
const productById = new Map(products.map((p) => [String(p.purchasable_id), p]));
|
||||
|
||||
const productIds = products.map((p) => p.id);
|
||||
const purchases = productIds.length ? await mdl_CoursePurchase.findAll({
|
||||
where: {
|
||||
user_id, product_id: { [Op.in]: productIds }, status: "completed",
|
||||
[Op.or]: [{ expires_at: null }, { expires_at: { [Op.gt]: new Date() } }],
|
||||
},
|
||||
attributes: ["product_id"],
|
||||
}) : [];
|
||||
const purchasedProductIds = new Set(purchases.map((p) => String(p.product_id)));
|
||||
const purchasedIds = new Set(
|
||||
products.filter((p) => purchasedProductIds.has(String(p.id))).map((p) => String(p.purchasable_id))
|
||||
);
|
||||
|
||||
return { productById, purchasedIds };
|
||||
}
|
||||
|
||||
// ─── UNIT LIBRARY (learner view) ──────────────────────────────────────────────
|
||||
|
||||
// Client-side Units/Lessons browsing shows ALL content, bound to a course or
|
||||
@@ -136,8 +104,6 @@ exports.getUnits = async (req, res) => {
|
||||
coursesByUnit.set(row.unit_id, list);
|
||||
}
|
||||
|
||||
const { productById, purchasedIds } = await attachProducts(req.user.user_id, "unit", unitIds);
|
||||
|
||||
// is_locked mirrors canAccessUnit: a unit with its own subscription or at
|
||||
// least one attached course needs an access check; a fully open standalone
|
||||
// unit (no subscription, no course links) is never locked.
|
||||
@@ -146,16 +112,10 @@ exports.getUnits = async (req, res) => {
|
||||
const is_locked = (row.subscription || Number(row.course_count) > 0)
|
||||
? !(await coursesCtrl.canAccessUnit(req.user.user_id, row.unit_id))
|
||||
: false;
|
||||
const product = productById.get(String(row.unit_id)) ?? null;
|
||||
const has_purchased = purchasedIds.has(String(row.unit_id));
|
||||
const purchase_eligible = true;
|
||||
result.push({
|
||||
...row,
|
||||
courses: coursesByUnit.get(row.unit_id) ?? [],
|
||||
is_locked,
|
||||
product,
|
||||
has_purchased,
|
||||
purchase_eligible,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -202,8 +162,6 @@ exports.getLessons = async (req, res) => {
|
||||
coursesByLesson.set(row.lesson_id, list);
|
||||
}
|
||||
|
||||
const { productById, purchasedIds } = await attachProducts(req.user.user_id, "lesson", lessonIds);
|
||||
|
||||
// is_locked mirrors canAccessLesson: a lesson with its own subscription or
|
||||
// at least one attached unit needs an access check; a fully open
|
||||
// standalone lesson (no subscription, no unit links) is never locked.
|
||||
@@ -212,16 +170,10 @@ exports.getLessons = async (req, res) => {
|
||||
const is_locked = (row.subscription || Number(row.unit_count) > 0)
|
||||
? !(await coursesCtrl.canAccessLesson(req.user.user_id, row.lesson_id))
|
||||
: false;
|
||||
const product = productById.get(String(row.lesson_id)) ?? null;
|
||||
const has_purchased = purchasedIds.has(String(row.lesson_id));
|
||||
const purchase_eligible = true;
|
||||
result.push({
|
||||
...row,
|
||||
courses: coursesByLesson.get(row.lesson_id) ?? [],
|
||||
is_locked,
|
||||
product,
|
||||
has_purchased,
|
||||
purchase_eligible,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -537,5 +489,3 @@ exports.markStandaloneLessonComplete = async (req, res) => {
|
||||
exports.getUnitByUuid = coursesCtrl.getUnitByUuid;
|
||||
exports.getLessonsByUnitUuid = coursesCtrl.getLessonsByUnitUuid;
|
||||
exports.getLessonByUuid = coursesCtrl.getLessonByUuid;
|
||||
exports.getUnitCheckoutInfo = coursesCtrl.getUnitCheckoutInfo;
|
||||
exports.getLessonCheckoutInfo = coursesCtrl.getLessonCheckoutInfo;
|
||||
|
||||
Reference in New Issue
Block a user