@defikitdotnet/education-module-ai
Version:
AI Education Module using Agent Framework
481 lines (480 loc) • 25.9 kB
JavaScript
;
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;