fix(admin-v2): Restore complete admin-v2 application
The admin-v2 application was incomplete in the repository. This commit restores all missing components: - Admin pages (76 pages): dashboard, ai, compliance, dsgvo, education, infrastructure, communication, development, onboarding, rbac - SDK pages (45 pages): tom, dsfa, vvt, loeschfristen, einwilligungen, vendor-compliance, tom-generator, dsr, and more - Developer portal (25 pages): API docs, SDK guides, frameworks - All components, lib files, hooks, and types - Updated package.json with all dependencies The issue was caused by incomplete initial repository state - the full admin-v2 codebase existed in backend/admin-v2 and docs-src/admin-v2 but was never fully synced to the main admin-v2 directory. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
548
admin-v2/lib/sdk/document-generator/datapoint-helpers.ts
Normal file
548
admin-v2/lib/sdk/document-generator/datapoint-helpers.ts
Normal file
@@ -0,0 +1,548 @@
|
||||
/**
|
||||
* Helper-Funktionen für die Integration von Einwilligungen-Datenpunkten
|
||||
* in den Dokumentengenerator.
|
||||
*
|
||||
* Diese Funktionen generieren DSGVO-konforme Textbausteine basierend auf
|
||||
* den vom Benutzer ausgewählten Datenpunkten.
|
||||
*/
|
||||
|
||||
import {
|
||||
DataPoint,
|
||||
DataPointCategory,
|
||||
LegalBasis,
|
||||
RetentionPeriod,
|
||||
RiskLevel,
|
||||
CATEGORY_METADATA,
|
||||
LEGAL_BASIS_INFO,
|
||||
RETENTION_PERIOD_INFO,
|
||||
RISK_LEVEL_STYLING,
|
||||
LocalizedText,
|
||||
SupportedLanguage
|
||||
} from '@/lib/sdk/einwilligungen/types'
|
||||
|
||||
// =============================================================================
|
||||
// TYPES
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Sprach-Option für alle Helper-Funktionen
|
||||
*/
|
||||
export type Language = SupportedLanguage
|
||||
|
||||
/**
|
||||
* Generierte Platzhalter-Map für den Dokumentengenerator
|
||||
*/
|
||||
export interface DataPointPlaceholders {
|
||||
'[DATENPUNKTE_COUNT]': string
|
||||
'[DATENPUNKTE_LIST]': string
|
||||
'[DATENPUNKTE_TABLE]': string
|
||||
'[VERARBEITUNGSZWECKE]': string
|
||||
'[RECHTSGRUNDLAGEN]': string
|
||||
'[SPEICHERFRISTEN]': string
|
||||
'[EMPFAENGER]': string
|
||||
'[BESONDERE_KATEGORIEN]': string
|
||||
'[DRITTLAND_TRANSFERS]': string
|
||||
'[RISIKO_ZUSAMMENFASSUNG]': string
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// HELPER FUNCTIONS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Extrahiert Text aus LocalizedText basierend auf Sprache
|
||||
*/
|
||||
function getText(text: LocalizedText, lang: Language): string {
|
||||
return text[lang] || text.de
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert eine Markdown-Tabelle der Datenpunkte
|
||||
*
|
||||
* @param dataPoints - Liste der ausgewählten Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Markdown-Tabelle als String
|
||||
*/
|
||||
export function generateDataPointsTable(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
if (dataPoints.length === 0) {
|
||||
return lang === 'de'
|
||||
? '*Keine Datenpunkte ausgewählt.*'
|
||||
: '*No data points selected.*'
|
||||
}
|
||||
|
||||
const header = lang === 'de'
|
||||
? '| Datenpunkt | Kategorie | Zweck | Rechtsgrundlage | Speicherfrist |'
|
||||
: '| Data Point | Category | Purpose | Legal Basis | Retention Period |'
|
||||
const separator = '|------------|-----------|-------|-----------------|---------------|'
|
||||
|
||||
const rows = dataPoints.map(dp => {
|
||||
const category = CATEGORY_METADATA[dp.category]
|
||||
const legalBasis = LEGAL_BASIS_INFO[dp.legalBasis]
|
||||
const retention = RETENTION_PERIOD_INFO[dp.retentionPeriod]
|
||||
|
||||
const name = getText(dp.name, lang)
|
||||
const categoryName = getText(category.name, lang)
|
||||
const purpose = getText(dp.purpose, lang)
|
||||
const legalBasisName = getText(legalBasis.name, lang)
|
||||
const retentionLabel = getText(retention.label, lang)
|
||||
|
||||
// Truncate long texts for table readability
|
||||
const truncatedPurpose = purpose.length > 50 ? purpose.slice(0, 47) + '...' : purpose
|
||||
|
||||
return `| ${name} | ${categoryName} | ${truncatedPurpose} | ${legalBasisName} | ${retentionLabel} |`
|
||||
}).join('\n')
|
||||
|
||||
return `${header}\n${separator}\n${rows}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gruppiert Datenpunkte nach Speicherfrist
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @returns Record mit Speicherfrist als Key und Datenpunkten als Value
|
||||
*/
|
||||
export function groupByRetention(
|
||||
dataPoints: DataPoint[]
|
||||
): Record<RetentionPeriod, DataPoint[]> {
|
||||
return dataPoints.reduce((acc, dp) => {
|
||||
const key = dp.retentionPeriod
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(dp)
|
||||
return acc
|
||||
}, {} as Record<RetentionPeriod, DataPoint[]>)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gruppiert Datenpunkte nach Kategorie
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @returns Record mit Kategorie als Key und Datenpunkten als Value
|
||||
*/
|
||||
export function groupByCategory(
|
||||
dataPoints: DataPoint[]
|
||||
): Record<DataPointCategory, DataPoint[]> {
|
||||
return dataPoints.reduce((acc, dp) => {
|
||||
const key = dp.category
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(dp)
|
||||
return acc
|
||||
}, {} as Record<DataPointCategory, DataPoint[]>)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert DSGVO-konformen Abschnitt für besondere Kategorien (Art. 9 DSGVO)
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Markdown-Abschnitt als String (leer wenn keine Art. 9 Daten)
|
||||
*/
|
||||
export function generateSpecialCategorySection(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
const special = dataPoints.filter(dp => dp.isSpecialCategory)
|
||||
|
||||
if (special.length === 0) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (lang === 'de') {
|
||||
const items = special.map(dp =>
|
||||
`- **${getText(dp.name, lang)}**: ${getText(dp.description, lang)}`
|
||||
).join('\n')
|
||||
|
||||
return `## Verarbeitung besonderer Kategorien personenbezogener Daten (Art. 9 DSGVO)
|
||||
|
||||
Wir verarbeiten folgende besondere Kategorien personenbezogener Daten:
|
||||
|
||||
${items}
|
||||
|
||||
Die Verarbeitung erfolgt auf Grundlage Ihrer ausdrücklichen Einwilligung gemäß Art. 9 Abs. 2 lit. a DSGVO. Sie können Ihre Einwilligung jederzeit mit Wirkung für die Zukunft widerrufen.`
|
||||
} else {
|
||||
const items = special.map(dp =>
|
||||
`- **${getText(dp.name, lang)}**: ${getText(dp.description, lang)}`
|
||||
).join('\n')
|
||||
|
||||
return `## Processing of Special Categories of Personal Data (Art. 9 GDPR)
|
||||
|
||||
We process the following special categories of personal data:
|
||||
|
||||
${items}
|
||||
|
||||
Processing is based on your explicit consent pursuant to Art. 9(2)(a) GDPR. You may withdraw your consent at any time with effect for the future.`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Liste aller eindeutigen Verarbeitungszwecke
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Kommaseparierte Liste der Zwecke
|
||||
*/
|
||||
export function generatePurposesList(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
const purposes = new Set<string>()
|
||||
|
||||
dataPoints.forEach(dp => {
|
||||
purposes.add(getText(dp.purpose, lang))
|
||||
})
|
||||
|
||||
return [...purposes].join(', ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Liste aller verwendeten Rechtsgrundlagen
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Formatierte Liste der Rechtsgrundlagen
|
||||
*/
|
||||
export function generateLegalBasisList(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
const bases = new Set<LegalBasis>()
|
||||
|
||||
dataPoints.forEach(dp => {
|
||||
bases.add(dp.legalBasis)
|
||||
})
|
||||
|
||||
return [...bases].map(basis => {
|
||||
const info = LEGAL_BASIS_INFO[basis]
|
||||
return `${info.article} (${getText(info.name, lang)})`
|
||||
}).join(', ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Liste aller Speicherfristen gruppiert
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Formatierte Liste der Speicherfristen mit zugehörigen Kategorien
|
||||
*/
|
||||
export function generateRetentionList(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
const grouped = groupByRetention(dataPoints)
|
||||
const entries: string[] = []
|
||||
|
||||
for (const [period, points] of Object.entries(grouped)) {
|
||||
const retentionInfo = RETENTION_PERIOD_INFO[period as RetentionPeriod]
|
||||
const categories = [...new Set(points.map(p => getText(CATEGORY_METADATA[p.category].name, lang)))]
|
||||
|
||||
entries.push(`${getText(retentionInfo.label, lang)}: ${categories.join(', ')}`)
|
||||
}
|
||||
|
||||
return entries.join('; ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Liste aller Empfänger/Drittparteien
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @returns Kommaseparierte Liste der Empfänger
|
||||
*/
|
||||
export function generateRecipientsList(dataPoints: DataPoint[]): string {
|
||||
const recipients = new Set<string>()
|
||||
|
||||
dataPoints.forEach(dp => {
|
||||
dp.thirdPartyRecipients?.forEach(r => recipients.add(r))
|
||||
})
|
||||
|
||||
if (recipients.size === 0) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return [...recipients].join(', ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Abschnitt für Drittland-Übermittlungen
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte mit thirdCountryTransfer === true
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Markdown-Abschnitt als String
|
||||
*/
|
||||
export function generateThirdCountrySection(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
// Note: We assume dataPoints have been filtered for thirdCountryTransfer
|
||||
// The actual flag would need to be added to the DataPoint interface
|
||||
// For now, we check if any thirdPartyRecipients suggest third country
|
||||
const thirdCountryIndicators = ['Google', 'AWS', 'Microsoft', 'Meta', 'Facebook', 'Cloudflare']
|
||||
|
||||
const thirdCountryPoints = dataPoints.filter(dp =>
|
||||
dp.thirdPartyRecipients?.some(r =>
|
||||
thirdCountryIndicators.some(indicator =>
|
||||
r.toLowerCase().includes(indicator.toLowerCase())
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if (thirdCountryPoints.length === 0) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const recipients = new Set<string>()
|
||||
thirdCountryPoints.forEach(dp => {
|
||||
dp.thirdPartyRecipients?.forEach(r => {
|
||||
if (thirdCountryIndicators.some(i => r.toLowerCase().includes(i.toLowerCase()))) {
|
||||
recipients.add(r)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (lang === 'de') {
|
||||
return `## Übermittlung in Drittländer
|
||||
|
||||
Wir übermitteln personenbezogene Daten an folgende Empfänger in Drittländern (außerhalb der EU/des EWR):
|
||||
|
||||
${[...recipients].map(r => `- ${r}`).join('\n')}
|
||||
|
||||
Die Übermittlung erfolgt auf Grundlage von Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO) bzw. einem Angemessenheitsbeschluss der EU-Kommission (Art. 45 DSGVO).`
|
||||
} else {
|
||||
return `## Transfers to Third Countries
|
||||
|
||||
We transfer personal data to the following recipients in third countries (outside the EU/EEA):
|
||||
|
||||
${[...recipients].map(r => `- ${r}`).join('\n')}
|
||||
|
||||
The transfer is based on Standard Contractual Clauses (Art. 46(2)(c) GDPR) or an adequacy decision by the EU Commission (Art. 45 GDPR).`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert Risiko-Zusammenfassung
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Formatierte Risiko-Zusammenfassung
|
||||
*/
|
||||
export function generateRiskSummary(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): string {
|
||||
const riskCounts: Record<RiskLevel, number> = {
|
||||
LOW: 0,
|
||||
MEDIUM: 0,
|
||||
HIGH: 0
|
||||
}
|
||||
|
||||
dataPoints.forEach(dp => {
|
||||
riskCounts[dp.riskLevel]++
|
||||
})
|
||||
|
||||
const parts = Object.entries(riskCounts)
|
||||
.filter(([, count]) => count > 0)
|
||||
.map(([level, count]) => {
|
||||
const styling = RISK_LEVEL_STYLING[level as RiskLevel]
|
||||
return `${count} ${getText(styling.label, lang).toLowerCase()}`
|
||||
})
|
||||
|
||||
return parts.join(', ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert alle Platzhalter für den Dokumentengenerator
|
||||
*
|
||||
* @param dataPoints - Liste der ausgewählten Datenpunkte
|
||||
* @param lang - Sprache für die Ausgabe
|
||||
* @returns Objekt mit allen Platzhaltern
|
||||
*/
|
||||
export function generateAllPlaceholders(
|
||||
dataPoints: DataPoint[],
|
||||
lang: Language = 'de'
|
||||
): DataPointPlaceholders {
|
||||
return {
|
||||
'[DATENPUNKTE_COUNT]': String(dataPoints.length),
|
||||
'[DATENPUNKTE_LIST]': dataPoints.map(dp => getText(dp.name, lang)).join(', '),
|
||||
'[DATENPUNKTE_TABLE]': generateDataPointsTable(dataPoints, lang),
|
||||
'[VERARBEITUNGSZWECKE]': generatePurposesList(dataPoints, lang),
|
||||
'[RECHTSGRUNDLAGEN]': generateLegalBasisList(dataPoints, lang),
|
||||
'[SPEICHERFRISTEN]': generateRetentionList(dataPoints, lang),
|
||||
'[EMPFAENGER]': generateRecipientsList(dataPoints),
|
||||
'[BESONDERE_KATEGORIEN]': generateSpecialCategorySection(dataPoints, lang),
|
||||
'[DRITTLAND_TRANSFERS]': generateThirdCountrySection(dataPoints, lang),
|
||||
'[RISIKO_ZUSAMMENFASSUNG]': generateRiskSummary(dataPoints, lang)
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// VALIDATION HELPERS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Validierungswarnung für den Dokumentengenerator
|
||||
*/
|
||||
export interface ValidationWarning {
|
||||
type: 'error' | 'warning' | 'info'
|
||||
code: string
|
||||
message: string
|
||||
suggestion: string
|
||||
affectedDataPoints?: DataPoint[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob besondere Kategorien vorhanden sind aber kein entsprechender Abschnitt
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param documentContent - Der generierte Dokumentinhalt
|
||||
* @param lang - Sprache
|
||||
* @returns ValidationWarning oder null
|
||||
*/
|
||||
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) ausgewählt, 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'
|
||||
? 'Fügen 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob Drittland-Übermittlungen vorhanden sind aber keine SCC erwähnt werden
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param documentContent - Der generierte Dokumentinhalt
|
||||
* @param lang - Sprache
|
||||
* @returns ValidationWarning oder 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-Übermittlung für ${thirdCountryPoints.length} Datenpunkte erkannt, aber keine Standardvertragsklauseln (SCC) erwähnt.`
|
||||
: `Third country transfer detected for ${thirdCountryPoints.length} data points, but no Standard Contractual Clauses (SCC) mentioned.`,
|
||||
suggestion: lang === 'de'
|
||||
? 'Erwägen Sie die Aufnahme eines Abschnitts zu Drittland-Übermittlungen 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob Datenpunkte mit expliziter Einwilligung korrekt behandelt werden
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param documentContent - Der generierte Dokumentinhalt
|
||||
* @param lang - Sprache
|
||||
* @returns ValidationWarning oder 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 ausdrückliche 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'
|
||||
? 'Fügen Sie einen Abschnitt zum Widerrufsrecht hinzu.'
|
||||
: 'Add a section about the right to withdraw consent.',
|
||||
affectedDataPoints: explicitConsentPoints
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt alle Validierungsprüfungen durch
|
||||
*
|
||||
* @param dataPoints - Liste der Datenpunkte
|
||||
* @param documentContent - Der generierte Dokumentinhalt
|
||||
* @param lang - Sprache
|
||||
* @returns Array aller Warnungen
|
||||
*/
|
||||
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
|
||||
}
|
||||
8
admin-v2/lib/sdk/document-generator/index.ts
Normal file
8
admin-v2/lib/sdk/document-generator/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Document Generator Library
|
||||
*
|
||||
* Helper-Funktionen für die Integration von Einwilligungen-Datenpunkten
|
||||
* in den Dokumentengenerator.
|
||||
*/
|
||||
|
||||
export * from './datapoint-helpers'
|
||||
Reference in New Issue
Block a user