mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
fix: throttle request issue per video,audio as indicated requirements in units and lessons
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -1350,6 +1350,13 @@ exports.getLessonsByUnitUuid = async (req, res) => {
|
||||
const unitEvaluation = await evaluateEntity({ entityType: "unit", entityId: unit.unit_id, userId, courseId: null });
|
||||
const is_completed = unitEvaluation.status === "completed";
|
||||
|
||||
// Admin-configured completion requirement for the unit itself (pass_quiz /
|
||||
// manual_complete / read_all_content) — null when nothing's configured.
|
||||
const unitRequirement = await CompletionRequirement.findOne({
|
||||
where: { entity_type: "unit", entity_id: unit.unit_id },
|
||||
attributes: ["type", "min_percent", "button_label"],
|
||||
});
|
||||
|
||||
return R.success(res, "Unit lessons retrieved.", {
|
||||
unit_id: unit.unit_id,
|
||||
uuid: unit.uuid,
|
||||
@@ -1360,6 +1367,9 @@ exports.getLessonsByUnitUuid = async (req, res) => {
|
||||
courses: plain.courses ?? [],
|
||||
quiz,
|
||||
is_completed,
|
||||
completion: unitRequirement
|
||||
? { type: unitRequirement.type, min_percent: unitRequirement.min_percent, button_label: unitRequirement.button_label }
|
||||
: null,
|
||||
lessons,
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -1421,6 +1431,15 @@ exports.getLessonByUuid = async (req, res) => {
|
||||
attributes: ["status", "completed_at"],
|
||||
});
|
||||
|
||||
// Admin-configured completion requirement (if any) — lets the standalone reader
|
||||
// show what a learner must do to complete this lesson, same info the course-scoped
|
||||
// reader gets via getCourse's per-lesson `completion` field. null when nothing's
|
||||
// configured (default read_all_content behavior — nothing to display).
|
||||
const requirement = await CompletionRequirement.findOne({
|
||||
where: { entity_type: "lesson", entity_id: lesson.lesson_id },
|
||||
attributes: ["type", "min_percent", "button_label"],
|
||||
});
|
||||
|
||||
const plain = lesson.toJSON();
|
||||
const firstUnit = plain.units?.[0] ?? null;
|
||||
const data = {
|
||||
@@ -1433,6 +1452,7 @@ exports.getLessonByUuid = async (req, res) => {
|
||||
objectives: plain.objectives ?? [],
|
||||
status: progress?.status ?? "not_started",
|
||||
completed_at: progress?.completed_at ?? null,
|
||||
completion: requirement ? { type: requirement.type, min_percent: requirement.min_percent, button_label: requirement.button_label } : null,
|
||||
unit: firstUnit ? { unit_id: firstUnit.unit_id, uuid: firstUnit.uuid, title: firstUnit.title, duration_seconds: firstUnit.duration_seconds, course: firstUnit.courses?.[0] ?? null } : null, // back-compat singular field
|
||||
units: plain.units ?? [],
|
||||
};
|
||||
|
||||
@@ -219,11 +219,17 @@ async function recomputeCourseAfterAssessment(userId, courseId, t) {
|
||||
* live block set on every write, not a snapshot taken when configured).
|
||||
* No-ops (returns null) if the lesson has neither type configured.
|
||||
*/
|
||||
// text-video counts as a video block for watch_video purposes — same <video> element
|
||||
// under the hood, just paired with text. A lesson mixing plain "video" and "text-video"
|
||||
// blocks needs both kinds counted together when checking "every video block hit 100%".
|
||||
const VIDEO_LIKE_BLOCK_TYPES = ['video', 'text-video'];
|
||||
|
||||
async function recordWatchProgress(userId, {
|
||||
lessonId, lessonUuid, unitId = null, unitUuid = null, courseId = null, courseUuid = null,
|
||||
percent, blockId = null, blockType = null,
|
||||
}) {
|
||||
const blockRequirementType = blockType === 'video' ? 'watch_video' : blockType === 'audio' ? 'listen_audio' : null;
|
||||
const isVideoLikeBlock = VIDEO_LIKE_BLOCK_TYPES.includes(blockType);
|
||||
const blockRequirementType = isVideoLikeBlock ? 'watch_video' : blockType === 'audio' ? 'listen_audio' : null;
|
||||
|
||||
const requirements = await CompletionRequirement.findAll({
|
||||
where: {
|
||||
@@ -273,7 +279,9 @@ async function recordWatchProgress(userId, {
|
||||
const nextBlockProgress = { ...prevBlockProgress, [blockId]: Math.max(prevBlockProgress[blockId] ?? 0, clampedPercent) };
|
||||
|
||||
const page = await LessonPage.findOne({ where: { lesson_id: lessonId }, attributes: ['blocks'], transaction: t });
|
||||
const matchingBlockIds = (page?.blocks ?? []).filter((b) => b.type === blockType).map((b) => b.id);
|
||||
const matchingBlockIds = (page?.blocks ?? [])
|
||||
.filter((b) => isVideoLikeBlock ? VIDEO_LIKE_BLOCK_TYPES.includes(b.type) : b.type === blockType)
|
||||
.map((b) => b.id);
|
||||
const completed = matchingBlockIds.length > 0 && matchingBlockIds.every((id) => (nextBlockProgress[id] ?? 0) >= 100);
|
||||
|
||||
await CompletionRequirementProgress.upsert({
|
||||
|
||||
Reference in New Issue
Block a user