File size: 1,865 Bytes
656ac31 ce7f322 656ac31 | 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 | import { NextResponse } from 'next/server'
/**
* Standard API response helpers.
* All API routes should use these for consistent response envelopes.
*
* Success: { ok: true, ...data }
* Error: { ok: false, error: string, ...extra }
*/
export function apiSuccess<T extends Record<string, unknown>>(
data: T,
status = 200
): NextResponse {
return NextResponse.json({ ok: true, ...data }, { status })
}
export function apiError(
error: string,
status = 500,
extra?: Record<string, unknown>
): NextResponse {
return NextResponse.json({ ok: false, error, ...extra }, { status })
}
/** Common error responses */
export const ApiErrors = {
noApiBase: () =>
apiError('API URL yapılandırılmamış. NEXT_PUBLIC_API_URL tanımlayın.', 500),
invalidJson: () => apiError('Geçersiz JSON body', 400),
bodyRequired: () => apiError('JSON body gerekli', 400),
invalidSymbol: () =>
apiError('Geçerli bir symbol alanı gerekli (ör: THYAO)', 400),
upstream: (route: string, status: number, detail?: unknown) =>
apiError(`Upstream ${route} error: ${status}`, status >= 400 ? status : 502, {
detail: detail ?? null,
}),
upstreamUnavailable: (
route: string,
options?: {
detail?: unknown
rootError?: string
hint?: string
}
) =>
NextResponse.json(
{
ok: false,
error: options?.rootError || `${route} backend geçici olarak kullanılamıyor`,
detail: options?.detail ?? null,
hint:
options?.hint ||
'HF backend geçici olarak ulaşılamaz durumda. Biraz sonra tekrar deneyin.',
unavailable: true,
},
{ status: 200 }
),
timeout: (route: string) =>
apiError(`${route} isteği zaman aşımına uğradı`, 504),
unknown: (msg?: string) =>
apiError(msg || 'Bilinmeyen hata', 502),
} as const
|