Initial commit: breakpilot-compliance - Compliance SDK Platform

Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Boenisch
2026-02-11 23:47:28 +01:00
commit 4435e7ea0a
734 changed files with 251369 additions and 0 deletions

View File

@@ -0,0 +1,197 @@
import { NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import {
Finding,
CONTRACT_REVIEW_SYSTEM_PROMPT,
} from '@/lib/sdk/vendor-compliance'
/**
* POST /api/sdk/v1/vendor-compliance/contracts/[id]/review
*
* Starts the LLM-based contract review process
*/
export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id: contractId } = await params
// In production:
// 1. Fetch contract from database
// 2. Extract text from PDF/DOCX using embedding-service
// 3. Send to LLM for analysis
// 4. Store findings in database
// 5. Update contract with compliance score
// For demo, return mock analysis results
const mockFindings: Finding[] = [
{
id: uuidv4(),
tenantId: 'default',
contractId,
vendorId: 'mock-vendor',
type: 'OK',
category: 'AVV_CONTENT',
severity: 'LOW',
title: {
de: 'Weisungsgebundenheit vorhanden',
en: 'Instruction binding present',
},
description: {
de: 'Der Vertrag enthält eine angemessene Regelung zur Weisungsgebundenheit des Auftragsverarbeiters.',
en: 'The contract contains an appropriate provision for processor instruction binding.',
},
citations: [
{
documentId: contractId,
page: 2,
startChar: 150,
endChar: 350,
quotedText: 'Der Auftragnehmer verarbeitet personenbezogene Daten ausschließlich auf dokumentierte Weisung des Auftraggebers.',
quoteHash: 'abc123',
},
],
affectedRequirement: 'Art. 28 Abs. 3 lit. a DSGVO',
triggeredControls: ['VND-CON-01'],
status: 'OPEN',
createdAt: new Date(),
updatedAt: new Date(),
},
{
id: uuidv4(),
tenantId: 'default',
contractId,
vendorId: 'mock-vendor',
type: 'GAP',
category: 'INCIDENT',
severity: 'HIGH',
title: {
de: 'Meldefrist für Datenpannen zu lang',
en: 'Data breach notification deadline too long',
},
description: {
de: 'Die vereinbarte Meldefrist von 72 Stunden ist zu lang, um die eigene Meldepflicht gegenüber der Aufsichtsbehörde fristgerecht erfüllen zu können.',
en: 'The agreed notification deadline of 72 hours is too long to meet own notification obligations to the supervisory authority in time.',
},
recommendation: {
de: 'Verhandeln Sie eine kürzere Meldefrist von maximal 24-48 Stunden.',
en: 'Negotiate a shorter notification deadline of maximum 24-48 hours.',
},
citations: [
{
documentId: contractId,
page: 5,
startChar: 820,
endChar: 950,
quotedText: 'Der Auftragnehmer wird den Auftraggeber innerhalb von 72 Stunden über eine Verletzung des Schutzes personenbezogener Daten informieren.',
quoteHash: 'def456',
},
],
affectedRequirement: 'Art. 33 Abs. 2 DSGVO',
triggeredControls: ['VND-INC-01'],
status: 'OPEN',
createdAt: new Date(),
updatedAt: new Date(),
},
{
id: uuidv4(),
tenantId: 'default',
contractId,
vendorId: 'mock-vendor',
type: 'RISK',
category: 'TRANSFER',
severity: 'MEDIUM',
title: {
de: 'Drittlandtransfer USA ohne TIA',
en: 'Third country transfer to USA without TIA',
},
description: {
de: 'Der Vertrag erlaubt Datenverarbeitung in den USA. Es liegt jedoch kein Transfer Impact Assessment (TIA) vor.',
en: 'The contract allows data processing in the USA. However, no Transfer Impact Assessment (TIA) is available.',
},
recommendation: {
de: 'Führen Sie ein TIA durch und dokumentieren Sie zusätzliche Schutzmaßnahmen.',
en: 'Conduct a TIA and document supplementary measures.',
},
citations: [
{
documentId: contractId,
page: 8,
startChar: 1200,
endChar: 1350,
quotedText: 'Die Verarbeitung kann auch in Rechenzentren in den Vereinigten Staaten von Amerika erfolgen.',
quoteHash: 'ghi789',
},
],
affectedRequirement: 'Art. 44-49 DSGVO, Schrems II',
triggeredControls: ['VND-TRF-01', 'VND-TRF-03'],
status: 'OPEN',
createdAt: new Date(),
updatedAt: new Date(),
},
]
// Calculate compliance score based on findings
const okFindings = mockFindings.filter((f) => f.type === 'OK').length
const totalChecks = mockFindings.length + 5 // Assume 5 additional checks passed
const complianceScore = Math.round((okFindings / totalChecks) * 100 + 60) // Base score + passed checks
return NextResponse.json({
success: true,
data: {
contractId,
findings: mockFindings,
complianceScore: Math.min(100, complianceScore),
reviewCompletedAt: new Date().toISOString(),
topRisks: [
{ de: 'Meldefrist für Datenpannen zu lang', en: 'Data breach notification deadline too long' },
{ de: 'Fehlende TIA für USA-Transfer', en: 'Missing TIA for USA transfer' },
],
requiredActions: [
{ de: 'Meldefrist auf 24-48h verkürzen', en: 'Reduce notification deadline to 24-48h' },
{ de: 'TIA für USA-Transfer durchführen', en: 'Conduct TIA for USA transfer' },
],
},
timestamp: new Date().toISOString(),
})
} catch (error) {
console.error('Error reviewing contract:', error)
return NextResponse.json(
{ success: false, error: 'Failed to review contract' },
{ status: 500 }
)
}
}
/**
* GET /api/sdk/v1/vendor-compliance/contracts/[id]/review
*
* Get existing review results
*/
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id: contractId } = await params
// In production, fetch from database
return NextResponse.json({
success: true,
data: {
contractId,
findings: [],
complianceScore: null,
reviewStatus: 'PENDING',
},
timestamp: new Date().toISOString(),
})
} catch (error) {
console.error('Error fetching review:', error)
return NextResponse.json(
{ success: false, error: 'Failed to fetch review' },
{ status: 500 }
)
}
}

