mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -17,10 +17,11 @@
|
||||
* be able to access at least one attached course. Lessons resolve through
|
||||
* their parent units the same way.
|
||||
*
|
||||
* Discovery rule (getUnits/getLessons only): only course-free content is
|
||||
* listed at all — a unit with any course affiliation, or a lesson with any
|
||||
* unit that has a course affiliation, is excluded outright rather than
|
||||
* listed-but-locked. This does not affect the single-item endpoints above
|
||||
* Discovery rule (getUnits/getLessons only): ALL non-deleted units/lessons
|
||||
* are listed, whether or not they're attached to a course — course_count/
|
||||
* courses[] (published courses only) and is_locked tell the learner whether
|
||||
* a given item is standalone or bound, and if bound, whether they already
|
||||
* have access. This does not affect the single-item endpoints above
|
||||
* (:uuid) — those still enforce access normally for direct links, and
|
||||
* course-scoped consumption runs through a separate controller entirely.
|
||||
*
|
||||
@@ -61,12 +62,11 @@ function sanitizeQuestions(questions = []) {
|
||||
|
||||
// ─── UNIT LIBRARY (learner view) ──────────────────────────────────────────────
|
||||
|
||||
// Client-side Units/Lessons browsing only ever shows INDEPENDENT content —
|
||||
// anything affiliated with a course (directly, or for a lesson, through any
|
||||
// of its attached units) is excluded from these listings entirely, not just
|
||||
// flagged locked. This does not affect course-scoped consumption (which runs
|
||||
// through ClientCoursesContext/getCourse, a separate path) or direct-link
|
||||
// access to UnitDetails/LessonDetails, which still enforce access normally.
|
||||
// Client-side Units/Lessons browsing shows ALL content, bound to a course or
|
||||
// not — course_count/courses[] + is_locked below tell the learner which is
|
||||
// which. This does not affect course-scoped consumption (which runs through
|
||||
// ClientCoursesContext/getCourse, a separate path) or direct-link access to
|
||||
// UnitDetails/LessonDetails, which still enforce access normally.
|
||||
exports.getUnits = async (req, res) => {
|
||||
try {
|
||||
const rows = await sequelize.query(`
|
||||
@@ -76,17 +76,12 @@ exports.getUnits = async (req, res) => {
|
||||
JOIN lessons l ON l.lesson_id = ul.lesson_id AND l."deletedAt" IS NULL
|
||||
WHERE ul.unit_id = u.unit_id) AS lesson_count,
|
||||
(SELECT CAST(COUNT(*) AS INTEGER) FROM course_units cu
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL AND c.status = 'published'
|
||||
WHERE cu.unit_id = u.unit_id) AS course_count,
|
||||
(SELECT quiz_id FROM unit_quizzes q
|
||||
WHERE q.unit_id = u.unit_id AND q."deletedAt" IS NULL LIMIT 1) AS quiz_id
|
||||
FROM units u
|
||||
WHERE u."deletedAt" IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM course_units cu
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL
|
||||
WHERE cu.unit_id = u.unit_id
|
||||
)
|
||||
ORDER BY u.title ASC
|
||||
`, { type: sequelize.QueryTypes.SELECT });
|
||||
|
||||
@@ -97,7 +92,7 @@ exports.getUnits = async (req, res) => {
|
||||
const courseLinkRows = unitIds.length ? await sequelize.query(`
|
||||
SELECT cu.unit_id, c.course_id, c.uuid, c.title, c.subscription
|
||||
FROM course_units cu
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL AND c.status = 'published'
|
||||
WHERE cu.unit_id IN (:unitIds)
|
||||
`, { replacements: { unitIds }, type: sequelize.QueryTypes.SELECT }) : [];
|
||||
|
||||
@@ -141,12 +136,6 @@ exports.getLessons = async (req, res) => {
|
||||
WHERE ul.lesson_id = l.lesson_id) AS unit_count
|
||||
FROM lessons l
|
||||
WHERE l."deletedAt" IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM unit_lessons ul
|
||||
JOIN course_units cu ON cu.unit_id = ul.unit_id
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL
|
||||
WHERE ul.lesson_id = l.lesson_id
|
||||
)
|
||||
ORDER BY l.title ASC
|
||||
`, { type: sequelize.QueryTypes.SELECT });
|
||||
|
||||
@@ -157,7 +146,7 @@ exports.getLessons = async (req, res) => {
|
||||
SELECT DISTINCT ul.lesson_id, c.course_id, c.uuid, c.title, c.subscription
|
||||
FROM unit_lessons ul
|
||||
JOIN course_units cu ON cu.unit_id = ul.unit_id
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL
|
||||
JOIN courses c ON c.course_id = cu.course_id AND c."deletedAt" IS NULL AND c.status = 'published'
|
||||
WHERE ul.lesson_id IN (:lessonIds)
|
||||
`, { replacements: { lessonIds }, type: sequelize.QueryTypes.SELECT }) : [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user