import { Get, Body, Post, Route, Tags, SuccessResponse, Response, Security, Put, Path, Delete, Request, Example } from 'tsoa'; import { ValidationError } from '../middleware/errorHandler'; import { CoursesInstructorService } from '../services/CoursesInstructor.service'; import { createCourses, createCourseResponse, GetMyCourseResponse, ListMyCourseResponse, addinstructorCourse, addinstructorCourseResponse, removeinstructorCourse, removeinstructorCourseResponse, setprimaryCourseInstructor, setprimaryCourseInstructorResponse, UpdateMyCourse, UpdateMyCourseResponse, DeleteMyCourseResponse, submitCourseResponse, listinstructorCourseResponse, GetCourseApprovalsResponse } from '../types/CoursesInstructor.types'; import { CreateCourseValidator } from "../validators/CoursesInstructor.validator"; import jwt from 'jsonwebtoken'; import { config } from '../config'; @Route('api/instructors/courses') @Tags('CoursesInstructor') export class CoursesInstructorController { /** * ดึงรายการคอร์สทั้งหมดของผู้สอน * Get all courses where the authenticated user is an instructor */ @Get('') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Courses retrieved successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Courses not found') public async listMyCourses(@Request() request: any): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.listMyCourses(token); } /** * ดึงข้อมูลคอร์สเฉพาะของผู้สอน (พร้อมบทเรียนและเนื้อหา) * Get detailed course information including chapters, lessons, attachments, and quizzes * @param courseId - รหัสคอร์ส / Course ID */ @Get('{courseId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Course retrieved successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Course not found') public async getMyCourse(@Request() request: any, @Path() courseId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.getmyCourse({ token, course_id: courseId }); } /** * แก้ไขข้อมูลคอร์ส * Update course information (only for course instructors) * @param courseId - รหัสคอร์ส / Course ID */ @Put('{courseId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Course updated successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Course not found') public async updateCourse(@Request() request: any, @Path() courseId: number, @Body() body: UpdateMyCourse): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.updateCourse(token, courseId, body.data); } /** * สร้างคอร์สใหม่ * Create a new course (status will be DRAFT by default) */ @Post('') @Security('jwt', ['instructor']) @SuccessResponse('201', 'Course created successfully') @Response('400', 'Validation error') @Response('500', 'Internal server error') public async createCourse(@Body() body: createCourses, @Request() request: any): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); const decoded = jwt.verify(token, config.jwt.secret) as { id: number }; const { error, value } = CreateCourseValidator.validate(body.data); if (error) throw new ValidationError(error.details[0].message); const course = await CoursesInstructorService.createCourse(value, decoded.id); return course; } /** * ลบคอร์ส (เฉพาะผู้สอนหลักเท่านั้น) * Delete a course (only primary instructor can delete) * @param courseId - รหัสคอร์ส / Course ID */ @Delete('{courseId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Course deleted successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Course not found') public async deleteCourse(@Request() request: any, @Path() courseId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.deleteCourse(token, courseId); } /** * ส่งคอร์สเพื่อขออนุมัติจากแอดมิน * Submit course for admin review and approval * @param courseId - รหัสคอร์ส / Course ID */ @Post('send-review/{courseId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Course submitted successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Course not found') public async submitCourse(@Request() request: any, @Path() courseId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.sendCourseForReview({ token, course_id: courseId }); } /** * ดึงประวัติการส่งอนุมัติคอร์สทั้งหมด * Get all course approval history * @param courseId - รหัสคอร์ส / Course ID */ @Get('{courseId}/approvals') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Course approvals retrieved successfully') @Response('401', 'Invalid or expired token') @Response('403', 'You are not an instructor of this course') @Response('404', 'Course not found') public async getCourseApprovals(@Request() request: any, @Path() courseId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.getCourseApprovals(token, courseId); } /** * ดึงรายชื่อผู้สอนทั้งหมดในคอร์ส * Get list of all instructors in a specific course * @param courseId - รหัสคอร์ส / Course ID */ @Get('listinstructor/{courseId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Instructors retrieved successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Instructors not found') public async listInstructorCourses(@Request() request: any, @Path() courseId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.listInstructorsOfCourse({ token, course_id: courseId }); } /** * เพิ่มผู้สอนเข้าในคอร์ส * Add a new instructor to the course * @param courseId - รหัสคอร์ส / Course ID * @param userId - รหัสผู้ใช้ที่ต้องการเพิ่มเป็นผู้สอน / User ID to add as instructor */ @Post('add-instructor/{courseId}/{userId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Instructor added successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Instructor not found') public async addInstructor(@Request() request: any, @Path() courseId: number, @Path() userId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.addInstructorToCourse({ token, course_id: courseId, user_id: userId }); } /** * ลบผู้สอนออกจากคอร์ส * Remove an instructor from the course * @param courseId - รหัสคอร์ส / Course ID * @param userId - รหัสผู้ใช้ที่ต้องการลบออกจากผู้สอน / User ID to remove from instructors */ @Delete('remove-instructor/{courseId}/{userId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Instructor removed successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Instructor not found') public async removeInstructor(@Request() request: any, @Path() courseId: number, @Path() userId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.removeInstructorFromCourse({ token, course_id: courseId, user_id: userId }); } /** * กำหนดผู้สอนหลักของคอร์ส * Set a user as the primary instructor of the course * @param courseId - รหัสคอร์ส / Course ID * @param userId - รหัสผู้ใช้ที่ต้องการตั้งเป็นผู้สอนหลัก / User ID to set as primary instructor */ @Put('set-primary-instructor/{courseId}/{userId}') @Security('jwt', ['instructor']) @SuccessResponse('200', 'Primary instructor set successfully') @Response('401', 'Invalid or expired token') @Response('404', 'Primary instructor not found') public async setPrimaryInstructor(@Request() request: any, @Path() courseId: number, @Path() userId: number): Promise { const token = request.headers.authorization?.replace('Bearer ', ''); if (!token) { throw new ValidationError('No token provided'); } return await CoursesInstructorService.setPrimaryInstructor({ token, course_id: courseId, user_id: userId }); } }