UNPKG

@defikitdotnet/education-module-ai

Version:
481 lines (480 loc) 25.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EnrollmentController = void 0; var controller_1 = require("../decorators/controller"); var auth_1 = require("../middleware/auth"); var errorHandler_1 = require("../middleware/errorHandler"); var EnrollmentService_1 = require("../services/EnrollmentService"); /** * EnrollmentController - Handles student enrollments and progress tracking */ var EnrollmentController = /** @class */ (function () { function EnrollmentController(enrollmentService) { this.enrollmentService = enrollmentService; } /** * Create a new enrollment */ EnrollmentController.prototype.createEnrollment = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, courseId, enrollment, error_1; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); if (!((_a = req.student) === null || _a === void 0 ? void 0 : _a.id)) { console.error("createEnrollment: req.student not found after authenticateStudent middleware"); throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; courseId = req.body.courseId; if (!courseId) { throw new errorHandler_1.ApiError("Course ID is required", 400); } return [4 /*yield*/, this.enrollmentService.enrollStudent(studentId, courseId)]; case 1: enrollment = _b.sent(); res.status(201).json(enrollment); return [3 /*break*/, 3]; case 2: error_1 = _b.sent(); if (error_1 instanceof errorHandler_1.ApiError) { res.status(error_1.statusCode).json({ message: error_1.message }); } else { console.error("Error creating enrollment:", error_1); res.status(500).json({ message: "Failed to create enrollment", error: error_1 instanceof Error ? error_1.message : String(error_1) }); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; /** * Get all enrollments for the current student */ EnrollmentController.prototype.getStudentEnrollments = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, enrollments, error_2; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); if (!((_a = req.student) === null || _a === void 0 ? void 0 : _a.id)) { console.error("getStudentEnrollments: req.student not found after authenticateStudent middleware"); throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; return [4 /*yield*/, this.enrollmentService.getStudentEnrollments(studentId)]; case 1: enrollments = _b.sent(); res.status(200).json(enrollments); return [3 /*break*/, 3]; case 2: error_2 = _b.sent(); if (error_2 instanceof errorHandler_1.ApiError) { res.status(error_2.statusCode).json({ message: error_2.message }); } else { console.error("Error fetching student enrollments:", error_2); res.status(500).json({ message: "Failed to fetch enrollments", error: error_2 instanceof Error ? error_2.message : String(error_2) }); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; /** * Get enrollment for a specific course */ EnrollmentController.prototype.getStudentCourseEnrollment = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, courseId, enrollment, error_3; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: console.log('getStudentCourseEnrollment'); _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); if (!((_a = req.student) === null || _a === void 0 ? void 0 : _a.id)) { console.error("getStudentCourseEnrollment: req.student not found after authenticateStudent middleware"); throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; courseId = req.params.courseId; if (!courseId) { throw new errorHandler_1.ApiError("Course ID is required", 400); } return [4 /*yield*/, this.enrollmentService.getStudentCourseEnrollment(studentId, courseId)]; case 2: enrollment = _b.sent(); if (!enrollment) { throw new errorHandler_1.ApiError("Enrollment not found", 404); } res.status(200).json(enrollment); return [3 /*break*/, 4]; case 3: error_3 = _b.sent(); if (error_3 instanceof errorHandler_1.ApiError) { res.status(error_3.statusCode).json({ message: error_3.message }); } else { console.error("Error fetching student enrollment:", error_3); res.status(500).json({ message: "Failed to fetch enrollment", error: error_3 instanceof Error ? error_3.message : String(error_3) }); } return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; /** * Get enrollment and completed lectures for a specific course for the current student */ EnrollmentController.prototype.getEnrollmentAndProgress = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, courseId, data, completedQuizzes, error_4; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 3, , 4]); if (!((_a = req.student) === null || _a === void 0 ? void 0 : _a.id)) { console.error("getEnrollmentAndProgress: req.student not found after authenticateStudent middleware"); throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; courseId = req.params.courseId; if (!courseId) { throw new errorHandler_1.ApiError("Course ID is required", 400); } return [4 /*yield*/, this.enrollmentService.getEnrollmentAndProgressForStudent(studentId, courseId)]; case 1: data = _b.sent(); return [4 /*yield*/, this.enrollmentService.getCompletedQuizzesForStudent(studentId, courseId)]; case 2: completedQuizzes = _b.sent(); // Ensure we're returning just an array of lecture IDs (strings), not objects console.log("Returning enrollment data:", { enrollment: data.enrollment, completedLectures: data.completedLectures, completedQuizzes: completedQuizzes, completedLecturesType: typeof data.completedLectures, isArray: Array.isArray(data.completedLectures) }); // Return combined data res.status(200).json({ enrollment: data.enrollment, completedLectures: data.completedLectures, completedQuizzes: completedQuizzes }); return [3 /*break*/, 4]; case 3: error_4 = _b.sent(); if (error_4 instanceof errorHandler_1.ApiError) { res.status(error_4.statusCode).json({ message: error_4.message }); } else { console.error("Error fetching enrollment and progress:", error_4); res.status(500).json({ message: "Failed to fetch enrollment and progress", error: error_4 instanceof Error ? error_4.message : String(error_4), }); } return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; /** * Mark a lecture as completed and update progress */ EnrollmentController.prototype.markLectureCompleted = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, _a, lectureId, courseId, progressData, error_5; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); if (!((_b = req.student) === null || _b === void 0 ? void 0 : _b.id)) { console.error("markLectureCompleted: req.student not found after authenticateStudent middleware"); throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; _a = req.body, lectureId = _a.lectureId, courseId = _a.courseId; if (!lectureId) { throw new errorHandler_1.ApiError("Lecture ID is required", 400); } if (!courseId) { throw new errorHandler_1.ApiError("Course ID is required", 400); } return [4 /*yield*/, this.enrollmentService.markLectureCompleted(studentId, lectureId, courseId)]; case 1: progressData = _c.sent(); res.status(200).json(progressData); return [3 /*break*/, 3]; case 2: error_5 = _c.sent(); if (error_5 instanceof errorHandler_1.ApiError) { res.status(error_5.statusCode).json({ message: error_5.message }); } else { console.error("Error marking lecture as completed:", error_5); res.status(500).json({ message: "Failed to mark lecture as completed", error: error_5 instanceof Error ? error_5.message : String(error_5) }); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; /** * Get all progress records for a student in a course (completed lectures) */ EnrollmentController.prototype.getStudentCourseProgress = function (req, res) { return __awaiter(this, void 0, void 0, function () { var _a, studentId, courseId, progressRecords, error_6; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); _a = req.params, studentId = _a.studentId, courseId = _a.courseId; if (!studentId || !courseId) { throw new errorHandler_1.ApiError("Student ID and Course ID are required in path", 400); } if (((_b = req.student) === null || _b === void 0 ? void 0 : _b.id) !== studentId) { throw new errorHandler_1.ApiError("Forbidden to access other student's progress", 403); } return [4 /*yield*/, this.enrollmentService.getStudentCourseProgress(studentId, courseId)]; case 1: progressRecords = _c.sent(); res.status(200).json(progressRecords); return [3 /*break*/, 3]; case 2: error_6 = _c.sent(); if (error_6 instanceof errorHandler_1.ApiError) { res.status(error_6.statusCode).json({ message: error_6.message }); } else { console.error("Error fetching student progress:", error_6); res.status(500).json({ message: "Failed to fetch student progress", error: error_6 instanceof Error ? error_6.message : String(error_6) }); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; /** * Mark a quiz as completed and update progress (alternative endpoint) */ EnrollmentController.prototype.recordQuizCompleteAlt = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, _a, quizId, courseId, score, progressData, error_7; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); if (!((_b = req.student) === null || _b === void 0 ? void 0 : _b.id)) { throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; _a = req.body, quizId = _a.quizId, courseId = _a.courseId, score = _a.score; if (!quizId || !courseId) { throw new errorHandler_1.ApiError("Quiz ID and Course ID are required", 400); } return [4 /*yield*/, this.enrollmentService.recordQuizCompleted(studentId, quizId, courseId, score)]; case 1: progressData = _c.sent(); res.status(200).json(progressData); return [3 /*break*/, 3]; case 2: error_7 = _c.sent(); if (error_7 instanceof errorHandler_1.ApiError) { res.status(error_7.statusCode).json({ message: error_7.message }); } else { console.error("Error recording quiz completion:", error_7); res.status(500).json({ message: "Failed to record quiz completion", error: error_7 instanceof Error ? error_7.message : String(error_7), }); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; EnrollmentController.prototype.recordQuizComplete = function (req, res) { return __awaiter(this, void 0, void 0, function () { var studentId, _a, quizId, courseId, score, progressData, error_8; var _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); if (!((_b = req.student) === null || _b === void 0 ? void 0 : _b.id)) { throw new errorHandler_1.ApiError("Unauthorized - Middleware Failed", 401); } studentId = req.student.id; _a = req.body, quizId = _a.quizId, courseId = _a.courseId, score = _a.score; if (!quizId || !courseId) { throw new errorHandler_1.ApiError("Quiz ID and Course ID are required", 400); } return [4 /*yield*/, this.enrollmentService.recordQuizCompleted(studentId, quizId, courseId, score)]; case 1: progressData = _c.sent(); res.status(200).json(progressData); return [3 /*break*/, 3]; case 2: error_8 = _c.sent(); if (error_8 instanceof errorHandler_1.ApiError) { res.status(error_8.statusCode).json({ message: error_8.message }); } else { console.error("Error recording quiz completion:", error_8); res.status(500).json({ message: "Failed to record quiz completion", error: error_8 instanceof Error ? error_8.message : String(error_8), }); } return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }; __decorate([ (0, controller_1.Post)("/"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "createEnrollment", null); __decorate([ (0, controller_1.Get)("/student"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "getStudentEnrollments", null); __decorate([ (0, controller_1.Get)("/student/course/:courseId"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "getStudentCourseEnrollment", null); __decorate([ (0, controller_1.Get)("/progress/:courseId"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "getEnrollmentAndProgress", null); __decorate([ (0, controller_1.Post)("/progress/complete-lecture"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "markLectureCompleted", null); __decorate([ (0, controller_1.Get)("/progress/student/:studentId/course/:courseId"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "getStudentCourseProgress", null); __decorate([ (0, controller_1.Post)("/quiz-complete"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "recordQuizCompleteAlt", null); __decorate([ (0, controller_1.Post)("/progress/record-quiz-complete"), (0, controller_1.Use)(auth_1.authenticateStudent), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], EnrollmentController.prototype, "recordQuizComplete", null); EnrollmentController = __decorate([ (0, controller_1.Controller)("/api/enrollments"), __metadata("design:paramtypes", [EnrollmentService_1.EnrollmentService]) ], EnrollmentController); return EnrollmentController; }()); exports.EnrollmentController = EnrollmentController;