View File

@@ -0,0 +1,88 @@
import { NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { ContractDocument } from '@/lib/sdk/vendor-compliance'
// In-memory storage for demo purposes
const contracts: Map<string, ContractDocument> = new Map()
export async function GET(request: NextRequest) {
try {
const contractList = Array.from(contracts.values())
return NextResponse.json({
success: true,
data: contractList,
timestamp: new Date().toISOString(),
})
} catch (error) {
console.error('Error fetching contracts:', error)
return NextResponse.json(
{ success: false, error: 'Failed to fetch contracts' },
{ status: 500 }
)
}
}
export async function POST(request: NextRequest) {
try {
// Handle multipart form data for file upload
const formData = await request.formData()
const file = formData.get('file') as File | null
const vendorId = formData.get('vendorId') as string
const metadataStr = formData.get('metadata') as string
if (!file || !vendorId) {
return NextResponse.json(
{ success: false, error: 'File and vendorId are required' },
{ status: 400 }
)
}
const metadata = metadataStr ? JSON.parse(metadataStr) : {}
const id = uuidv4()
// In production, upload file to storage (MinIO, S3, etc.)
const storagePath = `contracts/${id}/${file.name}`
const contract: ContractDocument = {
id,
tenantId: 'default',
vendorId,
fileName: `${id}-${file.name}`,
originalName: file.name,
mimeType: file.type,
fileSize: file.size,
storagePath,
documentType: metadata.documentType || 'OTHER',
version: metadata.version || '1.0',
previousVersionId: metadata.previousVersionId,
parties: metadata.parties,
effectiveDate: metadata.effectiveDate ? new Date(metadata.effectiveDate) : undefined,
expirationDate: metadata.expirationDate ? new Date(metadata.expirationDate) : undefined,
autoRenewal: metadata.autoRenewal,
renewalNoticePeriod: metadata.renewalNoticePeriod,
terminationNoticePeriod: metadata.terminationNoticePeriod,
reviewStatus: 'PENDING',
status: 'DRAFT',
createdAt: new Date(),
updatedAt: new Date(),
}
contracts.set(id, contract)
return NextResponse.json(
{
success: true,
data: contract,
timestamp: new Date().toISOString(),
},
{ status: 201 }
)
} catch (error) {
console.error('Error uploading contract:', error)
return NextResponse.json(
{ success: false, error: 'Failed to upload contract' },
{ status: 500 }
)
}
}