duration fix when data is deleted for courses

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-04 08:26:01 +08:00
parent 3c13bb9821
commit 7ba03ad4db
2 changed files with 78 additions and 23 deletions
+47 -22
View File
@@ -47,6 +47,44 @@ function estimateBlockDuration(block) {
}
}
/**
* Recompute and persist a unit's duration_seconds from the sum of its
* non-archived lessons. Used both by recomputeDurations() (a lesson's
* content changed) and directly by archive/restore/delete handlers (a
* lesson was added to or removed from the "counts toward duration" set
* without any of its content changing).
*/
async function recomputeUnitDuration(unitId) {
const Lesson = require("../models/courses/lessons.mdl");
const Unit = require("../models/courses/units.mdl");
const [unitResult] = await Lesson.sequelize.query(`
SELECT COALESCE(SUM(duration_seconds), 0) AS total
FROM lessons
WHERE unit_id = :unitId AND "deletedAt" IS NULL
`, { replacements: { unitId }, type: Lesson.sequelize.QueryTypes.SELECT });
await Unit.update({ duration_seconds: unitResult.total }, { where: { unit_id: unitId } });
}
/**
* Recompute and persist a course's duration_seconds from the sum of its
* non-archived units. See recomputeUnitDuration() above for why this is
* split out on its own instead of only living inside recomputeDurations().
*/
async function recomputeCourseDuration(courseId) {
const Unit = require("../models/courses/units.mdl");
const { Course } = require("../models/courses/courses.mdl");
const [courseResult] = await Unit.sequelize.query(`
SELECT COALESCE(SUM(duration_seconds), 0) AS total
FROM units
WHERE course_id = :courseId AND "deletedAt" IS NULL
`, { replacements: { courseId }, type: Unit.sequelize.QueryTypes.SELECT });
await Course.update({ duration_seconds: courseResult.total }, { where: { course_id: courseId } });
}
/**
* Recompute and persist duration_seconds up the chain:
* blocks → lesson → unit → course
@@ -54,7 +92,6 @@ function estimateBlockDuration(block) {
async function recomputeDurations(lessonId) {
const Lesson = require("../models/courses/lessons.mdl");
const Unit = require("../models/courses/units.mdl");
const { Course } = require("../models/courses/courses.mdl");
const LessonPage = require("../models/courses/lesson_page.mdl");
// 1. Lesson duration from blocks
@@ -69,29 +106,11 @@ async function recomputeDurations(lessonId) {
// 2. Unit duration — sum of its lessons
const lesson = await Lesson.findOne({ where: { lesson_id: lessonId } });
const [unitResult] = await Lesson.sequelize.query(`
SELECT COALESCE(SUM(duration_seconds), 0) AS total
FROM lessons
WHERE unit_id = :unitId AND "deletedAt" IS NULL
`, { replacements: { unitId: lesson.unit_id }, type: Lesson.sequelize.QueryTypes.SELECT });
await Unit.update(
{ duration_seconds: unitResult.total },
{ where: { unit_id: lesson.unit_id } }
);
await recomputeUnitDuration(lesson.unit_id);
// 3. Course duration — sum of its units
const unit = await Unit.findOne({ where: { unit_id: lesson.unit_id } });
const [courseResult] = await Lesson.sequelize.query(`
SELECT COALESCE(SUM(duration_seconds), 0) AS total
FROM units
WHERE course_id = :courseId AND "deletedAt" IS NULL
`, { replacements: { courseId: unit.course_id }, type: Lesson.sequelize.QueryTypes.SELECT });
await Course.update(
{ duration_seconds: courseResult.total },
{ where: { course_id: unit.course_id } }
);
await recomputeCourseDuration(unit.course_id);
}
/**
@@ -110,4 +129,10 @@ function formatDuration(seconds) {
return parts.join(" ");
}
module.exports = { estimateBlockDuration, recomputeDurations, formatDuration };
module.exports = {
estimateBlockDuration,
recomputeDurations,
recomputeUnitDuration,
recomputeCourseDuration,
formatDuration,
};