mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
course,tasklist,task and completed validation
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ const R = require("../../utils/response.util");
|
||||
const { paginate } = require("../../utils/paginate.util");
|
||||
const { recomputeDurations, recomputeUnitDuration, recomputeCourseDuration, formatDuration } = require("../../utils/duration.util");
|
||||
const { syncObjectivesCreate, syncObjectivesUpdate } = require("../../utils/courses/objectives.util");
|
||||
const { resolvePrerequisiteTitles } = require("../../utils/courses/resolvePrerequisiteTitles.util");
|
||||
const { syncJunction } = require("../../utils/courses/junction.util");
|
||||
const { archiveOne, archiveMany } = require("../../utils/courses/archive.util");
|
||||
const { restoreOne, restoreMany } = require("../../utils/courses/restore.util");
|
||||
@@ -23,7 +24,7 @@ const {
|
||||
Unit, Lesson, LessonPage,
|
||||
CourseUnit, UnitLesson,
|
||||
CourseObjective, LessonObjective,
|
||||
CoursePrerequisite, CourseAssessment,
|
||||
CoursePrerequisite, CourseRole, CourseAssessment,
|
||||
UnitQuiz, QuizQuestion, QuizOption,
|
||||
QuizAttempt, AssessmentSession,
|
||||
CourseInstructor, CourseAchievement,
|
||||
@@ -102,10 +103,12 @@ exports.getCourse = async (req, res) => {
|
||||
},
|
||||
{ model: CourseObjective, as: "objectives", required: false },
|
||||
{ model: CoursePrerequisite, as: "prerequisites", required: false },
|
||||
{ model: CourseRole, as: "roles", required: false },
|
||||
{ model: CourseAssessment, as: "assessment", required: false },
|
||||
],
|
||||
order: [
|
||||
[{ model: CourseObjective, as: "objectives" }, "order_index", "ASC"],
|
||||
[{ model: CourseRole, as: "roles" }, "order_index", "ASC"],
|
||||
],
|
||||
});
|
||||
|
||||
@@ -113,6 +116,7 @@ exports.getCourse = async (req, res) => {
|
||||
|
||||
const plain = course.toJSON();
|
||||
plain.units = flattenUnits(plain.units); // junction order_index → flat field, sorted
|
||||
plain.prerequisites = await resolvePrerequisiteTitles(plain.prerequisites, { Course, Unit, Lesson });
|
||||
return R.success(res, "Course retrieved.", { data: plain });
|
||||
} catch (err) {
|
||||
console.error("[COURSE][GET ONE]", err);
|
||||
@@ -127,6 +131,7 @@ exports.createCourse = async (req, res) => {
|
||||
title, description, order_index,
|
||||
course_code, level, subscription, status,
|
||||
objectives = [],
|
||||
roles = [],
|
||||
category_ids = [],
|
||||
achievement_keys = [],
|
||||
badge_color, badge_asset_id, badge_image_url,
|
||||
@@ -151,6 +156,7 @@ exports.createCourse = async (req, res) => {
|
||||
}, { transaction: t });
|
||||
|
||||
await syncObjectivesCreate(CourseObjective, "course_id", course.course_id, objectives, t);
|
||||
await syncObjectivesCreate(CourseRole, "course_id", course.course_id, roles, t);
|
||||
await syncJunction(CourseProductCat, course.course_id, category_ids, "category_id", t);
|
||||
|
||||
if (achievement_keys.length) {
|
||||
@@ -196,6 +202,8 @@ exports.createCourseFull = async (req, res) => {
|
||||
title, description, order_index,
|
||||
course_code, level, subscription, status,
|
||||
objectives = [],
|
||||
roles = [],
|
||||
prerequisites = [],
|
||||
category_ids = [],
|
||||
achievement_keys = [],
|
||||
badge_color, badge_asset_id, badge_image_url,
|
||||
@@ -218,6 +226,18 @@ exports.createCourseFull = async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
const validRefTypes = ["course", "unit", "lesson"];
|
||||
for (const p of prerequisites) {
|
||||
if (!validRefTypes.includes(p.ref_type)) {
|
||||
await t.rollback();
|
||||
return R.error(res, `Invalid ref_type: ${p.ref_type}`, 400);
|
||||
}
|
||||
if (p.ref_id === undefined || p.ref_id === null || p.ref_id === "") {
|
||||
await t.rollback();
|
||||
return R.error(res, "Each prerequisite needs an item selected.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
const course = await Course.create({
|
||||
title,
|
||||
description: description ?? null,
|
||||
@@ -234,8 +254,21 @@ exports.createCourseFull = async (req, res) => {
|
||||
}, { transaction: t });
|
||||
|
||||
await syncObjectivesCreate(CourseObjective, "course_id", course.course_id, objectives, t);
|
||||
await syncObjectivesCreate(CourseRole, "course_id", course.course_id, roles, t);
|
||||
await syncJunction(CourseProductCat, course.course_id, category_ids, "category_id", t);
|
||||
|
||||
if (prerequisites.length) {
|
||||
await CoursePrerequisite.bulkCreate(
|
||||
prerequisites.map((p, i) => ({
|
||||
course_id: course.course_id,
|
||||
ref_type: p.ref_type,
|
||||
ref_id: p.ref_id,
|
||||
order_index: i,
|
||||
})),
|
||||
{ transaction: t },
|
||||
);
|
||||
}
|
||||
|
||||
if (achievement_keys.length) {
|
||||
await CourseAchievement.bulkCreate(
|
||||
achievement_keys.slice(0, 1).map((key, i) => ({ course_id: course.course_id, achievement_key: key, order_index: i })),
|
||||
@@ -344,7 +377,7 @@ exports.updateCourse = async (req, res) => {
|
||||
const {
|
||||
title, description, order_index,
|
||||
course_code, level, subscription, status,
|
||||
objectives, category_ids,
|
||||
objectives, roles, category_ids,
|
||||
badge_color, badge_asset_id, badge_image_url,
|
||||
updatedBy,
|
||||
} = req.body;
|
||||
@@ -363,6 +396,7 @@ exports.updateCourse = async (req, res) => {
|
||||
await course.save({ transaction: t });
|
||||
|
||||
if (objectives !== undefined) await syncObjectivesUpdate(CourseObjective, "course_id", courseId, objectives, t);
|
||||
if (roles !== undefined) await syncObjectivesUpdate(CourseRole, "course_id", courseId, roles, t, "role_id");
|
||||
if (category_ids !== undefined) await syncJunction(CourseProductCat, courseId, category_ids, "category_id", t);
|
||||
|
||||
await t.commit();
|
||||
@@ -562,7 +596,8 @@ exports.getPrerequisites = async (req, res) => {
|
||||
where: { course_id: courseId },
|
||||
order: [["order_index", "ASC"]],
|
||||
});
|
||||
return R.success(res, "Prerequisites retrieved.", { data: prereqs });
|
||||
const data = await resolvePrerequisiteTitles(prereqs.map((p) => p.toJSON()), { Course, Unit, Lesson });
|
||||
return R.success(res, "Prerequisites retrieved.", { data });
|
||||
} catch (err) {
|
||||
console.error("[PREREQ][GET ALL]", err);
|
||||
return R.error(res, "Could not retrieve prerequisites.", 500);
|
||||
@@ -587,6 +622,10 @@ exports.syncPrerequisites = async (req, res) => {
|
||||
await t.rollback();
|
||||
return R.error(res, `Invalid ref_type: ${p.ref_type}`, 400);
|
||||
}
|
||||
if (p.ref_id === undefined || p.ref_id === null || p.ref_id === "") {
|
||||
await t.rollback();
|
||||
return R.error(res, "Each prerequisite needs an item selected.", 400);
|
||||
}
|
||||
}
|
||||
await CoursePrerequisite.bulkCreate(
|
||||
prerequisites.map((p, i) => ({
|
||||
@@ -2265,7 +2304,7 @@ exports.getCoursesFlat = async (req, res) => {
|
||||
try {
|
||||
const data = await Course.findAll({
|
||||
where: notDeleted,
|
||||
attributes: ["uuid", "title", "subscription", "duration_seconds"],
|
||||
attributes: ["course_id", "uuid", "title", "subscription", "duration_seconds"],
|
||||
order: [["title", "ASC"]],
|
||||
});
|
||||
return R.success(res, "Courses retrieved.", data);
|
||||
@@ -2343,6 +2382,7 @@ exports.getUnitsFlat = async (req, res) => {
|
||||
}
|
||||
|
||||
const data = rows.map((r) => ({
|
||||
unit_id: r.unit_id,
|
||||
uuid: r.uuid,
|
||||
title: r.title,
|
||||
duration_seconds: Number(r.duration_seconds ?? 0),
|
||||
@@ -2389,6 +2429,7 @@ exports.getLessonsFlat = async (req, res) => {
|
||||
}
|
||||
|
||||
const data = rows.map((r) => ({
|
||||
lesson_id: r.lesson_id,
|
||||
uuid: r.uuid,
|
||||
title: r.title,
|
||||
duration_seconds: Number(r.duration_seconds ?? 0),
|
||||
|
||||
Reference in New Issue
Block a user