elearning/Backend/src/controllers/CoursesStudentController.ts

205 lines
8.6 KiB
TypeScript

import { Get, Body, Post, Route, Tags, SuccessResponse, Response, Security, Path, Request, Query } from 'tsoa';
import { ValidationError } from '../middleware/errorHandler';
import { CoursesStudentService } from '../services/CoursesStudent.service';
import {
EnrollCourseResponse,
ListEnrolledCoursesResponse,
GetCourseLearningResponse,
GetLessonContentResponse,
CheckLessonAccessResponse,
SaveVideoProgressResponse,
SaveVideoProgressBody,
GetVideoProgressResponse,
CompleteLessonResponse,
} from '../types/CoursesStudent.types';
import { EnrollmentStatus } from '@prisma/client';
@Route('api/students')
@Tags('CoursesStudent')
export class CoursesStudentController {
private service = new CoursesStudentService();
/**
* ลงทะเบียนเรียนในคอร์ส
* Enroll in a course
* @param courseId - รหัสคอร์ส / Course ID
*/
@Post('courses/{courseId}/enroll')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Enrolled successfully')
@Response('401', 'Invalid or expired token')
@Response('404', 'Course not found')
@Response('409', 'Already enrolled in this course')
public async enrollCourse(@Request() request: any, @Path() courseId: number): Promise<EnrollCourseResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.enrollCourse({ token, course_id: courseId });
}
/**
* ดึงรายการคอร์สที่ลงทะเบียนเรียน
* Get list of enrolled courses
* @param page - หน้าที่ต้องการดึง / Page number
* @param limit - จำนวนรายการต่อหน้า / Items per page
* @param status - สถานะการลงทะเบียน / Enrollment status
*/
@Get('courses')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Enrolled courses retrieved successfully')
@Response('401', 'Invalid or expired token')
public async getEnrolledCourses(
@Request() request: any,
@Query() page?: number,
@Query() limit?: number,
@Query() status?: EnrollmentStatus
): Promise<ListEnrolledCoursesResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.GetEnrolledCourses({ token, page, limit, status });
}
/**
* ดึงข้อมูลหน้าเรียนคอร์ส (พร้อมสถานะการล็อคบทเรียน)
* Get course learning page with lesson lock status
* @param courseId - รหัสคอร์ส / Course ID
*/
@Get('courses/{courseId}/learn')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Course learning data retrieved successfully')
@Response('401', 'Invalid or expired token')
@Response('403', 'Not enrolled in this course')
@Response('404', 'Course not found')
public async getCourseLearning(@Request() request: any, @Path() courseId: number): Promise<GetCourseLearningResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.getCourseLearning({ token, course_id: courseId });
}
/**
* ดึงเนื้อหาบทเรียน (ตรวจสอบเงื่อนไขก่อนหน้า)
* Get lesson content (checks prerequisites)
* @param courseId - รหัสคอร์ส / Course ID
* @param lessonId - รหัสบทเรียน / Lesson ID
*/
@Get('courses/{courseId}/lessons/{lessonId}')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Lesson content retrieved successfully')
@Response('401', 'Invalid or expired token')
@Response('403', 'Not enrolled in this course or lesson is locked')
@Response('404', 'Lesson not found')
public async getLessonContent(
@Request() request: any,
@Path() courseId: number,
@Path() lessonId: number
): Promise<GetLessonContentResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.getlessonContent({ token, course_id: courseId, lesson_id: lessonId });
}
/**
* ตรวจสอบสิทธิ์เข้าถึงบทเรียน (ไม่โหลดเนื้อหา)
* Check lesson access without loading content
* @param courseId - รหัสคอร์ส / Course ID
* @param lessonId - รหัสบทเรียน / Lesson ID
*/
@Get('courses/{courseId}/lessons/{lessonId}/access-check')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Access check completed')
@Response('401', 'Invalid or expired token')
@Response('404', 'Lesson not found')
public async checkLessonAccess(
@Request() request: any,
@Path() courseId: number,
@Path() lessonId: number
): Promise<CheckLessonAccessResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.checkAccessLesson({ token, course_id: courseId, lesson_id: lessonId });
}
/**
* บันทึกความคืบหน้าการดูวิดีโอ
* Save video progress
* @param lessonId - รหัสบทเรียน / Lesson ID
*/
@Post('lessons/{lessonId}/progress')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Video progress saved successfully')
@Response('401', 'Invalid or expired token')
@Response('403', 'Not enrolled in this course')
@Response('404', 'Lesson not found')
public async saveVideoProgress(
@Request() request: any,
@Path() lessonId: number,
@Body() body: SaveVideoProgressBody
): Promise<SaveVideoProgressResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.saveVideoProgress({
token,
lesson_id: lessonId,
video_progress_seconds: body.video_progress_seconds,
video_duration_seconds: body.video_duration_seconds,
});
}
/**
* ดึงความคืบหน้าการดูวิดีโอ
* Get video progress
* @param lessonId - รหัสบทเรียน / Lesson ID
*/
@Get('lessons/{lessonId}/progress')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Video progress retrieved successfully')
@Response('401', 'Invalid or expired token')
@Response('403', 'Not enrolled in this course')
@Response('404', 'Lesson not found')
public async getVideoProgress(
@Request() request: any,
@Path() lessonId: number
): Promise<GetVideoProgressResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.getVideoProgress({ token, lesson_id: lessonId });
}
/**
* ทำเครื่องหมายบทเรียนว่าเรียนจบ
* Mark lesson as complete
* @param courseId - รหัสคอร์ส / Course ID
* @param lessonId - รหัสบทเรียน / Lesson ID
*/
@Post('courses/{courseId}/lessons/{lessonId}/complete')
@Security('jwt', ['student'])
@SuccessResponse('200', 'Lesson marked as complete')
@Response('401', 'Invalid or expired token')
@Response('403', 'Not enrolled in this course')
@Response('404', 'Lesson not found')
public async completeLesson(
@Request() request: any,
@Path() courseId: number,
@Path() lessonId: number
): Promise<CompleteLessonResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new ValidationError('No token provided');
}
return await this.service.completeLesson({ token, lesson_id: lessonId });
}
}