All files / src/app/api/admin/monitoring/performance/slow route.ts

87.77% Statements 79/90
89.47% Branches 17/19
100% Functions 1/1
87.77% Lines 79/90

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 911x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x             7x 7x 7x 7x 1x 1x 1x 1x 6x 6x 7x 7x 7x 7x 1x 1x 1x 1x 5x 7x 1x 1x 1x 1x 4x 4x 4x 4x 4x 7x 7x 7x 7x 4x 4x 7x           7x 1x 1x  
/**
 * Slow Requests API
 *
 * GET /api/admin/monitoring/performance/slow
 *
 * Returns slow requests with configurable threshold and filtering.
 */
 
export const dynamic = 'force-dynamic';
 
import { NextRequest, NextResponse } from 'next/server';
import { getSlowRequests, type SlowRequestsResponse } from '@/lib/monitoring/performanceQueries';
import { logger } from '@/lib/logging';
import {
  withAdmin,
  withErrorHandling,
  successResponse,
  errorResponse,
  type ApiSuccessResponse,
  type ApiErrorResponse,
} from '@/lib/api';
 
/**
 * GET handler for slow requests
 */
async function handleGet(
  request: NextRequest
): Promise<NextResponse<ApiSuccessResponse<SlowRequestsResponse> | ApiErrorResponse>> {
  const { searchParams } = new URL(request.url);
 
  // Parse query parameters
  const threshold = searchParams.get('threshold');
  const timeRange = searchParams.get('timeRange') || '24h';
  const path = searchParams.get('path');
  const limit = searchParams.get('limit');
  const page = searchParams.get('page');
 
  // Validate time range
  const validRanges = ['1h', '6h', '24h', '7d', '30d'];
  if (!validRanges.includes(timeRange)) {
    return errorResponse(
      'INVALID_PARAM',
      'Invalid timeRange. Must be one of: 1h, 6h, 24h, 7d, 30d',
      { status: 400 }
    );
  }
 
  // Validate threshold
  const thresholdMs = threshold ? parseInt(threshold, 10) : 500;
  if (isNaN(thresholdMs) || thresholdMs < 0) {
    return errorResponse('INVALID_PARAM', 'threshold must be a positive number', {
      status: 400,
    });
  }
 
  // Validate pagination
  const pageNum = page ? parseInt(page, 10) : 1;
  const limitNum = limit ? parseInt(limit, 10) : 50;
 
  if (isNaN(pageNum) || pageNum < 1) {
    return errorResponse('INVALID_PARAM', 'page must be a positive integer', {
      status: 400,
    });
  }
 
  if (isNaN(limitNum) || limitNum < 1 || limitNum > 200) {
    return errorResponse('INVALID_PARAM', 'limit must be between 1 and 200', {
      status: 400,
    });
  }
 
  try {
    const result = await getSlowRequests({
      threshold: thresholdMs,
      timeRange,
      path: path || undefined,
      limit: limitNum,
      page: pageNum,
    });
 
    return successResponse(result);
  } catch (error) {
    logger.error('Error fetching slow requests', error instanceof Error ? error : new Error(String(error)), { category: 'API' });
    return errorResponse('INTERNAL_ERROR', 'Failed to fetch slow requests', {
      status: 500,
    });
  }
}
 
export const GET = withErrorHandling(withAdmin(handleGet));