import { Path, Post, Put, Request, Response, Route, Security, SuccessResponse, Tags, UploadedFile, UploadedFiles } from 'tsoa'; import { ValidationError } from '../middleware/errorHandler'; import { ChaptersLessonService } from '../services/ChaptersLesson.service'; import { UploadedFileInfo, CreateLessonResponse, UpdateLessonResponse } from '../types/ChaptersLesson.typs'; const chaptersLessonService = new ChaptersLessonService(); @Route('api/instructors/courses/{courseId}/chapters/{chapterId}/lessons') @Tags('Lessons - File Upload') export class LessonsController { /** * เพิ่มวิดีโอและไฟล์แนบให้บทเรียน VIDEO ที่มีอยู่แล้ว * Add video and attachments to an existing VIDEO type lesson * * @param courseId Course ID * @param chapterId Chapter ID * @param lessonId Lesson ID * @param video ไฟล์วิดีโอ (required) * @param attachments ไฟล์แนบ */ @Post('{lessonId}/video') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Video added successfully') @Response('400', 'Validation error') @Response('401', 'Unauthorized') @Response('403', 'Forbidden') @Response('404', 'Lesson not found') public async addVideoToLesson( @Request() request: any, @Path() courseId: number, @Path() chapterId: number, @Path() lessonId: number, @UploadedFile() video: Express.Multer.File, @UploadedFiles() attachments?: Express.Multer.File[] ): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) throw new ValidationError('No token provided'); if (!video) { throw new ValidationError('Video file is required'); } // Transform files to UploadedFileInfo const videoInfo: UploadedFileInfo = { originalname: video.originalname, mimetype: video.mimetype, size: video.size, buffer: video.buffer, }; let attachmentsInfo: UploadedFileInfo[] | undefined; if (attachments && attachments.length > 0) { attachmentsInfo = attachments.map(file => ({ originalname: file.originalname, mimetype: file.mimetype, size: file.size, buffer: file.buffer, })); } return await chaptersLessonService.addVideoLesson({ token, course_id: courseId, lesson_id: lessonId, video: videoInfo, attachments: attachmentsInfo, }); } /** * อัปเดตวิดีโอและไฟล์แนบของบทเรียน VIDEO * Update video and attachments of an existing VIDEO type lesson * * @param courseId Course ID * @param chapterId Chapter ID * @param lessonId Lesson ID * @param video ไฟล์วิดีโอใหม่ * @param attachments ไฟล์แนบใหม่ */ @Put('{lessonId}/video') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Video updated successfully') @Response('400', 'Validation error') @Response('401', 'Unauthorized') @Response('403', 'Forbidden') @Response('404', 'Lesson not found') public async updateVideoLesson( @Request() request: any, @Path() courseId: number, @Path() chapterId: number, @Path() lessonId: number, @UploadedFile() video?: Express.Multer.File, @UploadedFiles() attachments?: Express.Multer.File[] ): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) throw new ValidationError('No token provided'); // Transform files to UploadedFileInfo let videoInfo: UploadedFileInfo | undefined; let attachmentsInfo: UploadedFileInfo[] | undefined; if (video) { videoInfo = { originalname: video.originalname, mimetype: video.mimetype, size: video.size, buffer: video.buffer, }; } if (attachments && attachments.length > 0) { attachmentsInfo = attachments.map(file => ({ originalname: file.originalname, mimetype: file.mimetype, size: file.size, buffer: file.buffer, })); } return await chaptersLessonService.updateVideoLesson({ token, course_id: courseId, lesson_id: lessonId, video: videoInfo, attachments: attachmentsInfo, }); } }