push that bricked err

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-17 15:20:42 +08:00
parent d49e3be4d2
commit bae079d5d8
2 changed files with 73 additions and 32 deletions
+25 -32
View File
@@ -32,6 +32,7 @@
'use strict';
const sequelize = require('../config/db.config');
const { withTransactionRetry } = require('../utils/withTransactionRetry.util');
const { evaluateEntity } = require('../utils/courses/completion_requirements.registry');
const CompletionRequirement = require('../models/courses/completion_requirement.mdl');
const CompletionRequirementProgress = require('../models/courses/completion_requirement_progress.mdl');
@@ -298,8 +299,7 @@ async function recordWatchProgress(userId, {
: null;
const durationSeconds = blockId ? getBlockDuration(page, blockId) : 0;
const t = await sequelize.transaction();
try {
const { anyCompleted, aggregatePercent, cascade } = await withTransactionRetry(sequelize, async (t) => {
let anyCompleted = false;
let aggregatePercent = null;
const now = new Date();
@@ -382,19 +382,16 @@ async function recordWatchProgress(userId, {
lessonStatus: anyCompleted ? 'completed' : 'in_progress',
}, t);
await t.commit();
return { anyCompleted, aggregatePercent, cascade };
});
// recomputeCascade skipped its own task-sync since it ran under our externalTransaction
// (would've read pre-commit state) — run it now that everything is durable. Runs
// regardless of courseId — a standalone (no parent course) lesson can satisfy a
// read_lesson task requirement via watch_video/listen_audio/watch_percent too.
const completedTasks = await syncCompletedEntitiesToTaskProgress(userId, { lessonUuid, unitUuid, courseUuid });
// recomputeCascade skipped its own task-sync since it ran under our externalTransaction
// (would've read pre-commit state) — run it now that everything is durable. Runs
// regardless of courseId — a standalone (no parent course) lesson can satisfy a
// read_lesson task requirement via watch_video/listen_audio/watch_percent too.
const completedTasks = await syncCompletedEntitiesToTaskProgress(userId, { lessonUuid, unitUuid, courseUuid });
return { progress_percent: aggregatePercent, completed: anyCompleted, cascade: { ...cascade, completed_tasks: completedTasks } };
} catch (err) {
await t.rollback();
throw err;
}
return { progress_percent: aggregatePercent, completed: anyCompleted, cascade: { ...cascade, completed_tasks: completedTasks } };
}
/**
@@ -408,8 +405,7 @@ async function recordManualComplete(userId, { entityType, entityId, lessonId = n
});
if (!requirement) return null;
const t = await sequelize.transaction();
try {
const result = await withTransactionRetry(sequelize, async (t) => {
await CompletionRequirementProgress.upsert({
requirement_id: requirement.requirement_id,
user_id: userId,
@@ -437,24 +433,21 @@ async function recordManualComplete(userId, { entityType, entityId, lessonId = n
result = { course: await recomputeAndPersist({ entityType: 'course', entityId, userId, courseId: entityId, referenceId: courseUuid }, t) };
}
await t.commit();
// Same reasoning as recordWatchProgress — recomputeCascade (lesson branch) skipped its
// own sync under our externalTransaction; the unit/course branches never called it at
// all. Runs regardless of courseId — a standalone (no parent course) lesson/unit
// manual_complete can satisfy a read_lesson/read_unit task requirement too.
const syncUuids = entityType === 'lesson'
? { lessonUuid, unitUuid, courseUuid }
: entityType === 'unit'
? { unitUuid, courseUuid }
: { courseUuid };
result.completed_tasks = await syncCompletedEntitiesToTaskProgress(userId, syncUuids);
return result;
} catch (err) {
await t.rollback();
throw err;
}
});
// Same reasoning as recordWatchProgress — recomputeCascade (lesson branch) skipped its
// own sync under our externalTransaction; the unit/course branches never called it at
// all. Runs regardless of courseId — a standalone (no parent course) lesson/unit
// manual_complete can satisfy a read_lesson/read_unit task requirement too.
const syncUuids = entityType === 'lesson'
? { lessonUuid, unitUuid, courseUuid }
: entityType === 'unit'
? { unitUuid, courseUuid }
: { courseUuid };
result.completed_tasks = await syncCompletedEntitiesToTaskProgress(userId, syncUuids);
return result;
}
module.exports = {