import { NextRequest, NextResponse } from 'next/server' // Types interface ExtractedSection { title: string content: string type?: string } interface ExtractedContent { title?: string version?: string lastModified?: string sections?: ExtractedSection[] metadata?: Record } interface UploadResponse { success: boolean documentId: string filename: string documentType: string extractedVersion?: string extractedContent?: ExtractedContent suggestedNextVersion?: string } // Helper: Detect version from filename function detectVersionFromFilename(filename: string): string | undefined { const patterns = [ /[vV](\d+(?:\.\d+)*)/, /version[_-]?(\d+(?:\.\d+)*)/i, /[_-]v?(\d+\.\d+(?:\.\d+)?)[_-]/, ] for (const pattern of patterns) { const match = filename.match(pattern) if (match) { return match[1] } } return undefined } // Helper: Suggest next version function suggestNextVersion(currentVersion?: string): string { if (!currentVersion) return '1.0' const parts = currentVersion.split('.').map(Number) if (parts.length >= 2) { parts[parts.length - 1] += 1 } else { parts.push(1) } return parts.join('.') } // Helper: Extract content from PDF/DOCX (simplified - would need proper libraries in production) async function extractDocumentContent( _file: File, documentType: string ): Promise { // In production, this would use libraries like: // - pdf-parse for PDFs // - mammoth for DOCX // For now, return mock extracted content based on document type const mockContentByType: Record = { tom: { title: 'Technische und Organisatorische Maßnahmen', sections: [ { title: 'Vertraulichkeit', content: 'Zugangskontrollen, Zugriffsbeschränkungen...', type: 'category' }, { title: 'Integrität', content: 'Eingabekontrollen, Änderungsprotokolle...', type: 'category' }, { title: 'Verfügbarkeit', content: 'Backup-Strategien, Disaster Recovery...', type: 'category' }, { title: 'Belastbarkeit', content: 'Redundanz, Lasttests...', type: 'category' }, ], metadata: { lastReview: new Date().toISOString(), responsible: 'Datenschutzbeauftragter', }, }, dsfa: { title: 'Datenschutz-Folgenabschätzung', sections: [ { title: 'Beschreibung der Verarbeitung', content: 'Systematische Beschreibung...', type: 'section' }, { title: 'Erforderlichkeit und Verhältnismäßigkeit', content: 'Bewertung...', type: 'section' }, { title: 'Risiken für Betroffene', content: 'Risikoanalyse...', type: 'section' }, { title: 'Abhilfemaßnahmen', content: 'Geplante Maßnahmen...', type: 'section' }, ], }, vvt: { title: 'Verzeichnis von Verarbeitungstätigkeiten', sections: [ { title: 'Verantwortlicher', content: 'Name und Kontaktdaten...', type: 'field' }, { title: 'Verarbeitungszwecke', content: 'Liste der Zwecke...', type: 'list' }, { title: 'Datenkategorien', content: 'Personenbezogene Daten...', type: 'list' }, { title: 'Empfängerkategorien', content: 'Interne und externe Empfänger...', type: 'list' }, ], }, loeschfristen: { title: 'Löschkonzept und Aufbewahrungsfristen', sections: [ { title: 'Personalakten', content: '10 Jahre nach Ausscheiden', type: 'retention' }, { title: 'Kundendaten', content: '3 Jahre nach letzter Aktivität', type: 'retention' }, { title: 'Buchhaltungsbelege', content: '10 Jahre (HGB)', type: 'retention' }, { title: 'Bewerbungsunterlagen', content: '6 Monate nach Absage', type: 'retention' }, ], }, consent: { title: 'Einwilligungserklärungen', sections: [ { title: 'Newsletter-Einwilligung', content: 'Vorlage für Newsletter...', type: 'template' }, { title: 'Marketing-Einwilligung', content: 'Vorlage für Marketing...', type: 'template' }, ], }, policy: { title: 'Datenschutzrichtlinie', sections: [ { title: 'Geltungsbereich', content: 'Diese Richtlinie gilt für...', type: 'section' }, { title: 'Verantwortlichkeiten', content: 'Rollen und Pflichten...', type: 'section' }, ], }, } return mockContentByType[documentType] || { title: 'Unbekanntes Dokument', sections: [], } } export async function POST(request: NextRequest) { try { const formData = await request.formData() const file = formData.get('file') as File | null const documentType = formData.get('documentType') as string || 'custom' const sessionId = formData.get('sessionId') as string || 'default' if (!file) { return NextResponse.json( { error: 'Keine Datei hochgeladen' }, { status: 400 } ) } // Validate file type const allowedTypes = [ 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/msword', ] if (!allowedTypes.includes(file.type)) { return NextResponse.json( { error: 'Ungültiger Dateityp. Erlaubt: PDF, DOCX, DOC' }, { status: 400 } ) } // Generate document ID const documentId = `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` // Extract version from filename const extractedVersion = detectVersionFromFilename(file.name) // Extract content (in production, this would parse the actual file) const extractedContent = await extractDocumentContent(file, documentType) // Add version to extracted content if found if (extractedVersion) { extractedContent.version = extractedVersion } // Store file (in production, save to MinIO/S3) // For now, we just process and return metadata console.log(`[SDK Documents] Uploaded: ${file.name} (${file.size} bytes) for session ${sessionId}`) const response: UploadResponse = { success: true, documentId, filename: file.name, documentType, extractedVersion, extractedContent, suggestedNextVersion: suggestNextVersion(extractedVersion), } return NextResponse.json(response) } catch (error) { console.error('[SDK Documents] Upload error:', error) return NextResponse.json( { error: 'Upload fehlgeschlagen' }, { status: 500 } ) } } export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) const sessionId = searchParams.get('sessionId') if (!sessionId) { return NextResponse.json( { error: 'Session ID erforderlich' }, { status: 400 } ) } // In production, fetch uploaded documents from storage // For now, return empty list return NextResponse.json({ uploads: [], sessionId, }) }