feat: update instructor search to exclude self and existing course instructors, add email_verified_at to user responses
Update searchInstructors endpoint to accept courseId parameter and filter out the requesting instructor and instructors already assigned to the course. Add email_verified_at field to UserResponse type and include it in auth and user service responses.
This commit is contained in:
parent
80d7372dfa
commit
48e8f56e22
6 changed files with 29 additions and 8 deletions
|
|
@ -48,18 +48,23 @@ export class CoursesInstructorController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ค้นหาผู้สอนทั้งหมดในระบบ
|
* ค้นหาผู้สอนทั้งหมดในระบบ (ไม่รวมตัวเองและคนที่อยู่ในคอร์สแล้ว)
|
||||||
* Search all instructors in database
|
* Search all instructors in database (excluding self and existing course instructors)
|
||||||
|
* @param courseId - รหัสคอร์ส / Course ID
|
||||||
* @param query - คำค้นหา (email หรือ username) / Search query (email or username)
|
* @param query - คำค้นหา (email หรือ username) / Search query (email or username)
|
||||||
*/
|
*/
|
||||||
@Get('search-instructors')
|
@Get('{courseId}/search-instructors')
|
||||||
@Security('jwt', ['instructor'])
|
@Security('jwt', ['instructor'])
|
||||||
@SuccessResponse('200', 'Instructors found')
|
@SuccessResponse('200', 'Instructors found')
|
||||||
@Response('401', 'Invalid or expired token')
|
@Response('401', 'Invalid or expired token')
|
||||||
public async searchInstructors(@Request() request: any, @Query() query: string): Promise<SearchInstructorResponse> {
|
public async searchInstructors(
|
||||||
|
@Request() request: any,
|
||||||
|
@Path() courseId: number,
|
||||||
|
@Query() query: string
|
||||||
|
): Promise<SearchInstructorResponse> {
|
||||||
const token = request.headers.authorization?.replace('Bearer ', '');
|
const token = request.headers.authorization?.replace('Bearer ', '');
|
||||||
if (!token) throw new ValidationError('No token provided');
|
if (!token) throw new ValidationError('No token provided');
|
||||||
return await CoursesInstructorService.searchInstructors({ token, query });
|
return await CoursesInstructorService.searchInstructors({ token, query, course_id: courseId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -356,16 +356,26 @@ export class CoursesInstructorService {
|
||||||
|
|
||||||
static async searchInstructors(input: SearchInstructorInput): Promise<SearchInstructorResponse> {
|
static async searchInstructors(input: SearchInstructorInput): Promise<SearchInstructorResponse> {
|
||||||
try {
|
try {
|
||||||
jwt.verify(input.token, config.jwt.secret) as { id: number };
|
const decoded = jwt.verify(input.token, config.jwt.secret) as { id: number };
|
||||||
|
|
||||||
// Search all instructors by email or username
|
// Get existing instructors in the course
|
||||||
|
const existingInstructors = await prisma.courseInstructor.findMany({
|
||||||
|
where: { course_id: input.course_id },
|
||||||
|
select: { user_id: true },
|
||||||
|
});
|
||||||
|
const existingInstructorIds = existingInstructors.map(i => i.user_id);
|
||||||
|
|
||||||
|
// Search all instructors by email or username, excluding self and existing course instructors
|
||||||
const users = await prisma.user.findMany({
|
const users = await prisma.user.findMany({
|
||||||
where: {
|
where: {
|
||||||
OR: [
|
OR: [
|
||||||
{ email: { contains: input.query, mode: 'insensitive' } },
|
{ email: { contains: input.query, mode: 'insensitive' } },
|
||||||
{ username: { contains: input.query, mode: 'insensitive' } },
|
{ username: { contains: input.query, mode: 'insensitive' } },
|
||||||
],
|
],
|
||||||
role: { code: 'INSTRUCTOR' }
|
role: { code: 'INSTRUCTOR' },
|
||||||
|
id: {
|
||||||
|
notIn: [decoded.id, ...existingInstructorIds],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
profile: true
|
profile: true
|
||||||
|
|
|
||||||
|
|
@ -398,6 +398,7 @@ export class AuthService {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
email_verified_at: user.email_verified_at,
|
||||||
updated_at: user.updated_at,
|
updated_at: user.updated_at,
|
||||||
created_at: user.created_at,
|
created_at: user.created_at,
|
||||||
role: {
|
role: {
|
||||||
|
|
@ -423,6 +424,7 @@ export class AuthService {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
email_verified_at: user.email_verified_at,
|
||||||
updated_at: user.updated_at,
|
updated_at: user.updated_at,
|
||||||
created_at: user.created_at,
|
created_at: user.created_at,
|
||||||
role: {
|
role: {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ export class UserService {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
email_verified_at: user.email_verified_at,
|
||||||
updated_at: user.updated_at,
|
updated_at: user.updated_at,
|
||||||
created_at: user.created_at,
|
created_at: user.created_at,
|
||||||
role: {
|
role: {
|
||||||
|
|
@ -285,6 +286,7 @@ export class UserService {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
|
email_verified_at: user.email_verified_at,
|
||||||
updated_at: user.updated_at,
|
updated_at: user.updated_at,
|
||||||
created_at: user.created_at,
|
created_at: user.created_at,
|
||||||
role: {
|
role: {
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ export interface addinstructorCourse {
|
||||||
export interface SearchInstructorInput {
|
export interface SearchInstructorInput {
|
||||||
token: string;
|
token: string;
|
||||||
query: string;
|
query: string;
|
||||||
|
course_id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchInstructorResult {
|
export interface SearchInstructorResult {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ export interface UserResponse {
|
||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
email_verified_at: Date | null;
|
||||||
updated_at: Date | null;
|
updated_at: Date | null;
|
||||||
created_at: Date | null;
|
created_at: Date | null;
|
||||||
role: {
|
role: {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue