mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
203 lines
16 KiB
JavaScript
203 lines
16 KiB
JavaScript
const router = require("express").Router();
|
|
const ctrl = require("../../controllers/admin/courses.controller");
|
|
const progressCtrl = require("../../controllers/admin/course_reading_progress.controller");
|
|
const requirementsCtrl = require("../../controllers/admin/completion_requirements.controller");
|
|
|
|
// Guards are applied by admin.routes.js (authenticate → requireAdmin → adminLimiter)
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// COURSES
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/", ctrl.getCourses);
|
|
router.post("/", ctrl.createCourse);
|
|
router.post("/full", ctrl.createCourseFull); // one-shot Add Course wizard submit (course + roadmap + rewards)
|
|
|
|
// ── static segments first ────────────────────────────────────────────────────
|
|
router.get("/field-values", ctrl.getCourseFieldValues);
|
|
router.delete("/bulk", ctrl.bulkArchiveCourses);
|
|
router.delete("/bulk/permanent", ctrl.bulkPermanentlyDeleteCourses);
|
|
router.get("/archives", ctrl.getArchivedCourses);
|
|
router.patch("/restore/bulk", ctrl.bulkRestoreCourses);
|
|
router.get("/flat", ctrl.getCoursesFlat);
|
|
router.get("/by-subscription", ctrl.getCoursesBySubscription);
|
|
router.get("/units-flat", ctrl.getUnitsFlat);
|
|
router.get("/lessons-flat", ctrl.getLessonsFlat);
|
|
router.get("/uuid/:uuid/structure-counts", ctrl.getCourseStructureCounts);
|
|
router.put("/order", ctrl.reorderCourses); // persist top-level course catalog ordering { course_ids }
|
|
|
|
// ── then :courseId ────────────────────────────────────────────────────────────
|
|
router.get("/archives/:courseId", ctrl.getArchivedCourse);
|
|
router.patch("/:courseId/restore", ctrl.restoreCourse);
|
|
router.get("/:courseId/archive-impact", ctrl.getCourseArchiveImpact);
|
|
router.get("/:courseId/permanent-delete-impact", ctrl.getCoursePermanentDeleteImpact);
|
|
router.get("/:courseId", ctrl.getCourse);
|
|
router.put("/:courseId", ctrl.updateCourse);
|
|
router.delete("/:courseId", ctrl.archiveCourse);
|
|
router.delete("/:courseId/permanent", ctrl.permanentlyDeleteCourse);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// COURSE INSTRUCTORS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/instructors", ctrl.getInstructors);
|
|
router.put("/:courseId/instructors", ctrl.syncInstructors);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// COURSE ACHIEVEMENTS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/achievements", ctrl.getCourseAchievements);
|
|
router.put("/:courseId/achievements", ctrl.syncCourseAchievements);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// PREREQUISITES
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/prerequisites", ctrl.getPrerequisites);
|
|
router.put("/:courseId/prerequisites", ctrl.syncPrerequisites);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// COMPLETION REQUIREMENTS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/requirements", requirementsCtrl.getCourseRequirements);
|
|
router.put("/:courseId/requirements", requirementsCtrl.syncCourseRequirements);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// COURSE ASSESSMENT
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/assessment", ctrl.getAssessment);
|
|
router.post("/:courseId/assessment", ctrl.createAssessment);
|
|
|
|
// ── static segments first ────────────────────────────────────────────────────
|
|
router.get("/:courseId/assessment/archives", ctrl.getArchivedAssessment);
|
|
|
|
// ── then :assessmentId ────────────────────────────────────────────────────────
|
|
router.patch("/:courseId/assessment/:assessmentId", ctrl.updateAssessment);
|
|
router.delete("/:courseId/assessment/:assessmentId", ctrl.deleteAssessment);
|
|
router.patch("/:courseId/assessment/:assessmentId/restore", ctrl.restoreAssessment);
|
|
|
|
// ── Assessment Questions ──────────────────────────────────────────────────────
|
|
router.get("/:courseId/assessment/:assessmentId/questions", ctrl.getQuestions);
|
|
router.post("/:courseId/assessment/:assessmentId/questions", ctrl.createQuestion);
|
|
|
|
// static before :questionId
|
|
router.delete("/:courseId/assessment/:assessmentId/questions/bulk", ctrl.bulkArchiveQuestions);
|
|
router.patch("/:courseId/assessment/:assessmentId/questions/restore/bulk", ctrl.bulkRestoreQuestions);
|
|
router.put("/:courseId/assessment/:assessmentId/questions/bulk-sync", ctrl.bulkSyncQuestions);
|
|
router.get("/:courseId/assessment/:assessmentId/questions/archives/:questionId", ctrl.getArchivedQuestion);
|
|
|
|
router.patch("/:courseId/assessment/:assessmentId/questions/:questionId", ctrl.updateQuestion);
|
|
router.delete("/:courseId/assessment/:assessmentId/questions/:questionId", ctrl.deleteQuestion);
|
|
router.patch("/:courseId/assessment/:assessmentId/questions/:questionId/restore", ctrl.restoreQuestion);
|
|
|
|
// ── Assessment Completions & Sessions ─────────────────────────────────────────
|
|
router.get("/:courseId/assessment/:assessmentId/completions", ctrl.getAssessmentCompletions);
|
|
router.get("/:courseId/assessment/:assessmentId/sessions", ctrl.getAssessmentSessions);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// UNITS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/field-values", ctrl.getUnitFieldValues);
|
|
router.get("/:courseId/units", ctrl.getUnits);
|
|
router.post("/:courseId/units", ctrl.createUnit); // create new unit + attach, or attach existing via body { unit_id }
|
|
|
|
// static before :unitId
|
|
router.post("/:courseId/units/attach", ctrl.attachUnits); // bulk-attach existing library units { unit_ids }
|
|
router.put("/:courseId/units/order", ctrl.reorderUnits); // persist course-level unit ordering { unit_ids }
|
|
router.delete("/:courseId/units/bulk", ctrl.bulkArchiveUnits);
|
|
router.delete("/:courseId/units/bulk/permanent", ctrl.bulkPermanentlyDeleteUnits);
|
|
router.get("/:courseId/units/archives", ctrl.getArchivedUnits);
|
|
router.patch("/:courseId/units/restore/bulk", ctrl.bulkRestoreUnits);
|
|
|
|
router.get("/:courseId/units/archives/:unitId", ctrl.getArchivedUnit);
|
|
router.patch("/:courseId/units/:unitId/restore", ctrl.restoreUnit);
|
|
router.get("/:courseId/units/:unitId/archive-impact", ctrl.getUnitArchiveImpact);
|
|
router.get("/:courseId/units/:unitId/permanent-delete-impact", ctrl.getUnitPermanentDeleteImpact);
|
|
router.get("/:courseId/units/:unitId", ctrl.getUnit);
|
|
router.put("/:courseId/units/:unitId", ctrl.updateUnit);
|
|
router.delete("/:courseId/units/:unitId", ctrl.archiveUnit);
|
|
router.delete("/:courseId/units/:unitId/permanent", ctrl.permanentlyDeleteUnit);
|
|
|
|
router.get("/:courseId/units/:unitId/requirements", requirementsCtrl.getUnitRequirements);
|
|
router.put("/:courseId/units/:unitId/requirements", requirementsCtrl.syncUnitRequirements);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// UNIT QUIZ
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/units/:unitId/quiz", ctrl.getQuiz);
|
|
router.post("/:courseId/units/:unitId/quiz", ctrl.createQuiz);
|
|
|
|
// static before :quizId
|
|
router.get("/:courseId/units/:unitId/quiz/archives", ctrl.getArchivedQuiz);
|
|
|
|
router.patch("/:courseId/units/:unitId/quiz/:quizId", ctrl.updateQuiz);
|
|
router.delete("/:courseId/units/:unitId/quiz/:quizId", ctrl.deleteQuiz);
|
|
router.patch("/:courseId/units/:unitId/quiz/:quizId/restore", ctrl.restoreQuiz);
|
|
|
|
// ── Quiz Questions ────────────────────────────────────────────────────────────
|
|
router.get("/:courseId/units/:unitId/quiz/:quizId/questions", ctrl.getQuestions);
|
|
router.post("/:courseId/units/:unitId/quiz/:quizId/questions", ctrl.createQuestion);
|
|
|
|
// static before :questionId
|
|
router.delete("/:courseId/units/:unitId/quiz/:quizId/questions/bulk", ctrl.bulkArchiveQuestions);
|
|
router.patch("/:courseId/units/:unitId/quiz/:quizId/questions/restore/bulk", ctrl.bulkRestoreQuestions);
|
|
router.put("/:courseId/units/:unitId/quiz/:quizId/questions/bulk-sync", ctrl.bulkSyncQuestions);
|
|
router.get("/:courseId/units/:unitId/quiz/:quizId/questions/archives/:questionId", ctrl.getArchivedQuestion);
|
|
|
|
router.patch("/:courseId/units/:unitId/quiz/:quizId/questions/:questionId", ctrl.updateQuestion);
|
|
router.delete("/:courseId/units/:unitId/quiz/:quizId/questions/:questionId", ctrl.deleteQuestion);
|
|
router.patch("/:courseId/units/:unitId/quiz/:quizId/questions/:questionId/restore", ctrl.restoreQuestion);
|
|
|
|
// ── Quiz Completions ──────────────────────────────────────────────────────────
|
|
router.get("/:courseId/units/:unitId/quiz/:quizId/completions", ctrl.getQuizCompletions);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// LESSONS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/units/:unitId/field-values", ctrl.getLessonFieldValues);
|
|
router.get("/:courseId/units/:unitId/lessons", ctrl.getLessons);
|
|
router.post("/:courseId/units/:unitId/lessons", ctrl.createLesson); // create new lesson + attach, or attach existing via body { lesson_id }
|
|
|
|
// static before :lessonId
|
|
router.put("/:courseId/units/:unitId/lessons/order", ctrl.reorderLessons); // persist unit-level lesson ordering { lesson_ids }
|
|
router.delete("/:courseId/units/:unitId/lessons/bulk", ctrl.bulkArchiveLessons);
|
|
router.delete("/:courseId/units/:unitId/lessons/bulk/permanent", ctrl.bulkPermanentlyDeleteLessons);
|
|
router.get("/:courseId/units/:unitId/lessons/archives", ctrl.getArchivedLessons);
|
|
router.patch("/:courseId/units/:unitId/lessons/restore/bulk", ctrl.bulkRestoreLessons);
|
|
|
|
router.get("/:courseId/units/:unitId/lessons/archives/:lessonId", ctrl.getArchivedLesson);
|
|
router.patch("/:courseId/units/:unitId/lessons/:lessonId/restore", ctrl.restoreLesson);
|
|
router.get("/:courseId/units/:unitId/lessons/:lessonId", ctrl.getLesson);
|
|
router.put("/:courseId/units/:unitId/lessons/:lessonId", ctrl.updateLesson);
|
|
router.delete("/:courseId/units/:unitId/lessons/:lessonId", ctrl.archiveLesson);
|
|
router.delete("/:courseId/units/:unitId/lessons/:lessonId/permanent", ctrl.permanentlyDeleteLesson);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// LESSON PAGE
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/units/:unitId/lessons/:lessonId/page", ctrl.getLessonPage);
|
|
router.put("/:courseId/units/:unitId/lessons/:lessonId/page", ctrl.upsertLessonPage);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// LESSON COMPLETION REQUIREMENTS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
router.get("/:courseId/units/:unitId/lessons/:lessonId/requirements", requirementsCtrl.getLessonRequirements);
|
|
router.put("/:courseId/units/:unitId/lessons/:lessonId/requirements", requirementsCtrl.syncLessonRequirements);
|
|
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
// COURSE READING PROGRESS
|
|
// ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
// static segment before :userId to avoid param collision
|
|
router.get("/:courseId/reading-progress/users/:userId", progressCtrl.getUserReadingProgress);
|
|
router.get("/:courseId/reading-progress", progressCtrl.getCourseReadingProgress);
|
|
|
|
module.exports = router; |