import VocabService from '../services/vocabService.js'; function extractHashedUserId(req) { return req.headers?.userid; } class VocabController { constructor() { this.service = new VocabService(); this.listLanguages = this._wrapWithUser((userId) => this.service.listLanguages(userId)); this.createLanguage = this._wrapWithUser((userId, req) => this.service.createLanguage(userId, req.body), { successStatus: 201 }); this.subscribe = this._wrapWithUser((userId, req) => this.service.subscribeByShareCode(userId, req.body), { successStatus: 201 }); this.getLanguage = this._wrapWithUser((userId, req) => this.service.getLanguage(userId, req.params.languageId)); this.listChapters = this._wrapWithUser((userId, req) => this.service.listChapters(userId, req.params.languageId)); this.createChapter = this._wrapWithUser((userId, req) => this.service.createChapter(userId, req.params.languageId, req.body), { successStatus: 201 }); this.listLanguageVocabs = this._wrapWithUser((userId, req) => this.service.listLanguageVocabs(userId, req.params.languageId)); this.searchVocabs = this._wrapWithUser((userId, req) => this.service.searchVocabs(userId, req.params.languageId, req.query)); this.getChapter = this._wrapWithUser((userId, req) => this.service.getChapter(userId, req.params.chapterId)); this.listChapterVocabs = this._wrapWithUser((userId, req) => this.service.listChapterVocabs(userId, req.params.chapterId)); this.addVocabToChapter = this._wrapWithUser((userId, req) => this.service.addVocabToChapter(userId, req.params.chapterId, req.body), { successStatus: 201 }); // Courses this.createCourse = this._wrapWithUser((userId, req) => this.service.createCourse(userId, req.body), { successStatus: 201 }); this.getCourses = this._wrapWithUser((userId, req) => this.service.getCourses(userId, req.query)); this.getCourse = this._wrapWithUser((userId, req) => this.service.getCourse(userId, req.params.courseId)); this.getCourseByShareCode = this._wrapWithUser((userId, req) => this.service.getCourseByShareCode(userId, req.body.shareCode)); this.updateCourse = this._wrapWithUser((userId, req) => this.service.updateCourse(userId, req.params.courseId, req.body)); this.deleteCourse = this._wrapWithUser((userId, req) => this.service.deleteCourse(userId, req.params.courseId)); // Lessons this.addLessonToCourse = this._wrapWithUser((userId, req) => this.service.addLessonToCourse(userId, req.params.courseId, req.body), { successStatus: 201 }); this.updateLesson = this._wrapWithUser((userId, req) => this.service.updateLesson(userId, req.params.lessonId, req.body)); this.deleteLesson = this._wrapWithUser((userId, req) => this.service.deleteLesson(userId, req.params.lessonId)); // Enrollment this.enrollInCourse = this._wrapWithUser((userId, req) => this.service.enrollInCourse(userId, req.params.courseId), { successStatus: 201 }); this.unenrollFromCourse = this._wrapWithUser((userId, req) => this.service.unenrollFromCourse(userId, req.params.courseId)); this.getMyCourses = this._wrapWithUser((userId) => this.service.getMyCourses(userId)); // Progress this.getCourseProgress = this._wrapWithUser((userId, req) => this.service.getCourseProgress(userId, req.params.courseId)); this.updateLessonProgress = this._wrapWithUser((userId, req) => this.service.updateLessonProgress(userId, req.params.lessonId, req.body)); // Grammar Exercises this.getExerciseTypes = this._wrapWithUser((userId) => this.service.getExerciseTypes()); this.createGrammarExercise = this._wrapWithUser((userId, req) => this.service.createGrammarExercise(userId, req.params.lessonId, req.body), { successStatus: 201 }); this.getGrammarExercisesForLesson = this._wrapWithUser((userId, req) => this.service.getGrammarExercisesForLesson(userId, req.params.lessonId)); this.getGrammarExercise = this._wrapWithUser((userId, req) => this.service.getGrammarExercise(userId, req.params.exerciseId)); this.checkGrammarExerciseAnswer = this._wrapWithUser((userId, req) => this.service.checkGrammarExerciseAnswer(userId, req.params.exerciseId, req.body.answer)); this.getGrammarExerciseProgress = this._wrapWithUser((userId, req) => this.service.getGrammarExerciseProgress(userId, req.params.lessonId)); this.updateGrammarExercise = this._wrapWithUser((userId, req) => this.service.updateGrammarExercise(userId, req.params.exerciseId, req.body)); this.deleteGrammarExercise = this._wrapWithUser((userId, req) => this.service.deleteGrammarExercise(userId, req.params.exerciseId)); } _wrapWithUser(fn, { successStatus = 200 } = {}) { return async (req, res) => { try { const hashedUserId = extractHashedUserId(req); if (!hashedUserId) { return res.status(400).json({ error: 'Missing user identifier' }); } const result = await fn(hashedUserId, req, res); res.status(successStatus).json(result); } catch (error) { console.error('Controller error:', error); const status = error.status && typeof error.status === 'number' ? error.status : 500; res.status(status).json({ error: error.message || 'Internal error' }); } }; } } export default VocabController;