mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -23,6 +23,7 @@
|
||||
const sequelize = require('../config/db.config');
|
||||
const LessonReadingProgress = require('../models/courses/lesson_reading_progress.mdl');
|
||||
const UnitReadingProgress = require('../models/courses/unit_reading_progress.mdl');
|
||||
const UnitLesson = require('../models/courses/unit_lessons.mdl');
|
||||
const Lesson = require('../models/courses/lessons.mdl');
|
||||
|
||||
// ─── Core UPSERTs ────────────────────────────────────────────────────────────
|
||||
@@ -32,8 +33,8 @@ async function upsertLessonProgress({ userId, courseId, unitId, lessonId, status
|
||||
const [record] = await LessonReadingProgress.upsert(
|
||||
{
|
||||
user_id: userId,
|
||||
course_id: courseId,
|
||||
unit_id: unitId,
|
||||
course_id: courseId ?? null, // NULL when read standalone
|
||||
unit_id: unitId ?? null, // NULL when read standalone
|
||||
lesson_id: lessonId,
|
||||
status,
|
||||
completed_at: status === 'completed' ? now : null,
|
||||
@@ -55,7 +56,7 @@ async function upsertUnitProgress({ userId, courseId, unitId, status }, t) {
|
||||
const [record] = await UnitReadingProgress.upsert(
|
||||
{
|
||||
user_id: userId,
|
||||
course_id: courseId,
|
||||
course_id: courseId ?? null, // NULL when read standalone
|
||||
unit_id: unitId,
|
||||
status,
|
||||
completed_at: status === 'completed' ? now : null,
|
||||
@@ -74,13 +75,21 @@ async function upsertUnitProgress({ userId, courseId, unitId, status }, t) {
|
||||
|
||||
// ─── Derivation helper ────────────────────────────────────────────────────────
|
||||
|
||||
// Unit is completed when every non-deleted lesson under it has a completed row for this user.
|
||||
// Unit is completed when every non-deleted lesson attached to it (via unit_lessons)
|
||||
// has a completed row for this user.
|
||||
async function deriveUnitStatus(userId, unitId, t) {
|
||||
const lessons = await Lesson.findAll({
|
||||
const links = await UnitLesson.findAll({
|
||||
where: { unit_id: unitId },
|
||||
attributes: ['lesson_id'],
|
||||
transaction: t,
|
||||
});
|
||||
if (!links.length) return 'in_progress';
|
||||
|
||||
const lessons = await Lesson.findAll({
|
||||
where: { lesson_id: links.map(l => l.lesson_id) },
|
||||
attributes: ['lesson_id'],
|
||||
transaction: t,
|
||||
});
|
||||
if (!lessons.length) return 'in_progress';
|
||||
|
||||
const lessonIds = lessons.map(l => l.lesson_id);
|
||||
@@ -110,7 +119,7 @@ async function deriveUnitStatus(userId, unitId, t) {
|
||||
* @param {string} payload.lessonStatus — 'in_progress' | 'completed'
|
||||
* @returns {{ lesson, unit }} — status snapshot for each level
|
||||
*/
|
||||
async function upsertLessonRead(userId, { courseId, unitId, lessonId, lessonStatus = 'in_progress' }) {
|
||||
async function upsertLessonRead(userId, { courseId = null, unitId = null, lessonId, lessonStatus = 'in_progress' }) {
|
||||
const t = await sequelize.transaction();
|
||||
try {
|
||||
// 1. Lesson
|
||||
@@ -122,20 +131,23 @@ async function upsertLessonRead(userId, { courseId, unitId, lessonId, lessonStat
|
||||
status: lessonStatus,
|
||||
}, t);
|
||||
|
||||
// 2. Unit — derived from all sibling lessons
|
||||
const unitStatus = await deriveUnitStatus(userId, unitId, t);
|
||||
await upsertUnitProgress({
|
||||
userId,
|
||||
courseId,
|
||||
unitId,
|
||||
status: unitStatus,
|
||||
}, t);
|
||||
// 2. Unit — derived from all sibling lessons (skipped for standalone lesson reads)
|
||||
let unitStatus = null;
|
||||
if (unitId) {
|
||||
unitStatus = await deriveUnitStatus(userId, unitId, t);
|
||||
await upsertUnitProgress({
|
||||
userId,
|
||||
courseId,
|
||||
unitId,
|
||||
status: unitStatus,
|
||||
}, t);
|
||||
}
|
||||
|
||||
await t.commit();
|
||||
|
||||
return {
|
||||
lesson: { lesson_id: lessonId, status: lessonStatus },
|
||||
unit: { unit_id: unitId, status: unitStatus },
|
||||
unit: unitId ? { unit_id: unitId, status: unitStatus } : null,
|
||||
};
|
||||
} catch (err) {
|
||||
await t.rollback();
|
||||
|
||||
Reference in New Issue
Block a user