@defikitdotnet/education-module-ai
Version:
AI Education Module using Agent Framework
716 lines (701 loc) • 39 kB
JavaScript
"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 };
}
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StudentController = void 0;
var controller_1 = require("../decorators/controller");
var bcrypt_1 = __importDefault(require("bcrypt"));
var SqliteAdapter_1 = require("../database/SqliteAdapter");
var StudentRepository_1 = require("../repositories/StudentRepository");
var auth_1 = require("../middleware/auth");
var QuizService_1 = require("../services/QuizService");
var QuizQuestionService_1 = require("../services/QuizQuestionService");
var QuizSubmissionService_1 = require("../services/QuizSubmissionService");
var errorHandler_1 = require("../middleware/errorHandler");
var jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
/**
* Student Controller - Handles student access, PROFILE management, and LOGIN
*/
var StudentController = /** @class */ (function () {
function StudentController(mainDatabaseAdapter, quizService, quizQuestionService, quizSubmissionService, studentRepository) {
this.quizService = quizService;
this.quizQuestionService = quizQuestionService;
this.quizSubmissionService = quizSubmissionService;
this.educationModuleAdapter = null;
// Define path for BaseController implementation
this.path = "/api/student";
this.mainDatabaseAdapter = mainDatabaseAdapter;
this.studentRepository = studentRepository;
console.log("StudentController initialized with required services and StudentRepository");
}
StudentController.prototype.setEducationModuleAdapter = function (adapter) {
this.educationModuleAdapter = adapter;
console.log("EducationModuleAdapter set in StudentController");
};
// Required for BaseController implementation
StudentController.prototype.initRoutes = function () {
// Routes are initialized through decorators
};
/**
* Register a new student profile
*/
StudentController.prototype.registerStudent = function (req, res, next) {
return __awaiter(this, void 0, void 0, function () {
var _a, name, email, password, tempDbAdapter, existingStudent, createdStudent, _b, passwordHash, safeStudent, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_a = req.body, name = _a.name, email = _a.email, password = _a.password;
if (!name || !email || !password) {
return [2 /*return*/, next(new errorHandler_1.ApiError("Missing required fields: name, email, password", 400))];
}
tempDbAdapter = null;
_c.label = 1;
case 1:
_c.trys.push([1, 4, 5, 6]);
return [4 /*yield*/, this.studentRepository.findByEmail(email)];
case 2:
existingStudent = _c.sent();
if (existingStudent) {
return [2 /*return*/, next(new errorHandler_1.ApiError("Email already in use", 409))]; // Use error handler middleware
}
return [4 /*yield*/, this.studentRepository.create({
// id: studentId, // Removed - Repository likely generates ID
name: name,
email: email,
password: password, // Pass the raw password
// passwordHash, // Removed - Repository likely handles hashing
createdAt: new Date(), // Add createdAt back as repository expects it
})];
case 3:
createdStudent = _c.sent();
_b = createdStudent || {}, passwordHash = _b.passwordHash, safeStudent = __rest(_b, ["passwordHash"]);
// Use default empty object {} if createdStudent is unexpectedly null/undefined
// Check if student creation actually succeeded (repository might return null on failure)
if (!createdStudent) {
console.error("[StudentController] StudentRepository.create returned null/undefined for email ".concat(email));
return [2 /*return*/, next(new errorHandler_1.ApiError("Failed to create student record.", 500))];
}
res.status(201).json({
message: "Student registered successfully",
student: safeStudent, // Return the created student data (without hash)
});
return [3 /*break*/, 6];
case 4:
error_1 = _c.sent();
console.error("[StudentController] Error registering student ".concat(email, ":"), error_1);
next(error_1); // Pass error to the centralized handler
return [3 /*break*/, 6];
case 5: return [7 /*endfinally*/];
case 6: return [2 /*return*/];
}
});
});
};
/**
* Get published content for students
*/
StudentController.prototype.getPublishedContent = function (req, res) {
return __awaiter(this, void 0, void 0, function () {
var _a, subject_1, level_1, publishedContent, contentList, contentStore, error_2;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 4, , 5]);
_a = req.query, subject_1 = _a.subject, level_1 = _a.level;
publishedContent = [];
if (!this.educationModuleAdapter) return [3 /*break*/, 2];
return [4 /*yield*/, this.educationModuleAdapter.getEducationalContents()];
case 1:
contentList = _b.sent();
// Filter to only published content - safely check if property exists
publishedContent = contentList.filter(function (c) { return "isPublished" in c && c.isPublished === true; });
// Apply additional filters if specified
if (subject_1) {
publishedContent = publishedContent.filter(function (c) { return c.subject === subject_1; });
}
if (level_1) {
publishedContent = publishedContent.filter(function (c) { return c.level === level_1; });
}
return [3 /*break*/, 3];
case 2:
contentStore = {};
publishedContent = Object.values(contentStore).filter(function (c) { return "isPublished" in c && c.isPublished === true; });
if (subject_1) {
publishedContent = publishedContent.filter(function (c) { return c.subject === subject_1; });
}
if (level_1) {
publishedContent = publishedContent.filter(function (c) { return c.level === level_1; });
}
_b.label = 3;
case 3:
res.status(200).json({ data: publishedContent });
return [3 /*break*/, 5];
case 4:
error_2 = _b.sent();
console.error("Error retrieving published content:", error_2);
res.status(500).json({ error: "Failed to retrieve published content" });
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
};
/**
* Get specific content by ID
*/
StudentController.prototype.getContentById = function (req, res) {
return __awaiter(this, void 0, void 0, function () {
var contentId, studentId, content, contentStore, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 4, , 5]);
contentId = req.params.contentId;
studentId = req.query.studentId || "anonymous";
content = void 0;
if (!this.educationModuleAdapter) return [3 /*break*/, 2];
return [4 /*yield*/, this.educationModuleAdapter.getEducationalContent(contentId)];
case 1:
content =
_a.sent();
return [3 /*break*/, 3];
case 2:
contentStore = {};
content = contentStore[contentId];
_a.label = 3;
case 3:
if (!content) {
res.status(404).json({ error: "Content not found" });
return [2 /*return*/];
}
// Safely check if property exists before comparing
if ("isPublished" in content && content.isPublished === false) {
res
.status(403)
.json({ error: "This content is not available for students" });
return [2 /*return*/];
}
// Record student access
// await pluginManager.notifyStudentAccessed(contentId, studentId);
res.status(200).json({ data: content });
return [3 /*break*/, 5];
case 4:
error_3 = _a.sent();
console.error("Error retrieving content:", error_3);
res.status(500).json({ error: "Failed to retrieve content" });
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
};
/**
* Submit assessment/quiz answers (Old endpoint - likely unused)
*/
StudentController.prototype.submitAssessment = function (req, res) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
/* // Entire method body commented out as it references unused/removed types
try {
const { contentId } = req.params;
const { studentId, answers } = req.body;
if (!studentId) {
res.status(400).json({ error: "Student ID is required" });
return;
}
if (!answers || !Array.isArray(answers)) {
res.status(400).json({ error: "Answers must be provided as an array" });
return;
}
// Get the content to check answers against
let content;
if (this.educationModuleAdapter) {
content = await this.educationModuleAdapter.getEducationalContent(contentId);
} else {
// In-memory implementation (would be empty in a real scenario)
const contentStore: Record<string, EducationalContentResource> = {};
content = contentStore[contentId];
}
if (!content) {
res.status(404).json({ error: "Content not found" });
return;
}
// Safely check if property exists before comparing
if ('isPublished' in content && content.isPublished === false) {
res.status(403).json({ error: "This content is not available for students" });
return;
}
// Process the answers
const contentHasQuestions = hasQuestions(content);
const results = {
contentId,
studentId,
timestamp: new Date(),
score: 0,
totalQuestions: contentHasQuestions ? (content as ContentWithQuestions).questions.length : 0,
correctAnswers: 0,
answerDetails: [] as Array<{
questionIndex: number,
correct: boolean,
studentAnswer: string,
correctAnswer?: string,
explanation?: string
}>
};
// Check answers if content has questions
if (contentHasQuestions) {
// Calculate score
const contentWithQuestions = content as ContentWithQuestions;
answers.forEach((answer: any, index: number) => {
const question = contentWithQuestions.questions[index];
if (!question) return;
let isCorrect = false;
if (question.type === 'multiple_choice' || question.type === 'true_false') {
isCorrect = question.correctAnswer === answer.answer;
} else {
// For essay or other types, we would need AI evaluation here
// Just mark as pending for now
isCorrect = false; // Requires teacher grading
}
results.answerDetails.push({
questionIndex: index,
correct: isCorrect,
studentAnswer: answer.answer,
correctAnswer: question.correctAnswer,
explanation: question.type !== 'essay' ? 'Auto-graded' : 'Requires teacher evaluation'
});
if (isCorrect) {
results.correctAnswers += 1;
}
});
// Calculate percentage score
results.score = results.totalQuestions > 0
? Math.round((results.correctAnswers / results.totalQuestions) * 100)
: 0;
}
// Notify plugins that student completed content
await pluginManager.notifyStudentCompleted(contentId, studentId, results);
res.status(200).json({
data: results,
message: "Assessment submitted successfully"
});
} catch (error) {
console.error("Error submitting assessment:", error);
res.status(500).json({ error: "Failed to submit assessment" });
}
*/
res
.status(501)
.json({
error: "This endpoint is deprecated. Use /api/student/quizzes/:quizId/submit instead.",
}); // Return Not Implemented
return [2 /*return*/];
});
});
};
/**
* Get feedback on submitted assessment
*/
StudentController.prototype.getAssessmentFeedback = function (req, res) {
return __awaiter(this, void 0, void 0, function () {
var contentId, studentId, feedback;
return __generator(this, function (_a) {
try {
contentId = req.params.contentId;
studentId = req.query.studentId;
if (!studentId) {
res.status(400).json({ error: "Student ID is required" });
return [2 /*return*/];
}
feedback = {
contentId: contentId,
studentId: studentId,
score: 85,
feedback: "Good work! You've demonstrated a solid understanding of the key concepts.",
recommendedResources: [
"Review Chapter 3 for more practice",
"Watch the supplementary video on topic X",
],
teacherComments: "I was particularly impressed with your answer to question 4.",
};
res.status(200).json({ data: feedback });
}
catch (error) {
console.error("Error retrieving feedback:", error);
res.status(500).json({ error: "Failed to retrieve feedback" });
}
return [2 /*return*/];
});
});
};
/**
* Submit answers for a specific Quiz identified by quizId
*/
StudentController.prototype.submitQuiz = function (req, res) {
return __awaiter(this, void 0, void 0, function () {
var quizId, _a, studentId, answers, quiz, questions, questionIds_1, submittedQuestionIds, correctCount, answerMap, answerDetails, _i, questions_1, question, studentAnswer, correctAnswer, isCorrect, score, submissionData, savedSubmission, result, error_4;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
quizId = req.params.quizId;
_a = req.body, studentId = _a.studentId, answers = _a.answers;
if (!studentId) {
// Or check req.student.id if using auth middleware
throw new errorHandler_1.ApiError("Student ID is required.", 400);
}
if (!quizId) {
throw new errorHandler_1.ApiError("Quiz ID is required.", 400);
}
if (!answers || !Array.isArray(answers) || answers.length === 0) {
throw new errorHandler_1.ApiError("Valid answers array is required.", 400);
}
_b.label = 1;
case 1:
_b.trys.push([1, 5, , 6]);
return [4 /*yield*/, this.quizService.getQuiz(quizId)];
case 2:
quiz = _b.sent();
if (!quiz) {
throw new errorHandler_1.ApiError("Quiz with ID ".concat(quizId, " not found."), 404);
}
return [4 /*yield*/, this.quizQuestionService.getQuestionsByQuizId(quizId)];
case 3:
questions = _b.sent();
if (!questions || questions.length === 0) {
throw new errorHandler_1.ApiError("No questions found for quiz ".concat(quizId, ". Cannot submit."), 400);
}
questionIds_1 = new Set(questions.map(function (q) { return q.id; }));
submittedQuestionIds = new Set(answers.map(function (a) { return a.questionId; }));
if (answers.length !== questions.length ||
!answers.every(function (a) { return questionIds_1.has(a.questionId); })) {
throw new errorHandler_1.ApiError("Submitted answers do not match the questions for quiz ".concat(quizId, "."), 400);
}
correctCount = 0;
answerMap = new Map(answers.map(function (a) { return [a.questionId, a.answer]; }));
answerDetails = [];
for (_i = 0, questions_1 = questions; _i < questions_1.length; _i++) {
question = questions_1[_i];
studentAnswer = answerMap.get(question.id);
correctAnswer = question.answer;
isCorrect = false;
// Check if the student provided an answer for this question
if (studentAnswer !== undefined) {
// Simple comparison (adjust for case sensitivity or trimming if needed)
isCorrect = String(studentAnswer) === String(correctAnswer);
} // else: student didn't answer, isCorrect remains false
if (isCorrect) {
correctCount++;
}
// Add details for this question
answerDetails.push({
questionId: question.id,
questionText: question.question, // Add the question text
studentAnswer: studentAnswer !== null && studentAnswer !== void 0 ? studentAnswer : "Not Answered", // Handle undefined answer
correctAnswer: correctAnswer,
explanation: question.explanation, // Include explanation if available
correct: isCorrect,
});
}
score = questions.length > 0
? Math.round((correctCount / questions.length) * 100)
: 0;
submissionData = {
studentId: studentId,
quizId: quizId,
score: score,
answers: JSON.stringify(answers), // Store submitted answers as JSON
submittedAt: new Date(),
};
return [4 /*yield*/, this.quizSubmissionService.createSubmission(submissionData)];
case 4:
savedSubmission = _b.sent();
result = {
submissionId: savedSubmission.id,
quizId: quizId,
studentId: studentId,
score: score,
totalQuestions: questions.length,
correctAnswers: correctCount,
feedback: "You answered ".concat(correctCount, " out of ").concat(questions.length, " questions correctly."),
submittedAt: savedSubmission.submittedAt,
answerDetails: answerDetails, // Include the generated details
};
res.status(201).json({
message: "Quiz submitted successfully.",
data: result,
});
return [3 /*break*/, 6];
case 5:
error_4 = _b.sent();
// Log the error for debugging
console.error("Error submitting quiz ".concat(quizId, " for student ").concat(studentId, ":"), error_4);
// Rethrow ApiError or wrap other errors
if (error_4 instanceof errorHandler_1.ApiError) {
throw error_4;
}
else {
// Use a generic error for unexpected issues
throw new errorHandler_1.ApiError("An unexpected error occurred while submitting the quiz.", 500);
}
return [3 /*break*/, 6];
case 6: return [2 /*return*/];
}
});
});
};
/**
* Get courses for a specific teacher
* Requires student authentication
*/
StudentController.prototype.getCoursesByTeacherId = function (req, res) {
return __awaiter(this, void 0, void 0, function () {
var student, teacherId, tempDbAdapter, teacher, courses, error_5, closeError_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
student = req.student;
if (!student) {
// This check might be redundant if middleware guarantees req.student
res.status(401).json({ message: "Authentication required" });
return [2 /*return*/];
}
teacherId = req.params.teacherId;
if (!teacherId) {
res.status(400).json({ message: "Teacher ID is required in the URL path" });
return [2 /*return*/];
}
tempDbAdapter = null;
_a.label = 1;
case 1:
_a.trys.push([1, 4, 5, 10]);
// Create a temporary adapter instance for this request scope
// TODO: Replace with proper dependency injection
tempDbAdapter = new SqliteAdapter_1.SqliteAdapter();
return [4 /*yield*/, tempDbAdapter.findTeacherById(teacherId)];
case 2:
teacher = _a.sent();
if (!teacher) {
// tempDbAdapter.close(); // Close before throwing/sending response
res
.status(404)
.json({
message: "Teacher profile not found for the provided link.",
});
return [2 /*return*/];
}
return [4 /*yield*/, tempDbAdapter.findCoursesByTeacherId(teacherId)];
case 3:
courses = _a.sent();
// tempDbAdapter.close(); // Close after successful fetch
res.status(200).json({ courses: courses || [] });
return [3 /*break*/, 10];
case 4:
error_5 = _a.sent();
console.error("Error fetching courses for teacher ".concat(teacherId, " for student ").concat(student.id, ":"), error_5);
// Use centralized error handler if available
res.status(500).json({ message: "Failed to retrieve courses" });
return [3 /*break*/, 10];
case 5:
if (!(tempDbAdapter && typeof tempDbAdapter.close === "function")) return [3 /*break*/, 9];
_a.label = 6;
case 6:
_a.trys.push([6, 8, , 9]);
return [4 /*yield*/, tempDbAdapter.close()];
case 7:
_a.sent();
return [3 /*break*/, 9];
case 8:
closeError_1 = _a.sent();
console.error("Error closing DB adapter:", closeError_1);
return [3 /*break*/, 9];
case 9: return [7 /*endfinally*/];
case 10: return [2 /*return*/];
}
});
});
};
/**
* Login a student using email and password (Moved from AuthController)
*/
StudentController.prototype.loginStudent = function (req, res, next) {
return __awaiter(this, void 0, void 0, function () {
var _a, email, password, secret, student, isPasswordValid, tokenPayload, token, error_6;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = req.body, email = _a.email, password = _a.password;
secret = process.env.JWT_SECRET;
if (!email || !password) {
return [2 /*return*/, next(new errorHandler_1.ApiError("Email and password are required", 400))];
}
if (!secret) {
console.error("JWT_SECRET is not set in environment variables");
return [2 /*return*/, next(new errorHandler_1.ApiError("Server configuration error", 500))];
}
_b.label = 1;
case 1:
_b.trys.push([1, 4, , 5]);
return [4 /*yield*/, this.studentRepository.findByEmail(email)];
case 2:
student = _b.sent();
if (!student) {
// Use next() to pass error to centralized handler
return [2 /*return*/, next(new errorHandler_1.ApiError("Invalid credentials", 401))];
}
// Ensure student.passwordHash is available and is a string
if (typeof student.passwordHash !== 'string' || student.passwordHash.length === 0) {
console.error("[StudentController.login] Missing or invalid password hash for student ".concat(email));
return [2 /*return*/, next(new errorHandler_1.ApiError("Authentication error - invalid user data.", 500))];
}
return [4 /*yield*/, bcrypt_1.default.compare(password, student.passwordHash)];
case 3:
isPasswordValid = _b.sent();
if (!isPasswordValid) {
return [2 /*return*/, next(new errorHandler_1.ApiError("Invalid credentials", 401))];
}
tokenPayload = { studentId: student.id };
token = jsonwebtoken_1.default.sign(tokenPayload, secret, { expiresIn: "1h" });
// Set HTTP-only cookie
res.cookie("studentAuthToken", token, {
httpOnly: true, // Prevent client-side JS access
secure: process.env.NODE_ENV === "production", // Use secure cookies in production
sameSite: "lax", // Adjust as needed for your cross-origin setup ('none' requires secure)
maxAge: 3600000, // 1 hour in milliseconds
});
// Send success response with student ID and basic info
res.status(200).json({
message: "Login successful",
student: {
id: student.id, // Send the correct UUID
email: student.email,
name: student.name,
},
});
return [3 /*break*/, 5];
case 4:
error_6 = _b.sent();
console.error("[StudentController] Student login error for ".concat(email, ":"), error_6);
next(error_6); // Pass error to the centralized handler
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
};
__decorate([
(0, controller_1.Post)("/register"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Function]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "registerStudent", null);
__decorate([
(0, controller_1.Get)("/content"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "getPublishedContent", null);
__decorate([
(0, controller_1.Get)("/content/:contentId"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "getContentById", null);
__decorate([
(0, controller_1.Post)("/submit/:contentId"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "submitAssessment", null);
__decorate([
(0, controller_1.Get)("/feedback/:contentId"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "getAssessmentFeedback", null);
__decorate([
(0, controller_1.Post)("/quizzes/:quizId/submit"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "submitQuiz", null);
__decorate([
(0, controller_1.Use)(auth_1.authenticateStudent),
(0, controller_1.Get)("/courses/:teacherId"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "getCoursesByTeacherId", null);
__decorate([
(0, controller_1.Post)("/login"),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, Function]),
__metadata("design:returntype", Promise)
], StudentController.prototype, "loginStudent", null);
StudentController = __decorate([
(0, controller_1.Controller)("/api/student"),
__metadata("design:paramtypes", [Object, QuizService_1.QuizService,
QuizQuestionService_1.QuizQuestionService,
QuizSubmissionService_1.QuizSubmissionService,
StudentRepository_1.StudentRepository])
], StudentController);
return StudentController;
}());
exports.StudentController = StudentController;