Split these files that exceeded the 500-line hard cap: - privacy-policy.ts (965 LOC) -> sections + renderers - academy/api.ts (787 LOC) -> courses + mock-data - whistleblower/api.ts (755 LOC) -> operations + mock-data - vvt-profiling.ts (659 LOC) -> data + logic - cookie-banner.ts (595 LOC) -> config + embed - dsr/types.ts (581 LOC) -> core + api types - tom-generator/rules-engine.ts (560 LOC) -> evaluator + gap-analysis - datapoint-helpers.ts (548 LOC) -> generators + validators Each original file becomes a barrel re-export for backward compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
560 lines
20 KiB
TypeScript
560 lines
20 KiB
TypeScript
/**
|
|
* Privacy Policy Section Generators
|
|
*
|
|
* Generiert die 9 Abschnitte der Datenschutzerklaerung (DSI)
|
|
* aus dem Datenpunktkatalog.
|
|
*/
|
|
|
|
import {
|
|
DataPoint,
|
|
DataPointCategory,
|
|
CompanyInfo,
|
|
PrivacyPolicySection,
|
|
SupportedLanguage,
|
|
LocalizedText,
|
|
RetentionMatrixEntry,
|
|
LegalBasis,
|
|
CATEGORY_METADATA,
|
|
LEGAL_BASIS_INFO,
|
|
RETENTION_PERIOD_INFO,
|
|
} from '../types'
|
|
|
|
// =============================================================================
|
|
// KONSTANTEN
|
|
// =============================================================================
|
|
|
|
const ALL_CATEGORIES: DataPointCategory[] = [
|
|
'MASTER_DATA', 'CONTACT_DATA', 'AUTHENTICATION', 'CONSENT',
|
|
'COMMUNICATION', 'PAYMENT', 'USAGE_DATA', 'LOCATION',
|
|
'DEVICE_DATA', 'MARKETING', 'ANALYTICS', 'SOCIAL_MEDIA',
|
|
'HEALTH_DATA', 'EMPLOYEE_DATA', 'CONTRACT_DATA', 'LOG_DATA',
|
|
'AI_DATA', 'SECURITY',
|
|
]
|
|
|
|
const ALL_LEGAL_BASES: LegalBasis[] = [
|
|
'CONTRACT', 'CONSENT', 'EXPLICIT_CONSENT', 'LEGITIMATE_INTEREST',
|
|
'LEGAL_OBLIGATION', 'VITAL_INTERESTS', 'PUBLIC_INTEREST',
|
|
]
|
|
|
|
// =============================================================================
|
|
// HELPER FUNCTIONS
|
|
// =============================================================================
|
|
|
|
function t(text: LocalizedText, language: SupportedLanguage): string {
|
|
return text[language]
|
|
}
|
|
|
|
function groupByCategory(dataPoints: DataPoint[]): Map<DataPointCategory, DataPoint[]> {
|
|
const grouped = new Map<DataPointCategory, DataPoint[]>()
|
|
for (const dp of dataPoints) {
|
|
const existing = grouped.get(dp.category) || []
|
|
grouped.set(dp.category, [...existing, dp])
|
|
}
|
|
return grouped
|
|
}
|
|
|
|
function groupByLegalBasis(dataPoints: DataPoint[]): Map<LegalBasis, DataPoint[]> {
|
|
const grouped = new Map<LegalBasis, DataPoint[]>()
|
|
for (const dp of dataPoints) {
|
|
const existing = grouped.get(dp.legalBasis) || []
|
|
grouped.set(dp.legalBasis, [...existing, dp])
|
|
}
|
|
return grouped
|
|
}
|
|
|
|
function extractThirdParties(dataPoints: DataPoint[]): string[] {
|
|
const thirdParties = new Set<string>()
|
|
for (const dp of dataPoints) {
|
|
for (const recipient of dp.thirdPartyRecipients) {
|
|
thirdParties.add(recipient)
|
|
}
|
|
}
|
|
return Array.from(thirdParties).sort()
|
|
}
|
|
|
|
export function formatDate(date: Date, language: SupportedLanguage): string {
|
|
return date.toLocaleDateString(language === 'de' ? 'de-DE' : 'en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
})
|
|
}
|
|
|
|
// =============================================================================
|
|
// SECTION GENERATORS
|
|
// =============================================================================
|
|
|
|
export function generateControllerSection(
|
|
companyInfo: CompanyInfo,
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '1. Verantwortlicher',
|
|
en: '1. Data Controller',
|
|
}
|
|
|
|
const dpoSection = companyInfo.dpoName
|
|
? language === 'de'
|
|
? `\n\n**Datenschutzbeauftragter:**\n${companyInfo.dpoName}${companyInfo.dpoEmail ? `\nE-Mail: ${companyInfo.dpoEmail}` : ''}${companyInfo.dpoPhone ? `\nTelefon: ${companyInfo.dpoPhone}` : ''}`
|
|
: `\n\n**Data Protection Officer:**\n${companyInfo.dpoName}${companyInfo.dpoEmail ? `\nEmail: ${companyInfo.dpoEmail}` : ''}${companyInfo.dpoPhone ? `\nPhone: ${companyInfo.dpoPhone}` : ''}`
|
|
: ''
|
|
|
|
const content: LocalizedText = {
|
|
de: `Verantwortlich fuer die Datenverarbeitung auf dieser Website ist:
|
|
|
|
**${companyInfo.name}**
|
|
${companyInfo.address}
|
|
${companyInfo.postalCode} ${companyInfo.city}
|
|
${companyInfo.country}
|
|
|
|
E-Mail: ${companyInfo.email}${companyInfo.phone ? `\nTelefon: ${companyInfo.phone}` : ''}${companyInfo.website ? `\nWebsite: ${companyInfo.website}` : ''}${companyInfo.registrationNumber ? `\n\nHandelsregister: ${companyInfo.registrationNumber}` : ''}${companyInfo.vatId ? `\nUSt-IdNr.: ${companyInfo.vatId}` : ''}${dpoSection}`,
|
|
en: `The controller responsible for data processing on this website is:
|
|
|
|
**${companyInfo.name}**
|
|
${companyInfo.address}
|
|
${companyInfo.postalCode} ${companyInfo.city}
|
|
${companyInfo.country}
|
|
|
|
Email: ${companyInfo.email}${companyInfo.phone ? `\nPhone: ${companyInfo.phone}` : ''}${companyInfo.website ? `\nWebsite: ${companyInfo.website}` : ''}${companyInfo.registrationNumber ? `\n\nCommercial Register: ${companyInfo.registrationNumber}` : ''}${companyInfo.vatId ? `\nVAT ID: ${companyInfo.vatId}` : ''}${dpoSection}`,
|
|
}
|
|
|
|
return {
|
|
id: 'controller',
|
|
order: 1,
|
|
title,
|
|
content,
|
|
dataPointIds: [],
|
|
isRequired: true,
|
|
isGenerated: false,
|
|
}
|
|
}
|
|
|
|
export function generateDataCollectionSection(
|
|
dataPoints: DataPoint[],
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '2. Erhobene personenbezogene Daten',
|
|
en: '2. Personal Data We Collect',
|
|
}
|
|
|
|
const grouped = groupByCategory(dataPoints)
|
|
const sections: string[] = []
|
|
const hasSpecialCategoryData = dataPoints.some(dp => dp.isSpecialCategory || dp.category === 'HEALTH_DATA')
|
|
|
|
for (const category of ALL_CATEGORIES) {
|
|
const categoryData = grouped.get(category)
|
|
if (!categoryData || categoryData.length === 0) continue
|
|
|
|
const categoryMeta = CATEGORY_METADATA[category]
|
|
if (!categoryMeta) continue
|
|
|
|
const categoryTitle = t(categoryMeta.name, language)
|
|
|
|
let categoryNote = ''
|
|
if (category === 'HEALTH_DATA') {
|
|
categoryNote = language === 'de'
|
|
? `\n\n> **Hinweis:** Diese Daten gehoeren zu den besonderen Kategorien personenbezogener Daten gemaess Art. 9 DSGVO und erfordern eine ausdrueckliche Einwilligung.`
|
|
: `\n\n> **Note:** This data belongs to special categories of personal data under Art. 9 GDPR and requires explicit consent.`
|
|
} else if (category === 'EMPLOYEE_DATA') {
|
|
categoryNote = language === 'de'
|
|
? `\n\n> **Hinweis:** Die Verarbeitung von Beschaeftigtendaten erfolgt gemaess § 26 BDSG.`
|
|
: `\n\n> **Note:** Processing of employee data is carried out in accordance with § 26 BDSG (German Federal Data Protection Act).`
|
|
} else if (category === 'AI_DATA') {
|
|
categoryNote = language === 'de'
|
|
? `\n\n> **Hinweis:** Die Verarbeitung von KI-bezogenen Daten unterliegt den Transparenzpflichten des AI Acts.`
|
|
: `\n\n> **Note:** Processing of AI-related data is subject to AI Act transparency requirements.`
|
|
}
|
|
|
|
const dataList = categoryData
|
|
.map((dp) => {
|
|
const specialTag = dp.isSpecialCategory
|
|
? (language === 'de' ? ' *(Art. 9 DSGVO)*' : ' *(Art. 9 GDPR)*')
|
|
: ''
|
|
return `- **${t(dp.name, language)}**${specialTag}: ${t(dp.description, language)}`
|
|
})
|
|
.join('\n')
|
|
|
|
sections.push(`### ${categoryMeta.code}. ${categoryTitle}\n\n${dataList}${categoryNote}`)
|
|
}
|
|
|
|
const intro: LocalizedText = {
|
|
de: 'Wir erheben und verarbeiten die folgenden personenbezogenen Daten:',
|
|
en: 'We collect and process the following personal data:',
|
|
}
|
|
|
|
const specialCategoryNote: LocalizedText = hasSpecialCategoryData
|
|
? {
|
|
de: '\n\n**Wichtig:** Einige der unten aufgefuehrten Daten gehoeren zu den besonderen Kategorien personenbezogener Daten nach Art. 9 DSGVO und werden nur mit Ihrer ausdruecklichen Einwilligung verarbeitet.',
|
|
en: '\n\n**Important:** Some of the data listed below belongs to special categories of personal data under Art. 9 GDPR and is only processed with your explicit consent.',
|
|
}
|
|
: { de: '', en: '' }
|
|
|
|
const content: LocalizedText = {
|
|
de: `${intro.de}${specialCategoryNote.de}\n\n${sections.join('\n\n')}`,
|
|
en: `${intro.en}${specialCategoryNote.en}\n\n${sections.join('\n\n')}`,
|
|
}
|
|
|
|
return {
|
|
id: 'data-collection',
|
|
order: 2,
|
|
title,
|
|
content,
|
|
dataPointIds: dataPoints.map((dp) => dp.id),
|
|
isRequired: true,
|
|
isGenerated: true,
|
|
}
|
|
}
|
|
|
|
export function generatePurposesSection(
|
|
dataPoints: DataPoint[],
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '3. Zwecke der Datenverarbeitung',
|
|
en: '3. Purposes of Data Processing',
|
|
}
|
|
|
|
const purposes = new Map<string, DataPoint[]>()
|
|
for (const dp of dataPoints) {
|
|
const purpose = t(dp.purpose, language)
|
|
const existing = purposes.get(purpose) || []
|
|
purposes.set(purpose, [...existing, dp])
|
|
}
|
|
|
|
const purposeList = Array.from(purposes.entries())
|
|
.map(([purpose, dps]) => {
|
|
const dataNames = dps.map((dp) => t(dp.name, language)).join(', ')
|
|
return `- **${purpose}**\n Betroffene Daten: ${dataNames}`
|
|
})
|
|
.join('\n\n')
|
|
|
|
const content: LocalizedText = {
|
|
de: `Wir verarbeiten Ihre personenbezogenen Daten fuer folgende Zwecke:\n\n${purposeList}`,
|
|
en: `We process your personal data for the following purposes:\n\n${purposeList}`,
|
|
}
|
|
|
|
return {
|
|
id: 'purposes',
|
|
order: 3,
|
|
title,
|
|
content,
|
|
dataPointIds: dataPoints.map((dp) => dp.id),
|
|
isRequired: true,
|
|
isGenerated: true,
|
|
}
|
|
}
|
|
|
|
export function generateLegalBasisSection(
|
|
dataPoints: DataPoint[],
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '4. Rechtsgrundlagen der Verarbeitung',
|
|
en: '4. Legal Basis for Processing',
|
|
}
|
|
|
|
const grouped = groupByLegalBasis(dataPoints)
|
|
const sections: string[] = []
|
|
|
|
for (const basis of ALL_LEGAL_BASES) {
|
|
const basisData = grouped.get(basis)
|
|
if (!basisData || basisData.length === 0) continue
|
|
|
|
const basisInfo = LEGAL_BASIS_INFO[basis]
|
|
if (!basisInfo) continue
|
|
|
|
const basisTitle = `${t(basisInfo.name, language)} (${basisInfo.article})`
|
|
const basisDesc = t(basisInfo.description, language)
|
|
|
|
let additionalWarning = ''
|
|
if (basis === 'EXPLICIT_CONSENT') {
|
|
additionalWarning = language === 'de'
|
|
? `\n\n> **Wichtig:** Fuer die Verarbeitung dieser besonderen Kategorien personenbezogener Daten (Art. 9 DSGVO) ist eine separate, ausdrueckliche Einwilligung erforderlich, die Sie jederzeit widerrufen koennen.`
|
|
: `\n\n> **Important:** Processing of these special categories of personal data (Art. 9 GDPR) requires a separate, explicit consent that you can withdraw at any time.`
|
|
}
|
|
|
|
const dataLabel = language === 'de' ? 'Betroffene Daten' : 'Affected Data'
|
|
const dataList = basisData
|
|
.map((dp) => {
|
|
const specialTag = dp.isSpecialCategory
|
|
? (language === 'de' ? ' *(Art. 9 DSGVO)*' : ' *(Art. 9 GDPR)*')
|
|
: ''
|
|
return `- ${t(dp.name, language)}${specialTag}: ${t(dp.legalBasisJustification, language)}`
|
|
})
|
|
.join('\n')
|
|
|
|
sections.push(`### ${basisTitle}\n\n${basisDesc}${additionalWarning}\n\n**${dataLabel}:**\n${dataList}`)
|
|
}
|
|
|
|
const content: LocalizedText = {
|
|
de: `Die Verarbeitung Ihrer personenbezogenen Daten erfolgt auf Grundlage folgender Rechtsgrundlagen:\n\n${sections.join('\n\n')}`,
|
|
en: `The processing of your personal data is based on the following legal grounds:\n\n${sections.join('\n\n')}`,
|
|
}
|
|
|
|
return {
|
|
id: 'legal-basis',
|
|
order: 4,
|
|
title,
|
|
content,
|
|
dataPointIds: dataPoints.map((dp) => dp.id),
|
|
isRequired: true,
|
|
isGenerated: true,
|
|
}
|
|
}
|
|
|
|
export function generateRecipientsSection(
|
|
dataPoints: DataPoint[],
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '5. Empfaenger und Datenweitergabe',
|
|
en: '5. Recipients and Data Sharing',
|
|
}
|
|
|
|
const thirdParties = extractThirdParties(dataPoints)
|
|
|
|
if (thirdParties.length === 0) {
|
|
const content: LocalizedText = {
|
|
de: 'Wir geben Ihre personenbezogenen Daten grundsaetzlich nicht an Dritte weiter, es sei denn, dies ist zur Vertragserfuellung erforderlich oder Sie haben ausdruecklich eingewilligt.',
|
|
en: 'We generally do not share your personal data with third parties unless this is necessary for contract performance or you have expressly consented.',
|
|
}
|
|
return {
|
|
id: 'recipients',
|
|
order: 5,
|
|
title,
|
|
content,
|
|
dataPointIds: [],
|
|
isRequired: true,
|
|
isGenerated: false,
|
|
}
|
|
}
|
|
|
|
const recipientDetails = new Map<string, DataPoint[]>()
|
|
for (const dp of dataPoints) {
|
|
for (const recipient of dp.thirdPartyRecipients) {
|
|
const existing = recipientDetails.get(recipient) || []
|
|
recipientDetails.set(recipient, [...existing, dp])
|
|
}
|
|
}
|
|
|
|
const recipientList = Array.from(recipientDetails.entries())
|
|
.map(([recipient, dps]) => {
|
|
const dataNames = dps.map((dp) => t(dp.name, language)).join(', ')
|
|
return `- **${recipient}**: ${dataNames}`
|
|
})
|
|
.join('\n')
|
|
|
|
const content: LocalizedText = {
|
|
de: `Wir uebermitteln Ihre personenbezogenen Daten an folgende Empfaenger bzw. Kategorien von Empfaengern:\n\n${recipientList}\n\nMit allen Auftragsverarbeitern haben wir Auftragsverarbeitungsvertraege nach Art. 28 DSGVO abgeschlossen.`,
|
|
en: `We share your personal data with the following recipients or categories of recipients:\n\n${recipientList}\n\nWe have concluded data processing agreements pursuant to Art. 28 GDPR with all processors.`,
|
|
}
|
|
|
|
return {
|
|
id: 'recipients',
|
|
order: 5,
|
|
title,
|
|
content,
|
|
dataPointIds: dataPoints.filter((dp) => dp.thirdPartyRecipients.length > 0).map((dp) => dp.id),
|
|
isRequired: true,
|
|
isGenerated: true,
|
|
}
|
|
}
|
|
|
|
export function generateRetentionSection(
|
|
dataPoints: DataPoint[],
|
|
retentionMatrix: RetentionMatrixEntry[],
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '6. Speicherdauer',
|
|
en: '6. Data Retention',
|
|
}
|
|
|
|
const grouped = groupByCategory(dataPoints)
|
|
const sections: string[] = []
|
|
|
|
for (const entry of retentionMatrix) {
|
|
const categoryData = grouped.get(entry.category)
|
|
if (!categoryData || categoryData.length === 0) continue
|
|
|
|
const categoryName = t(entry.categoryName, language)
|
|
const standardPeriod = t(RETENTION_PERIOD_INFO[entry.standardPeriod].label, language)
|
|
|
|
const dataRetention = categoryData
|
|
.map((dp) => {
|
|
const period = t(RETENTION_PERIOD_INFO[dp.retentionPeriod].label, language)
|
|
return `- ${t(dp.name, language)}: ${period}`
|
|
})
|
|
.join('\n')
|
|
|
|
sections.push(`### ${categoryName}\n\n**Standardfrist:** ${standardPeriod}\n\n${dataRetention}`)
|
|
}
|
|
|
|
const content: LocalizedText = {
|
|
de: `Wir speichern Ihre personenbezogenen Daten nur so lange, wie dies fuer die jeweiligen Zwecke erforderlich ist oder gesetzliche Aufbewahrungsfristen bestehen.\n\n${sections.join('\n\n')}`,
|
|
en: `We store your personal data only for as long as is necessary for the respective purposes or as required by statutory retention periods.\n\n${sections.join('\n\n')}`,
|
|
}
|
|
|
|
return {
|
|
id: 'retention',
|
|
order: 6,
|
|
title,
|
|
content,
|
|
dataPointIds: dataPoints.map((dp) => dp.id),
|
|
isRequired: true,
|
|
isGenerated: true,
|
|
}
|
|
}
|
|
|
|
export function generateSpecialCategoriesSection(
|
|
dataPoints: DataPoint[],
|
|
language: SupportedLanguage
|
|
): PrivacyPolicySection | null {
|
|
const specialCategoryDataPoints = dataPoints.filter(dp => dp.isSpecialCategory || dp.category === 'HEALTH_DATA')
|
|
|
|
if (specialCategoryDataPoints.length === 0) {
|
|
return null
|
|
}
|
|
|
|
const title: LocalizedText = {
|
|
de: '6a. Besondere Kategorien personenbezogener Daten (Art. 9 DSGVO)',
|
|
en: '6a. Special Categories of Personal Data (Art. 9 GDPR)',
|
|
}
|
|
|
|
const dataList = specialCategoryDataPoints
|
|
.map((dp) => `- **${t(dp.name, language)}**: ${t(dp.description, language)}`)
|
|
.join('\n')
|
|
|
|
const content: LocalizedText = {
|
|
de: `Gemaess Art. 9 DSGVO verarbeiten wir auch besondere Kategorien personenbezogener Daten, die einen erhoehten Schutz geniessen. Diese Daten umfassen:
|
|
|
|
${dataList}
|
|
|
|
### Ihre ausdrueckliche Einwilligung
|
|
|
|
Die Verarbeitung dieser besonderen Kategorien personenbezogener Daten erfolgt nur auf Grundlage Ihrer **ausdruecklichen Einwilligung** gemaess Art. 9 Abs. 2 lit. a DSGVO.
|
|
|
|
### Ihre Rechte bei Art. 9 Daten
|
|
|
|
- Sie koennen Ihre Einwilligung **jederzeit widerrufen**
|
|
- Der Widerruf beruehrt nicht die Rechtmaessigkeit der bisherigen Verarbeitung
|
|
- Bei Widerruf werden Ihre Daten unverzueglich geloescht
|
|
- Sie haben das Recht auf **Auskunft, Berichtigung und Loeschung**
|
|
|
|
### Besondere Schutzmassnahmen
|
|
|
|
Fuer diese sensiblen Daten haben wir besondere technische und organisatorische Massnahmen implementiert:
|
|
- Ende-zu-Ende-Verschluesselung
|
|
- Strenge Zugriffskontrolle (Need-to-Know-Prinzip)
|
|
- Audit-Logging aller Zugriffe
|
|
- Regelmaessige Datenschutz-Folgenabschaetzungen`,
|
|
en: `In accordance with Art. 9 GDPR, we also process special categories of personal data that enjoy enhanced protection. This data includes:
|
|
|
|
${dataList}
|
|
|
|
### Your Explicit Consent
|
|
|
|
Processing of these special categories of personal data only takes place on the basis of your **explicit consent** pursuant to Art. 9(2)(a) GDPR.
|
|
|
|
### Your Rights Regarding Art. 9 Data
|
|
|
|
- You can **withdraw your consent at any time**
|
|
- Withdrawal does not affect the lawfulness of previous processing
|
|
- Upon withdrawal, your data will be deleted immediately
|
|
- You have the right to **access, rectification, and erasure**
|
|
|
|
### Special Protection Measures
|
|
|
|
For this sensitive data, we have implemented special technical and organizational measures:
|
|
- End-to-end encryption
|
|
- Strict access control (need-to-know principle)
|
|
- Audit logging of all access
|
|
- Regular data protection impact assessments`,
|
|
}
|
|
|
|
return {
|
|
id: 'special-categories',
|
|
order: 6.5,
|
|
title,
|
|
content,
|
|
dataPointIds: specialCategoryDataPoints.map((dp) => dp.id),
|
|
isRequired: false,
|
|
isGenerated: true,
|
|
}
|
|
}
|
|
|
|
export function generateRightsSection(language: SupportedLanguage): PrivacyPolicySection {
|
|
const title: LocalizedText = {
|
|
de: '7. Ihre Rechte als betroffene Person',
|
|
en: '7. Your Rights as a Data Subject',
|
|
}
|
|
|
|
const content: LocalizedText = {
|
|
de: `Sie haben gegenueber uns folgende Rechte hinsichtlich der Sie betreffenden personenbezogenen Daten:
|
|
|
|
### Auskunftsrecht (Art. 15 DSGVO)
|
|
Sie haben das Recht, Auskunft ueber die von uns verarbeiteten personenbezogenen Daten zu verlangen.
|
|
|
|
### Recht auf Berichtigung (Art. 16 DSGVO)
|
|
Sie haben das Recht, die Berichtigung unrichtiger oder die Vervollstaendigung unvollstaendiger Daten zu verlangen.
|
|
|
|
### Recht auf Loeschung (Art. 17 DSGVO)
|
|
Sie haben das Recht, die Loeschung Ihrer personenbezogenen Daten zu verlangen, sofern keine gesetzlichen Aufbewahrungspflichten entgegenstehen.
|
|
|
|
### Recht auf Einschraenkung der Verarbeitung (Art. 18 DSGVO)
|
|
Sie haben das Recht, die Einschraenkung der Verarbeitung Ihrer Daten zu verlangen.
|
|
|
|
### Recht auf Datenuebertragbarkeit (Art. 20 DSGVO)
|
|
Sie haben das Recht, Ihre Daten in einem strukturierten, gaengigen und maschinenlesbaren Format zu erhalten.
|
|
|
|
### Widerspruchsrecht (Art. 21 DSGVO)
|
|
Sie haben das Recht, der Verarbeitung Ihrer Daten jederzeit zu widersprechen, soweit die Verarbeitung auf berechtigtem Interesse beruht.
|
|
|
|
### Recht auf Widerruf der Einwilligung (Art. 7 Abs. 3 DSGVO)
|
|
Sie haben das Recht, Ihre erteilte Einwilligung jederzeit zu widerrufen. Die Rechtmaessigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Verarbeitung wird dadurch nicht beruehrt.
|
|
|
|
### Beschwerderecht bei der Aufsichtsbehoerde (Art. 77 DSGVO)
|
|
Sie haben das Recht, sich bei einer Datenschutz-Aufsichtsbehoerde ueber die Verarbeitung Ihrer personenbezogenen Daten zu beschweren.
|
|
|
|
**Zur Ausuebung Ihrer Rechte wenden Sie sich bitte an die oben angegebenen Kontaktdaten.**`,
|
|
en: `You have the following rights regarding your personal data:
|
|
|
|
### Right of Access (Art. 15 GDPR)
|
|
You have the right to request information about the personal data we process about you.
|
|
|
|
### Right to Rectification (Art. 16 GDPR)
|
|
You have the right to request the correction of inaccurate data or the completion of incomplete data.
|
|
|
|
### Right to Erasure (Art. 17 GDPR)
|
|
You have the right to request the deletion of your personal data, unless statutory retention obligations apply.
|
|
|
|
### Right to Restriction of Processing (Art. 18 GDPR)
|
|
You have the right to request the restriction of processing of your data.
|
|
|
|
### Right to Data Portability (Art. 20 GDPR)
|
|
You have the right to receive your data in a structured, commonly used, and machine-readable format.
|
|
|
|
### Right to Object (Art. 21 GDPR)
|
|
You have the right to object to the processing of your data at any time, insofar as the processing is based on legitimate interest.
|
|
|
|
### Right to Withdraw Consent (Art. 7(3) GDPR)
|
|
You have the right to withdraw your consent at any time. The lawfulness of processing based on consent before its withdrawal is not affected.
|
|
|
|
### Right to Lodge a Complaint with a Supervisory Authority (Art. 77 GDPR)
|
|
You have the right to lodge a complaint with a data protection supervisory authority about the processing of your personal data.
|
|
|
|
**To exercise your rights, please contact us using the contact details provided above.**`,
|
|
}
|
|
|
|
return {
|
|
id: 'rights',
|
|
order: 7,
|
|
title,
|
|
content,
|
|
dataPointIds: [],
|
|
isRequired: true,
|
|
isGenerated: false,
|
|
}
|
|
}
|