feat(audit-report): deterministischer Textreport je Audit (MD + PDF) + Bericht-Tab
Firmen-tauglicher Bericht aus den Snapshot-Modulergebnissen (kein Re-Crawl, kein LLM): Einleitung, Testumfang+Methodik, Management-Summary (4-Status), Detail- befunde je Modul, Maßnahmen, Rechtlicher Hinweis. Co-Pilot-Tonalität, Tracking- statt Cookie-Rohzahl, Norm nur referenziert (kein Normtext). - audit_report.py: assemble_report (pur) + render_markdown + render_pdf (reportlab) - snapshot_check_routes: GET /report (struktur+md) + GET /report.pdf - Frontend: AuditReportTab + Proxys (report, report/pdf) + "Bericht"-Tab - Tests: 5 Assembler (compliance/tests → CI-geprüft) + 1 Vitest Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Audit-Report PDF — Proxy (streamt die PDF-Bytes durch)
|
||||
* GET /api/sdk/v1/agent/snapshots/{snapshotId}/report/pdf
|
||||
* → backend /api/compliance/agent/snapshots/{snapshotId}/report.pdf
|
||||
*/
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL =
|
||||
process.env.BACKEND_API_URL || process.env.BACKEND_URL ||
|
||||
'http://backend-compliance:8002'
|
||||
|
||||
export async function GET(
|
||||
_request: NextRequest,
|
||||
{ params }: { params: Promise<{ snapshotId: string }> },
|
||||
) {
|
||||
const { snapshotId } = await params
|
||||
try {
|
||||
const res = await fetch(
|
||||
`${BACKEND_URL}/api/compliance/agent/snapshots/${snapshotId}/report.pdf`,
|
||||
{ signal: AbortSignal.timeout(120_000) },
|
||||
)
|
||||
if (!res.ok) {
|
||||
return NextResponse.json(
|
||||
{ error: `PDF fehlgeschlagen (${res.status})` }, { status: res.status })
|
||||
}
|
||||
const buf = await res.arrayBuffer()
|
||||
return new NextResponse(buf, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/pdf',
|
||||
'Content-Disposition':
|
||||
res.headers.get('content-disposition') ||
|
||||
'attachment; filename="audit-report.pdf"',
|
||||
},
|
||||
})
|
||||
} catch {
|
||||
return NextResponse.json({ error: 'PDF fehlgeschlagen' }, { status: 503 })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Audit-Report (strukturiert + Markdown) — Proxy
|
||||
* GET /api/sdk/v1/agent/snapshots/{snapshotId}/report
|
||||
* → backend /api/compliance/agent/snapshots/{snapshotId}/report
|
||||
*/
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL =
|
||||
process.env.BACKEND_API_URL || process.env.BACKEND_URL ||
|
||||
'http://backend-compliance:8002'
|
||||
|
||||
export async function GET(
|
||||
_request: NextRequest,
|
||||
{ params }: { params: Promise<{ snapshotId: string }> },
|
||||
) {
|
||||
const { snapshotId } = await params
|
||||
try {
|
||||
const res = await fetch(
|
||||
`${BACKEND_URL}/api/compliance/agent/snapshots/${snapshotId}/report`,
|
||||
{ signal: AbortSignal.timeout(120_000) },
|
||||
)
|
||||
const data = await res.json()
|
||||
return NextResponse.json(data, { status: res.status })
|
||||
} catch {
|
||||
return NextResponse.json(
|
||||
{ error: 'Report-Erzeugung fehlgeschlagen' }, { status: 503 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user