/** * Datapoint Helpers — Validation Functions * * Document validation checks for DSGVO compliance. */ import { DataPoint, LocalizedText, SupportedLanguage, } from '@/lib/sdk/einwilligungen/types' import type { Language } from './datapoint-generators' // ============================================================================= // TYPES // ============================================================================= export interface ValidationWarning { type: 'error' | 'warning' | 'info' code: string message: string suggestion: string affectedDataPoints?: DataPoint[] } // ============================================================================= // VALIDATION FUNCTIONS // ============================================================================= export function checkSpecialCategoriesWarning( dataPoints: DataPoint[], documentContent: string, lang: Language = 'de' ): ValidationWarning | null { const specialCategories = dataPoints.filter(dp => dp.isSpecialCategory) if (specialCategories.length === 0) return null const hasSection = lang === 'de' ? documentContent.includes('Art. 9') || documentContent.includes('Artikel 9') || documentContent.includes('besondere Kategorie') : documentContent.includes('Art. 9') || documentContent.includes('Article 9') || documentContent.includes('special categor') if (!hasSection) { return { type: 'error', code: 'MISSING_ART9_SECTION', message: lang === 'de' ? `${specialCategories.length} besondere Datenkategorien (Art. 9 DSGVO) ausgewaehlt, aber kein entsprechender Abschnitt im Dokument gefunden.` : `${specialCategories.length} special data categories (Art. 9 GDPR) selected, but no corresponding section found in document.`, suggestion: lang === 'de' ? 'Fuegen Sie einen Abschnitt zu besonderen Kategorien personenbezogener Daten hinzu oder verwenden Sie [BESONDERE_KATEGORIEN] als Platzhalter.' : 'Add a section about special categories of personal data or use [BESONDERE_KATEGORIEN] as placeholder.', affectedDataPoints: specialCategories } } return null } export function checkThirdCountryWarning( dataPoints: DataPoint[], documentContent: string, lang: Language = 'de' ): ValidationWarning | null { const thirdCountryIndicators = ['Google', 'AWS', 'Microsoft', 'Meta', 'Facebook', 'Cloudflare', 'USA', 'US'] const thirdCountryPoints = dataPoints.filter(dp => dp.thirdPartyRecipients?.some(r => thirdCountryIndicators.some(i => r.toLowerCase().includes(i.toLowerCase())) ) ) if (thirdCountryPoints.length === 0) return null const hasSCCMention = lang === 'de' ? documentContent.includes('Standardvertragsklauseln') || documentContent.includes('SCC') || documentContent.includes('Art. 46') : documentContent.includes('Standard Contractual Clauses') || documentContent.includes('SCC') || documentContent.includes('Art. 46') if (!hasSCCMention) { return { type: 'warning', code: 'MISSING_SCC_SECTION', message: lang === 'de' ? `Drittland-Uebermittlung fuer ${thirdCountryPoints.length} Datenpunkte erkannt, aber keine Standardvertragsklauseln (SCC) erwaehnt.` : `Third country transfer detected for ${thirdCountryPoints.length} data points, but no Standard Contractual Clauses (SCC) mentioned.`, suggestion: lang === 'de' ? 'Erwaegen Sie die Aufnahme eines Abschnitts zu Drittland-Uebermittlungen und Standardvertragsklauseln oder verwenden Sie [DRITTLAND_TRANSFERS] als Platzhalter.' : 'Consider adding a section about third country transfers and Standard Contractual Clauses or use [DRITTLAND_TRANSFERS] as placeholder.', affectedDataPoints: thirdCountryPoints } } return null } export function checkExplicitConsentWarning( dataPoints: DataPoint[], documentContent: string, lang: Language = 'de' ): ValidationWarning | null { const explicitConsentPoints = dataPoints.filter(dp => dp.requiresExplicitConsent) if (explicitConsentPoints.length === 0) return null const hasConsentSection = lang === 'de' ? documentContent.includes('Einwilligung') || documentContent.includes('Widerruf') || documentContent.includes('Art. 7') : documentContent.includes('consent') || documentContent.includes('withdraw') || documentContent.includes('Art. 7') if (!hasConsentSection) { return { type: 'warning', code: 'MISSING_CONSENT_SECTION', message: lang === 'de' ? `${explicitConsentPoints.length} Datenpunkte erfordern ausdrueckliche Einwilligung, aber kein Abschnitt zu Einwilligung/Widerruf gefunden.` : `${explicitConsentPoints.length} data points require explicit consent, but no section about consent/withdrawal found.`, suggestion: lang === 'de' ? 'Fuegen Sie einen Abschnitt zum Widerrufsrecht hinzu.' : 'Add a section about the right to withdraw consent.', affectedDataPoints: explicitConsentPoints } } return null } export function validateDocument( dataPoints: DataPoint[], documentContent: string, lang: Language = 'de' ): ValidationWarning[] { const warnings: ValidationWarning[] = [] const specialCatWarning = checkSpecialCategoriesWarning(dataPoints, documentContent, lang) if (specialCatWarning) warnings.push(specialCatWarning) const thirdCountryWarning = checkThirdCountryWarning(dataPoints, documentContent, lang) if (thirdCountryWarning) warnings.push(thirdCountryWarning) const consentWarning = checkExplicitConsentWarning(dataPoints, documentContent, lang) if (consentWarning) warnings.push(consentWarning) return warnings }