Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | export const dynamic = "force-dynamic"; /** * Admin Canned Responses API * GET /api/admin/support/canned-responses - List all canned responses * POST /api/admin/support/canned-responses - Create canned response */ import { NextRequest, NextResponse } from 'next/server'; import { requireAdminRole, handleAuthError } from '@/lib/auth'; import { prisma } from '@/lib/prisma'; import { CreateCannedResponseSchema } from '@/lib/validation/support-schemas'; import { handleError } from '@/lib/error-handler'; import { logger } from '@/lib/logging'; export async function GET(request: NextRequest) { try { await requireAdminRole(); // Parse query parameters const { searchParams } = new URL(request.url); const category = searchParams.get('category'); const search = searchParams.get('search'); // Build where clause const where: Record<string, unknown> = {}; if (category) { where.category = category; } if (search) { where.OR = [ { title: { contains: search } }, { shortcut: { contains: search } }, { content: { contains: search } }, ]; } // Get canned responses const responses = await prisma.cannedResponse.findMany({ where, include: { creator: { select: { id: true, name: true }}}, orderBy: [{ category: 'asc' }, { usageCount: 'desc' }]}); return NextResponse.json({ success: true, data: responses}); } catch (error) { const authResponse = handleAuthError(error as Error); if (authResponse) return authResponse; logger.error('Error fetching canned responses', error instanceof Error ? error : new Error(String(error)), { category: 'ADMIN_SUPPORT' }); return handleError(error); } } export async function POST(request: NextRequest) { try { const session = await requireAdminRole(); const adminId = Number(session.user.id); // Validate input const body = await request.json(); const validationResult = CreateCannedResponseSchema.safeParse(body); if (!validationResult.success) { return NextResponse.json( { success: false, error: 'Validation failed', details: validationResult.error.flatten().fieldErrors}, { status: 400 } ); } const data = validationResult.data; // Check if shortcut is unique const existingResponse = await prisma.cannedResponse.findUnique({ where: { shortcut: data.shortcut }}); if (existingResponse) { return NextResponse.json( { success: false, error: 'A canned response with this shortcut already exists' }, { status: 409 } ); } // Create the canned response const response = await prisma.cannedResponse.create({ data: { title: data.title, shortcut: data.shortcut, content: data.content, category: data.category, createdBy: adminId}, include: { creator: { select: { id: true, name: true }}}}); logger.info('Canned response created', { category: 'ADMIN_SUPPORT', responseId: response.id, shortcut: response.shortcut, adminId}); return NextResponse.json( { success: true, data: response, message: 'Canned response created successfully'}, { status: 201 } ); } catch (error) { const authResponse = handleAuthError(error as Error); if (authResponse) return authResponse; logger.error('Error creating canned response', error instanceof Error ? error : new Error(String(error)), { category: 'ADMIN_SUPPORT' }); return handleError(error); } } |