hfpush
fix: add ai/sentiment_model.py facade
c3c81a6
import { NextRequest, NextResponse } from 'next/server'
import { API_BASE } from '@/lib/runtime-config'
import { requireAuth } from '@/lib/api-auth'
export const dynamic = 'force-dynamic'
export async function POST(req: NextRequest) {
const auth = await requireAuth(req)
if (!auth.authenticated) return auth.response
if (!API_BASE) {
return NextResponse.json(
{ ok: false, error: 'API URL yapılandırılmamış. NEXT_PUBLIC_API_URL tanımlayın.' },
{ status: 500 }
)
}
let body: Record<string, unknown> | null = null
try {
body = await req.json()
} catch {
return NextResponse.json({ ok: false, error: 'Geçersiz JSON body' }, { status: 400 })
}
if (!body || typeof body !== 'object') {
return NextResponse.json({ ok: false, error: 'JSON body gerekli' }, { status: 400 })
}
// Validate symbols array for batch predictions
const symbols = Array.isArray(body.symbols) ? body.symbols : []
if (symbols.length === 0) {
return NextResponse.json({ ok: false, error: 'En az bir symbol gerekli (symbols: ["THYAO", ...])' }, { status: 400 })
}
// Validate each symbol
const validSymbols: string[] = []
for (const sym of symbols) {
if (typeof sym === 'string') {
const cleaned = sym.trim().toUpperCase()
if (cleaned && /^[A-Z0-9.]{1,20}$/.test(cleaned)) {
validSymbols.push(cleaned)
}
}
}
if (validSymbols.length === 0) {
return NextResponse.json({ ok: false, error: 'Geçerli symbol bulunamadı' }, { status: 400 })
}
body.symbols = validSymbols
try {
// Longer timeout for batch predictions (10+ stocks can take time)
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 60000)
let resp: Response
try {
resp = await fetch(`${API_BASE}/api/ml-predictions`, {
method: 'POST',
headers: { 'content-type': 'application/json', accept: 'application/json' },
cache: 'no-store',
body: JSON.stringify(body ?? {}),
signal: controller.signal,
})
} finally {
clearTimeout(timeout)
}
const payload = await resp.json().catch(() => null)
if (!resp.ok) {
return NextResponse.json(
{ ok: false, error: `Upstream ml-predictions error: ${resp.status}`, detail: payload },
{ status: resp.status }
)
}
return NextResponse.json(payload ?? { ok: false, error: 'Invalid upstream payload' }, { status: 200 })
} catch (e: unknown) {
const message = e instanceof Error ? e.message : 'Unknown error'
return NextResponse.json({ ok: false, error: message }, { status: 502 })
}
}