Files
breakpilot-lehrer/website/app/api/admin/zeugnisse-crawler/route.ts
Benjamin Boenisch 5a31f52310 Initial commit: breakpilot-lehrer - Lehrer KI Platform
Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website,
Klausur-Service, School-Service, Voice-Service, Geo-Service,
BreakPilot Drive, Agent-Core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:26 +01:00

220 lines
6.1 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
// Backend URL - klausur-service
const KLAUSUR_SERVICE_URL = process.env.KLAUSUR_SERVICE_URL || 'http://localhost:8086'
// Helper to proxy requests to backend
async function proxyRequest(
endpoint: string,
method: string = 'GET',
body?: any
): Promise<Response> {
const url = `${KLAUSUR_SERVICE_URL}${endpoint}`
const options: RequestInit = {
method,
headers: {
'Content-Type': 'application/json',
},
}
if (body) {
options.body = JSON.stringify(body)
}
return fetch(url, options)
}
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const action = searchParams.get('action')
const bundesland = searchParams.get('bundesland')
try {
let response: Response
switch (action) {
case 'stats':
response = await proxyRequest('/api/v1/admin/zeugnis/stats')
break
case 'bundesland-stats':
response = await proxyRequest('/api/v1/admin/zeugnis/stats/bundesland')
break
case 'status':
response = await proxyRequest('/api/v1/admin/zeugnis/crawler/status')
break
case 'queue':
response = await proxyRequest('/api/v1/admin/zeugnis/crawler/queue')
break
case 'sources':
response = await proxyRequest('/api/v1/admin/zeugnis/sources')
break
case 'documents':
const docsEndpoint = bundesland
? `/api/v1/admin/zeugnis/documents?bundesland=${bundesland}`
: '/api/v1/admin/zeugnis/documents'
response = await proxyRequest(docsEndpoint)
break
case 'audit':
const days = searchParams.get('days') || '30'
response = await proxyRequest(`/api/v1/admin/zeugnis/audit/events?days=${days}`)
break
default:
return NextResponse.json(
{ error: 'Unknown action', validActions: ['stats', 'bundesland-stats', 'status', 'queue', 'sources', 'documents', 'audit'] },
{ status: 400 }
)
}
if (!response.ok) {
const errorText = await response.text()
console.error(`Backend error: ${response.status} - ${errorText}`)
return NextResponse.json(
{ error: 'Backend error', detail: errorText },
{ status: response.status }
)
}
const data = await response.json()
return NextResponse.json(data)
} catch (error) {
console.error('Zeugnis API proxy error:', error)
return NextResponse.json(
{ error: 'Failed to connect to backend', detail: String(error) },
{ status: 503 }
)
}
}
export async function POST(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const action = searchParams.get('action')
try {
let response: Response
let body: any = null
// Parse body if present
try {
const text = await request.text()
if (text) {
body = JSON.parse(text)
}
} catch {
// No body or invalid JSON
}
switch (action) {
case 'start':
response = await proxyRequest(
'/api/v1/admin/zeugnis/crawler/start',
'POST',
body || {}
)
break
case 'stop':
response = await proxyRequest('/api/v1/admin/zeugnis/crawler/stop', 'POST')
break
case 'init':
response = await proxyRequest('/api/v1/admin/zeugnis/init', 'POST')
break
case 'add-to-queue':
if (!body) {
return NextResponse.json({ error: 'Body required' }, { status: 400 })
}
response = await proxyRequest('/api/v1/admin/zeugnis/crawler/queue', 'POST', body)
break
case 'add-source':
if (!body) {
return NextResponse.json({ error: 'Body required' }, { status: 400 })
}
response = await proxyRequest('/api/v1/admin/zeugnis/sources', 'POST', body)
break
case 'verify-source':
const sourceId = searchParams.get('source_id')
if (!sourceId || !body) {
return NextResponse.json({ error: 'source_id and body required' }, { status: 400 })
}
response = await proxyRequest(
`/api/v1/admin/zeugnis/sources/${sourceId}/verify`,
'PUT',
body
)
break
case 'add-url':
const urlSourceId = searchParams.get('source_id')
if (!urlSourceId || !body) {
return NextResponse.json({ error: 'source_id and body required' }, { status: 400 })
}
response = await proxyRequest(
`/api/v1/admin/zeugnis/sources/${urlSourceId}/urls`,
'POST',
body
)
break
default:
return NextResponse.json(
{ error: 'Unknown action', validActions: ['start', 'stop', 'init', 'add-to-queue', 'add-source', 'verify-source', 'add-url'] },
{ status: 400 }
)
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))
return NextResponse.json(errorData, { status: response.status })
}
const data = await response.json()
return NextResponse.json(data)
} catch (error) {
console.error('Zeugnis API proxy error:', error)
return NextResponse.json(
{ error: 'Failed to connect to backend', detail: String(error) },
{ status: 503 }
)
}
}
export async function DELETE(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const urlId = searchParams.get('url_id')
if (!urlId) {
return NextResponse.json({ error: 'url_id required' }, { status: 400 })
}
try {
const response = await proxyRequest(`/api/v1/admin/zeugnis/urls/${urlId}`, 'DELETE')
if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }))
return NextResponse.json(errorData, { status: response.status })
}
const data = await response.json()
return NextResponse.json(data)
} catch (error) {
console.error('Zeugnis API proxy error:', error)
return NextResponse.json(
{ error: 'Failed to connect to backend', detail: String(error) },
{ status: 503 }
)
}
}