import { auth } from '@/auth'; import { NextResponse } from 'next/server'; import { prisma } from '@/prisma'; import { z } from 'zod/v4'; export const getSearchUserSchema = z.object({ query: z.string().optional().default(''), count: z.int().min(1).max(100).default(10), page: z.int().min(1).default(1), sort_by: z .enum(['created_at', 'name', 'first_name', 'last_name', 'id']) .optional() .default('created_at'), sort_order: z.enum(['asc', 'desc']).optional().default('desc'), }); /** * @swagger * /api/search/user: * get: * summary: Search for users * description: Search for users by name, first name, or last name with pagination and sorting. * tags: * - Search * parameters: * - in: query * name: query * required: false * schema: * type: string * description: The search query to filter users by name, first name, or last name. * - in: query * name: count * required: false * schema: * type: integer * description: The number of users to return per page (default is 10). * - in: query * name: page * required: false * schema: * type: integer * description: The page number to return (default is 1). * - in: query * name: sort_by * required: false * schema: * type: string * enum: ['created_at', 'name', 'first_name', 'last_name', 'id'] * description: The field to sort by (default is 'created_at'). * - in: query * name: sort_order * required: false * schema: * type: string * enum: ['asc', 'desc'] * description: The order to sort by, either 'asc' or 'desc' (default is 'desc'). * responses: * 200: * description: Users found successfully. * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * users: * type: array * items: * $ref: '#/components/schemas/PublicUser' * count: * type: integer * description: The number of users returned. * 400: * description: Invalid request data. * content: * application/json: * schema: * $ref: '#/components/schemas/ZodErrorResponse' * 401: * description: User is not authenticated. * content: * application/json: * schema: * $ref: '#/components/schemas/ErrorResponse' * example: * success: false * message: 'Not authenticated' * 404: * description: User not found. * content: * application/json: * schema: * $ref: '#/components/schemas/ErrorResponse' * example: * success: false * message: 'User not found' */ export const GET = auth(async function GET(req) { if (!req.auth) return NextResponse.json( { success: false, message: 'Not authenticated' }, { status: 401 }, ); if (!req.auth.user || !req.auth.user.id) return NextResponse.json( { success: false, message: 'User not found' }, { status: 404 }, ); const dataRaw = new URL(req.url).searchParams; const data = await getSearchUserSchema.safeParseAsync(dataRaw); if (!data.success) { return NextResponse.json( { success: false, message: 'Invalid request data', errors: data.error.issues, }, { status: 400 }, ); } const { query, count, page, sort_by, sort_order } = data.data; const dbUsers = await prisma.user.findMany({ where: { OR: [ { name: { contains: query } }, { first_name: { contains: query } }, { last_name: { contains: query } }, ], }, orderBy: { [sort_by]: sort_order, }, skip: (page - 1) * count, take: count, select: { id: true, name: true, first_name: true, last_name: true, timezone: true, image: true, }, }); return NextResponse.json({ success: true, users: dbUsers, count: dbUsers.length, }); });