feat: add search and filter capabilities to student and quiz endpoints, implement YouTube video support for lessons

Add search and status filter parameters to getEnrolledStudents endpoint to filter students by name/email/username and enrollment status. Add search and isPassed filter parameters to getQuizScores endpoint to filter quiz results by student details and pass status. Remove separate searchStudents endpoint as its functionality is now integrated into getEnrolledStudents. Add setYouTubeVideo endpoint to
This commit is contained in:
JakkrapartXD 2026-02-03 17:23:35 +07:00
parent e8a10e5024
commit ff841c7638
6 changed files with 246 additions and 125 deletions

View file

@ -19,7 +19,6 @@ import {
GetEnrolledStudentsResponse,
GetQuizScoresResponse,
GetQuizAttemptDetailResponse,
SearchStudentsResponse,
GetEnrolledStudentDetailResponse,
} from '../types/CoursesInstructor.types';
import { CreateCourseValidator } from "../validators/CoursesInstructor.validator";
@ -279,6 +278,8 @@ export class CoursesInstructorController {
* @param courseId - / Course ID
* @param page - / Page number
* @param limit - / Items per page
* @param search - firstname, lastname, email, username
* @param status - (ENROLLED, COMPLETED)
*/
@Get('{courseId}/students')
@Security('jwt', ['instructor'])
@ -289,7 +290,9 @@ export class CoursesInstructorController {
@Request() request: any,
@Path() courseId: number,
@Query() page?: number,
@Query() limit?: number
@Query() limit?: number,
@Query() search?: string,
@Query() status?: 'ENROLLED' | 'COMPLETED'
): Promise<GetEnrolledStudentsResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
@ -298,34 +301,8 @@ export class CoursesInstructorController {
course_id: courseId,
page,
limit,
});
}
/**
*
* Search students in course by firstname, lastname, email, or username
* @param courseId - / Course ID
* @param query - / Search query
* @param limit - / Max results
*/
@Get('{courseId}/students/search')
@Security('jwt', ['instructor'])
@SuccessResponse('200', 'Students found successfully')
@Response('401', 'Invalid or expired token')
@Response('403', 'Not an instructor of this course')
public async searchStudents(
@Request() request: any,
@Path() courseId: number,
@Query() query: string,
@Query() limit?: number
): Promise<SearchStudentsResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
return await CoursesInstructorService.searchStudentsInCourse({
token,
course_id: courseId,
query,
limit,
search,
status,
});
}
@ -362,6 +339,8 @@ export class CoursesInstructorController {
* @param lessonId - / Lesson ID
* @param page - / Page number
* @param limit - / Items per page
* @param search - firstname, lastname, email, username
* @param isPassed - (true = , false = )
*/
@Get('{courseId}/lessons/{lessonId}/quiz/scores')
@Security('jwt', ['instructor'])
@ -374,7 +353,9 @@ export class CoursesInstructorController {
@Path() courseId: number,
@Path() lessonId: number,
@Query() page?: number,
@Query() limit?: number
@Query() limit?: number,
@Query() search?: string,
@Query() isPassed?: boolean
): Promise<GetQuizScoresResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
@ -384,6 +365,8 @@ export class CoursesInstructorController {
lesson_id: lessonId,
page,
limit,
search,
is_passed: isPassed,
});
}