Files
breakpilot-compliance/admin-compliance/app/api/sdk/v1/dsfa/[[...path]]/route.ts
Benjamin Admin a694b9d9ea
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 38s
CI / test-python-backend-compliance (push) Successful in 38s
CI / test-python-document-crawler (push) Successful in 22s
CI / test-python-dsms-gateway (push) Successful in 19s
feat: DSFA Modul — Backend, Proxy, Frontend-Migration, Tests + Mock-Daten entfernt
- Migration 024: compliance_dsfas + compliance_dsfa_audit_log Tabellen
- dsfa_routes.py: CRUD + stats + audit-log + PATCH status Endpoints
- Proxy: /api/sdk/v1/dsfa/[[...path]] → backend-compliance:8002/api/v1/dsfa
- dsfa/page.tsx: mockDSFAs entfernt → echte API (loadDSFAs, handleCreateDSFA, handleStatusChange, handleDeleteDSFA)
- GeneratorWizard: kontrollierte Inputs + onSubmit-Handler
- reporting/page.tsx: getMockReport() Fallback entfernt → Fehlerstate
- dsr/[requestId]/page.tsx: mockCommunications entfernt → leeres Array (TODO: Backend fehlt)
- 52 neue Tests (680 gesamt, alle grün)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 22:41:05 +01:00

124 lines
3.4 KiB
TypeScript

/**
* DSFA API Proxy — Datenschutz-Folgenabschaetzung (Art. 35 DSGVO)
* Proxies /api/sdk/v1/dsfa/* → backend-compliance:8002/api/v1/dsfa/*
*/
import { NextRequest, NextResponse } from 'next/server'
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-compliance:8002'
async function proxyRequest(
request: NextRequest,
pathSegments: string[] | undefined,
method: string
) {
const pathStr = pathSegments?.join('/') || ''
const searchParams = request.nextUrl.searchParams.toString()
const basePath = `${BACKEND_URL}/api/v1/dsfa`
const url = pathStr
? `${basePath}/${pathStr}${searchParams ? `?${searchParams}` : ''}`
: `${basePath}${searchParams ? `?${searchParams}` : ''}`
try {
const headers: HeadersInit = {
'Content-Type': 'application/json',
}
const headerNames = ['authorization', 'x-namespace-id', 'x-tenant-slug']
for (const name of headerNames) {
const value = request.headers.get(name)
if (value) {
headers[name] = value
}
}
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
const clientUserId = request.headers.get('x-user-id')
const clientTenantId = request.headers.get('x-tenant-id')
headers['X-User-ID'] = (clientUserId && uuidRegex.test(clientUserId))
? clientUserId
: '00000000-0000-0000-0000-000000000001'
headers['X-Tenant-ID'] = (clientTenantId && uuidRegex.test(clientTenantId))
? clientTenantId
: (process.env.DEFAULT_TENANT_ID || '9282a473-5c95-4b3a-bf78-0ecc0ec71d3e')
const fetchOptions: RequestInit = {
method,
headers,
signal: AbortSignal.timeout(60000),
}
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
const body = await request.text()
if (body) {
fetchOptions.body = body
}
}
const response = await fetch(url, fetchOptions)
if (!response.ok) {
const errorText = await response.text()
let errorJson
try {
errorJson = JSON.parse(errorText)
} catch {
errorJson = { error: errorText }
}
return NextResponse.json(
{ error: `Backend Error: ${response.status}`, ...errorJson },
{ status: response.status }
)
}
const data = await response.json()
return NextResponse.json(data)
} catch (error) {
console.error('DSFA API proxy error:', error)
return NextResponse.json(
{ error: 'Verbindung zum Compliance Backend fehlgeschlagen' },
{ status: 503 }
)
}
}
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ path?: string[] }> }
) {
const { path } = await params
return proxyRequest(request, path, 'GET')
}
export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ path?: string[] }> }
) {
const { path } = await params
return proxyRequest(request, path, 'POST')
}
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ path?: string[] }> }
) {
const { path } = await params
return proxyRequest(request, path, 'PUT')
}
export async function PATCH(
request: NextRequest,
{ params }: { params: Promise<{ path?: string[] }> }
) {
const { path } = await params
return proxyRequest(request, path, 'PATCH')
}
export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ path?: string[] }> }
) {
const { path } = await params
return proxyRequest(request, path, 'DELETE')
}