e536247c20
Wire the 195 Clean-Room QUAIDAL controls (from breakpilot-core migration 011)
into the compliance SaaS UI.
Backend:
- GET /api/v1/quaidal/stats - counts by kind + source provenance
- GET /api/v1/quaidal/controls - list, optional kind= filter
- GET /api/v1/quaidal/controls/{id} - single derived control
- GET /api/v1/quaidal/criteria - 10 QKB criteria
- GET /api/v1/quaidal/criteria/{id} - QKB with QB/MA/QM tree
Frontend:
- /sdk/quality: new "Trainingsdaten-Qualität (BSI QUAIDAL)" tab with
10 QKB cards and a drill-down modal showing the full QB→MA→QM tree
plus original BSI source link and license note.
- /sdk/ai-act: Art. 10 tile on each high-risk/unacceptable result,
linking to /sdk/quality?category=data_quality.
Pattern matches existing IACE module DIN-reference handling:
own wording, source section + URL preserved for due diligence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
26 lines
930 B
TypeScript
26 lines
930 B
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
const BACKEND_URL = process.env.BACKEND_URL || 'http://backend-compliance:8002'
|
|
|
|
function tenantHeader(request: NextRequest): string {
|
|
return request.headers.get('x-tenant-id') || '00000000-0000-0000-0000-000000000001'
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const { searchParams } = new URL(request.url)
|
|
const qs = searchParams.toString()
|
|
try {
|
|
const resp = await fetch(
|
|
`${BACKEND_URL}/api/v1/quaidal/controls${qs ? `?${qs}` : ''}`,
|
|
{ headers: { 'X-Tenant-ID': tenantHeader(request) }, cache: 'no-store' }
|
|
)
|
|
const body = await resp.text()
|
|
return new NextResponse(body, {
|
|
status: resp.status,
|
|
headers: { 'Content-Type': resp.headers.get('Content-Type') || 'application/json' },
|
|
})
|
|
} catch (err) {
|
|
return NextResponse.json({ error: 'Backend unreachable', details: String(err) }, { status: 502 })
|
|
}
|
|
}
|