refactor(admin): split 4 large type-definition files into per-section modules

Split vendor-compliance/types.ts (1217 LOC), dsfa/types.ts (1082 LOC),
tom-generator/types.ts (963 LOC), and einwilligungen/types.ts (838 LOC)
into types/ directories with per-section domain files and barrel-export
index.ts files, matching the pattern in lib/sdk/types/index.ts.
All files are under 500 LOC. Build verified with npx next build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-04-10 13:42:27 +02:00
parent 911d872178
commit aae07b7a9b
55 changed files with 4336 additions and 4100 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,98 @@
// =============================================================================
// API REQUEST/RESPONSE TYPES
// =============================================================================
import type { DSFAStatus, DSFARiskLevel } from './enums-constants'
import type { DSFA } from './main-dsfa'
export interface DSFAListResponse {
dsfas: DSFA[]
}
export interface DSFAStatsResponse {
status_stats: Record<DSFAStatus | 'total', number>
risk_stats: Record<DSFARiskLevel, number>
total: number
}
export interface CreateDSFARequest {
name: string
description?: string
processing_description?: string
processing_purpose?: string
data_categories?: string[]
legal_basis?: string
}
export interface CreateDSFAFromAssessmentRequest {
name?: string
description?: string
}
export interface CreateDSFAFromAssessmentResponse {
dsfa: DSFA
prefilled: boolean
assessment: unknown // UCCA Assessment
message: string
}
export interface UpdateDSFASectionRequest {
// Section 1
processing_description?: string
processing_purpose?: string
data_categories?: string[]
data_subjects?: string[]
recipients?: string[]
legal_basis?: string
legal_basis_details?: string
// Section 2
necessity_assessment?: string
proportionality_assessment?: string
data_minimization?: string
alternatives_considered?: string
retention_justification?: string
// Section 3
overall_risk_level?: DSFARiskLevel
risk_score?: number
affected_rights?: string[]
// Section 5
dpo_consulted?: boolean
dpo_name?: string
dpo_opinion?: string
authority_consulted?: boolean
authority_reference?: string
authority_decision?: string
}
export interface SubmitForReviewResponse {
message: string
dsfa: DSFA
}
export interface ApproveDSFARequest {
dpo_opinion: string
approved: boolean
}
// =============================================================================
// UCCA INTEGRATION TYPES
// =============================================================================
export interface DSFATriggerInfo {
required: boolean
reason: string
triggered_rules: string[]
assessment_id?: string
existing_dsfa_id?: string
}
export interface UCCATriggeredRule {
code: string
title: string
description: string
severity: 'INFO' | 'WARN' | 'BLOCK'
gdpr_ref?: string
}

View File

@@ -0,0 +1,171 @@
// =============================================================================
// DSFA MUSS-LISTEN NACH BUNDESLÄNDERN
// Quellen: Jeweilige Landesdatenschutzbeauftragte
// =============================================================================
export interface DSFAAuthorityResource {
id: string
name: string
shortName: string
state: string // Bundesland oder 'Bund'
overviewUrl: string
publicSectorListUrl?: string
privateSectorListUrl?: string
templateUrl?: string
additionalResources?: Array<{ title: string; url: string }>
}
export const DSFA_AUTHORITY_RESOURCES: DSFAAuthorityResource[] = [
{
id: 'bund',
name: 'Bundesbeauftragter für den Datenschutz und die Informationsfreiheit',
shortName: 'BfDI',
state: 'Bund',
overviewUrl: 'https://www.bfdi.bund.de/DE/Fachthemen/Inhalte/Technik/Datenschutz-Folgenabschaetzungen.html',
publicSectorListUrl: 'https://www.bfdi.bund.de/SharedDocs/Downloads/DE/Muster/Liste_VerarbeitungsvorgaengeArt35.pdf',
templateUrl: 'https://www.bfdi.bund.de/SharedDocs/Downloads/DE/Muster/Muster_Hinweise_DSFA.html',
},
{
id: 'bw',
name: 'Landesbeauftragter für den Datenschutz und die Informationsfreiheit Baden-Württemberg',
shortName: 'LfDI BW',
state: 'Baden-Württemberg',
overviewUrl: 'https://www.baden-wuerttemberg.datenschutz.de/datenschutz-folgenabschaetzung/',
privateSectorListUrl: 'https://www.baden-wuerttemberg.datenschutz.de/wp-content/uploads/2018/05/Liste-von-Verarbeitungsvorg%C3%A4ngen-nach-Art.-35-Abs.-4-DS-GVO-LfDI-BW.pdf',
},
{
id: 'by',
name: 'Bayerischer Landesbeauftragter für den Datenschutz',
shortName: 'BayLfD',
state: 'Bayern',
overviewUrl: 'https://www.datenschutz-bayern.de/dsfa/',
additionalResources: [
{ title: 'DSFA-Module und Formulare', url: 'https://www.datenschutz-bayern.de/dsfa/' },
],
},
{
id: 'be',
name: 'Berliner Beauftragte für Datenschutz und Informationsfreiheit',
shortName: 'BlnBDI',
state: 'Berlin',
overviewUrl: 'https://www.datenschutz-berlin.de/themen/unternehmen/datenschutz-folgenabschaetzung/',
publicSectorListUrl: 'https://www.datenschutz-berlin.de/fileadmin/user_upload/pdf/dokumente/2018-BlnBDI_DSFA-oeffentlich.pdf',
privateSectorListUrl: 'https://www.datenschutz-berlin.de/fileadmin/user_upload/pdf/dokumente/2018-BlnBDI_DSFA-nicht-oeffentlich.pdf',
},
{
id: 'bb',
name: 'Landesbeauftragte für den Datenschutz und für das Recht auf Akteneinsicht Brandenburg',
shortName: 'LDA BB',
state: 'Brandenburg',
overviewUrl: 'https://www.lda.brandenburg.de/lda/de/datenschutz/datenschutz-folgenabschaetzung/',
publicSectorListUrl: 'https://www.lda.brandenburg.de/sixcms/media.php/9/DSFA-Liste_%C3%B6ffentlicher_Bereich.pdf',
privateSectorListUrl: 'https://www.lda.brandenburg.de/sixcms/media.php/9/DSFA-Liste_nicht_%C3%B6ffentlicher_Bereich.pdf',
},
{
id: 'hb',
name: 'Landesbeauftragte für Datenschutz und Informationsfreiheit Bremen',
shortName: 'LfDI HB',
state: 'Bremen',
overviewUrl: 'https://www.datenschutz.bremen.de/datenschutz/datenschutz-folgenabschaetzung-3884',
publicSectorListUrl: 'https://www.datenschutz.bremen.de/sixcms/media.php/13/Liste%20von%20Verarbeitungsvorg%C3%A4ngen%20nach%20Artikel%2035.pdf',
privateSectorListUrl: 'https://www.datenschutz.bremen.de/sixcms/media.php/13/DSFA%20Muss-Liste%20LfDI%20HB.pdf',
},
{
id: 'hh',
name: 'Hamburgischer Beauftragter für Datenschutz und Informationsfreiheit',
shortName: 'HmbBfDI',
state: 'Hamburg',
overviewUrl: 'https://datenschutz-hamburg.de/datenschutz-folgenabschaetzung',
publicSectorListUrl: 'https://datenschutz-hamburg.de/fileadmin/user_upload/HmbBfDI/Datenschutz/Informationen/Liste_Art_35-4_DSGVO_HmbBfDI-oeffentlicher_Bereich_v2.0a.pdf',
privateSectorListUrl: 'https://datenschutz-hamburg.de/fileadmin/user_upload/HmbBfDI/Datenschutz/Informationen/DSFA_Muss-Liste_fuer_den_nicht-oeffentlicher_Bereich_-_Stand_17.10.2018.pdf',
},
{
id: 'he',
name: 'Hessischer Beauftragter für Datenschutz und Informationsfreiheit',
shortName: 'HBDI',
state: 'Hessen',
overviewUrl: 'https://datenschutz.hessen.de/datenschutz/it-und-datenschutz/datenschutz-folgenabschaetzung',
},
{
id: 'mv',
name: 'Landesbeauftragter für Datenschutz und Informationsfreiheit Mecklenburg-Vorpommern',
shortName: 'LfDI MV',
state: 'Mecklenburg-Vorpommern',
overviewUrl: 'https://www.datenschutz-mv.de/datenschutz/DSGVO/Hilfsmittel-zur-Umsetzung/',
publicSectorListUrl: 'https://www.datenschutz-mv.de/static/DS/Dateien/DS-GVO/HilfsmittelzurUmsetzung/MV-DSFA-Muss-Liste-Oeffentlicher-Bereich.pdf',
},
{
id: 'ni',
name: 'Die Landesbeauftragte für den Datenschutz Niedersachsen',
shortName: 'LfD NI',
state: 'Niedersachsen',
overviewUrl: 'https://www.lfd.niedersachsen.de/dsgvo/liste_von_verarbeitungsvorgangen_nach_art_35_abs_4_ds_gvo/muss-listen-zur-datenschutz-folgenabschatzung-179663.html',
publicSectorListUrl: 'https://www.lfd.niedersachsen.de/download/134414/DSFA_Muss-Liste_fuer_den_oeffentlichen_Bereich.pdf',
privateSectorListUrl: 'https://www.lfd.niedersachsen.de/download/131098/Liste_von_Verarbeitungsvorgaengen_nach_Art._35_Abs._4_DS-GVO.pdf',
},
{
id: 'nw',
name: 'Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen',
shortName: 'LDI NRW',
state: 'Nordrhein-Westfalen',
overviewUrl: 'https://www.ldi.nrw.de/datenschutz/wirtschaft/datenschutz-folgenabschaetzung',
publicSectorListUrl: 'https://www.ldi.nrw.de/liste-von-verarbeitungsvorgaengen-nach-art-35-abs-4-ds-gvo-fuer-den-oeffentlichen-bereich',
},
{
id: 'rp',
name: 'Landesbeauftragter für den Datenschutz und die Informationsfreiheit Rheinland-Pfalz',
shortName: 'LfDI RP',
state: 'Rheinland-Pfalz',
overviewUrl: 'https://www.datenschutz.rlp.de/themen/datenschutz-folgenabschaetzung',
},
{
id: 'sl',
name: 'Unabhängiges Datenschutzzentrum Saarland',
shortName: 'UDZ SL',
state: 'Saarland',
overviewUrl: 'https://www.datenschutz.saarland.de/themen/datenschutz-folgenabschaetzung',
privateSectorListUrl: 'https://www.datenschutz.saarland.de/fileadmin/user_upload/uds/alle_Dateien_und_Ordner_bis_2025/Download/dsfa_muss_liste_dsk_de.pdf',
},
{
id: 'sn',
name: 'Sächsische Datenschutz- und Transparenzbeauftragte',
shortName: 'SDTB',
state: 'Sachsen',
overviewUrl: 'https://www.datenschutz.sachsen.de/datenschutz-folgenabschaetzung.html',
additionalResources: [
{ title: 'Erforderlichkeit der DSFA', url: 'https://www.datenschutz.sachsen.de/erforderlichkeit.html' },
],
},
{
id: 'st',
name: 'Landesbeauftragter für den Datenschutz Sachsen-Anhalt',
shortName: 'LfD ST',
state: 'Sachsen-Anhalt',
overviewUrl: 'https://datenschutz.sachsen-anhalt.de/informationen/datenschutz-grundverordnung/liste-datenschutz-folgenabschaetzung',
publicSectorListUrl: 'https://datenschutz.sachsen-anhalt.de/fileadmin/Bibliothek/Landesaemter/LfD/Informationen/Internationales/Datenschutz-Grundverordnung/Liste_DSFA/Art-35-Liste-oeffentlicher_Bereich.pdf',
privateSectorListUrl: 'https://datenschutz.sachsen-anhalt.de/fileadmin/Bibliothek/Landesaemter/LfD/Informationen/Internationales/Datenschutz-Grundverordnung/Liste_DSFA/Art-35-Liste-nichtoeffentlicher_Bereich.pdf',
},
{
id: 'sh',
name: 'Unabhängiges Landeszentrum für Datenschutz Schleswig-Holstein',
shortName: 'ULD SH',
state: 'Schleswig-Holstein',
overviewUrl: 'https://www.datenschutzzentrum.de/datenschutzfolgenabschaetzung/',
privateSectorListUrl: 'https://www.datenschutzzentrum.de/uploads/datenschutzfolgenabschaetzung/20180525_LfD-SH_DSFA_Muss-Liste_V1.0.pdf',
additionalResources: [
{ title: 'Begleittext zur DSFA-Liste', url: 'https://www.datenschutzzentrum.de/uploads/dsgvo/2018_0807_LfD-SH_DSFA_Begleittext_V1.0a.pdf' },
],
},
{
id: 'th',
name: 'Thüringer Landesbeauftragter für den Datenschutz und die Informationsfreiheit',
shortName: 'TLfDI',
state: 'Thüringen',
overviewUrl: 'https://www.tlfdi.de/datenschutz/datenschutz-folgenabschaetzung/',
privateSectorListUrl: 'https://tlfdi.de/fileadmin/tlfdi/datenschutz/dsfa_muss-liste_04_07_18.pdf',
additionalResources: [
{ title: 'Handreichung DS-FA (nicht-öffentlich)', url: 'https://tlfdi.de/fileadmin/tlfdi/datenschutz/handreichung_ds-fa.pdf' },
{ title: 'Handreichung DS-FA (öffentlich)', url: 'https://tlfdi.de/fileadmin/tlfdi/Europa/Handreichung_zur_Datenschutz-Folgenabschaetzung_oeffentlicher_Bereich.pdf' },
],
},
]

View File

@@ -0,0 +1,84 @@
// =============================================================================
// DSK KURZPAPIER NR. 5 REFERENZEN
// =============================================================================
export const DSK_KURZPAPIER_5 = {
title: 'Kurzpapier Nr. 5: Datenschutz-Folgenabschätzung nach Art. 35 DS-GVO',
source: 'Datenschutzkonferenz (DSK)',
url: 'https://www.datenschutzkonferenz-online.de/media/kp/dsk_kpnr_5.pdf',
license: 'Datenlizenz Deutschland Namensnennung Version 2.0 (DL-DE BY 2.0)',
licenseUrl: 'https://www.govdata.de/dl-de/by-2-0',
processSteps: [
{ step: 1, title: 'Projektteam bilden', description: 'Interdisziplinäres Team aus Datenschutz, Fachprozess, IT/Sicherheit' },
{ step: 2, title: 'Verarbeitung abgrenzen', description: 'Scope definieren, Datenflüsse und Zwecke beschreiben' },
{ step: 3, title: 'Prüfung der Notwendigkeit', description: 'Alternativen prüfen, Datenminimierung bewerten' },
{ step: 4, title: 'Risiken identifizieren', description: 'Risikoquellen ermitteln, Schäden bewerten' },
{ step: 5, title: 'Maßnahmen festlegen', description: 'TOM definieren, Restrisiko bewerten' },
{ step: 6, title: 'Bericht erstellen', description: 'DSFA-Bericht dokumentieren, ggf. veröffentlichen' },
{ step: 7, title: 'Fortschreibung', description: 'DSFA bei Änderungen aktualisieren' },
],
}
// =============================================================================
// ART. 35 ABS. 3 DSGVO - REGELBEISPIELE
// =============================================================================
export const ART35_ABS3_CASES = [
{
id: 'profiling_legal_effects',
lit: 'a',
title: 'Profiling mit Rechtswirkung',
description: 'Systematische und umfassende Bewertung persönlicher Aspekte natürlicher Personen, die sich auf automatisierte Verarbeitung einschließlich Profiling gründet und die ihrerseits als Grundlage für Entscheidungen dient, die Rechtswirkung gegenüber natürlichen Personen entfalten oder diese in ähnlich erheblicher Weise beeinträchtigen.',
gdprRef: 'Art. 35 Abs. 3 lit. a DSGVO',
},
{
id: 'special_categories',
lit: 'b',
title: 'Besondere Datenkategorien in großem Umfang',
description: 'Umfangreiche Verarbeitung besonderer Kategorien von personenbezogenen Daten gemäß Artikel 9 Absatz 1 oder von personenbezogenen Daten über strafrechtliche Verurteilungen und Straftaten gemäß Artikel 10.',
gdprRef: 'Art. 35 Abs. 3 lit. b DSGVO',
},
{
id: 'public_monitoring',
lit: 'c',
title: 'Systematische Überwachung öffentlicher Bereiche',
description: 'Systematische umfangreiche Überwachung öffentlich zugänglicher Bereiche.',
gdprRef: 'Art. 35 Abs. 3 lit. c DSGVO',
},
]
// =============================================================================
// KI-SPEZIFISCHE DSFA-TRIGGER
// Quelle: Deutsche DSFA-Liste (nicht-öffentlicher Bereich)
// =============================================================================
export const AI_DSFA_TRIGGERS = [
{
id: 'ai_interaction',
title: 'KI zur Steuerung der Interaktion mit Betroffenen',
description: 'Einsatz von künstlicher Intelligenz zur Steuerung der Interaktion mit betroffenen Personen.',
examples: ['KI-gestützter Kundensupport', 'Chatbots mit personenbezogener Verarbeitung', 'Automatisierte Kommunikation'],
requiresDSFA: true,
},
{
id: 'ai_personal_aspects',
title: 'KI zur Bewertung persönlicher Aspekte',
description: 'Einsatz von künstlicher Intelligenz zur Bewertung persönlicher Aspekte natürlicher Personen.',
examples: ['Automatisierte Stimmungsanalyse', 'Verhaltensvorhersagen', 'Persönlichkeitsprofile'],
requiresDSFA: true,
},
{
id: 'ai_decision_making',
title: 'KI-basierte automatisierte Entscheidungen',
description: 'Automatisierte Entscheidungsfindung auf Basis von KI mit erheblicher Auswirkung auf Betroffene.',
examples: ['Automatische Kreditvergabe', 'KI-basiertes Recruiting', 'Algorithmenbasierte Preisgestaltung'],
requiresDSFA: true,
},
{
id: 'ai_training_personal_data',
title: 'KI-Training mit personenbezogenen Daten',
description: 'Training von KI-Modellen mit personenbezogenen Daten, insbesondere sensiblen Daten.',
examples: ['Training mit Gesundheitsdaten', 'Fine-Tuning mit Kundendaten', 'ML mit biometrischen Daten'],
requiresDSFA: true,
},
]

View File

@@ -0,0 +1,52 @@
// =============================================================================
// ENUMS & CONSTANTS
// =============================================================================
export type DSFAStatus = 'draft' | 'in_review' | 'approved' | 'rejected' | 'needs_update'
export type DSFARiskLevel = 'low' | 'medium' | 'high' | 'very_high'
export type DSFARiskCategory = 'confidentiality' | 'integrity' | 'availability' | 'rights_freedoms'
export type DSFAMitigationType = 'technical' | 'organizational' | 'legal'
export type DSFAMitigationStatus = 'planned' | 'in_progress' | 'implemented' | 'verified'
export const DSFA_STATUS_LABELS: Record<DSFAStatus, string> = {
draft: 'Entwurf',
in_review: 'In Prüfung',
approved: 'Genehmigt',
rejected: 'Abgelehnt',
needs_update: 'Überarbeitung erforderlich',
}
export const DSFA_RISK_LEVEL_LABELS: Record<DSFARiskLevel, string> = {
low: 'Niedrig',
medium: 'Mittel',
high: 'Hoch',
very_high: 'Sehr Hoch',
}
export const DSFA_LEGAL_BASES = {
consent: 'Art. 6 Abs. 1 lit. a DSGVO - Einwilligung',
contract: 'Art. 6 Abs. 1 lit. b DSGVO - Vertrag',
legal_obligation: 'Art. 6 Abs. 1 lit. c DSGVO - Rechtliche Verpflichtung',
vital_interests: 'Art. 6 Abs. 1 lit. d DSGVO - Lebenswichtige Interessen',
public_interest: 'Art. 6 Abs. 1 lit. e DSGVO - Öffentliches Interesse',
legitimate_interest: 'Art. 6 Abs. 1 lit. f DSGVO - Berechtigtes Interesse',
}
export const DSFA_AFFECTED_RIGHTS = [
{ id: 'right_to_information', label: 'Recht auf Information (Art. 13/14)' },
{ id: 'right_of_access', label: 'Auskunftsrecht (Art. 15)' },
{ id: 'right_to_rectification', label: 'Recht auf Berichtigung (Art. 16)' },
{ id: 'right_to_erasure', label: 'Recht auf Löschung (Art. 17)' },
{ id: 'right_to_restriction', label: 'Recht auf Einschränkung (Art. 18)' },
{ id: 'right_to_data_portability', label: 'Recht auf Datenübertragbarkeit (Art. 20)' },
{ id: 'right_to_object', label: 'Widerspruchsrecht (Art. 21)' },
{ id: 'right_not_to_be_profiled', label: 'Recht bzgl. Profiling (Art. 22)' },
{ id: 'freedom_of_expression', label: 'Meinungsfreiheit' },
{ id: 'freedom_of_association', label: 'Versammlungsfreiheit' },
{ id: 'non_discrimination', label: 'Nichtdiskriminierung' },
{ id: 'data_security', label: 'Datensicherheit' },
]

View File

@@ -0,0 +1,162 @@
// =============================================================================
// HELPER FUNCTIONS
// =============================================================================
import type { DSFARiskLevel } from './enums-constants'
import type { DSFAConsultationRequirement, DSFAReviewTrigger, DSFAReviewSchedule } from './sub-types'
import type { DSFAAuthorityResource } from './authority-resources'
import { DSFA_AUTHORITY_RESOURCES } from './authority-resources'
import { WP248_CRITERIA } from './wp248-criteria'
import { ART35_ABS3_CASES, AI_DSFA_TRIGGERS } from './dsk-references'
/**
* Prüft anhand der WP248-Kriterien, ob eine DSFA erforderlich ist.
* Regel: Bei >= 2 erfüllten Kriterien ist DSFA in den meisten Fällen erforderlich.
* @param criteriaIds Array der erfüllten Kriterien-IDs (z.B. ['K1', 'K4'])
* @returns Objekt mit Ergebnis und Begründung
*/
export function checkDSFARequiredByWP248(criteriaIds: string[]): {
required: boolean
confidence: 'definite' | 'likely' | 'possible' | 'unlikely'
reason: string
} {
const count = criteriaIds.length
if (count >= 2) {
return {
required: true,
confidence: 'definite',
reason: `${count} WP248-Kriterien erfüllt (>= 2). DSFA ist in den meisten Fällen erforderlich.`,
}
}
if (count === 1) {
return {
required: false,
confidence: 'possible',
reason: '1 WP248-Kriterium erfüllt. DSFA kann je nach Risiko dennoch erforderlich sein. Einzelfallprüfung empfohlen.',
}
}
return {
required: false,
confidence: 'unlikely',
reason: 'Keine WP248-Kriterien erfüllt. DSFA wahrscheinlich nicht erforderlich, sofern kein Art. 35 Abs. 3 Fall vorliegt.',
}
}
/**
* Prüft, ob eine Konsultation der Aufsichtsbehörde gem. Art. 36 DSGVO erforderlich ist.
* Erforderlich wenn: Hohes Restrisiko trotz geplanter Maßnahmen.
*/
export function checkArt36ConsultationRequired(
residualRiskLevel: DSFARiskLevel,
mitigationsImplemented: boolean
): DSFAConsultationRequirement {
const highResidual = residualRiskLevel === 'high' || residualRiskLevel === 'very_high'
const consultationRequired = highResidual && mitigationsImplemented
return {
high_residual_risk: highResidual,
consultation_required: consultationRequired,
consultation_reason: consultationRequired
? 'Trotz geplanter Maßnahmen verbleibt ein hohes Restrisiko. Gem. Art. 36 Abs. 1 DSGVO ist vor der Verarbeitung die Aufsichtsbehörde zu konsultieren.'
: highResidual
? 'Hohes Restrisiko festgestellt, aber Maßnahmen noch nicht vollständig umgesetzt.'
: undefined,
authority_notified: false,
waiting_period_observed: false,
}
}
/**
* Gibt die zuständige Aufsichtsbehörde für ein Bundesland zurück.
*/
export function getAuthorityResource(stateId: string): DSFAAuthorityResource | undefined {
return DSFA_AUTHORITY_RESOURCES.find(r => r.id === stateId)
}
/**
* Gibt alle Bundesländer als Auswahlliste zurück.
*/
export function getFederalStateOptions(): Array<{ value: string; label: string }> {
return DSFA_AUTHORITY_RESOURCES.map(r => ({
value: r.id,
label: r.state,
}))
}
/**
* Prüft, ob ein Review-Trigger eine Aktualisierung der DSFA erfordert.
*/
export function checkReviewRequired(triggers: DSFAReviewTrigger[]): {
required: boolean
pendingTriggers: DSFAReviewTrigger[]
} {
const pendingTriggers = triggers.filter(t => t.review_required && !t.review_completed)
return {
required: pendingTriggers.length > 0,
pendingTriggers,
}
}
/**
* Berechnet das nächste Review-Datum basierend auf dem Schedule.
*/
export function calculateNextReviewDate(schedule: DSFAReviewSchedule): Date {
const lastReview = schedule.last_review_date
? new Date(schedule.last_review_date)
: new Date()
const nextReview = new Date(lastReview)
nextReview.setMonth(nextReview.getMonth() + schedule.review_frequency_months)
return nextReview
}
/**
* Prüft, ob KI-spezifische DSFA-Trigger erfüllt sind.
*/
export function checkAIDSFATriggers(
aiTriggerIds: string[]
): { triggered: boolean; triggers: typeof AI_DSFA_TRIGGERS } {
const triggered = AI_DSFA_TRIGGERS.filter(t => aiTriggerIds.includes(t.id))
return {
triggered: triggered.length > 0,
triggers: triggered,
}
}
/**
* Generiert eine Checkliste für die Schwellwertanalyse.
*/
export function generateThresholdAnalysisChecklist(): Array<{
category: string
items: Array<{ id: string; label: string; description: string }>
}> {
return [
{
category: 'WP248 Kriterien (Art.-29-Datenschutzgruppe)',
items: WP248_CRITERIA.map(c => ({
id: c.id,
label: `${c.code}: ${c.title}`,
description: c.description,
})),
},
{
category: 'Art. 35 Abs. 3 DSGVO Regelbeispiele',
items: ART35_ABS3_CASES.map(c => ({
id: c.id,
label: `lit. ${c.lit}: ${c.title}`,
description: c.description,
})),
},
{
category: 'KI-spezifische Trigger (Deutsche DSFA-Liste)',
items: AI_DSFA_TRIGGERS.map(t => ({
id: t.id,
label: t.title,
description: t.description,
})),
},
]
}

View File

@@ -0,0 +1,17 @@
/**
* DSFA Types - Datenschutz-Folgenabschätzung (Art. 35 DSGVO)
*
* Barrel re-export of all domain modules.
*/
export * from './sdm-goals'
export * from './enums-constants'
export * from './wp248-criteria'
export * from './authority-resources'
export * from './dsk-references'
export * from './sub-types'
export * from './main-dsfa'
export * from './api-types'
export * from './ui-helpers'
export * from './risk-matrix'
export * from './helper-functions'

View File

@@ -0,0 +1,116 @@
// =============================================================================
// MAIN DSFA TYPE
// =============================================================================
import type { AIUseCaseModule } from '../ai-use-case-types'
export type { AIUseCaseModule } from '../ai-use-case-types'
import type { DSFAStatus, DSFARiskLevel } from './enums-constants'
import type {
DSFARisk,
DSFAMitigation,
DSFAReviewComment,
DSFASectionProgress,
DSFAThresholdAnalysis,
DSFAStakeholderConsultation,
DSFAConsultationRequirement,
DSFAReviewSchedule,
DSFAReviewTrigger,
} from './sub-types'
export interface DSFA {
id: string
tenant_id: string
namespace_id?: string
processing_activity_id?: string
assessment_id?: string
name: string
description: string
// Section 0: Schwellwertanalyse / Vorabprüfung (NEU - Art. 35 Abs. 1)
threshold_analysis?: DSFAThresholdAnalysis
wp248_criteria_met?: string[] // IDs der erfüllten WP248-Kriterien (K1-K9)
art35_abs3_triggered?: string[] // IDs der ausgelösten Art. 35 Abs. 3 Fälle
// Section 1: Systematische Beschreibung (Art. 35 Abs. 7 lit. a)
processing_description: string
processing_purpose: string
data_categories: string[]
data_subjects: string[]
recipients: string[]
legal_basis: string
legal_basis_details?: string
// Section 2: Notwendigkeit & Verhältnismäßigkeit (Art. 35 Abs. 7 lit. b)
necessity_assessment: string
proportionality_assessment: string
data_minimization?: string
alternatives_considered?: string
retention_justification?: string
// Section 3: Risikobewertung (Art. 35 Abs. 7 lit. c)
risks: DSFARisk[]
overall_risk_level: DSFARiskLevel
risk_score: number
affected_rights?: string[]
triggered_rule_codes?: string[]
// KI-spezifische Trigger (NEU)
involves_ai?: boolean
ai_trigger_ids?: string[] // IDs der ausgelösten KI-Trigger
// Section 8: KI-Anwendungsfälle (NEU)
ai_use_case_modules?: AIUseCaseModule[]
// Section 4: Abhilfemaßnahmen (Art. 35 Abs. 7 lit. d)
mitigations: DSFAMitigation[]
tom_references?: string[]
residual_risk_level?: DSFARiskLevel // Restrisiko nach Maßnahmen
// Section 5: Stellungnahme DSB (Art. 35 Abs. 2 + Art. 36)
dpo_consulted: boolean
dpo_consulted_at?: string
dpo_name?: string
dpo_opinion?: string
dpo_approved?: boolean
authority_consulted: boolean
authority_consulted_at?: string
authority_reference?: string
authority_decision?: string
// Art. 36 Konsultationspflicht (NEU)
consultation_requirement?: DSFAConsultationRequirement
// Betroffenenperspektive (NEU - Art. 35 Abs. 9)
stakeholder_consultations?: DSFAStakeholderConsultation[]
stakeholder_consultation_not_appropriate?: boolean
stakeholder_consultation_not_appropriate_reason?: string
// Workflow & Approval
status: DSFAStatus
submitted_for_review_at?: string
submitted_by?: string
conclusion: string
review_comments?: DSFAReviewComment[]
// Section Progress Tracking
section_progress: DSFASectionProgress
// Fortschreibung / Review (NEU - Art. 35 Abs. 11)
review_schedule?: DSFAReviewSchedule
review_triggers?: DSFAReviewTrigger[]
version: number // DSFA-Version für Fortschreibung
previous_version_id?: string
// Referenzen zu behördlichen Ressourcen
federal_state?: string // Bundesland für zuständige Aufsichtsbehörde
authority_resource_id?: string // ID aus DSFA_AUTHORITY_RESOURCES
// Metadata & Audit
metadata?: Record<string, unknown>
created_at: string
updated_at: string
created_by: string
approved_by?: string
approved_at?: string
}

View File

@@ -0,0 +1,35 @@
// =============================================================================
// RISK MATRIX HELPERS
// =============================================================================
import type { DSFARiskLevel } from './enums-constants'
export interface RiskMatrixCell {
likelihood: 'low' | 'medium' | 'high'
impact: 'low' | 'medium' | 'high'
level: DSFARiskLevel
score: number
}
export const RISK_MATRIX: RiskMatrixCell[] = [
// Low likelihood
{ likelihood: 'low', impact: 'low', level: 'low', score: 10 },
{ likelihood: 'low', impact: 'medium', level: 'low', score: 20 },
{ likelihood: 'low', impact: 'high', level: 'medium', score: 40 },
// Medium likelihood
{ likelihood: 'medium', impact: 'low', level: 'low', score: 20 },
{ likelihood: 'medium', impact: 'medium', level: 'medium', score: 50 },
{ likelihood: 'medium', impact: 'high', level: 'high', score: 70 },
// High likelihood
{ likelihood: 'high', impact: 'low', level: 'medium', score: 40 },
{ likelihood: 'high', impact: 'medium', level: 'high', score: 70 },
{ likelihood: 'high', impact: 'high', level: 'very_high', score: 90 },
]
export function calculateRiskLevel(
likelihood: 'low' | 'medium' | 'high',
impact: 'low' | 'medium' | 'high'
): { level: DSFARiskLevel; score: number } {
const cell = RISK_MATRIX.find(c => c.likelihood === likelihood && c.impact === impact)
return cell ? { level: cell.level, score: cell.score } : { level: 'medium', score: 50 }
}

View File

@@ -0,0 +1,50 @@
// =============================================================================
// SDM GEWAEHRLEISTUNGSZIELE (Standard-Datenschutzmodell V2.0)
// =============================================================================
export type SDMGoal =
| 'datenminimierung'
| 'verfuegbarkeit'
| 'integritaet'
| 'vertraulichkeit'
| 'nichtverkettung'
| 'transparenz'
| 'intervenierbarkeit'
export const SDM_GOALS: Record<SDMGoal, { name: string; description: string; article: string }> = {
datenminimierung: {
name: 'Datenminimierung',
description: 'Verarbeitung personenbezogener Daten auf das dem Zweck angemessene, erhebliche und notwendige Mass beschraenken.',
article: 'Art. 5 Abs. 1 lit. c DSGVO',
},
verfuegbarkeit: {
name: 'Verfuegbarkeit',
description: 'Personenbezogene Daten muessen dem Verantwortlichen zur Verfuegung stehen und ordnungsgemaess im vorgesehenen Prozess verwendet werden koennen.',
article: 'Art. 32 Abs. 1 lit. b DSGVO',
},
integritaet: {
name: 'Integritaet',
description: 'Personenbezogene Daten bleiben waehrend der Verarbeitung unversehrt, vollstaendig und aktuell.',
article: 'Art. 5 Abs. 1 lit. d DSGVO',
},
vertraulichkeit: {
name: 'Vertraulichkeit',
description: 'Kein unbefugter Zugriff auf personenbezogene Daten. Nur befugte Personen koennen auf Daten zugreifen.',
article: 'Art. 32 Abs. 1 lit. b DSGVO',
},
nichtverkettung: {
name: 'Nichtverkettung',
description: 'Personenbezogene Daten duerfen nicht ohne Weiteres fuer einen anderen als den erhobenen Zweck zusammengefuehrt werden (Zweckbindung).',
article: 'Art. 5 Abs. 1 lit. b DSGVO',
},
transparenz: {
name: 'Transparenz',
description: 'Die Verarbeitung personenbezogener Daten muss fuer Betroffene und Aufsichtsbehoerden nachvollziehbar sein.',
article: 'Art. 5 Abs. 1 lit. a DSGVO',
},
intervenierbarkeit: {
name: 'Intervenierbarkeit',
description: 'Den Betroffenen werden wirksame Moeglichkeiten der Einflussnahme (Auskunft, Berichtigung, Loeschung, Widerspruch) auf die Verarbeitung gewaehrt.',
article: 'Art. 15-21 DSGVO',
},
}

View File

@@ -0,0 +1,136 @@
// =============================================================================
// SUB-TYPES & SECTION PROGRESS
// =============================================================================
import type { DSFARiskCategory, DSFAMitigationType, DSFAMitigationStatus } from './enums-constants'
export interface DSFARisk {
id: string
category: DSFARiskCategory
description: string
likelihood: 'low' | 'medium' | 'high'
impact: 'low' | 'medium' | 'high'
risk_level: string
affected_data: string[]
}
export interface DSFAMitigation {
id: string
risk_id: string
description: string
type: DSFAMitigationType
status: DSFAMitigationStatus
implemented_at?: string
verified_at?: string
residual_risk: 'low' | 'medium' | 'high'
tom_reference?: string
responsible_party: string
}
export interface DSFAReviewComment {
id: string
section: number
comment: string
created_by: string
created_at: string
resolved: boolean
}
export interface DSFASectionProgress {
section_0_complete: boolean // Schwellwertanalyse
section_1_complete: boolean // Systematische Beschreibung
section_2_complete: boolean // Notwendigkeit & Verhältnismäßigkeit
section_3_complete: boolean // Risikobewertung
section_4_complete: boolean // Abhilfemaßnahmen
section_5_complete: boolean // Betroffenenperspektive (optional)
section_6_complete: boolean // DSB & Behördenkonsultation
section_7_complete: boolean // Fortschreibung & Review
section_8_complete?: boolean // KI-Anwendungsfälle (optional)
}
// =============================================================================
// SCHWELLWERTANALYSE / VORABPRÜFUNG (Art. 35 Abs. 1 DSGVO)
// =============================================================================
export interface DSFAThresholdAnalysis {
id: string
dsfa_id?: string
performed_at: string
performed_by: string
// WP248 Kriterien-Bewertung
criteria_assessment: Array<{
criterion_id: string // K1-K9
applies: boolean
justification: string
}>
// Art. 35 Abs. 3 Prüfung
art35_abs3_assessment: Array<{
case_id: string // a, b, c
applies: boolean
justification: string
}>
// Ergebnis
dsfa_required: boolean
decision_justification: string
// Dokumentation der Entscheidung (gem. DSK Kurzpapier Nr. 5)
documented: boolean
documentation_reference?: string
}
// =============================================================================
// BETROFFENENPERSPEKTIVE (Art. 35 Abs. 9 DSGVO)
// =============================================================================
export interface DSFAStakeholderConsultation {
id: string
stakeholder_type: 'data_subjects' | 'representatives' | 'works_council' | 'other'
stakeholder_description: string
consultation_date?: string
consultation_method: 'survey' | 'interview' | 'workshop' | 'written' | 'other'
summary: string
concerns_raised: string[]
addressed_in_dsfa: boolean
response_documentation?: string
}
// =============================================================================
// ART. 36 KONSULTATIONSPFLICHT
// =============================================================================
export interface DSFAConsultationRequirement {
high_residual_risk: boolean
consultation_required: boolean // Art. 36 Abs. 1 DSGVO
consultation_reason?: string
authority_notified: boolean
notification_date?: string
authority_response?: string
authority_recommendations?: string[]
waiting_period_observed: boolean // 8 Wochen gem. Art. 36 Abs. 2
}
// =============================================================================
// FORTSCHREIBUNG / REVIEW (Art. 35 Abs. 11 DSGVO)
// =============================================================================
export interface DSFAReviewTrigger {
id: string
trigger_type: 'scheduled' | 'risk_change' | 'new_technology' | 'new_purpose' | 'incident' | 'regulatory' | 'other'
description: string
detected_at: string
detected_by: string
review_required: boolean
review_completed: boolean
review_date?: string
changes_made: string[]
}
export interface DSFAReviewSchedule {
next_review_date: string
review_frequency_months: number
last_review_date?: string
review_responsible: string
}

View File

@@ -0,0 +1,97 @@
// =============================================================================
// HELPER TYPES FOR UI
// =============================================================================
export interface DSFASectionConfig {
number: number
title: string
titleDE: string
description: string
gdprRef: string
fields: string[]
required: boolean
}
export const DSFA_SECTIONS: DSFASectionConfig[] = [
{
number: 0,
title: 'Threshold Analysis',
titleDE: 'Schwellwertanalyse',
description: 'Prüfen Sie anhand der WP248-Kriterien und Art. 35 Abs. 3, ob eine DSFA erforderlich ist. Die Entscheidung ist zu dokumentieren.',
gdprRef: 'Art. 35 Abs. 1 DSGVO, WP248 rev.01',
fields: ['threshold_analysis', 'wp248_criteria_met', 'art35_abs3_triggered'],
required: true,
},
{
number: 1,
title: 'Processing Description',
titleDE: 'Systematische Beschreibung',
description: 'Beschreiben Sie die geplante Verarbeitung, ihren Zweck, die Datenkategorien und Rechtsgrundlage.',
gdprRef: 'Art. 35 Abs. 7 lit. a DSGVO',
fields: ['processing_description', 'processing_purpose', 'data_categories', 'data_subjects', 'recipients', 'legal_basis'],
required: true,
},
{
number: 2,
title: 'Necessity & Proportionality',
titleDE: 'Notwendigkeit & Verhältnismäßigkeit',
description: 'Begründen Sie, warum die Verarbeitung notwendig ist und welche Alternativen geprüft wurden.',
gdprRef: 'Art. 35 Abs. 7 lit. b DSGVO',
fields: ['necessity_assessment', 'proportionality_assessment', 'data_minimization', 'alternatives_considered'],
required: true,
},
{
number: 3,
title: 'Risk Assessment',
titleDE: 'Risikobewertung',
description: 'Identifizieren und bewerten Sie die Risiken für die Rechte und Freiheiten der Betroffenen.',
gdprRef: 'Art. 35 Abs. 7 lit. c DSGVO',
fields: ['risks', 'overall_risk_level', 'risk_score', 'affected_rights', 'involves_ai', 'ai_trigger_ids'],
required: true,
},
{
number: 4,
title: 'Mitigation Measures',
titleDE: 'Abhilfemaßnahmen',
description: 'Definieren Sie technische und organisatorische Maßnahmen zur Risikominimierung und bewerten Sie das Restrisiko.',
gdprRef: 'Art. 35 Abs. 7 lit. d DSGVO',
fields: ['mitigations', 'tom_references', 'residual_risk_level'],
required: true,
},
{
number: 5,
title: 'Stakeholder Consultation',
titleDE: 'Betroffenenperspektive',
description: 'Dokumentieren Sie, ob und wie die Standpunkte der Betroffenen eingeholt wurden (z.B. Betriebsrat, Nutzerumfragen).',
gdprRef: 'Art. 35 Abs. 9 DSGVO',
fields: ['stakeholder_consultations', 'stakeholder_consultation_not_appropriate', 'stakeholder_consultation_not_appropriate_reason'],
required: false,
},
{
number: 6,
title: 'DPO Opinion & Authority Consultation',
titleDE: 'DSB-Stellungnahme & Behördenkonsultation',
description: 'Dokumentieren Sie die Konsultation des DSB und prüfen Sie, ob bei hohem Restrisiko eine Behördenkonsultation erforderlich ist.',
gdprRef: 'Art. 35 Abs. 2, Art. 36 DSGVO',
fields: ['dpo_consulted', 'dpo_opinion', 'consultation_requirement', 'authority_consulted', 'authority_reference'],
required: true,
},
{
number: 7,
title: 'Review & Maintenance',
titleDE: 'Fortschreibung & Review',
description: 'Planen Sie regelmäßige Überprüfungen und dokumentieren Sie Änderungen, die eine Aktualisierung der DSFA erfordern.',
gdprRef: 'Art. 35 Abs. 11 DSGVO',
fields: ['review_schedule', 'review_triggers', 'version'],
required: true,
},
{
number: 8,
title: 'AI Use Cases',
titleDE: 'KI-Anwendungsfälle',
description: 'Modulare Anhänge für KI-spezifische Risiken und Maßnahmen nach Art. 22 DSGVO und EU AI Act.',
gdprRef: 'Art. 35 DSGVO, Art. 22 DSGVO, EU AI Act',
fields: ['ai_use_case_modules'],
required: false,
},
]

View File

@@ -0,0 +1,91 @@
// =============================================================================
// WP248 REV.01 KRITERIEN (Schwellwertanalyse)
// Quelle: Artikel-29-Datenschutzgruppe, bestätigt durch EDSA
// =============================================================================
export interface WP248Criterion {
id: string
code: string
title: string
description: string
examples: string[]
gdprRef?: string
}
/**
* WP248 rev.01 Kriterien zur Bestimmung der DSFA-Pflicht
* Regel: Bei >= 2 erfüllten Kriterien ist DSFA in den meisten Fällen erforderlich
*/
export const WP248_CRITERIA: WP248Criterion[] = [
{
id: 'scoring_profiling',
code: 'K1',
title: 'Bewertung oder Scoring',
description: 'Einschließlich Profiling und Prognosen, insbesondere zu Arbeitsleistung, wirtschaftlicher Lage, Gesundheit, persönlichen Vorlieben, Zuverlässigkeit, Verhalten, Aufenthaltsort oder Ortswechsel.',
examples: ['Bonitätsprüfung', 'Leistungsbeurteilung', 'Verhaltensanalyse'],
gdprRef: 'Art. 35 Abs. 3 lit. a DSGVO',
},
{
id: 'automated_decision',
code: 'K2',
title: 'Automatisierte Entscheidungsfindung mit Rechtswirkung',
description: 'Automatisierte Verarbeitung, die als Grundlage für Entscheidungen dient, die Rechtswirkung gegenüber natürlichen Personen entfalten oder diese erheblich beeinträchtigen.',
examples: ['Automatische Kreditvergabe', 'Automatische Bewerbungsablehnung', 'Algorithmenbasierte Preisgestaltung'],
gdprRef: 'Art. 22 DSGVO',
},
{
id: 'systematic_monitoring',
code: 'K3',
title: 'Systematische Überwachung',
description: 'Verarbeitung zur Beobachtung, Überwachung oder Kontrolle von betroffenen Personen, einschließlich Datenerhebung über Netzwerke oder systematische Überwachung öffentlicher Bereiche.',
examples: ['Videoüberwachung', 'WLAN-Tracking', 'GPS-Ortung', 'Mitarbeiterüberwachung'],
gdprRef: 'Art. 35 Abs. 3 lit. c DSGVO',
},
{
id: 'sensitive_data',
code: 'K4',
title: 'Sensible Daten oder höchst persönliche Daten',
description: 'Verarbeitung besonderer Kategorien personenbezogener Daten (Art. 9), strafrechtlicher Daten (Art. 10) oder anderer höchst persönlicher Daten wie Kommunikationsinhalte, Standortdaten, Finanzinformationen.',
examples: ['Gesundheitsdaten', 'Biometrische Daten', 'Genetische Daten', 'Politische Meinungen', 'Gewerkschaftszugehörigkeit'],
gdprRef: 'Art. 9, Art. 10 DSGVO',
},
{
id: 'large_scale',
code: 'K5',
title: 'Datenverarbeitung in großem Umfang',
description: 'Berücksichtigt werden: Zahl der Betroffenen, Datenmenge, Dauer der Verarbeitung, geografische Reichweite.',
examples: ['Landesweite Datenbanken', 'Millionen von Nutzern', 'Mehrjährige Speicherung'],
gdprRef: 'Erwägungsgrund 91 DSGVO',
},
{
id: 'matching_combining',
code: 'K6',
title: 'Abgleichen oder Zusammenführen von Datensätzen',
description: 'Datensätze aus verschiedenen Quellen, die für unterschiedliche Zwecke und/oder von verschiedenen Verantwortlichen erhoben wurden, werden abgeglichen oder zusammengeführt.',
examples: ['Data Warehousing', 'Big Data Analytics', 'Zusammenführung von Online-/Offline-Daten'],
},
{
id: 'vulnerable_subjects',
code: 'K7',
title: 'Daten zu schutzbedürftigen Betroffenen',
description: 'Verarbeitung von Daten schutzbedürftiger Personen, bei denen ein Ungleichgewicht zwischen Betroffenem und Verantwortlichem besteht.',
examples: ['Kinder/Minderjährige', 'Arbeitnehmer', 'Patienten', 'Ältere Menschen', 'Asylbewerber'],
gdprRef: 'Erwägungsgrund 75 DSGVO',
},
{
id: 'innovative_technology',
code: 'K8',
title: 'Innovative Nutzung oder Anwendung neuer technologischer oder organisatorischer Lösungen',
description: 'Einsatz neuer Technologien kann neue Formen der Datenerhebung und -nutzung mit sich bringen, möglicherweise mit hohem Risiko für Rechte und Freiheiten.',
examples: ['Künstliche Intelligenz', 'Machine Learning', 'IoT-Geräte', 'Biometrische Erkennung', 'Blockchain'],
gdprRef: 'Erwägungsgrund 89, 91 DSGVO',
},
{
id: 'preventing_rights',
code: 'K9',
title: 'Verarbeitung, die Betroffene an der Ausübung eines Rechts oder der Nutzung einer Dienstleistung hindert',
description: 'Verarbeitungsvorgänge, die darauf abzielen, einer Person den Zugang zu einer Dienstleistung oder den Abschluss eines Vertrags zu ermöglichen oder zu verweigern.',
examples: ['Zugang zu Sozialleistungen', 'Kreditvergabe', 'Versicherungsabschluss'],
gdprRef: 'Art. 22 DSGVO',
},
]

View File

@@ -1,838 +0,0 @@
/**
* Datenpunktkatalog & Datenschutzinformationen-Generator
* TypeScript Interfaces
*
* Dieses Modul definiert alle Typen für:
* - Datenpunktkatalog (32 vordefinierte + kundenspezifische)
* - Privacy Policy Generator
* - Cookie Banner Configuration
* - Retention Matrix
*/
// =============================================================================
// ENUMS
// =============================================================================
/**
* Kategorien für Datenpunkte (18 Kategorien: A-R)
*/
export type DataPointCategory =
| 'MASTER_DATA' // A: Stammdaten
| 'CONTACT_DATA' // B: Kontaktdaten
| 'AUTHENTICATION' // C: Authentifizierungsdaten
| 'CONSENT' // D: Einwilligungsdaten
| 'COMMUNICATION' // E: Kommunikationsdaten
| 'PAYMENT' // F: Zahlungsdaten
| 'USAGE_DATA' // G: Nutzungsdaten
| 'LOCATION' // H: Standortdaten
| 'DEVICE_DATA' // I: Gerätedaten
| 'MARKETING' // J: Marketingdaten
| 'ANALYTICS' // K: Analysedaten
| 'SOCIAL_MEDIA' // L: Social-Media-Daten
| 'HEALTH_DATA' // M: Gesundheitsdaten (Art. 9 DSGVO)
| 'EMPLOYEE_DATA' // N: Beschäftigtendaten
| 'CONTRACT_DATA' // O: Vertragsdaten
| 'LOG_DATA' // P: Protokolldaten
| 'AI_DATA' // Q: KI-Daten
| 'SECURITY' // R: Sicherheitsdaten
/**
* Risikoniveau für Datenpunkte
*/
export type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH'
/**
* Rechtsgrundlagen nach DSGVO Art. 6 und Art. 9
*/
export type LegalBasis =
| 'CONTRACT' // Art. 6 Abs. 1 lit. b DSGVO
| 'CONSENT' // Art. 6 Abs. 1 lit. a DSGVO
| 'EXPLICIT_CONSENT' // Art. 9 Abs. 2 lit. a DSGVO (für Art. 9 Daten)
| 'LEGITIMATE_INTEREST' // Art. 6 Abs. 1 lit. f DSGVO
| 'LEGAL_OBLIGATION' // Art. 6 Abs. 1 lit. c DSGVO
| 'VITAL_INTERESTS' // Art. 6 Abs. 1 lit. d DSGVO
| 'PUBLIC_INTEREST' // Art. 6 Abs. 1 lit. e DSGVO
/**
* Aufbewahrungsfristen
*/
export type RetentionPeriod =
| '24_HOURS'
| '30_DAYS'
| '90_DAYS'
| '12_MONTHS'
| '24_MONTHS'
| '26_MONTHS' // Google Analytics Standard
| '36_MONTHS'
| '48_MONTHS'
| '6_YEARS'
| '10_YEARS'
| 'UNTIL_REVOCATION'
| 'UNTIL_PURPOSE_FULFILLED'
| 'UNTIL_ACCOUNT_DELETION'
/**
* Cookie-Kategorien für Cookie-Banner
*/
export type CookieCategory =
| 'ESSENTIAL' // Technisch notwendig
| 'PERFORMANCE' // Analyse & Performance
| 'PERSONALIZATION' // Personalisierung
| 'EXTERNAL_MEDIA' // Externe Medien
/**
* Export-Formate für Privacy Policy
*/
export type ExportFormat = 'HTML' | 'MARKDOWN' | 'PDF' | 'DOCX'
/**
* Sprachen
*/
export type SupportedLanguage = 'de' | 'en'
// =============================================================================
// DATA POINT
// =============================================================================
/**
* Lokalisierter Text (DE/EN)
*/
export interface LocalizedText {
de: string
en: string
}
/**
* Einzelner Datenpunkt im Katalog
*/
export interface DataPoint {
id: string
code: string // z.B. "A1", "B2", "C3"
category: DataPointCategory
name: LocalizedText
description: LocalizedText
purpose: LocalizedText
riskLevel: RiskLevel
legalBasis: LegalBasis
legalBasisJustification: LocalizedText
retentionPeriod: RetentionPeriod
retentionJustification: LocalizedText
cookieCategory: CookieCategory | null // null = kein Cookie
isSpecialCategory: boolean // Art. 9 DSGVO (sensible Daten)
requiresExplicitConsent: boolean
thirdPartyRecipients: string[]
technicalMeasures: string[]
tags: string[]
isCustom?: boolean // Kundenspezifischer Datenpunkt
isActive?: boolean // Aktiviert fuer diesen Tenant
}
/**
* YAML-Struktur fuer Datenpunkte (fuer Loader)
*/
export interface DataPointYAML {
id: string
code: string
category: string
name_de: string
name_en: string
description_de: string
description_en: string
purpose_de: string
purpose_en: string
risk_level: string
legal_basis: string
legal_basis_justification_de: string
legal_basis_justification_en: string
retention_period: string
retention_justification_de: string
retention_justification_en: string
cookie_category: string | null
is_special_category: boolean
requires_explicit_consent: boolean
third_party_recipients: string[]
technical_measures: string[]
tags: string[]
}
// =============================================================================
// CATALOG & RETENTION MATRIX
// =============================================================================
/**
* Gesamter Datenpunktkatalog eines Tenants
*/
export interface DataPointCatalog {
id: string
tenantId: string
version: string
dataPoints: DataPoint[] // Vordefinierte (32)
customDataPoints: DataPoint[] // Kundenspezifische
retentionMatrix: RetentionMatrixEntry[]
createdAt: Date
updatedAt: Date
}
/**
* Eintrag in der Retention Matrix
*/
export interface RetentionMatrixEntry {
category: DataPointCategory
categoryName: LocalizedText
standardPeriod: RetentionPeriod
legalBasis: string
exceptions: RetentionException[]
}
/**
* Ausnahme von der Standard-Loeschfrist
*/
export interface RetentionException {
condition: LocalizedText
period: RetentionPeriod
reason: LocalizedText
}
// =============================================================================
// PRIVACY POLICY GENERATION
// =============================================================================
/**
* Abschnitt in der Privacy Policy
*/
export interface PrivacyPolicySection {
id: string
order: number
title: LocalizedText
content: LocalizedText
dataPointIds: string[]
isRequired: boolean
isGenerated: boolean // true = aus Datenpunkten generiert
}
/**
* Unternehmensinfo fuer Privacy Policy
*/
export interface CompanyInfo {
name: string
address: string
city: string
postalCode: string
country: string
email: string
phone?: string
website?: string
dpoName?: string // Datenschutzbeauftragter
dpoEmail?: string
dpoPhone?: string
registrationNumber?: string // Handelsregister
vatId?: string // USt-IdNr
}
/**
* Generierte Privacy Policy
*/
export interface GeneratedPrivacyPolicy {
id: string
tenantId: string
language: SupportedLanguage
sections: PrivacyPolicySection[]
companyInfo: CompanyInfo
generatedAt: Date
version: string
format: ExportFormat
content?: string // Rendered content (HTML/MD)
}
/**
* Optionen fuer Privacy Policy Generierung
*/
export interface PrivacyPolicyGenerationOptions {
language: SupportedLanguage
format: ExportFormat
includeDataPoints: string[] // Welche Datenpunkte einschliessen
customSections?: PrivacyPolicySection[] // Zusaetzliche Abschnitte
styling?: PrivacyPolicyStyling
}
/**
* Styling-Optionen fuer PDF/HTML Export
*/
export interface PrivacyPolicyStyling {
primaryColor?: string
fontFamily?: string
fontSize?: number
headerFontSize?: number
includeTableOfContents?: boolean
includeDateFooter?: boolean
logoUrl?: string
}
// =============================================================================
// COOKIE BANNER CONFIG
// =============================================================================
/**
* Einzelner Cookie in einer Kategorie
*/
export interface CookieInfo {
name: string
provider: string
purpose: LocalizedText
expiry: string
type: 'FIRST_PARTY' | 'THIRD_PARTY'
}
/**
* Cookie-Banner Kategorie
*/
export interface CookieBannerCategory {
id: CookieCategory
name: LocalizedText
description: LocalizedText
isRequired: boolean // Essentiell = required
defaultEnabled: boolean
dataPointIds: string[] // Verknuepfte Datenpunkte
cookies: CookieInfo[]
}
/**
* Styling fuer Cookie Banner
*/
export interface CookieBannerStyling {
position: 'BOTTOM' | 'TOP' | 'CENTER'
theme: 'LIGHT' | 'DARK' | 'CUSTOM'
primaryColor?: string
secondaryColor?: string
textColor?: string
backgroundColor?: string
borderRadius?: number
maxWidth?: number
}
/**
* Texte fuer Cookie Banner
*/
export interface CookieBannerTexts {
title: LocalizedText
description: LocalizedText
acceptAll: LocalizedText
rejectAll: LocalizedText
customize: LocalizedText
save: LocalizedText
privacyPolicyLink: LocalizedText
}
/**
* Generierter Code fuer Cookie Banner
*/
export interface CookieBannerEmbedCode {
html: string
css: string
js: string
scriptTag: string // Fertiger Script-Tag zum Einbinden
}
/**
* Vollstaendige Cookie Banner Konfiguration
*/
export interface CookieBannerConfig {
id: string
tenantId: string
categories: CookieBannerCategory[]
styling: CookieBannerStyling
texts: CookieBannerTexts
embedCode?: CookieBannerEmbedCode
updatedAt: Date
}
// =============================================================================
// CONSENT MANAGEMENT
// =============================================================================
/**
* Einzelne Einwilligung eines Nutzers
*/
export interface ConsentEntry {
id: string
userId: string
dataPointId: string
granted: boolean
grantedAt: Date
revokedAt?: Date
ipAddress?: string
userAgent?: string
consentVersion: string
}
/**
* Aggregierte Consent-Statistiken
*/
export interface ConsentStatistics {
totalConsents: number
activeConsents: number
revokedConsents: number
byCategory: Record<DataPointCategory, {
total: number
active: number
revoked: number
}>
byLegalBasis: Record<LegalBasis, {
total: number
active: number
}>
conversionRate: number // Prozent der Nutzer mit Consent
}
// =============================================================================
// EINWILLIGUNGEN STATE & ACTIONS
// =============================================================================
/**
* Aktiver Tab in der Einwilligungen-Ansicht
*/
export type EinwilligungenTab =
| 'catalog'
| 'privacy-policy'
| 'cookie-banner'
| 'retention'
| 'consents'
/**
* State fuer Einwilligungen-Modul
*/
export interface EinwilligungenState {
// Data
catalog: DataPointCatalog | null
selectedDataPoints: string[]
privacyPolicy: GeneratedPrivacyPolicy | null
cookieBannerConfig: CookieBannerConfig | null
companyInfo: CompanyInfo | null
consentStatistics: ConsentStatistics | null
// UI State
activeTab: EinwilligungenTab
isLoading: boolean
isSaving: boolean
error: string | null
// Editor State
editingDataPoint: DataPoint | null
editingSection: PrivacyPolicySection | null
// Preview
previewLanguage: SupportedLanguage
previewFormat: ExportFormat
}
/**
* Actions fuer Einwilligungen-Reducer
*/
export type EinwilligungenAction =
| { type: 'SET_CATALOG'; payload: DataPointCatalog }
| { type: 'SET_SELECTED_DATA_POINTS'; payload: string[] }
| { type: 'TOGGLE_DATA_POINT'; payload: string }
| { type: 'ADD_CUSTOM_DATA_POINT'; payload: DataPoint }
| { type: 'UPDATE_DATA_POINT'; payload: { id: string; data: Partial<DataPoint> } }
| { type: 'DELETE_CUSTOM_DATA_POINT'; payload: string }
| { type: 'SET_PRIVACY_POLICY'; payload: GeneratedPrivacyPolicy }
| { type: 'SET_COOKIE_BANNER_CONFIG'; payload: CookieBannerConfig }
| { type: 'UPDATE_COOKIE_BANNER_STYLING'; payload: Partial<CookieBannerStyling> }
| { type: 'UPDATE_COOKIE_BANNER_TEXTS'; payload: Partial<CookieBannerTexts> }
| { type: 'SET_COMPANY_INFO'; payload: CompanyInfo }
| { type: 'SET_CONSENT_STATISTICS'; payload: ConsentStatistics }
| { type: 'SET_ACTIVE_TAB'; payload: EinwilligungenTab }
| { type: 'SET_LOADING'; payload: boolean }
| { type: 'SET_SAVING'; payload: boolean }
| { type: 'SET_ERROR'; payload: string | null }
| { type: 'SET_EDITING_DATA_POINT'; payload: DataPoint | null }
| { type: 'SET_EDITING_SECTION'; payload: PrivacyPolicySection | null }
| { type: 'SET_PREVIEW_LANGUAGE'; payload: SupportedLanguage }
| { type: 'SET_PREVIEW_FORMAT'; payload: ExportFormat }
| { type: 'RESET_STATE' }
// =============================================================================
// HELPER TYPES
// =============================================================================
/**
* Kategorie-Metadaten
*/
export interface CategoryMetadata {
id: DataPointCategory
code: string // A, B, C, etc.
name: LocalizedText
description: LocalizedText
icon: string // Icon name
color: string // Tailwind color class
}
/**
* Mapping von Kategorie zu Metadaten (18 Kategorien)
*/
export const CATEGORY_METADATA: Record<DataPointCategory, CategoryMetadata> = {
MASTER_DATA: {
id: 'MASTER_DATA',
code: 'A',
name: { de: 'Stammdaten', en: 'Master Data' },
description: { de: 'Grundlegende personenbezogene Daten', en: 'Basic personal data' },
icon: 'User',
color: 'blue'
},
CONTACT_DATA: {
id: 'CONTACT_DATA',
code: 'B',
name: { de: 'Kontaktdaten', en: 'Contact Data' },
description: { de: 'Kontaktinformationen und Erreichbarkeit', en: 'Contact information and availability' },
icon: 'Mail',
color: 'sky'
},
AUTHENTICATION: {
id: 'AUTHENTICATION',
code: 'C',
name: { de: 'Authentifizierungsdaten', en: 'Authentication Data' },
description: { de: 'Daten zur Benutzeranmeldung und Session-Verwaltung', en: 'Data for user login and session management' },
icon: 'Key',
color: 'slate'
},
CONSENT: {
id: 'CONSENT',
code: 'D',
name: { de: 'Einwilligungsdaten', en: 'Consent Data' },
description: { de: 'Einwilligungen und Datenschutzpraeferenzen', en: 'Consents and privacy preferences' },
icon: 'CheckCircle',
color: 'green'
},
COMMUNICATION: {
id: 'COMMUNICATION',
code: 'E',
name: { de: 'Kommunikationsdaten', en: 'Communication Data' },
description: { de: 'Kundenservice und Kommunikationsdaten', en: 'Customer service and communication data' },
icon: 'MessageSquare',
color: 'cyan'
},
PAYMENT: {
id: 'PAYMENT',
code: 'F',
name: { de: 'Zahlungsdaten', en: 'Payment Data' },
description: { de: 'Rechnungs- und Zahlungsinformationen', en: 'Billing and payment information' },
icon: 'CreditCard',
color: 'amber'
},
USAGE_DATA: {
id: 'USAGE_DATA',
code: 'G',
name: { de: 'Nutzungsdaten', en: 'Usage Data' },
description: { de: 'Daten zur Nutzung des Dienstes', en: 'Data about service usage' },
icon: 'Activity',
color: 'violet'
},
LOCATION: {
id: 'LOCATION',
code: 'H',
name: { de: 'Standortdaten', en: 'Location Data' },
description: { de: 'Geografische Standortinformationen', en: 'Geographic location information' },
icon: 'MapPin',
color: 'emerald'
},
DEVICE_DATA: {
id: 'DEVICE_DATA',
code: 'I',
name: { de: 'Geraetedaten', en: 'Device Data' },
description: { de: 'Technische Geraete- und Browserinformationen', en: 'Technical device and browser information' },
icon: 'Smartphone',
color: 'zinc'
},
MARKETING: {
id: 'MARKETING',
code: 'J',
name: { de: 'Marketingdaten', en: 'Marketing Data' },
description: { de: 'Marketing- und Werbedaten', en: 'Marketing and advertising data' },
icon: 'Megaphone',
color: 'purple'
},
ANALYTICS: {
id: 'ANALYTICS',
code: 'K',
name: { de: 'Analysedaten', en: 'Analytics Data' },
description: { de: 'Web-Analyse und Nutzungsstatistiken', en: 'Web analytics and usage statistics' },
icon: 'BarChart3',
color: 'indigo'
},
SOCIAL_MEDIA: {
id: 'SOCIAL_MEDIA',
code: 'L',
name: { de: 'Social-Media-Daten', en: 'Social Media Data' },
description: { de: 'Daten aus sozialen Netzwerken', en: 'Data from social networks' },
icon: 'Share2',
color: 'pink'
},
HEALTH_DATA: {
id: 'HEALTH_DATA',
code: 'M',
name: { de: 'Gesundheitsdaten', en: 'Health Data' },
description: { de: 'Besondere Kategorie nach Art. 9 DSGVO - Gesundheitsbezogene Daten', en: 'Special category under Art. 9 GDPR - Health-related data' },
icon: 'Heart',
color: 'rose'
},
EMPLOYEE_DATA: {
id: 'EMPLOYEE_DATA',
code: 'N',
name: { de: 'Beschaeftigtendaten', en: 'Employee Data' },
description: { de: 'Personalverwaltung und Arbeitnehmerinformationen (BDSG § 26)', en: 'HR management and employee information' },
icon: 'Briefcase',
color: 'orange'
},
CONTRACT_DATA: {
id: 'CONTRACT_DATA',
code: 'O',
name: { de: 'Vertragsdaten', en: 'Contract Data' },
description: { de: 'Vertragsinformationen und -dokumente', en: 'Contract information and documents' },
icon: 'FileText',
color: 'teal'
},
LOG_DATA: {
id: 'LOG_DATA',
code: 'P',
name: { de: 'Protokolldaten', en: 'Log Data' },
description: { de: 'System- und Zugriffsprotokolle', en: 'System and access logs' },
icon: 'FileCode',
color: 'gray'
},
AI_DATA: {
id: 'AI_DATA',
code: 'Q',
name: { de: 'KI-Daten', en: 'AI Data' },
description: { de: 'KI-Interaktionen, Prompts und generierte Inhalte (AI Act)', en: 'AI interactions, prompts and generated content (AI Act)' },
icon: 'Bot',
color: 'fuchsia'
},
SECURITY: {
id: 'SECURITY',
code: 'R',
name: { de: 'Sicherheitsdaten', en: 'Security Data' },
description: { de: 'Sicherheitsrelevante Daten und Vorfallberichte', en: 'Security-relevant data and incident reports' },
icon: 'Shield',
color: 'red'
}
}
/**
* Mapping von Rechtsgrundlage zu Beschreibung
*/
export const LEGAL_BASIS_INFO: Record<LegalBasis, { article: string; name: LocalizedText; description: LocalizedText }> = {
CONTRACT: {
article: 'Art. 6 Abs. 1 lit. b DSGVO',
name: { de: 'Vertragserfuellung', en: 'Contract Performance' },
description: {
de: 'Die Verarbeitung ist erforderlich fuer die Erfuellung eines Vertrags oder zur Durchfuehrung vorvertraglicher Massnahmen.',
en: 'Processing is necessary for the performance of a contract or pre-contractual measures.'
}
},
CONSENT: {
article: 'Art. 6 Abs. 1 lit. a DSGVO',
name: { de: 'Einwilligung', en: 'Consent' },
description: {
de: 'Die betroffene Person hat ihre Einwilligung zu der Verarbeitung gegeben.',
en: 'The data subject has given consent to the processing.'
}
},
EXPLICIT_CONSENT: {
article: 'Art. 9 Abs. 2 lit. a DSGVO',
name: { de: 'Ausdrueckliche Einwilligung', en: 'Explicit Consent' },
description: {
de: 'Die betroffene Person hat ausdruecklich in die Verarbeitung besonderer Kategorien personenbezogener Daten (Art. 9 DSGVO) eingewilligt. Dies betrifft Gesundheitsdaten, biometrische Daten, Daten zur ethnischen Herkunft, politische Meinungen, religiöse Überzeugungen etc.',
en: 'The data subject has given explicit consent to the processing of special categories of personal data (Art. 9 GDPR). This includes health data, biometric data, racial or ethnic origin, political opinions, religious beliefs, etc.'
}
},
LEGITIMATE_INTEREST: {
article: 'Art. 6 Abs. 1 lit. f DSGVO',
name: { de: 'Berechtigtes Interesse', en: 'Legitimate Interest' },
description: {
de: 'Die Verarbeitung ist zur Wahrung berechtigter Interessen des Verantwortlichen erforderlich.',
en: 'Processing is necessary for legitimate interests pursued by the controller.'
}
},
LEGAL_OBLIGATION: {
article: 'Art. 6 Abs. 1 lit. c DSGVO',
name: { de: 'Rechtliche Verpflichtung', en: 'Legal Obligation' },
description: {
de: 'Die Verarbeitung ist zur Erfuellung einer rechtlichen Verpflichtung erforderlich.',
en: 'Processing is necessary for compliance with a legal obligation.'
}
},
VITAL_INTERESTS: {
article: 'Art. 6 Abs. 1 lit. d DSGVO',
name: { de: 'Lebenswichtige Interessen', en: 'Vital Interests' },
description: {
de: 'Die Verarbeitung ist erforderlich, um lebenswichtige Interessen der betroffenen Person oder einer anderen natuerlichen Person zu schuetzen.',
en: 'Processing is necessary to protect the vital interests of the data subject or another natural person.'
}
},
PUBLIC_INTEREST: {
article: 'Art. 6 Abs. 1 lit. e DSGVO',
name: { de: 'Oeffentliches Interesse', en: 'Public Interest' },
description: {
de: 'Die Verarbeitung ist fuer die Wahrnehmung einer Aufgabe erforderlich, die im oeffentlichen Interesse liegt oder in Ausuebung oeffentlicher Gewalt erfolgt.',
en: 'Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority.'
}
}
}
/**
* Mapping von Aufbewahrungsfrist zu Beschreibung
*/
export const RETENTION_PERIOD_INFO: Record<RetentionPeriod, { label: LocalizedText; days: number | null }> = {
'24_HOURS': { label: { de: '24 Stunden', en: '24 Hours' }, days: 1 },
'30_DAYS': { label: { de: '30 Tage', en: '30 Days' }, days: 30 },
'90_DAYS': { label: { de: '90 Tage', en: '90 Days' }, days: 90 },
'12_MONTHS': { label: { de: '12 Monate', en: '12 Months' }, days: 365 },
'24_MONTHS': { label: { de: '24 Monate', en: '24 Months' }, days: 730 },
'26_MONTHS': { label: { de: '26 Monate (Google Analytics)', en: '26 Months (Google Analytics)' }, days: 790 },
'36_MONTHS': { label: { de: '36 Monate', en: '36 Months' }, days: 1095 },
'48_MONTHS': { label: { de: '48 Monate', en: '48 Months' }, days: 1460 },
'6_YEARS': { label: { de: '6 Jahre', en: '6 Years' }, days: 2190 },
'10_YEARS': { label: { de: '10 Jahre', en: '10 Years' }, days: 3650 },
'UNTIL_REVOCATION': { label: { de: 'Bis Widerruf', en: 'Until Revocation' }, days: null },
'UNTIL_PURPOSE_FULFILLED': { label: { de: 'Bis Zweckerfuellung', en: 'Until Purpose Fulfilled' }, days: null },
'UNTIL_ACCOUNT_DELETION': { label: { de: 'Bis Kontoschliessung', en: 'Until Account Deletion' }, days: null }
}
/**
* Spezielle Hinweise für Art. 9 DSGVO Kategorien
*/
export interface Article9Warning {
title: LocalizedText
description: LocalizedText
requirements: LocalizedText[]
}
export const ARTICLE_9_WARNING: Article9Warning = {
title: {
de: 'Besondere Kategorie personenbezogener Daten (Art. 9 DSGVO)',
en: 'Special Category of Personal Data (Art. 9 GDPR)'
},
description: {
de: 'Die Verarbeitung dieser Daten unterliegt besonderen Anforderungen nach Art. 9 DSGVO. Diese Daten sind besonders schuetzenswert.',
en: 'Processing of this data is subject to special requirements under Art. 9 GDPR. This data requires special protection.'
},
requirements: [
{
de: 'Ausdrueckliche Einwilligung erforderlich (Art. 9 Abs. 2 lit. a DSGVO)',
en: 'Explicit consent required (Art. 9(2)(a) GDPR)'
},
{
de: 'Separate Einwilligungserklaerung im UI notwendig',
en: 'Separate consent declaration required in UI'
},
{
de: 'Hoehere Dokumentationspflichten',
en: 'Higher documentation requirements'
},
{
de: 'Spezielle Loeschverfahren erforderlich',
en: 'Special deletion procedures required'
},
{
de: 'Datenschutz-Folgenabschaetzung (DSFA) empfohlen',
en: 'Data Protection Impact Assessment (DPIA) recommended'
}
]
}
/**
* Spezielle Hinweise für Beschäftigtendaten (BDSG § 26)
*/
export interface EmployeeDataWarning {
title: LocalizedText
description: LocalizedText
requirements: LocalizedText[]
}
export const EMPLOYEE_DATA_WARNING: EmployeeDataWarning = {
title: {
de: 'Beschaeftigtendaten (BDSG § 26)',
en: 'Employee Data (BDSG § 26)'
},
description: {
de: 'Die Verarbeitung von Beschaeftigtendaten unterliegt besonderen Anforderungen nach § 26 BDSG.',
en: 'Processing of employee data is subject to special requirements under § 26 BDSG (German Federal Data Protection Act).'
},
requirements: [
{
de: 'Aufbewahrungspflichten fuer Lohnunterlagen (6-10 Jahre)',
en: 'Retention obligations for payroll records (6-10 years)'
},
{
de: 'Betriebsrat-Beteiligung ggf. erforderlich',
en: 'Works council involvement may be required'
},
{
de: 'Verarbeitung nur fuer Zwecke des Beschaeftigungsverhaeltnisses',
en: 'Processing only for employment purposes'
},
{
de: 'Besondere Vertraulichkeit bei Gesundheitsdaten',
en: 'Special confidentiality for health data'
}
]
}
/**
* Spezielle Hinweise für KI-Daten (AI Act)
*/
export interface AIDataWarning {
title: LocalizedText
description: LocalizedText
requirements: LocalizedText[]
}
export const AI_DATA_WARNING: AIDataWarning = {
title: {
de: 'KI-Daten (AI Act)',
en: 'AI Data (AI Act)'
},
description: {
de: 'Die Verarbeitung von KI-bezogenen Daten unterliegt den Transparenzpflichten des AI Acts.',
en: 'Processing of AI-related data is subject to AI Act transparency requirements.'
},
requirements: [
{
de: 'Transparenzpflichten bei KI-Verarbeitung',
en: 'Transparency obligations for AI processing'
},
{
de: 'Kennzeichnung von KI-generierten Inhalten',
en: 'Labeling of AI-generated content'
},
{
de: 'Dokumentation der KI-Modell-Nutzung',
en: 'Documentation of AI model usage'
},
{
de: 'Keine Verwendung fuer unerlaubtes Training ohne Einwilligung',
en: 'No use for unauthorized training without consent'
}
]
}
/**
* Risk Level Styling
*/
export const RISK_LEVEL_STYLING: Record<RiskLevel, { label: LocalizedText; color: string; bgColor: string }> = {
LOW: {
label: { de: 'Niedrig', en: 'Low' },
color: 'text-green-700',
bgColor: 'bg-green-100'
},
MEDIUM: {
label: { de: 'Mittel', en: 'Medium' },
color: 'text-yellow-700',
bgColor: 'bg-yellow-100'
},
HIGH: {
label: { de: 'Hoch', en: 'High' },
color: 'text-red-700',
bgColor: 'bg-red-100'
}
}

View File

@@ -0,0 +1,40 @@
// =============================================================================
// CATALOG & RETENTION MATRIX
// =============================================================================
import type { DataPointCategory, RetentionPeriod } from './enums'
import type { LocalizedText, DataPoint } from './data-point'
/**
* Gesamter Datenpunktkatalog eines Tenants
*/
export interface DataPointCatalog {
id: string
tenantId: string
version: string
dataPoints: DataPoint[] // Vordefinierte (32)
customDataPoints: DataPoint[] // Kundenspezifische
retentionMatrix: RetentionMatrixEntry[]
createdAt: Date
updatedAt: Date
}
/**
* Eintrag in der Retention Matrix
*/
export interface RetentionMatrixEntry {
category: DataPointCategory
categoryName: LocalizedText
standardPeriod: RetentionPeriod
legalBasis: string
exceptions: RetentionException[]
}
/**
* Ausnahme von der Standard-Loeschfrist
*/
export interface RetentionException {
condition: LocalizedText
period: RetentionPeriod
reason: LocalizedText
}

View File

@@ -0,0 +1,39 @@
// =============================================================================
// CONSENT MANAGEMENT
// =============================================================================
import type { DataPointCategory, LegalBasis } from './enums'
/**
* Einzelne Einwilligung eines Nutzers
*/
export interface ConsentEntry {
id: string
userId: string
dataPointId: string
granted: boolean
grantedAt: Date
revokedAt?: Date
ipAddress?: string
userAgent?: string
consentVersion: string
}
/**
* Aggregierte Consent-Statistiken
*/
export interface ConsentStatistics {
totalConsents: number
activeConsents: number
revokedConsents: number
byCategory: Record<DataPointCategory, {
total: number
active: number
revoked: number
}>
byLegalBasis: Record<LegalBasis, {
total: number
active: number
}>
conversionRate: number // Prozent der Nutzer mit Consent
}

View File

@@ -0,0 +1,259 @@
// =============================================================================
// CONSTANTS - CATEGORY METADATA & LEGAL BASIS INFO
// =============================================================================
import type { DataPointCategory, LegalBasis, RetentionPeriod, RiskLevel } from './enums'
import type { LocalizedText } from './data-point'
import type { CategoryMetadata } from './helpers'
/**
* Mapping von Kategorie zu Metadaten (18 Kategorien)
*/
export const CATEGORY_METADATA: Record<DataPointCategory, CategoryMetadata> = {
MASTER_DATA: {
id: 'MASTER_DATA',
code: 'A',
name: { de: 'Stammdaten', en: 'Master Data' },
description: { de: 'Grundlegende personenbezogene Daten', en: 'Basic personal data' },
icon: 'User',
color: 'blue'
},
CONTACT_DATA: {
id: 'CONTACT_DATA',
code: 'B',
name: { de: 'Kontaktdaten', en: 'Contact Data' },
description: { de: 'Kontaktinformationen und Erreichbarkeit', en: 'Contact information and availability' },
icon: 'Mail',
color: 'sky'
},
AUTHENTICATION: {
id: 'AUTHENTICATION',
code: 'C',
name: { de: 'Authentifizierungsdaten', en: 'Authentication Data' },
description: { de: 'Daten zur Benutzeranmeldung und Session-Verwaltung', en: 'Data for user login and session management' },
icon: 'Key',
color: 'slate'
},
CONSENT: {
id: 'CONSENT',
code: 'D',
name: { de: 'Einwilligungsdaten', en: 'Consent Data' },
description: { de: 'Einwilligungen und Datenschutzpraeferenzen', en: 'Consents and privacy preferences' },
icon: 'CheckCircle',
color: 'green'
},
COMMUNICATION: {
id: 'COMMUNICATION',
code: 'E',
name: { de: 'Kommunikationsdaten', en: 'Communication Data' },
description: { de: 'Kundenservice und Kommunikationsdaten', en: 'Customer service and communication data' },
icon: 'MessageSquare',
color: 'cyan'
},
PAYMENT: {
id: 'PAYMENT',
code: 'F',
name: { de: 'Zahlungsdaten', en: 'Payment Data' },
description: { de: 'Rechnungs- und Zahlungsinformationen', en: 'Billing and payment information' },
icon: 'CreditCard',
color: 'amber'
},
USAGE_DATA: {
id: 'USAGE_DATA',
code: 'G',
name: { de: 'Nutzungsdaten', en: 'Usage Data' },
description: { de: 'Daten zur Nutzung des Dienstes', en: 'Data about service usage' },
icon: 'Activity',
color: 'violet'
},
LOCATION: {
id: 'LOCATION',
code: 'H',
name: { de: 'Standortdaten', en: 'Location Data' },
description: { de: 'Geografische Standortinformationen', en: 'Geographic location information' },
icon: 'MapPin',
color: 'emerald'
},
DEVICE_DATA: {
id: 'DEVICE_DATA',
code: 'I',
name: { de: 'Geraetedaten', en: 'Device Data' },
description: { de: 'Technische Geraete- und Browserinformationen', en: 'Technical device and browser information' },
icon: 'Smartphone',
color: 'zinc'
},
MARKETING: {
id: 'MARKETING',
code: 'J',
name: { de: 'Marketingdaten', en: 'Marketing Data' },
description: { de: 'Marketing- und Werbedaten', en: 'Marketing and advertising data' },
icon: 'Megaphone',
color: 'purple'
},
ANALYTICS: {
id: 'ANALYTICS',
code: 'K',
name: { de: 'Analysedaten', en: 'Analytics Data' },
description: { de: 'Web-Analyse und Nutzungsstatistiken', en: 'Web analytics and usage statistics' },
icon: 'BarChart3',
color: 'indigo'
},
SOCIAL_MEDIA: {
id: 'SOCIAL_MEDIA',
code: 'L',
name: { de: 'Social-Media-Daten', en: 'Social Media Data' },
description: { de: 'Daten aus sozialen Netzwerken', en: 'Data from social networks' },
icon: 'Share2',
color: 'pink'
},
HEALTH_DATA: {
id: 'HEALTH_DATA',
code: 'M',
name: { de: 'Gesundheitsdaten', en: 'Health Data' },
description: { de: 'Besondere Kategorie nach Art. 9 DSGVO - Gesundheitsbezogene Daten', en: 'Special category under Art. 9 GDPR - Health-related data' },
icon: 'Heart',
color: 'rose'
},
EMPLOYEE_DATA: {
id: 'EMPLOYEE_DATA',
code: 'N',
name: { de: 'Beschaeftigtendaten', en: 'Employee Data' },
description: { de: 'Personalverwaltung und Arbeitnehmerinformationen (BDSG § 26)', en: 'HR management and employee information' },
icon: 'Briefcase',
color: 'orange'
},
CONTRACT_DATA: {
id: 'CONTRACT_DATA',
code: 'O',
name: { de: 'Vertragsdaten', en: 'Contract Data' },
description: { de: 'Vertragsinformationen und -dokumente', en: 'Contract information and documents' },
icon: 'FileText',
color: 'teal'
},
LOG_DATA: {
id: 'LOG_DATA',
code: 'P',
name: { de: 'Protokolldaten', en: 'Log Data' },
description: { de: 'System- und Zugriffsprotokolle', en: 'System and access logs' },
icon: 'FileCode',
color: 'gray'
},
AI_DATA: {
id: 'AI_DATA',
code: 'Q',
name: { de: 'KI-Daten', en: 'AI Data' },
description: { de: 'KI-Interaktionen, Prompts und generierte Inhalte (AI Act)', en: 'AI interactions, prompts and generated content (AI Act)' },
icon: 'Bot',
color: 'fuchsia'
},
SECURITY: {
id: 'SECURITY',
code: 'R',
name: { de: 'Sicherheitsdaten', en: 'Security Data' },
description: { de: 'Sicherheitsrelevante Daten und Vorfallberichte', en: 'Security-relevant data and incident reports' },
icon: 'Shield',
color: 'red'
}
}
/**
* Mapping von Rechtsgrundlage zu Beschreibung
*/
export const LEGAL_BASIS_INFO: Record<LegalBasis, { article: string; name: LocalizedText; description: LocalizedText }> = {
CONTRACT: {
article: 'Art. 6 Abs. 1 lit. b DSGVO',
name: { de: 'Vertragserfuellung', en: 'Contract Performance' },
description: {
de: 'Die Verarbeitung ist erforderlich fuer die Erfuellung eines Vertrags oder zur Durchfuehrung vorvertraglicher Massnahmen.',
en: 'Processing is necessary for the performance of a contract or pre-contractual measures.'
}
},
CONSENT: {
article: 'Art. 6 Abs. 1 lit. a DSGVO',
name: { de: 'Einwilligung', en: 'Consent' },
description: {
de: 'Die betroffene Person hat ihre Einwilligung zu der Verarbeitung gegeben.',
en: 'The data subject has given consent to the processing.'
}
},
EXPLICIT_CONSENT: {
article: 'Art. 9 Abs. 2 lit. a DSGVO',
name: { de: 'Ausdrueckliche Einwilligung', en: 'Explicit Consent' },
description: {
de: 'Die betroffene Person hat ausdruecklich in die Verarbeitung besonderer Kategorien personenbezogener Daten (Art. 9 DSGVO) eingewilligt. Dies betrifft Gesundheitsdaten, biometrische Daten, Daten zur ethnischen Herkunft, politische Meinungen, religiöse Überzeugungen etc.',
en: 'The data subject has given explicit consent to the processing of special categories of personal data (Art. 9 GDPR). This includes health data, biometric data, racial or ethnic origin, political opinions, religious beliefs, etc.'
}
},
LEGITIMATE_INTEREST: {
article: 'Art. 6 Abs. 1 lit. f DSGVO',
name: { de: 'Berechtigtes Interesse', en: 'Legitimate Interest' },
description: {
de: 'Die Verarbeitung ist zur Wahrung berechtigter Interessen des Verantwortlichen erforderlich.',
en: 'Processing is necessary for legitimate interests pursued by the controller.'
}
},
LEGAL_OBLIGATION: {
article: 'Art. 6 Abs. 1 lit. c DSGVO',
name: { de: 'Rechtliche Verpflichtung', en: 'Legal Obligation' },
description: {
de: 'Die Verarbeitung ist zur Erfuellung einer rechtlichen Verpflichtung erforderlich.',
en: 'Processing is necessary for compliance with a legal obligation.'
}
},
VITAL_INTERESTS: {
article: 'Art. 6 Abs. 1 lit. d DSGVO',
name: { de: 'Lebenswichtige Interessen', en: 'Vital Interests' },
description: {
de: 'Die Verarbeitung ist erforderlich, um lebenswichtige Interessen der betroffenen Person oder einer anderen natuerlichen Person zu schuetzen.',
en: 'Processing is necessary to protect the vital interests of the data subject or another natural person.'
}
},
PUBLIC_INTEREST: {
article: 'Art. 6 Abs. 1 lit. e DSGVO',
name: { de: 'Oeffentliches Interesse', en: 'Public Interest' },
description: {
de: 'Die Verarbeitung ist fuer die Wahrnehmung einer Aufgabe erforderlich, die im oeffentlichen Interesse liegt oder in Ausuebung oeffentlicher Gewalt erfolgt.',
en: 'Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority.'
}
}
}
/**
* Mapping von Aufbewahrungsfrist zu Beschreibung
*/
export const RETENTION_PERIOD_INFO: Record<RetentionPeriod, { label: LocalizedText; days: number | null }> = {
'24_HOURS': { label: { de: '24 Stunden', en: '24 Hours' }, days: 1 },
'30_DAYS': { label: { de: '30 Tage', en: '30 Days' }, days: 30 },
'90_DAYS': { label: { de: '90 Tage', en: '90 Days' }, days: 90 },
'12_MONTHS': { label: { de: '12 Monate', en: '12 Months' }, days: 365 },
'24_MONTHS': { label: { de: '24 Monate', en: '24 Months' }, days: 730 },
'26_MONTHS': { label: { de: '26 Monate (Google Analytics)', en: '26 Months (Google Analytics)' }, days: 790 },
'36_MONTHS': { label: { de: '36 Monate', en: '36 Months' }, days: 1095 },
'48_MONTHS': { label: { de: '48 Monate', en: '48 Months' }, days: 1460 },
'6_YEARS': { label: { de: '6 Jahre', en: '6 Years' }, days: 2190 },
'10_YEARS': { label: { de: '10 Jahre', en: '10 Years' }, days: 3650 },
'UNTIL_REVOCATION': { label: { de: 'Bis Widerruf', en: 'Until Revocation' }, days: null },
'UNTIL_PURPOSE_FULFILLED': { label: { de: 'Bis Zweckerfuellung', en: 'Until Purpose Fulfilled' }, days: null },
'UNTIL_ACCOUNT_DELETION': { label: { de: 'Bis Kontoschliessung', en: 'Until Account Deletion' }, days: null }
}
/**
* Risk Level Styling
*/
export const RISK_LEVEL_STYLING: Record<RiskLevel, { label: LocalizedText; color: string; bgColor: string }> = {
LOW: {
label: { de: 'Niedrig', en: 'Low' },
color: 'text-green-700',
bgColor: 'bg-green-100'
},
MEDIUM: {
label: { de: 'Mittel', en: 'Medium' },
color: 'text-yellow-700',
bgColor: 'bg-yellow-100'
},
HIGH: {
label: { de: 'Hoch', en: 'High' },
color: 'text-red-700',
bgColor: 'bg-red-100'
}
}

View File

@@ -0,0 +1,80 @@
// =============================================================================
// COOKIE BANNER CONFIG
// =============================================================================
import type { CookieCategory } from './enums'
import type { LocalizedText } from './data-point'
/**
* Einzelner Cookie in einer Kategorie
*/
export interface CookieInfo {
name: string
provider: string
purpose: LocalizedText
expiry: string
type: 'FIRST_PARTY' | 'THIRD_PARTY'
}
/**
* Cookie-Banner Kategorie
*/
export interface CookieBannerCategory {
id: CookieCategory
name: LocalizedText
description: LocalizedText
isRequired: boolean // Essentiell = required
defaultEnabled: boolean
dataPointIds: string[] // Verknuepfte Datenpunkte
cookies: CookieInfo[]
}
/**
* Styling fuer Cookie Banner
*/
export interface CookieBannerStyling {
position: 'BOTTOM' | 'TOP' | 'CENTER'
theme: 'LIGHT' | 'DARK' | 'CUSTOM'
primaryColor?: string
secondaryColor?: string
textColor?: string
backgroundColor?: string
borderRadius?: number
maxWidth?: number
}
/**
* Texte fuer Cookie Banner
*/
export interface CookieBannerTexts {
title: LocalizedText
description: LocalizedText
acceptAll: LocalizedText
rejectAll: LocalizedText
customize: LocalizedText
save: LocalizedText
privacyPolicyLink: LocalizedText
}
/**
* Generierter Code fuer Cookie Banner
*/
export interface CookieBannerEmbedCode {
html: string
css: string
js: string
scriptTag: string // Fertiger Script-Tag zum Einbinden
}
/**
* Vollstaendige Cookie Banner Konfiguration
*/
export interface CookieBannerConfig {
id: string
tenantId: string
categories: CookieBannerCategory[]
styling: CookieBannerStyling
texts: CookieBannerTexts
embedCode?: CookieBannerEmbedCode
updatedAt: Date
}

View File

@@ -0,0 +1,72 @@
// =============================================================================
// DATA POINT
// =============================================================================
import type {
DataPointCategory,
RiskLevel,
LegalBasis,
RetentionPeriod,
CookieCategory,
} from './enums'
/**
* Lokalisierter Text (DE/EN)
*/
export interface LocalizedText {
de: string
en: string
}
/**
* Einzelner Datenpunkt im Katalog
*/
export interface DataPoint {
id: string
code: string // z.B. "A1", "B2", "C3"
category: DataPointCategory
name: LocalizedText
description: LocalizedText
purpose: LocalizedText
riskLevel: RiskLevel
legalBasis: LegalBasis
legalBasisJustification: LocalizedText
retentionPeriod: RetentionPeriod
retentionJustification: LocalizedText
cookieCategory: CookieCategory | null // null = kein Cookie
isSpecialCategory: boolean // Art. 9 DSGVO (sensible Daten)
requiresExplicitConsent: boolean
thirdPartyRecipients: string[]
technicalMeasures: string[]
tags: string[]
isCustom?: boolean // Kundenspezifischer Datenpunkt
isActive?: boolean // Aktiviert fuer diesen Tenant
}
/**
* YAML-Struktur fuer Datenpunkte (fuer Loader)
*/
export interface DataPointYAML {
id: string
code: string
category: string
name_de: string
name_en: string
description_de: string
description_en: string
purpose_de: string
purpose_en: string
risk_level: string
legal_basis: string
legal_basis_justification_de: string
legal_basis_justification_en: string
retention_period: string
retention_justification_de: string
retention_justification_en: string
cookie_category: string | null
is_special_category: boolean
requires_explicit_consent: boolean
third_party_recipients: string[]
technical_measures: string[]
tags: string[]
}

View File

@@ -0,0 +1,85 @@
/**
* Datenpunktkatalog & Datenschutzinformationen-Generator
* Enums & Literal Types
*/
// =============================================================================
// ENUMS
// =============================================================================
/**
* Kategorien fuer Datenpunkte (18 Kategorien: A-R)
*/
export type DataPointCategory =
| 'MASTER_DATA' // A: Stammdaten
| 'CONTACT_DATA' // B: Kontaktdaten
| 'AUTHENTICATION' // C: Authentifizierungsdaten
| 'CONSENT' // D: Einwilligungsdaten
| 'COMMUNICATION' // E: Kommunikationsdaten
| 'PAYMENT' // F: Zahlungsdaten
| 'USAGE_DATA' // G: Nutzungsdaten
| 'LOCATION' // H: Standortdaten
| 'DEVICE_DATA' // I: Gerätedaten
| 'MARKETING' // J: Marketingdaten
| 'ANALYTICS' // K: Analysedaten
| 'SOCIAL_MEDIA' // L: Social-Media-Daten
| 'HEALTH_DATA' // M: Gesundheitsdaten (Art. 9 DSGVO)
| 'EMPLOYEE_DATA' // N: Beschäftigtendaten
| 'CONTRACT_DATA' // O: Vertragsdaten
| 'LOG_DATA' // P: Protokolldaten
| 'AI_DATA' // Q: KI-Daten
| 'SECURITY' // R: Sicherheitsdaten
/**
* Risikoniveau fuer Datenpunkte
*/
export type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH'
/**
* Rechtsgrundlagen nach DSGVO Art. 6 und Art. 9
*/
export type LegalBasis =
| 'CONTRACT' // Art. 6 Abs. 1 lit. b DSGVO
| 'CONSENT' // Art. 6 Abs. 1 lit. a DSGVO
| 'EXPLICIT_CONSENT' // Art. 9 Abs. 2 lit. a DSGVO (fuer Art. 9 Daten)
| 'LEGITIMATE_INTEREST' // Art. 6 Abs. 1 lit. f DSGVO
| 'LEGAL_OBLIGATION' // Art. 6 Abs. 1 lit. c DSGVO
| 'VITAL_INTERESTS' // Art. 6 Abs. 1 lit. d DSGVO
| 'PUBLIC_INTEREST' // Art. 6 Abs. 1 lit. e DSGVO
/**
* Aufbewahrungsfristen
*/
export type RetentionPeriod =
| '24_HOURS'
| '30_DAYS'
| '90_DAYS'
| '12_MONTHS'
| '24_MONTHS'
| '26_MONTHS' // Google Analytics Standard
| '36_MONTHS'
| '48_MONTHS'
| '6_YEARS'
| '10_YEARS'
| 'UNTIL_REVOCATION'
| 'UNTIL_PURPOSE_FULFILLED'
| 'UNTIL_ACCOUNT_DELETION'
/**
* Cookie-Kategorien fuer Cookie-Banner
*/
export type CookieCategory =
| 'ESSENTIAL' // Technisch notwendig
| 'PERFORMANCE' // Analyse & Performance
| 'PERSONALIZATION' // Personalisierung
| 'EXTERNAL_MEDIA' // Externe Medien
/**
* Export-Formate fuer Privacy Policy
*/
export type ExportFormat = 'HTML' | 'MARKDOWN' | 'PDF' | 'DOCX'
/**
* Sprachen
*/
export type SupportedLanguage = 'de' | 'en'

View File

@@ -0,0 +1,18 @@
// =============================================================================
// HELPER TYPES
// =============================================================================
import type { DataPointCategory } from './enums'
import type { LocalizedText } from './data-point'
/**
* Kategorie-Metadaten
*/
export interface CategoryMetadata {
id: DataPointCategory
code: string // A, B, C, etc.
name: LocalizedText
description: LocalizedText
icon: string // Icon name
color: string // Tailwind color class
}

View File

@@ -0,0 +1,17 @@
/**
* Datenpunktkatalog & Datenschutzinformationen-Generator
* TypeScript Interfaces
*
* Barrel re-export of all domain modules.
*/
export * from './enums'
export * from './data-point'
export * from './catalog-retention'
export * from './privacy-policy'
export * from './cookie-banner'
export * from './consent-management'
export * from './state-actions'
export * from './helpers'
export * from './constants'
export * from './warnings'

View File

@@ -0,0 +1,77 @@
// =============================================================================
// PRIVACY POLICY GENERATION
// =============================================================================
import type { SupportedLanguage, ExportFormat } from './enums'
import type { LocalizedText } from './data-point'
/**
* Abschnitt in der Privacy Policy
*/
export interface PrivacyPolicySection {
id: string
order: number
title: LocalizedText
content: LocalizedText
dataPointIds: string[]
isRequired: boolean
isGenerated: boolean // true = aus Datenpunkten generiert
}
/**
* Unternehmensinfo fuer Privacy Policy
*/
export interface CompanyInfo {
name: string
address: string
city: string
postalCode: string
country: string
email: string
phone?: string
website?: string
dpoName?: string // Datenschutzbeauftragter
dpoEmail?: string
dpoPhone?: string
registrationNumber?: string // Handelsregister
vatId?: string // USt-IdNr
}
/**
* Generierte Privacy Policy
*/
export interface GeneratedPrivacyPolicy {
id: string
tenantId: string
language: SupportedLanguage
sections: PrivacyPolicySection[]
companyInfo: CompanyInfo
generatedAt: Date
version: string
format: ExportFormat
content?: string // Rendered content (HTML/MD)
}
/**
* Optionen fuer Privacy Policy Generierung
*/
export interface PrivacyPolicyGenerationOptions {
language: SupportedLanguage
format: ExportFormat
includeDataPoints: string[] // Welche Datenpunkte einschliessen
customSections?: PrivacyPolicySection[] // Zusaetzliche Abschnitte
styling?: PrivacyPolicyStyling
}
/**
* Styling-Optionen fuer PDF/HTML Export
*/
export interface PrivacyPolicyStyling {
primaryColor?: string
fontFamily?: string
fontSize?: number
headerFontSize?: number
includeTableOfContents?: boolean
includeDateFooter?: boolean
logoUrl?: string
}

View File

@@ -0,0 +1,73 @@
// =============================================================================
// EINWILLIGUNGEN STATE & ACTIONS
// =============================================================================
import type { SupportedLanguage, ExportFormat } from './enums'
import type { DataPoint } from './data-point'
import type { DataPointCatalog } from './catalog-retention'
import type { PrivacyPolicySection, GeneratedPrivacyPolicy, CompanyInfo } from './privacy-policy'
import type { CookieBannerConfig, CookieBannerStyling, CookieBannerTexts } from './cookie-banner'
import type { ConsentStatistics } from './consent-management'
/**
* Aktiver Tab in der Einwilligungen-Ansicht
*/
export type EinwilligungenTab =
| 'catalog'
| 'privacy-policy'
| 'cookie-banner'
| 'retention'
| 'consents'
/**
* State fuer Einwilligungen-Modul
*/
export interface EinwilligungenState {
// Data
catalog: DataPointCatalog | null
selectedDataPoints: string[]
privacyPolicy: GeneratedPrivacyPolicy | null
cookieBannerConfig: CookieBannerConfig | null
companyInfo: CompanyInfo | null
consentStatistics: ConsentStatistics | null
// UI State
activeTab: EinwilligungenTab
isLoading: boolean
isSaving: boolean
error: string | null
// Editor State
editingDataPoint: DataPoint | null
editingSection: PrivacyPolicySection | null
// Preview
previewLanguage: SupportedLanguage
previewFormat: ExportFormat
}
/**
* Actions fuer Einwilligungen-Reducer
*/
export type EinwilligungenAction =
| { type: 'SET_CATALOG'; payload: DataPointCatalog }
| { type: 'SET_SELECTED_DATA_POINTS'; payload: string[] }
| { type: 'TOGGLE_DATA_POINT'; payload: string }
| { type: 'ADD_CUSTOM_DATA_POINT'; payload: DataPoint }
| { type: 'UPDATE_DATA_POINT'; payload: { id: string; data: Partial<DataPoint> } }
| { type: 'DELETE_CUSTOM_DATA_POINT'; payload: string }
| { type: 'SET_PRIVACY_POLICY'; payload: GeneratedPrivacyPolicy }
| { type: 'SET_COOKIE_BANNER_CONFIG'; payload: CookieBannerConfig }
| { type: 'UPDATE_COOKIE_BANNER_STYLING'; payload: Partial<CookieBannerStyling> }
| { type: 'UPDATE_COOKIE_BANNER_TEXTS'; payload: Partial<CookieBannerTexts> }
| { type: 'SET_COMPANY_INFO'; payload: CompanyInfo }
| { type: 'SET_CONSENT_STATISTICS'; payload: ConsentStatistics }
| { type: 'SET_ACTIVE_TAB'; payload: EinwilligungenTab }
| { type: 'SET_LOADING'; payload: boolean }
| { type: 'SET_SAVING'; payload: boolean }
| { type: 'SET_ERROR'; payload: string | null }
| { type: 'SET_EDITING_DATA_POINT'; payload: DataPoint | null }
| { type: 'SET_EDITING_SECTION'; payload: PrivacyPolicySection | null }
| { type: 'SET_PREVIEW_LANGUAGE'; payload: SupportedLanguage }
| { type: 'SET_PREVIEW_FORMAT'; payload: ExportFormat }
| { type: 'RESET_STATE' }

View File

@@ -0,0 +1,123 @@
// =============================================================================
// SPECIAL DATA CATEGORY WARNINGS
// =============================================================================
import type { LocalizedText } from './data-point'
/**
* Spezielle Hinweise fuer Art. 9 DSGVO Kategorien
*/
export interface Article9Warning {
title: LocalizedText
description: LocalizedText
requirements: LocalizedText[]
}
export const ARTICLE_9_WARNING: Article9Warning = {
title: {
de: 'Besondere Kategorie personenbezogener Daten (Art. 9 DSGVO)',
en: 'Special Category of Personal Data (Art. 9 GDPR)'
},
description: {
de: 'Die Verarbeitung dieser Daten unterliegt besonderen Anforderungen nach Art. 9 DSGVO. Diese Daten sind besonders schuetzenswert.',
en: 'Processing of this data is subject to special requirements under Art. 9 GDPR. This data requires special protection.'
},
requirements: [
{
de: 'Ausdrueckliche Einwilligung erforderlich (Art. 9 Abs. 2 lit. a DSGVO)',
en: 'Explicit consent required (Art. 9(2)(a) GDPR)'
},
{
de: 'Separate Einwilligungserklaerung im UI notwendig',
en: 'Separate consent declaration required in UI'
},
{
de: 'Hoehere Dokumentationspflichten',
en: 'Higher documentation requirements'
},
{
de: 'Spezielle Loeschverfahren erforderlich',
en: 'Special deletion procedures required'
},
{
de: 'Datenschutz-Folgenabschaetzung (DSFA) empfohlen',
en: 'Data Protection Impact Assessment (DPIA) recommended'
}
]
}
/**
* Spezielle Hinweise fuer Beschaeftigtendaten (BDSG § 26)
*/
export interface EmployeeDataWarning {
title: LocalizedText
description: LocalizedText
requirements: LocalizedText[]
}
export const EMPLOYEE_DATA_WARNING: EmployeeDataWarning = {
title: {
de: 'Beschaeftigtendaten (BDSG § 26)',
en: 'Employee Data (BDSG § 26)'
},
description: {
de: 'Die Verarbeitung von Beschaeftigtendaten unterliegt besonderen Anforderungen nach § 26 BDSG.',
en: 'Processing of employee data is subject to special requirements under § 26 BDSG (German Federal Data Protection Act).'
},
requirements: [
{
de: 'Aufbewahrungspflichten fuer Lohnunterlagen (6-10 Jahre)',
en: 'Retention obligations for payroll records (6-10 years)'
},
{
de: 'Betriebsrat-Beteiligung ggf. erforderlich',
en: 'Works council involvement may be required'
},
{
de: 'Verarbeitung nur fuer Zwecke des Beschaeftigungsverhaeltnisses',
en: 'Processing only for employment purposes'
},
{
de: 'Besondere Vertraulichkeit bei Gesundheitsdaten',
en: 'Special confidentiality for health data'
}
]
}
/**
* Spezielle Hinweise fuer KI-Daten (AI Act)
*/
export interface AIDataWarning {
title: LocalizedText
description: LocalizedText
requirements: LocalizedText[]
}
export const AI_DATA_WARNING: AIDataWarning = {
title: {
de: 'KI-Daten (AI Act)',
en: 'AI Data (AI Act)'
},
description: {
de: 'Die Verarbeitung von KI-bezogenen Daten unterliegt den Transparenzpflichten des AI Acts.',
en: 'Processing of AI-related data is subject to AI Act transparency requirements.'
},
requirements: [
{
de: 'Transparenzpflichten bei KI-Verarbeitung',
en: 'Transparency obligations for AI processing'
},
{
de: 'Kennzeichnung von KI-generierten Inhalten',
en: 'Labeling of AI-generated content'
},
{
de: 'Dokumentation der KI-Modell-Nutzung',
en: 'Documentation of AI model usage'
},
{
de: 'Keine Verwendung fuer unerlaubtes Training ohne Einwilligung',
en: 'No use for unauthorized training without consent'
}
]
}

View File

@@ -1,963 +0,0 @@
// =============================================================================
// TOM Generator Module - TypeScript Types
// DSGVO Art. 32 Technical and Organizational Measures
// =============================================================================
// =============================================================================
// ENUMS & LITERAL TYPES
// =============================================================================
export type TOMGeneratorStepId =
| 'scope-roles'
| 'data-categories'
| 'architecture-hosting'
| 'security-profile'
| 'risk-protection'
| 'review-export'
export type CompanyRole = 'CONTROLLER' | 'PROCESSOR' | 'JOINT_CONTROLLER'
export type DataCategory =
| 'IDENTIFICATION'
| 'CONTACT'
| 'FINANCIAL'
| 'PROFESSIONAL'
| 'LOCATION'
| 'BEHAVIORAL'
| 'BIOMETRIC'
| 'HEALTH'
| 'GENETIC'
| 'POLITICAL'
| 'RELIGIOUS'
| 'SEXUAL_ORIENTATION'
| 'CRIMINAL'
export type DataSubject =
| 'EMPLOYEES'
| 'CUSTOMERS'
| 'PROSPECTS'
| 'SUPPLIERS'
| 'MINORS'
| 'PATIENTS'
| 'STUDENTS'
| 'GENERAL_PUBLIC'
export type HostingLocation =
| 'DE'
| 'EU'
| 'EEA'
| 'THIRD_COUNTRY_ADEQUATE'
| 'THIRD_COUNTRY'
export type HostingModel = 'ON_PREMISE' | 'PRIVATE_CLOUD' | 'PUBLIC_CLOUD' | 'HYBRID'
export type MultiTenancy = 'SINGLE_TENANT' | 'MULTI_TENANT' | 'DEDICATED'
export type ControlApplicability =
| 'REQUIRED'
| 'RECOMMENDED'
| 'OPTIONAL'
| 'NOT_APPLICABLE'
export type DocumentType =
| 'AVV'
| 'DPA'
| 'SLA'
| 'NDA'
| 'POLICY'
| 'CERTIFICATE'
| 'AUDIT_REPORT'
| 'OTHER'
export type ProtectionLevel = 'NORMAL' | 'HIGH' | 'VERY_HIGH'
export type CIARating = 1 | 2 | 3 | 4 | 5
export type ControlCategory =
| 'ACCESS_CONTROL'
| 'ADMISSION_CONTROL'
| 'ACCESS_AUTHORIZATION'
| 'TRANSFER_CONTROL'
| 'INPUT_CONTROL'
| 'ORDER_CONTROL'
| 'AVAILABILITY'
| 'SEPARATION'
| 'ENCRYPTION'
| 'PSEUDONYMIZATION'
| 'RESILIENCE'
| 'RECOVERY'
| 'REVIEW'
export type CompanySize = 'MICRO' | 'SMALL' | 'MEDIUM' | 'LARGE' | 'ENTERPRISE'
export type DataVolume = 'LOW' | 'MEDIUM' | 'HIGH' | 'VERY_HIGH'
export type AuthMethodType =
| 'PASSWORD'
| 'MFA'
| 'SSO'
| 'CERTIFICATE'
| 'BIOMETRIC'
export type BackupFrequency = 'HOURLY' | 'DAILY' | 'WEEKLY' | 'MONTHLY'
export type ReviewFrequency = 'MONTHLY' | 'QUARTERLY' | 'SEMI_ANNUAL' | 'ANNUAL'
export type ControlPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
export type ControlComplexity = 'LOW' | 'MEDIUM' | 'HIGH'
export type ImplementationStatus = 'NOT_IMPLEMENTED' | 'PARTIAL' | 'IMPLEMENTED'
export type EvidenceStatus = 'PENDING' | 'ANALYZED' | 'VERIFIED' | 'REJECTED'
export type ConditionOperator =
| 'EQUALS'
| 'NOT_EQUALS'
| 'CONTAINS'
| 'GREATER_THAN'
| 'IN'
// =============================================================================
// PROFILE INTERFACES (Wizard Steps 1-5)
// =============================================================================
export interface CompanyProfile {
id: string
name: string
industry: string
size: CompanySize
role: CompanyRole
products: string[]
dpoPerson: string | null
dpoEmail: string | null
itSecurityContact: string | null
}
export interface DataProfile {
categories: DataCategory[]
subjects: DataSubject[]
hasSpecialCategories: boolean
processesMinors: boolean
dataVolume: DataVolume
thirdCountryTransfers: boolean
thirdCountryList: string[]
}
export interface CloudProvider {
name: string
location: HostingLocation
certifications: string[]
}
export interface ArchitectureProfile {
hostingModel: HostingModel
hostingLocation: HostingLocation
providers: CloudProvider[]
multiTenancy: MultiTenancy
hasSubprocessors: boolean
subprocessorCount: number
encryptionAtRest: boolean
encryptionInTransit: boolean
}
export interface AuthMethod {
type: AuthMethodType
provider: string | null
}
export interface SecurityProfile {
authMethods: AuthMethod[]
hasMFA: boolean
hasSSO: boolean
hasIAM: boolean
hasPAM: boolean
hasEncryptionAtRest: boolean
hasEncryptionInTransit: boolean
hasLogging: boolean
logRetentionDays: number
hasBackup: boolean
backupFrequency: BackupFrequency
backupRetentionDays: number
hasDRPlan: boolean
rtoHours: number | null
rpoHours: number | null
hasVulnerabilityManagement: boolean
hasPenetrationTests: boolean
hasSecurityTraining: boolean
}
export interface CIAAssessment {
confidentiality: CIARating
integrity: CIARating
availability: CIARating
justification: string
}
export interface RiskProfile {
ciaAssessment: CIAAssessment
protectionLevel: ProtectionLevel
specialRisks: string[]
regulatoryRequirements: string[]
hasHighRiskProcessing: boolean
dsfaRequired: boolean
}
// =============================================================================
// EVIDENCE DOCUMENT
// =============================================================================
export interface ExtractedClause {
id: string
text: string
type: string
relatedControlId: string | null
}
export interface AIDocumentAnalysis {
summary: string
extractedClauses: ExtractedClause[]
applicableControls: string[]
gaps: string[]
confidence: number
analyzedAt: Date
}
export interface EvidenceDocument {
id: string
filename: string
originalName: string
mimeType: string
size: number
uploadedAt: Date
uploadedBy: string
documentType: DocumentType
detectedType: DocumentType | null
hash: string
validFrom: Date | null
validUntil: Date | null
linkedControlIds: string[]
aiAnalysis: AIDocumentAnalysis | null
status: EvidenceStatus
}
// =============================================================================
// CONTROL LIBRARY
// =============================================================================
export interface LocalizedString {
de: string
en: string
}
export interface FrameworkMapping {
framework: string
reference: string
}
export interface ApplicabilityCondition {
field: string
operator: ConditionOperator
value: unknown
result: ControlApplicability
priority: number
}
export interface ControlLibraryEntry {
id: string
code: string
category: ControlCategory
type: 'TECHNICAL' | 'ORGANIZATIONAL'
name: LocalizedString
description: LocalizedString
mappings: FrameworkMapping[]
applicabilityConditions: ApplicabilityCondition[]
defaultApplicability: ControlApplicability
evidenceRequirements: string[]
reviewFrequency: ReviewFrequency
priority: ControlPriority
complexity: ControlComplexity
tags: string[]
}
// =============================================================================
// DERIVED TOM
// =============================================================================
export interface DerivedTOM {
id: string
controlId: string
name: string
description: string
applicability: ControlApplicability
applicabilityReason: string
implementationStatus: ImplementationStatus
responsiblePerson: string | null
responsibleDepartment: string | null
implementationDate: Date | null
reviewDate: Date | null
linkedEvidence: string[]
evidenceGaps: string[]
aiGeneratedDescription: string | null
aiRecommendations: string[]
}
// =============================================================================
// GAP ANALYSIS
// =============================================================================
export interface MissingControl {
controlId: string
reason: string
priority: string
}
export interface PartialControl {
controlId: string
missingAspects: string[]
}
export interface MissingEvidence {
controlId: string
requiredEvidence: string[]
}
export interface GapAnalysisResult {
overallScore: number
missingControls: MissingControl[]
partialControls: PartialControl[]
missingEvidence: MissingEvidence[]
recommendations: string[]
generatedAt: Date
}
// =============================================================================
// WIZARD STEP
// =============================================================================
export interface WizardStep {
id: TOMGeneratorStepId
completed: boolean
data: unknown
validatedAt: Date | null
}
// =============================================================================
// EXPORT RECORD
// =============================================================================
export interface ExportRecord {
id: string
format: 'DOCX' | 'PDF' | 'JSON' | 'ZIP'
generatedAt: Date
filename: string
}
// =============================================================================
// TOM GENERATOR STATE
// =============================================================================
export interface TOMGeneratorState {
id: string
tenantId: string
companyProfile: CompanyProfile | null
dataProfile: DataProfile | null
architectureProfile: ArchitectureProfile | null
securityProfile: SecurityProfile | null
riskProfile: RiskProfile | null
currentStep: TOMGeneratorStepId
steps: WizardStep[]
documents: EvidenceDocument[]
derivedTOMs: DerivedTOM[]
gapAnalysis: GapAnalysisResult | null
exports: ExportRecord[]
createdAt: Date
updatedAt: Date
}
// =============================================================================
// RULES ENGINE TYPES
// =============================================================================
export interface RulesEngineResult {
controlId: string
applicability: ControlApplicability
reason: string
matchedCondition?: ApplicabilityCondition
}
export interface RulesEngineEvaluationContext {
companyProfile: CompanyProfile | null
dataProfile: DataProfile | null
architectureProfile: ArchitectureProfile | null
securityProfile: SecurityProfile | null
riskProfile: RiskProfile | null
}
// =============================================================================
// API TYPES
// =============================================================================
export interface TOMGeneratorStateRequest {
tenantId: string
}
export interface TOMGeneratorStateResponse {
success: boolean
state: TOMGeneratorState | null
error?: string
}
export interface ControlsEvaluationRequest {
tenantId: string
context: RulesEngineEvaluationContext
}
export interface ControlsEvaluationResponse {
success: boolean
results: RulesEngineResult[]
evaluatedAt: string
}
export interface EvidenceUploadRequest {
tenantId: string
documentType: DocumentType
validFrom?: string
validUntil?: string
}
export interface EvidenceUploadResponse {
success: boolean
document: EvidenceDocument | null
error?: string
}
export interface EvidenceAnalyzeRequest {
documentId: string
tenantId: string
}
export interface EvidenceAnalyzeResponse {
success: boolean
analysis: AIDocumentAnalysis | null
error?: string
}
export interface ExportRequest {
tenantId: string
format: 'DOCX' | 'PDF' | 'JSON' | 'ZIP'
language: 'de' | 'en'
}
export interface ExportResponse {
success: boolean
exportId: string
filename: string
downloadUrl?: string
error?: string
}
export interface GapAnalysisRequest {
tenantId: string
}
export interface GapAnalysisResponse {
success: boolean
result: GapAnalysisResult | null
error?: string
}
// =============================================================================
// STEP CONFIGURATION
// =============================================================================
export interface StepConfig {
id: TOMGeneratorStepId
title: LocalizedString
description: LocalizedString
checkpointId: string
path: string
/** Alias for path (for convenience) */
url: string
/** German title for display (for convenience) */
name: string
}
export const TOM_GENERATOR_STEPS: StepConfig[] = [
{
id: 'scope-roles',
title: { de: 'Scope & Rollen', en: 'Scope & Roles' },
description: {
de: 'Unternehmensname, Branche, Größe und Rolle definieren',
en: 'Define company name, industry, size and role',
},
checkpointId: 'CP-TOM-SCOPE',
path: '/sdk/tom-generator/scope',
url: '/sdk/tom-generator/scope',
name: 'Scope & Rollen',
},
{
id: 'data-categories',
title: { de: 'Datenkategorien', en: 'Data Categories' },
description: {
de: 'Datenkategorien und betroffene Personen erfassen',
en: 'Capture data categories and data subjects',
},
checkpointId: 'CP-TOM-DATA',
path: '/sdk/tom-generator/data',
url: '/sdk/tom-generator/data',
name: 'Datenkategorien',
},
{
id: 'architecture-hosting',
title: { de: 'Architektur & Hosting', en: 'Architecture & Hosting' },
description: {
de: 'Hosting-Modell, Standort und Provider definieren',
en: 'Define hosting model, location and providers',
},
checkpointId: 'CP-TOM-ARCH',
path: '/sdk/tom-generator/architecture',
url: '/sdk/tom-generator/architecture',
name: 'Architektur & Hosting',
},
{
id: 'security-profile',
title: { de: 'Security-Profil', en: 'Security Profile' },
description: {
de: 'Authentifizierung, Verschlüsselung und Backup konfigurieren',
en: 'Configure authentication, encryption and backup',
},
checkpointId: 'CP-TOM-SEC',
path: '/sdk/tom-generator/security',
url: '/sdk/tom-generator/security',
name: 'Security-Profil',
},
{
id: 'risk-protection',
title: { de: 'Risiko & Schutzbedarf', en: 'Risk & Protection Level' },
description: {
de: 'CIA-Bewertung und Schutzbedarf ermitteln',
en: 'Determine CIA assessment and protection level',
},
checkpointId: 'CP-TOM-RISK',
path: '/sdk/tom-generator/risk',
url: '/sdk/tom-generator/risk',
name: 'Risiko & Schutzbedarf',
},
{
id: 'review-export',
title: { de: 'Review & Export', en: 'Review & Export' },
description: {
de: 'Zusammenfassung prüfen und TOMs exportieren',
en: 'Review summary and export TOMs',
},
checkpointId: 'CP-TOM-REVIEW',
path: '/sdk/tom-generator/review',
url: '/sdk/tom-generator/review',
name: 'Review & Export',
},
]
// =============================================================================
// CATEGORY METADATA
// =============================================================================
export interface CategoryMetadata {
id: ControlCategory
name: LocalizedString
gdprReference: string
icon?: string
}
export const CONTROL_CATEGORIES: CategoryMetadata[] = [
{
id: 'ACCESS_CONTROL',
name: { de: 'Zutrittskontrolle', en: 'Physical Access Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ADMISSION_CONTROL',
name: { de: 'Zugangskontrolle', en: 'System Access Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ACCESS_AUTHORIZATION',
name: { de: 'Zugriffskontrolle', en: 'Access Authorization' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'TRANSFER_CONTROL',
name: { de: 'Weitergabekontrolle', en: 'Transfer Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'INPUT_CONTROL',
name: { de: 'Eingabekontrolle', en: 'Input Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ORDER_CONTROL',
name: { de: 'Auftragskontrolle', en: 'Order Control' },
gdprReference: 'Art. 28',
},
{
id: 'AVAILABILITY',
name: { de: 'Verfügbarkeit', en: 'Availability' },
gdprReference: 'Art. 32 Abs. 1 lit. b, c',
},
{
id: 'SEPARATION',
name: { de: 'Trennbarkeit', en: 'Separation' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ENCRYPTION',
name: { de: 'Verschlüsselung', en: 'Encryption' },
gdprReference: 'Art. 32 Abs. 1 lit. a',
},
{
id: 'PSEUDONYMIZATION',
name: { de: 'Pseudonymisierung', en: 'Pseudonymization' },
gdprReference: 'Art. 32 Abs. 1 lit. a',
},
{
id: 'RESILIENCE',
name: { de: 'Belastbarkeit', en: 'Resilience' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'RECOVERY',
name: { de: 'Wiederherstellbarkeit', en: 'Recovery' },
gdprReference: 'Art. 32 Abs. 1 lit. c',
},
{
id: 'REVIEW',
name: { de: 'Überprüfung & Bewertung', en: 'Review & Assessment' },
gdprReference: 'Art. 32 Abs. 1 lit. d',
},
]
// =============================================================================
// DATA CATEGORY METADATA
// =============================================================================
export interface DataCategoryMetadata {
id: DataCategory
name: LocalizedString
isSpecialCategory: boolean
gdprReference?: string
}
export const DATA_CATEGORIES_METADATA: DataCategoryMetadata[] = [
{
id: 'IDENTIFICATION',
name: { de: 'Identifikationsdaten', en: 'Identification Data' },
isSpecialCategory: false,
},
{
id: 'CONTACT',
name: { de: 'Kontaktdaten', en: 'Contact Data' },
isSpecialCategory: false,
},
{
id: 'FINANCIAL',
name: { de: 'Finanzdaten', en: 'Financial Data' },
isSpecialCategory: false,
},
{
id: 'PROFESSIONAL',
name: { de: 'Berufliche Daten', en: 'Professional Data' },
isSpecialCategory: false,
},
{
id: 'LOCATION',
name: { de: 'Standortdaten', en: 'Location Data' },
isSpecialCategory: false,
},
{
id: 'BEHAVIORAL',
name: { de: 'Verhaltensdaten', en: 'Behavioral Data' },
isSpecialCategory: false,
},
{
id: 'BIOMETRIC',
name: { de: 'Biometrische Daten', en: 'Biometric Data' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'HEALTH',
name: { de: 'Gesundheitsdaten', en: 'Health Data' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'GENETIC',
name: { de: 'Genetische Daten', en: 'Genetic Data' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'POLITICAL',
name: { de: 'Politische Meinungen', en: 'Political Opinions' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'RELIGIOUS',
name: { de: 'Religiöse Überzeugungen', en: 'Religious Beliefs' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'SEXUAL_ORIENTATION',
name: { de: 'Sexuelle Orientierung', en: 'Sexual Orientation' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'CRIMINAL',
name: { de: 'Strafrechtliche Daten', en: 'Criminal Data' },
isSpecialCategory: true,
gdprReference: 'Art. 10',
},
]
// =============================================================================
// DATA SUBJECT METADATA
// =============================================================================
export interface DataSubjectMetadata {
id: DataSubject
name: LocalizedString
isVulnerable: boolean
}
export const DATA_SUBJECTS_METADATA: DataSubjectMetadata[] = [
{
id: 'EMPLOYEES',
name: { de: 'Mitarbeiter', en: 'Employees' },
isVulnerable: false,
},
{
id: 'CUSTOMERS',
name: { de: 'Kunden', en: 'Customers' },
isVulnerable: false,
},
{
id: 'PROSPECTS',
name: { de: 'Interessenten', en: 'Prospects' },
isVulnerable: false,
},
{
id: 'SUPPLIERS',
name: { de: 'Lieferanten', en: 'Suppliers' },
isVulnerable: false,
},
{
id: 'MINORS',
name: { de: 'Minderjährige', en: 'Minors' },
isVulnerable: true,
},
{
id: 'PATIENTS',
name: { de: 'Patienten', en: 'Patients' },
isVulnerable: true,
},
{
id: 'STUDENTS',
name: { de: 'Schüler/Studenten', en: 'Students' },
isVulnerable: false,
},
{
id: 'GENERAL_PUBLIC',
name: { de: 'Allgemeine Öffentlichkeit', en: 'General Public' },
isVulnerable: false,
},
]
// =============================================================================
// HELPER FUNCTIONS
// =============================================================================
export function getStepByIndex(index: number): StepConfig | undefined {
return TOM_GENERATOR_STEPS[index]
}
export function getStepById(id: TOMGeneratorStepId): StepConfig | undefined {
return TOM_GENERATOR_STEPS.find((step) => step.id === id)
}
export function getStepIndex(id: TOMGeneratorStepId): number {
return TOM_GENERATOR_STEPS.findIndex((step) => step.id === id)
}
export function getNextStep(
currentId: TOMGeneratorStepId
): StepConfig | undefined {
const currentIndex = getStepIndex(currentId)
return TOM_GENERATOR_STEPS[currentIndex + 1]
}
export function getPreviousStep(
currentId: TOMGeneratorStepId
): StepConfig | undefined {
const currentIndex = getStepIndex(currentId)
return currentIndex > 0 ? TOM_GENERATOR_STEPS[currentIndex - 1] : undefined
}
export function isSpecialCategory(category: DataCategory): boolean {
const meta = DATA_CATEGORIES_METADATA.find((c) => c.id === category)
return meta?.isSpecialCategory ?? false
}
export function hasSpecialCategories(categories: DataCategory[]): boolean {
return categories.some(isSpecialCategory)
}
export function isVulnerableSubject(subject: DataSubject): boolean {
const meta = DATA_SUBJECTS_METADATA.find((s) => s.id === subject)
return meta?.isVulnerable ?? false
}
export function hasVulnerableSubjects(subjects: DataSubject[]): boolean {
return subjects.some(isVulnerableSubject)
}
export function calculateProtectionLevel(
ciaAssessment: CIAAssessment
): ProtectionLevel {
const maxRating = Math.max(
ciaAssessment.confidentiality,
ciaAssessment.integrity,
ciaAssessment.availability
)
if (maxRating >= 4) return 'VERY_HIGH'
if (maxRating >= 3) return 'HIGH'
return 'NORMAL'
}
export function isDSFARequired(
dataProfile: DataProfile | null,
riskProfile: RiskProfile | null
): boolean {
if (!dataProfile) return false
// DSFA required if:
// 1. Special categories are processed
if (dataProfile.hasSpecialCategories) return true
// 2. Minors data is processed
if (dataProfile.processesMinors) return true
// 3. Large scale processing
if (dataProfile.dataVolume === 'VERY_HIGH') return true
// 4. High risk processing indicated
if (riskProfile?.hasHighRiskProcessing) return true
// 5. Very high protection level
if (riskProfile?.protectionLevel === 'VERY_HIGH') return true
return false
}
// =============================================================================
// INITIAL STATE FACTORY
// =============================================================================
export function createInitialTOMGeneratorState(
tenantId: string
): TOMGeneratorState {
const now = new Date()
return {
id: crypto.randomUUID(),
tenantId,
companyProfile: null,
dataProfile: null,
architectureProfile: null,
securityProfile: null,
riskProfile: null,
currentStep: 'scope-roles',
steps: TOM_GENERATOR_STEPS.map((step) => ({
id: step.id,
completed: false,
data: null,
validatedAt: null,
})),
documents: [],
derivedTOMs: [],
gapAnalysis: null,
exports: [],
createdAt: now,
updatedAt: now,
}
}
/**
* Alias for createInitialTOMGeneratorState (for API compatibility)
*/
export const createEmptyTOMGeneratorState = createInitialTOMGeneratorState
// =============================================================================
// SDM TYPES (Standard-Datenschutzmodell)
// =============================================================================
export type SDMGewaehrleistungsziel =
| 'Verfuegbarkeit'
| 'Integritaet'
| 'Vertraulichkeit'
| 'Nichtverkettung'
| 'Intervenierbarkeit'
| 'Transparenz'
| 'Datenminimierung'
export type TOMModuleCategory =
| 'IDENTITY_AUTH'
| 'LOGGING'
| 'DOCUMENTATION'
| 'SEPARATION'
| 'RETENTION'
| 'DELETION'
| 'TRAINING'
| 'REVIEW'
/**
* Maps ControlCategory to SDM Gewaehrleistungsziele.
* Used by the TOM Dashboard to display SDM coverage.
*/
export const SDM_CATEGORY_MAPPING: Record<ControlCategory, SDMGewaehrleistungsziel[]> = {
ACCESS_CONTROL: ['Vertraulichkeit'],
ADMISSION_CONTROL: ['Vertraulichkeit', 'Integritaet'],
ACCESS_AUTHORIZATION: ['Vertraulichkeit', 'Nichtverkettung'],
TRANSFER_CONTROL: ['Vertraulichkeit', 'Integritaet'],
INPUT_CONTROL: ['Integritaet', 'Transparenz'],
ORDER_CONTROL: ['Transparenz', 'Intervenierbarkeit'],
AVAILABILITY: ['Verfuegbarkeit'],
SEPARATION: ['Nichtverkettung', 'Datenminimierung'],
ENCRYPTION: ['Vertraulichkeit', 'Integritaet'],
PSEUDONYMIZATION: ['Datenminimierung', 'Nichtverkettung'],
RESILIENCE: ['Verfuegbarkeit'],
RECOVERY: ['Verfuegbarkeit', 'Integritaet'],
REVIEW: ['Transparenz', 'Intervenierbarkeit'],
}
/**
* Maps ControlCategory to Spec Module Categories.
*/
export const MODULE_CATEGORY_MAPPING: Record<ControlCategory, TOMModuleCategory[]> = {
ACCESS_CONTROL: ['IDENTITY_AUTH'],
ADMISSION_CONTROL: ['IDENTITY_AUTH'],
ACCESS_AUTHORIZATION: ['IDENTITY_AUTH', 'DOCUMENTATION'],
TRANSFER_CONTROL: ['DOCUMENTATION'],
INPUT_CONTROL: ['LOGGING'],
ORDER_CONTROL: ['DOCUMENTATION'],
AVAILABILITY: ['REVIEW'],
SEPARATION: ['SEPARATION'],
ENCRYPTION: ['IDENTITY_AUTH'],
PSEUDONYMIZATION: ['SEPARATION', 'DELETION'],
RESILIENCE: ['REVIEW'],
RECOVERY: ['REVIEW'],
REVIEW: ['REVIEW', 'TRAINING'],
}

View File

@@ -0,0 +1,77 @@
// =============================================================================
// API TYPES
// =============================================================================
import type { DocumentType } from './enums'
import type { AIDocumentAnalysis, EvidenceDocument } from './evidence'
import type { GapAnalysisResult } from './gap-analysis'
import type { TOMGeneratorState, RulesEngineEvaluationContext, RulesEngineResult } from './state'
export interface TOMGeneratorStateRequest {
tenantId: string
}
export interface TOMGeneratorStateResponse {
success: boolean
state: TOMGeneratorState | null
error?: string
}
export interface ControlsEvaluationRequest {
tenantId: string
context: RulesEngineEvaluationContext
}
export interface ControlsEvaluationResponse {
success: boolean
results: RulesEngineResult[]
evaluatedAt: string
}
export interface EvidenceUploadRequest {
tenantId: string
documentType: DocumentType
validFrom?: string
validUntil?: string
}
export interface EvidenceUploadResponse {
success: boolean
document: EvidenceDocument | null
error?: string
}
export interface EvidenceAnalyzeRequest {
documentId: string
tenantId: string
}
export interface EvidenceAnalyzeResponse {
success: boolean
analysis: AIDocumentAnalysis | null
error?: string
}
export interface ExportRequest {
tenantId: string
format: 'DOCX' | 'PDF' | 'JSON' | 'ZIP'
language: 'de' | 'en'
}
export interface ExportResponse {
success: boolean
exportId: string
filename: string
downloadUrl?: string
error?: string
}
export interface GapAnalysisRequest {
tenantId: string
}
export interface GapAnalysisResponse {
success: boolean
result: GapAnalysisResult | null
error?: string
}

View File

@@ -0,0 +1,81 @@
// =============================================================================
// CATEGORY METADATA
// =============================================================================
import type { ControlCategory } from './enums'
import type { LocalizedString } from './control-library'
export interface CategoryMetadata {
id: ControlCategory
name: LocalizedString
gdprReference: string
icon?: string
}
export const CONTROL_CATEGORIES: CategoryMetadata[] = [
{
id: 'ACCESS_CONTROL',
name: { de: 'Zutrittskontrolle', en: 'Physical Access Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ADMISSION_CONTROL',
name: { de: 'Zugangskontrolle', en: 'System Access Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ACCESS_AUTHORIZATION',
name: { de: 'Zugriffskontrolle', en: 'Access Authorization' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'TRANSFER_CONTROL',
name: { de: 'Weitergabekontrolle', en: 'Transfer Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'INPUT_CONTROL',
name: { de: 'Eingabekontrolle', en: 'Input Control' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ORDER_CONTROL',
name: { de: 'Auftragskontrolle', en: 'Order Control' },
gdprReference: 'Art. 28',
},
{
id: 'AVAILABILITY',
name: { de: 'Verfügbarkeit', en: 'Availability' },
gdprReference: 'Art. 32 Abs. 1 lit. b, c',
},
{
id: 'SEPARATION',
name: { de: 'Trennbarkeit', en: 'Separation' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'ENCRYPTION',
name: { de: 'Verschlüsselung', en: 'Encryption' },
gdprReference: 'Art. 32 Abs. 1 lit. a',
},
{
id: 'PSEUDONYMIZATION',
name: { de: 'Pseudonymisierung', en: 'Pseudonymization' },
gdprReference: 'Art. 32 Abs. 1 lit. a',
},
{
id: 'RESILIENCE',
name: { de: 'Belastbarkeit', en: 'Resilience' },
gdprReference: 'Art. 32 Abs. 1 lit. b',
},
{
id: 'RECOVERY',
name: { de: 'Wiederherstellbarkeit', en: 'Recovery' },
gdprReference: 'Art. 32 Abs. 1 lit. c',
},
{
id: 'REVIEW',
name: { de: 'Überprüfung & Bewertung', en: 'Review & Assessment' },
gdprReference: 'Art. 32 Abs. 1 lit. d',
},
]

View File

@@ -0,0 +1,47 @@
// =============================================================================
// CONTROL LIBRARY
// =============================================================================
import type {
ControlCategory,
ControlApplicability,
ConditionOperator,
ReviewFrequency,
ControlPriority,
ControlComplexity,
} from './enums'
export interface LocalizedString {
de: string
en: string
}
export interface FrameworkMapping {
framework: string
reference: string
}
export interface ApplicabilityCondition {
field: string
operator: ConditionOperator
value: unknown
result: ControlApplicability
priority: number
}
export interface ControlLibraryEntry {
id: string
code: string
category: ControlCategory
type: 'TECHNICAL' | 'ORGANIZATIONAL'
name: LocalizedString
description: LocalizedString
mappings: FrameworkMapping[]
applicabilityConditions: ApplicabilityCondition[]
defaultApplicability: ControlApplicability
evidenceRequirements: string[]
reviewFrequency: ReviewFrequency
priority: ControlPriority
complexity: ControlComplexity
tags: string[]
}

View File

@@ -0,0 +1,141 @@
// =============================================================================
// DATA CATEGORY METADATA
// =============================================================================
import type { DataCategory, DataSubject } from './enums'
import type { LocalizedString } from './control-library'
export interface DataCategoryMetadata {
id: DataCategory
name: LocalizedString
isSpecialCategory: boolean
gdprReference?: string
}
export const DATA_CATEGORIES_METADATA: DataCategoryMetadata[] = [
{
id: 'IDENTIFICATION',
name: { de: 'Identifikationsdaten', en: 'Identification Data' },
isSpecialCategory: false,
},
{
id: 'CONTACT',
name: { de: 'Kontaktdaten', en: 'Contact Data' },
isSpecialCategory: false,
},
{
id: 'FINANCIAL',
name: { de: 'Finanzdaten', en: 'Financial Data' },
isSpecialCategory: false,
},
{
id: 'PROFESSIONAL',
name: { de: 'Berufliche Daten', en: 'Professional Data' },
isSpecialCategory: false,
},
{
id: 'LOCATION',
name: { de: 'Standortdaten', en: 'Location Data' },
isSpecialCategory: false,
},
{
id: 'BEHAVIORAL',
name: { de: 'Verhaltensdaten', en: 'Behavioral Data' },
isSpecialCategory: false,
},
{
id: 'BIOMETRIC',
name: { de: 'Biometrische Daten', en: 'Biometric Data' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'HEALTH',
name: { de: 'Gesundheitsdaten', en: 'Health Data' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'GENETIC',
name: { de: 'Genetische Daten', en: 'Genetic Data' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'POLITICAL',
name: { de: 'Politische Meinungen', en: 'Political Opinions' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'RELIGIOUS',
name: { de: 'Religiöse Überzeugungen', en: 'Religious Beliefs' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'SEXUAL_ORIENTATION',
name: { de: 'Sexuelle Orientierung', en: 'Sexual Orientation' },
isSpecialCategory: true,
gdprReference: 'Art. 9 Abs. 1',
},
{
id: 'CRIMINAL',
name: { de: 'Strafrechtliche Daten', en: 'Criminal Data' },
isSpecialCategory: true,
gdprReference: 'Art. 10',
},
]
// =============================================================================
// DATA SUBJECT METADATA
// =============================================================================
export interface DataSubjectMetadata {
id: DataSubject
name: LocalizedString
isVulnerable: boolean
}
export const DATA_SUBJECTS_METADATA: DataSubjectMetadata[] = [
{
id: 'EMPLOYEES',
name: { de: 'Mitarbeiter', en: 'Employees' },
isVulnerable: false,
},
{
id: 'CUSTOMERS',
name: { de: 'Kunden', en: 'Customers' },
isVulnerable: false,
},
{
id: 'PROSPECTS',
name: { de: 'Interessenten', en: 'Prospects' },
isVulnerable: false,
},
{
id: 'SUPPLIERS',
name: { de: 'Lieferanten', en: 'Suppliers' },
isVulnerable: false,
},
{
id: 'MINORS',
name: { de: 'Minderjährige', en: 'Minors' },
isVulnerable: true,
},
{
id: 'PATIENTS',
name: { de: 'Patienten', en: 'Patients' },
isVulnerable: true,
},
{
id: 'STUDENTS',
name: { de: 'Schüler/Studenten', en: 'Students' },
isVulnerable: false,
},
{
id: 'GENERAL_PUBLIC',
name: { de: 'Allgemeine Öffentlichkeit', en: 'General Public' },
isVulnerable: false,
},
]

View File

@@ -0,0 +1,23 @@
// =============================================================================
// DERIVED TOM
// =============================================================================
import type { ControlApplicability, ImplementationStatus } from './enums'
export interface DerivedTOM {
id: string
controlId: string
name: string
description: string
applicability: ControlApplicability
applicabilityReason: string
implementationStatus: ImplementationStatus
responsiblePerson: string | null
responsibleDepartment: string | null
implementationDate: Date | null
reviewDate: Date | null
linkedEvidence: string[]
evidenceGaps: string[]
aiGeneratedDescription: string | null
aiRecommendations: string[]
}

View File

@@ -0,0 +1,115 @@
// =============================================================================
// TOM Generator Module - Enums & Literal Types
// DSGVO Art. 32 Technical and Organizational Measures
// =============================================================================
export type TOMGeneratorStepId =
| 'scope-roles'
| 'data-categories'
| 'architecture-hosting'
| 'security-profile'
| 'risk-protection'
| 'review-export'
export type CompanyRole = 'CONTROLLER' | 'PROCESSOR' | 'JOINT_CONTROLLER'
export type DataCategory =
| 'IDENTIFICATION'
| 'CONTACT'
| 'FINANCIAL'
| 'PROFESSIONAL'
| 'LOCATION'
| 'BEHAVIORAL'
| 'BIOMETRIC'
| 'HEALTH'
| 'GENETIC'
| 'POLITICAL'
| 'RELIGIOUS'
| 'SEXUAL_ORIENTATION'
| 'CRIMINAL'
export type DataSubject =
| 'EMPLOYEES'
| 'CUSTOMERS'
| 'PROSPECTS'
| 'SUPPLIERS'
| 'MINORS'
| 'PATIENTS'
| 'STUDENTS'
| 'GENERAL_PUBLIC'
export type HostingLocation =
| 'DE'
| 'EU'
| 'EEA'
| 'THIRD_COUNTRY_ADEQUATE'
| 'THIRD_COUNTRY'
export type HostingModel = 'ON_PREMISE' | 'PRIVATE_CLOUD' | 'PUBLIC_CLOUD' | 'HYBRID'
export type MultiTenancy = 'SINGLE_TENANT' | 'MULTI_TENANT' | 'DEDICATED'
export type ControlApplicability =
| 'REQUIRED'
| 'RECOMMENDED'
| 'OPTIONAL'
| 'NOT_APPLICABLE'
export type DocumentType =
| 'AVV'
| 'DPA'
| 'SLA'
| 'NDA'
| 'POLICY'
| 'CERTIFICATE'
| 'AUDIT_REPORT'
| 'OTHER'
export type ProtectionLevel = 'NORMAL' | 'HIGH' | 'VERY_HIGH'
export type CIARating = 1 | 2 | 3 | 4 | 5
export type ControlCategory =
| 'ACCESS_CONTROL'
| 'ADMISSION_CONTROL'
| 'ACCESS_AUTHORIZATION'
| 'TRANSFER_CONTROL'
| 'INPUT_CONTROL'
| 'ORDER_CONTROL'
| 'AVAILABILITY'
| 'SEPARATION'
| 'ENCRYPTION'
| 'PSEUDONYMIZATION'
| 'RESILIENCE'
| 'RECOVERY'
| 'REVIEW'
export type CompanySize = 'MICRO' | 'SMALL' | 'MEDIUM' | 'LARGE' | 'ENTERPRISE'
export type DataVolume = 'LOW' | 'MEDIUM' | 'HIGH' | 'VERY_HIGH'
export type AuthMethodType =
| 'PASSWORD'
| 'MFA'
| 'SSO'
| 'CERTIFICATE'
| 'BIOMETRIC'
export type BackupFrequency = 'HOURLY' | 'DAILY' | 'WEEKLY' | 'MONTHLY'
export type ReviewFrequency = 'MONTHLY' | 'QUARTERLY' | 'SEMI_ANNUAL' | 'ANNUAL'
export type ControlPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
export type ControlComplexity = 'LOW' | 'MEDIUM' | 'HIGH'
export type ImplementationStatus = 'NOT_IMPLEMENTED' | 'PARTIAL' | 'IMPLEMENTED'
export type EvidenceStatus = 'PENDING' | 'ANALYZED' | 'VERIFIED' | 'REJECTED'
export type ConditionOperator =
| 'EQUALS'
| 'NOT_EQUALS'
| 'CONTAINS'
| 'GREATER_THAN'
| 'IN'

View File

@@ -0,0 +1,39 @@
// =============================================================================
// EVIDENCE DOCUMENT
// =============================================================================
import type { DocumentType, EvidenceStatus } from './enums'
export interface ExtractedClause {
id: string
text: string
type: string
relatedControlId: string | null
}
export interface AIDocumentAnalysis {
summary: string
extractedClauses: ExtractedClause[]
applicableControls: string[]
gaps: string[]
confidence: number
analyzedAt: Date
}
export interface EvidenceDocument {
id: string
filename: string
originalName: string
mimeType: string
size: number
uploadedAt: Date
uploadedBy: string
documentType: DocumentType
detectedType: DocumentType | null
hash: string
validFrom: Date | null
validUntil: Date | null
linkedControlIds: string[]
aiAnalysis: AIDocumentAnalysis | null
status: EvidenceStatus
}

View File

@@ -0,0 +1,28 @@
// =============================================================================
// GAP ANALYSIS
// =============================================================================
export interface MissingControl {
controlId: string
reason: string
priority: string
}
export interface PartialControl {
controlId: string
missingAspects: string[]
}
export interface MissingEvidence {
controlId: string
requiredEvidence: string[]
}
export interface GapAnalysisResult {
overallScore: number
missingControls: MissingControl[]
partialControls: PartialControl[]
missingEvidence: MissingEvidence[]
recommendations: string[]
generatedAt: Date
}

View File

@@ -0,0 +1,131 @@
// =============================================================================
// HELPER FUNCTIONS & INITIAL STATE FACTORY
// =============================================================================
import type { TOMGeneratorStepId, DataCategory, DataSubject, ProtectionLevel } from './enums'
import type { CIAAssessment, DataProfile, RiskProfile } from './profiles'
import type { TOMGeneratorState } from './state'
import type { StepConfig } from './step-config'
import { TOM_GENERATOR_STEPS } from './step-config'
import { DATA_CATEGORIES_METADATA } from './data-metadata'
import { DATA_SUBJECTS_METADATA } from './data-metadata'
export function getStepByIndex(index: number): StepConfig | undefined {
return TOM_GENERATOR_STEPS[index]
}
export function getStepById(id: TOMGeneratorStepId): StepConfig | undefined {
return TOM_GENERATOR_STEPS.find((step) => step.id === id)
}
export function getStepIndex(id: TOMGeneratorStepId): number {
return TOM_GENERATOR_STEPS.findIndex((step) => step.id === id)
}
export function getNextStep(
currentId: TOMGeneratorStepId
): StepConfig | undefined {
const currentIndex = getStepIndex(currentId)
return TOM_GENERATOR_STEPS[currentIndex + 1]
}
export function getPreviousStep(
currentId: TOMGeneratorStepId
): StepConfig | undefined {
const currentIndex = getStepIndex(currentId)
return currentIndex > 0 ? TOM_GENERATOR_STEPS[currentIndex - 1] : undefined
}
export function isSpecialCategory(category: DataCategory): boolean {
const meta = DATA_CATEGORIES_METADATA.find((c) => c.id === category)
return meta?.isSpecialCategory ?? false
}
export function hasSpecialCategories(categories: DataCategory[]): boolean {
return categories.some(isSpecialCategory)
}
export function isVulnerableSubject(subject: DataSubject): boolean {
const meta = DATA_SUBJECTS_METADATA.find((s) => s.id === subject)
return meta?.isVulnerable ?? false
}
export function hasVulnerableSubjects(subjects: DataSubject[]): boolean {
return subjects.some(isVulnerableSubject)
}
export function calculateProtectionLevel(
ciaAssessment: CIAAssessment
): ProtectionLevel {
const maxRating = Math.max(
ciaAssessment.confidentiality,
ciaAssessment.integrity,
ciaAssessment.availability
)
if (maxRating >= 4) return 'VERY_HIGH'
if (maxRating >= 3) return 'HIGH'
return 'NORMAL'
}
export function isDSFARequired(
dataProfile: DataProfile | null,
riskProfile: RiskProfile | null
): boolean {
if (!dataProfile) return false
// DSFA required if:
// 1. Special categories are processed
if (dataProfile.hasSpecialCategories) return true
// 2. Minors data is processed
if (dataProfile.processesMinors) return true
// 3. Large scale processing
if (dataProfile.dataVolume === 'VERY_HIGH') return true
// 4. High risk processing indicated
if (riskProfile?.hasHighRiskProcessing) return true
// 5. Very high protection level
if (riskProfile?.protectionLevel === 'VERY_HIGH') return true
return false
}
// =============================================================================
// INITIAL STATE FACTORY
// =============================================================================
export function createInitialTOMGeneratorState(
tenantId: string
): TOMGeneratorState {
const now = new Date()
return {
id: crypto.randomUUID(),
tenantId,
companyProfile: null,
dataProfile: null,
architectureProfile: null,
securityProfile: null,
riskProfile: null,
currentStep: 'scope-roles',
steps: TOM_GENERATOR_STEPS.map((step) => ({
id: step.id,
completed: false,
data: null,
validatedAt: null,
})),
documents: [],
derivedTOMs: [],
gapAnalysis: null,
exports: [],
createdAt: now,
updatedAt: now,
}
}
/**
* Alias for createInitialTOMGeneratorState (for API compatibility)
*/
export const createEmptyTOMGeneratorState = createInitialTOMGeneratorState

View File

@@ -0,0 +1,20 @@
/**
* TOM Generator Module - TypeScript Types
* DSGVO Art. 32 Technical and Organizational Measures
*
* Barrel re-export of all domain modules.
*/
export * from './enums'
export * from './profiles'
export * from './evidence'
export * from './control-library'
export * from './derived-tom'
export * from './gap-analysis'
export * from './state'
export * from './api'
export * from './step-config'
export * from './category-metadata'
export * from './data-metadata'
export * from './helpers'
export * from './sdm'

View File

@@ -0,0 +1,99 @@
// =============================================================================
// PROFILE INTERFACES (Wizard Steps 1-5)
// =============================================================================
import type {
CompanySize,
CompanyRole,
DataCategory,
DataSubject,
DataVolume,
HostingLocation,
HostingModel,
MultiTenancy,
AuthMethodType,
BackupFrequency,
CIARating,
ProtectionLevel,
} from './enums'
export interface CompanyProfile {
id: string
name: string
industry: string
size: CompanySize
role: CompanyRole
products: string[]
dpoPerson: string | null
dpoEmail: string | null
itSecurityContact: string | null
}
export interface DataProfile {
categories: DataCategory[]
subjects: DataSubject[]
hasSpecialCategories: boolean
processesMinors: boolean
dataVolume: DataVolume
thirdCountryTransfers: boolean
thirdCountryList: string[]
}
export interface CloudProvider {
name: string
location: HostingLocation
certifications: string[]
}
export interface ArchitectureProfile {
hostingModel: HostingModel
hostingLocation: HostingLocation
providers: CloudProvider[]
multiTenancy: MultiTenancy
hasSubprocessors: boolean
subprocessorCount: number
encryptionAtRest: boolean
encryptionInTransit: boolean
}
export interface AuthMethod {
type: AuthMethodType
provider: string | null
}
export interface SecurityProfile {
authMethods: AuthMethod[]
hasMFA: boolean
hasSSO: boolean
hasIAM: boolean
hasPAM: boolean
hasEncryptionAtRest: boolean
hasEncryptionInTransit: boolean
hasLogging: boolean
logRetentionDays: number
hasBackup: boolean
backupFrequency: BackupFrequency
backupRetentionDays: number
hasDRPlan: boolean
rtoHours: number | null
rpoHours: number | null
hasVulnerabilityManagement: boolean
hasPenetrationTests: boolean
hasSecurityTraining: boolean
}
export interface CIAAssessment {
confidentiality: CIARating
integrity: CIARating
availability: CIARating
justification: string
}
export interface RiskProfile {
ciaAssessment: CIAAssessment
protectionLevel: ProtectionLevel
specialRisks: string[]
regulatoryRequirements: string[]
hasHighRiskProcessing: boolean
dsfaRequired: boolean
}

View File

@@ -0,0 +1,63 @@
// =============================================================================
// SDM TYPES (Standard-Datenschutzmodell)
// =============================================================================
import type { ControlCategory } from './enums'
export type SDMGewaehrleistungsziel =
| 'Verfuegbarkeit'
| 'Integritaet'
| 'Vertraulichkeit'
| 'Nichtverkettung'
| 'Intervenierbarkeit'
| 'Transparenz'
| 'Datenminimierung'
export type TOMModuleCategory =
| 'IDENTITY_AUTH'
| 'LOGGING'
| 'DOCUMENTATION'
| 'SEPARATION'
| 'RETENTION'
| 'DELETION'
| 'TRAINING'
| 'REVIEW'
/**
* Maps ControlCategory to SDM Gewaehrleistungsziele.
* Used by the TOM Dashboard to display SDM coverage.
*/
export const SDM_CATEGORY_MAPPING: Record<ControlCategory, SDMGewaehrleistungsziel[]> = {
ACCESS_CONTROL: ['Vertraulichkeit'],
ADMISSION_CONTROL: ['Vertraulichkeit', 'Integritaet'],
ACCESS_AUTHORIZATION: ['Vertraulichkeit', 'Nichtverkettung'],
TRANSFER_CONTROL: ['Vertraulichkeit', 'Integritaet'],
INPUT_CONTROL: ['Integritaet', 'Transparenz'],
ORDER_CONTROL: ['Transparenz', 'Intervenierbarkeit'],
AVAILABILITY: ['Verfuegbarkeit'],
SEPARATION: ['Nichtverkettung', 'Datenminimierung'],
ENCRYPTION: ['Vertraulichkeit', 'Integritaet'],
PSEUDONYMIZATION: ['Datenminimierung', 'Nichtverkettung'],
RESILIENCE: ['Verfuegbarkeit'],
RECOVERY: ['Verfuegbarkeit', 'Integritaet'],
REVIEW: ['Transparenz', 'Intervenierbarkeit'],
}
/**
* Maps ControlCategory to Spec Module Categories.
*/
export const MODULE_CATEGORY_MAPPING: Record<ControlCategory, TOMModuleCategory[]> = {
ACCESS_CONTROL: ['IDENTITY_AUTH'],
ADMISSION_CONTROL: ['IDENTITY_AUTH'],
ACCESS_AUTHORIZATION: ['IDENTITY_AUTH', 'DOCUMENTATION'],
TRANSFER_CONTROL: ['DOCUMENTATION'],
INPUT_CONTROL: ['LOGGING'],
ORDER_CONTROL: ['DOCUMENTATION'],
AVAILABILITY: ['REVIEW'],
SEPARATION: ['SEPARATION'],
ENCRYPTION: ['IDENTITY_AUTH'],
PSEUDONYMIZATION: ['SEPARATION', 'DELETION'],
RESILIENCE: ['REVIEW'],
RECOVERY: ['REVIEW'],
REVIEW: ['REVIEW', 'TRAINING'],
}

View File

@@ -0,0 +1,76 @@
// =============================================================================
// WIZARD STEP, EXPORT RECORD, TOM GENERATOR STATE & RULES ENGINE
// =============================================================================
import type {
TOMGeneratorStepId,
ControlApplicability,
} from './enums'
import type { CompanyProfile, DataProfile, ArchitectureProfile, SecurityProfile, RiskProfile } from './profiles'
import type { EvidenceDocument } from './evidence'
import type { ApplicabilityCondition } from './control-library'
import type { DerivedTOM } from './derived-tom'
import type { GapAnalysisResult } from './gap-analysis'
// =============================================================================
// WIZARD STEP
// =============================================================================
export interface WizardStep {
id: TOMGeneratorStepId
completed: boolean
data: unknown
validatedAt: Date | null
}
// =============================================================================
// EXPORT RECORD
// =============================================================================
export interface ExportRecord {
id: string
format: 'DOCX' | 'PDF' | 'JSON' | 'ZIP'
generatedAt: Date
filename: string
}
// =============================================================================
// TOM GENERATOR STATE
// =============================================================================
export interface TOMGeneratorState {
id: string
tenantId: string
companyProfile: CompanyProfile | null
dataProfile: DataProfile | null
architectureProfile: ArchitectureProfile | null
securityProfile: SecurityProfile | null
riskProfile: RiskProfile | null
currentStep: TOMGeneratorStepId
steps: WizardStep[]
documents: EvidenceDocument[]
derivedTOMs: DerivedTOM[]
gapAnalysis: GapAnalysisResult | null
exports: ExportRecord[]
createdAt: Date
updatedAt: Date
}
// =============================================================================
// RULES ENGINE TYPES
// =============================================================================
export interface RulesEngineResult {
controlId: string
applicability: ControlApplicability
reason: string
matchedCondition?: ApplicabilityCondition
}
export interface RulesEngineEvaluationContext {
companyProfile: CompanyProfile | null
dataProfile: DataProfile | null
architectureProfile: ArchitectureProfile | null
securityProfile: SecurityProfile | null
riskProfile: RiskProfile | null
}

View File

@@ -0,0 +1,93 @@
// =============================================================================
// STEP CONFIGURATION
// =============================================================================
import type { TOMGeneratorStepId } from './enums'
import type { LocalizedString } from './control-library'
export interface StepConfig {
id: TOMGeneratorStepId
title: LocalizedString
description: LocalizedString
checkpointId: string
path: string
/** Alias for path (for convenience) */
url: string
/** German title for display (for convenience) */
name: string
}
export const TOM_GENERATOR_STEPS: StepConfig[] = [
{
id: 'scope-roles',
title: { de: 'Scope & Rollen', en: 'Scope & Roles' },
description: {
de: 'Unternehmensname, Branche, Größe und Rolle definieren',
en: 'Define company name, industry, size and role',
},
checkpointId: 'CP-TOM-SCOPE',
path: '/sdk/tom-generator/scope',
url: '/sdk/tom-generator/scope',
name: 'Scope & Rollen',
},
{
id: 'data-categories',
title: { de: 'Datenkategorien', en: 'Data Categories' },
description: {
de: 'Datenkategorien und betroffene Personen erfassen',
en: 'Capture data categories and data subjects',
},
checkpointId: 'CP-TOM-DATA',
path: '/sdk/tom-generator/data',
url: '/sdk/tom-generator/data',
name: 'Datenkategorien',
},
{
id: 'architecture-hosting',
title: { de: 'Architektur & Hosting', en: 'Architecture & Hosting' },
description: {
de: 'Hosting-Modell, Standort und Provider definieren',
en: 'Define hosting model, location and providers',
},
checkpointId: 'CP-TOM-ARCH',
path: '/sdk/tom-generator/architecture',
url: '/sdk/tom-generator/architecture',
name: 'Architektur & Hosting',
},
{
id: 'security-profile',
title: { de: 'Security-Profil', en: 'Security Profile' },
description: {
de: 'Authentifizierung, Verschlüsselung und Backup konfigurieren',
en: 'Configure authentication, encryption and backup',
},
checkpointId: 'CP-TOM-SEC',
path: '/sdk/tom-generator/security',
url: '/sdk/tom-generator/security',
name: 'Security-Profil',
},
{
id: 'risk-protection',
title: { de: 'Risiko & Schutzbedarf', en: 'Risk & Protection Level' },
description: {
de: 'CIA-Bewertung und Schutzbedarf ermitteln',
en: 'Determine CIA assessment and protection level',
},
checkpointId: 'CP-TOM-RISK',
path: '/sdk/tom-generator/risk',
url: '/sdk/tom-generator/risk',
name: 'Risiko & Schutzbedarf',
},
{
id: 'review-export',
title: { de: 'Review & Export', en: 'Review & Export' },
description: {
de: 'Zusammenfassung prüfen und TOMs exportieren',
en: 'Review summary and export TOMs',
},
checkpointId: 'CP-TOM-REVIEW',
path: '/sdk/tom-generator/review',
url: '/sdk/tom-generator/review',
name: 'Review & Export',
},
]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
// ==========================================
// INTERFACES - AUDIT REPORTS
// ==========================================
import type { ReportType, ExportFormat } from './enums'
export interface ReportScope {
vendorIds?: string[]
processingActivityIds?: string[]
dateRange?: { from: Date; to: Date }
}
export interface AuditReport {
id: string
tenantId: string
type: ReportType
// Scope
scope: ReportScope
// Generierung
format: ExportFormat
storagePath: string
generatedAt: Date
generatedBy: string
// Snapshot-Daten (fuer Revisionssicherheit)
snapshotHash: string // SHA-256 des Inhalts
}

View File

@@ -0,0 +1,47 @@
// ==========================================
// LOCALIZED TEXT & COMMON TYPES
// ==========================================
export interface LocalizedText {
de: string
en: string
}
export interface Address {
street: string
city: string
postalCode: string
country: string // ISO 3166-1 alpha-2
state?: string
}
export interface Contact {
name: string
email: string
phone?: string
department?: string
role?: string
}
export interface ResponsibleParty {
organizationName: string
legalForm?: string
address: Address
contact: Contact
}
// ==========================================
// ORGANISATION / TENANT
// ==========================================
export interface Organization {
id: string
name: string
legalForm: string // GmbH, AG, e.V., etc.
address: Address
country: string // ISO 3166-1 alpha-2
vatId?: string
dpoContact: Contact // Datenschutzbeauftragter
createdAt: Date
updatedAt: Date
}

View File

@@ -0,0 +1,140 @@
// ==========================================
// CONSTANTS - METADATA
// ==========================================
import type { LocalizedText } from './common'
import type {
DataSubjectCategory,
PersonalDataCategory,
LegalBasisType,
VendorRole,
ServiceCategory,
DocumentType,
TransferMechanismType,
} from './enums'
export const DATA_SUBJECT_CATEGORY_META: Record<DataSubjectCategory, LocalizedText> = {
EMPLOYEES: { de: 'Beschäftigte', en: 'Employees' },
APPLICANTS: { de: 'Bewerber', en: 'Applicants' },
CUSTOMERS: { de: 'Kunden', en: 'Customers' },
PROSPECTIVE_CUSTOMERS: { de: 'Interessenten', en: 'Prospective Customers' },
SUPPLIERS: { de: 'Lieferanten', en: 'Suppliers' },
BUSINESS_PARTNERS: { de: 'Geschäftspartner', en: 'Business Partners' },
VISITORS: { de: 'Besucher', en: 'Visitors' },
WEBSITE_USERS: { de: 'Website-Nutzer', en: 'Website Users' },
APP_USERS: { de: 'App-Nutzer', en: 'App Users' },
NEWSLETTER_SUBSCRIBERS: { de: 'Newsletter-Abonnenten', en: 'Newsletter Subscribers' },
MEMBERS: { de: 'Mitglieder', en: 'Members' },
PATIENTS: { de: 'Patienten', en: 'Patients' },
STUDENTS: { de: 'Schüler/Studenten', en: 'Students' },
MINORS: { de: 'Minderjährige', en: 'Minors' },
OTHER: { de: 'Sonstige', en: 'Other' },
}
export const PERSONAL_DATA_CATEGORY_META: Record<PersonalDataCategory, { label: LocalizedText; isSpecial: boolean }> = {
NAME: { label: { de: 'Name', en: 'Name' }, isSpecial: false },
CONTACT: { label: { de: 'Kontaktdaten', en: 'Contact Data' }, isSpecial: false },
ADDRESS: { label: { de: 'Adressdaten', en: 'Address Data' }, isSpecial: false },
DOB: { label: { de: 'Geburtsdatum', en: 'Date of Birth' }, isSpecial: false },
ID_NUMBER: { label: { de: 'Ausweisnummern', en: 'ID Numbers' }, isSpecial: false },
SOCIAL_SECURITY: { label: { de: 'Sozialversicherungsnummer', en: 'Social Security Number' }, isSpecial: false },
TAX_ID: { label: { de: 'Steuer-ID', en: 'Tax ID' }, isSpecial: false },
BANK_ACCOUNT: { label: { de: 'Bankverbindung', en: 'Bank Account' }, isSpecial: false },
PAYMENT_DATA: { label: { de: 'Zahlungsdaten', en: 'Payment Data' }, isSpecial: false },
EMPLOYMENT_DATA: { label: { de: 'Beschäftigungsdaten', en: 'Employment Data' }, isSpecial: false },
SALARY_DATA: { label: { de: 'Gehaltsdaten', en: 'Salary Data' }, isSpecial: false },
EDUCATION_DATA: { label: { de: 'Bildungsdaten', en: 'Education Data' }, isSpecial: false },
PHOTO_VIDEO: { label: { de: 'Fotos/Videos', en: 'Photos/Videos' }, isSpecial: false },
IP_ADDRESS: { label: { de: 'IP-Adressen', en: 'IP Addresses' }, isSpecial: false },
DEVICE_ID: { label: { de: 'Gerätekennungen', en: 'Device IDs' }, isSpecial: false },
LOCATION_DATA: { label: { de: 'Standortdaten', en: 'Location Data' }, isSpecial: false },
USAGE_DATA: { label: { de: 'Nutzungsdaten', en: 'Usage Data' }, isSpecial: false },
COMMUNICATION_DATA: { label: { de: 'Kommunikationsdaten', en: 'Communication Data' }, isSpecial: false },
CONTRACT_DATA: { label: { de: 'Vertragsdaten', en: 'Contract Data' }, isSpecial: false },
LOGIN_DATA: { label: { de: 'Login-Daten', en: 'Login Data' }, isSpecial: false },
HEALTH_DATA: { label: { de: 'Gesundheitsdaten', en: 'Health Data' }, isSpecial: true },
GENETIC_DATA: { label: { de: 'Genetische Daten', en: 'Genetic Data' }, isSpecial: true },
BIOMETRIC_DATA: { label: { de: 'Biometrische Daten', en: 'Biometric Data' }, isSpecial: true },
RACIAL_ETHNIC: { label: { de: 'Rassische/Ethnische Herkunft', en: 'Racial/Ethnic Origin' }, isSpecial: true },
POLITICAL_OPINIONS: { label: { de: 'Politische Meinungen', en: 'Political Opinions' }, isSpecial: true },
RELIGIOUS_BELIEFS: { label: { de: 'Religiöse Überzeugungen', en: 'Religious Beliefs' }, isSpecial: true },
TRADE_UNION: { label: { de: 'Gewerkschaftszugehörigkeit', en: 'Trade Union Membership' }, isSpecial: true },
SEX_LIFE: { label: { de: 'Sexualleben/Orientierung', en: 'Sex Life/Orientation' }, isSpecial: true },
CRIMINAL_DATA: { label: { de: 'Strafrechtliche Daten', en: 'Criminal Data' }, isSpecial: true },
OTHER: { label: { de: 'Sonstige', en: 'Other' }, isSpecial: false },
}
export const LEGAL_BASIS_META: Record<LegalBasisType, { label: LocalizedText; article: string }> = {
CONSENT: { label: { de: 'Einwilligung', en: 'Consent' }, article: 'Art. 6 Abs. 1 lit. a DSGVO' },
CONTRACT: { label: { de: 'Vertragserfüllung', en: 'Contract Performance' }, article: 'Art. 6 Abs. 1 lit. b DSGVO' },
LEGAL_OBLIGATION: { label: { de: 'Rechtliche Verpflichtung', en: 'Legal Obligation' }, article: 'Art. 6 Abs. 1 lit. c DSGVO' },
VITAL_INTEREST: { label: { de: 'Lebenswichtige Interessen', en: 'Vital Interests' }, article: 'Art. 6 Abs. 1 lit. d DSGVO' },
PUBLIC_TASK: { label: { de: 'Öffentliche Aufgabe', en: 'Public Task' }, article: 'Art. 6 Abs. 1 lit. e DSGVO' },
LEGITIMATE_INTEREST: { label: { de: 'Berechtigtes Interesse', en: 'Legitimate Interest' }, article: 'Art. 6 Abs. 1 lit. f DSGVO' },
ART9_CONSENT: { label: { de: 'Ausdrückliche Einwilligung', en: 'Explicit Consent' }, article: 'Art. 9 Abs. 2 lit. a DSGVO' },
ART9_EMPLOYMENT: { label: { de: 'Arbeitsrecht', en: 'Employment Law' }, article: 'Art. 9 Abs. 2 lit. b DSGVO' },
ART9_VITAL_INTEREST: { label: { de: 'Lebenswichtige Interessen', en: 'Vital Interests' }, article: 'Art. 9 Abs. 2 lit. c DSGVO' },
ART9_FOUNDATION: { label: { de: 'Stiftung/Verein', en: 'Foundation/Association' }, article: 'Art. 9 Abs. 2 lit. d DSGVO' },
ART9_PUBLIC: { label: { de: 'Offenkundig öffentlich', en: 'Manifestly Public' }, article: 'Art. 9 Abs. 2 lit. e DSGVO' },
ART9_LEGAL_CLAIMS: { label: { de: 'Rechtsansprüche', en: 'Legal Claims' }, article: 'Art. 9 Abs. 2 lit. f DSGVO' },
ART9_PUBLIC_INTEREST: { label: { de: 'Öffentliches Interesse', en: 'Public Interest' }, article: 'Art. 9 Abs. 2 lit. g DSGVO' },
ART9_HEALTH: { label: { de: 'Gesundheitsversorgung', en: 'Health Care' }, article: 'Art. 9 Abs. 2 lit. h DSGVO' },
ART9_PUBLIC_HEALTH: { label: { de: 'Öffentliche Gesundheit', en: 'Public Health' }, article: 'Art. 9 Abs. 2 lit. i DSGVO' },
ART9_ARCHIVING: { label: { de: 'Archivzwecke', en: 'Archiving Purposes' }, article: 'Art. 9 Abs. 2 lit. j DSGVO' },
}
export const VENDOR_ROLE_META: Record<VendorRole, LocalizedText> = {
PROCESSOR: { de: 'Auftragsverarbeiter', en: 'Processor' },
JOINT_CONTROLLER: { de: 'Gemeinsam Verantwortlicher', en: 'Joint Controller' },
CONTROLLER: { de: 'Eigenständiger Verantwortlicher', en: 'Independent Controller' },
SUB_PROCESSOR: { de: 'Unterauftragnehmer', en: 'Sub-Processor' },
THIRD_PARTY: { de: 'Dritter', en: 'Third Party' },
}
export const SERVICE_CATEGORY_META: Record<ServiceCategory, LocalizedText> = {
HOSTING: { de: 'Hosting', en: 'Hosting' },
CLOUD_INFRASTRUCTURE: { de: 'Cloud-Infrastruktur', en: 'Cloud Infrastructure' },
ANALYTICS: { de: 'Analytics', en: 'Analytics' },
CRM: { de: 'CRM', en: 'CRM' },
ERP: { de: 'ERP', en: 'ERP' },
HR_SOFTWARE: { de: 'HR-Software', en: 'HR Software' },
PAYMENT: { de: 'Zahlungsabwicklung', en: 'Payment Processing' },
EMAIL: { de: 'E-Mail', en: 'Email' },
MARKETING: { de: 'Marketing', en: 'Marketing' },
SUPPORT: { de: 'Support', en: 'Support' },
SECURITY: { de: 'Sicherheit', en: 'Security' },
INTEGRATION: { de: 'Integration', en: 'Integration' },
CONSULTING: { de: 'Beratung', en: 'Consulting' },
LEGAL: { de: 'Rechtliches', en: 'Legal' },
ACCOUNTING: { de: 'Buchhaltung', en: 'Accounting' },
COMMUNICATION: { de: 'Kommunikation', en: 'Communication' },
STORAGE: { de: 'Speicher', en: 'Storage' },
BACKUP: { de: 'Backup', en: 'Backup' },
CDN: { de: 'CDN', en: 'CDN' },
OTHER: { de: 'Sonstige', en: 'Other' },
}
export const DOCUMENT_TYPE_META: Record<DocumentType, LocalizedText> = {
AVV: { de: 'Auftragsverarbeitungsvertrag', en: 'Data Processing Agreement' },
MSA: { de: 'Rahmenvertrag', en: 'Master Service Agreement' },
SLA: { de: 'Service Level Agreement', en: 'Service Level Agreement' },
SCC: { de: 'Standardvertragsklauseln', en: 'Standard Contractual Clauses' },
NDA: { de: 'Geheimhaltungsvereinbarung', en: 'Non-Disclosure Agreement' },
TOM_ANNEX: { de: 'TOM-Anlage', en: 'TOM Annex' },
CERTIFICATION: { de: 'Zertifikat', en: 'Certification' },
SUB_PROCESSOR_LIST: { de: 'Unterauftragnehmer-Liste', en: 'Sub-Processor List' },
OTHER: { de: 'Sonstige', en: 'Other' },
}
export const TRANSFER_MECHANISM_META: Record<TransferMechanismType, LocalizedText> = {
ADEQUACY_DECISION: { de: 'Angemessenheitsbeschluss', en: 'Adequacy Decision' },
SCC_CONTROLLER: { de: 'SCC (Controller-to-Controller)', en: 'SCC (Controller-to-Controller)' },
SCC_PROCESSOR: { de: 'SCC (Controller-to-Processor)', en: 'SCC (Controller-to-Processor)' },
BCR: { de: 'Binding Corporate Rules', en: 'Binding Corporate Rules' },
DEROGATION_CONSENT: { de: 'Ausdrückliche Einwilligung', en: 'Explicit Consent' },
DEROGATION_CONTRACT: { de: 'Vertragserfüllung', en: 'Contract Performance' },
DEROGATION_LEGAL: { de: 'Rechtsansprüche', en: 'Legal Claims' },
DEROGATION_PUBLIC: { de: 'Öffentliches Interesse', en: 'Public Interest' },
CERTIFICATION: { de: 'Zertifizierung', en: 'Certification' },
CODE_OF_CONDUCT: { de: 'Verhaltensregeln', en: 'Code of Conduct' },
}

View File

@@ -0,0 +1,68 @@
// ==========================================
// INTERFACES - CONTRACT
// ==========================================
import type { Address } from './common'
import type { DocumentType, ContractReviewStatus, ContractStatus } from './enums'
export interface ContractParty {
role: 'CONTROLLER' | 'PROCESSOR' | 'PARTY'
name: string
address?: Address
signatoryName?: string
signatoryRole?: string
}
export interface ContractDocument {
id: string
tenantId: string
vendorId: string
// Dokument
fileName: string
originalName: string
mimeType: string
fileSize: number
storagePath: string // MinIO path
// Klassifikation
documentType: DocumentType
// Versioning
version: string
previousVersionId?: string
// Metadaten (extrahiert)
parties?: ContractParty[]
effectiveDate?: Date
expirationDate?: Date
autoRenewal?: boolean
renewalNoticePeriod?: number // Tage
terminationNoticePeriod?: number // Tage
// Review Status
reviewStatus: ContractReviewStatus
reviewCompletedAt?: Date
complianceScore?: number // 0-100
// Workflow
status: ContractStatus
signedAt?: Date
// Extracted text for search
extractedText?: string
pageCount?: number
createdAt: Date
updatedAt: Date
}
export interface DocumentVersion {
id: string
documentId: string
version: string
storagePath: string
extractedText?: string
pageCount: number
createdAt: Date
}

View File

@@ -0,0 +1,262 @@
// ==========================================
// ENUMS - VVT / PROCESSING ACTIVITIES
// ==========================================
export type ProcessingActivityStatus = 'DRAFT' | 'REVIEW' | 'APPROVED' | 'ARCHIVED'
export type ProtectionLevel = 'LOW' | 'MEDIUM' | 'HIGH'
export type DataSubjectCategory =
| 'EMPLOYEES' // Beschaeftigte
| 'APPLICANTS' // Bewerber
| 'CUSTOMERS' // Kunden
| 'PROSPECTIVE_CUSTOMERS' // Interessenten
| 'SUPPLIERS' // Lieferanten
| 'BUSINESS_PARTNERS' // Geschaeftspartner
| 'VISITORS' // Besucher
| 'WEBSITE_USERS' // Website-Nutzer
| 'APP_USERS' // App-Nutzer
| 'NEWSLETTER_SUBSCRIBERS' // Newsletter-Abonnenten
| 'MEMBERS' // Mitglieder
| 'PATIENTS' // Patienten
| 'STUDENTS' // Schueler/Studenten
| 'MINORS' // Minderjaehrige
| 'OTHER'
export type PersonalDataCategory =
| 'NAME' // Name
| 'CONTACT' // Kontaktdaten
| 'ADDRESS' // Adressdaten
| 'DOB' // Geburtsdatum
| 'ID_NUMBER' // Ausweisnummern
| 'SOCIAL_SECURITY' // Sozialversicherungsnummer
| 'TAX_ID' // Steuer-ID
| 'BANK_ACCOUNT' // Bankverbindung
| 'PAYMENT_DATA' // Zahlungsdaten
| 'EMPLOYMENT_DATA' // Beschaeftigungsdaten
| 'SALARY_DATA' // Gehaltsdaten
| 'EDUCATION_DATA' // Bildungsdaten
| 'PHOTO_VIDEO' // Fotos/Videos
| 'IP_ADDRESS' // IP-Adressen
| 'DEVICE_ID' // Geraete-Kennungen
| 'LOCATION_DATA' // Standortdaten
| 'USAGE_DATA' // Nutzungsdaten
| 'COMMUNICATION_DATA' // Kommunikationsdaten
| 'CONTRACT_DATA' // Vertragsdaten
| 'LOGIN_DATA' // Login-Daten
// Besondere Kategorien Art. 9 DSGVO
| 'HEALTH_DATA' // Gesundheitsdaten
| 'GENETIC_DATA' // Genetische Daten
| 'BIOMETRIC_DATA' // Biometrische Daten
| 'RACIAL_ETHNIC' // Rassische/Ethnische Herkunft
| 'POLITICAL_OPINIONS' // Politische Meinungen
| 'RELIGIOUS_BELIEFS' // Religiose Ueberzeugungen
| 'TRADE_UNION' // Gewerkschaftszugehoerigkeit
| 'SEX_LIFE' // Sexualleben/Orientierung
// Art. 10 DSGVO
| 'CRIMINAL_DATA' // Strafrechtliche Daten
| 'OTHER'
export type RecipientCategoryType =
| 'INTERNAL' // Interne Stellen
| 'GROUP_COMPANY' // Konzernunternehmen
| 'PROCESSOR' // Auftragsverarbeiter
| 'CONTROLLER' // Verantwortlicher
| 'AUTHORITY' // Behoerden
| 'OTHER'
export type LegalBasisType =
// Art. 6 Abs. 1 DSGVO
| 'CONSENT' // lit. a - Einwilligung
| 'CONTRACT' // lit. b - Vertragsdurchfuehrung
| 'LEGAL_OBLIGATION' // lit. c - Rechtliche Verpflichtung
| 'VITAL_INTEREST' // lit. d - Lebenswichtige Interessen
| 'PUBLIC_TASK' // lit. e - Oeffentliche Aufgabe
| 'LEGITIMATE_INTEREST' // lit. f - Berechtigtes Interesse
// Art. 9 Abs. 2 DSGVO (besondere Kategorien)
| 'ART9_CONSENT' // lit. a - Ausdrueckliche Einwilligung
| 'ART9_EMPLOYMENT' // lit. b - Arbeitsrecht
| 'ART9_VITAL_INTEREST' // lit. c - Lebenswichtige Interessen
| 'ART9_FOUNDATION' // lit. d - Stiftung/Verein
| 'ART9_PUBLIC' // lit. e - Offenkundig oeffentlich
| 'ART9_LEGAL_CLAIMS' // lit. f - Rechtsansprueche
| 'ART9_PUBLIC_INTEREST'// lit. g - Oeffentliches Interesse
| 'ART9_HEALTH' // lit. h - Gesundheitsversorgung
| 'ART9_PUBLIC_HEALTH' // lit. i - Oeffentliche Gesundheit
| 'ART9_ARCHIVING' // lit. j - Archivzwecke
export type TransferMechanismType =
| 'ADEQUACY_DECISION' // Angemessenheitsbeschluss
| 'SCC_CONTROLLER' // SCC Controller-to-Controller
| 'SCC_PROCESSOR' // SCC Controller-to-Processor
| 'BCR' // Binding Corporate Rules
| 'DEROGATION_CONSENT' // Ausdrueckliche Einwilligung
| 'DEROGATION_CONTRACT' // Vertragserfuellung
| 'DEROGATION_LEGAL' // Rechtsansprueche
| 'DEROGATION_PUBLIC' // Oeffentliches Interesse
| 'CERTIFICATION' // Zertifizierung
| 'CODE_OF_CONDUCT' // Verhaltensregeln
export type DataSourceType =
| 'DATA_SUBJECT' // Betroffene Person selbst
| 'THIRD_PARTY' // Dritte
| 'PUBLIC_SOURCE' // Oeffentliche Quellen
| 'AUTOMATED' // Automatisiert generiert
| 'EMPLOYEE' // Mitarbeiter
| 'OTHER'
// ==========================================
// ENUMS - VENDOR
// ==========================================
export type VendorRole =
| 'PROCESSOR' // Auftragsverarbeiter
| 'JOINT_CONTROLLER' // Gemeinsam Verantwortlicher
| 'CONTROLLER' // Eigenstaendiger Verantwortlicher
| 'SUB_PROCESSOR' // Unterauftragnehmer
| 'THIRD_PARTY' // Dritter (kein Datenzugriff)
export type ServiceCategory =
| 'HOSTING'
| 'CLOUD_INFRASTRUCTURE'
| 'ANALYTICS'
| 'CRM'
| 'ERP'
| 'HR_SOFTWARE'
| 'PAYMENT'
| 'EMAIL'
| 'MARKETING'
| 'SUPPORT'
| 'SECURITY'
| 'INTEGRATION'
| 'CONSULTING'
| 'LEGAL'
| 'ACCOUNTING'
| 'COMMUNICATION'
| 'STORAGE'
| 'BACKUP'
| 'CDN'
| 'OTHER'
export type DataAccessLevel =
| 'NONE' // Kein Datenzugriff
| 'POTENTIAL' // Potenzieller Zugriff (z.B. Admin)
| 'ADMINISTRATIVE' // Administrativer Zugriff
| 'CONTENT' // Inhaltlicher Zugriff
export type VendorStatus =
| 'ACTIVE'
| 'INACTIVE'
| 'PENDING_REVIEW'
| 'TERMINATED'
export type ReviewFrequency =
| 'QUARTERLY'
| 'SEMI_ANNUAL'
| 'ANNUAL'
| 'BIENNIAL'
// ==========================================
// ENUMS - CONTRACT
// ==========================================
export type DocumentType =
| 'AVV' // Auftragsverarbeitungsvertrag
| 'MSA' // Master Service Agreement
| 'SLA' // Service Level Agreement
| 'SCC' // Standard Contractual Clauses
| 'NDA' // Non-Disclosure Agreement
| 'TOM_ANNEX' // TOM-Anlage
| 'CERTIFICATION' // Zertifikat
| 'SUB_PROCESSOR_LIST' // Unterauftragsverarbeiter-Liste
| 'OTHER'
export type ContractReviewStatus =
| 'PENDING'
| 'IN_PROGRESS'
| 'COMPLETED'
| 'FAILED'
export type ContractStatus =
| 'DRAFT'
| 'SIGNED'
| 'ACTIVE'
| 'EXPIRED'
| 'TERMINATED'
// ==========================================
// ENUMS - FINDINGS
// ==========================================
export type FindingType =
| 'OK' // Anforderung erfuellt
| 'GAP' // Luecke/fehlend
| 'RISK' // Risiko identifiziert
| 'UNKNOWN' // Nicht eindeutig
export type FindingCategory =
| 'AVV_CONTENT' // Art. 28 Abs. 3 Mindestinhalte
| 'SUBPROCESSOR' // Unterauftragnehmer-Regelung
| 'INCIDENT' // Incident-Meldepflichten
| 'AUDIT_RIGHTS' // Audit-/Inspektionsrechte
| 'DELETION' // Loeschung/Rueckgabe
| 'TOM' // Technische/Org. Massnahmen
| 'TRANSFER' // Drittlandtransfer
| 'LIABILITY' // Haftung/Indemnity
| 'SLA' // Verfuegbarkeit
| 'DATA_SUBJECT_RIGHTS' // Betroffenenrechte
| 'CONFIDENTIALITY' // Vertraulichkeit
| 'INSTRUCTION' // Weisungsgebundenheit
| 'TERMINATION' // Vertragsbeendigung
| 'GENERAL' // Allgemein
export type FindingSeverity = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
export type FindingStatus =
| 'OPEN'
| 'IN_PROGRESS'
| 'RESOLVED'
| 'ACCEPTED'
| 'FALSE_POSITIVE'
// ==========================================
// ENUMS - RISK & CONTROLS
// ==========================================
export type ControlDomain =
| 'TRANSFER' // Drittlandtransfer
| 'AUDIT' // Auditrechte
| 'DELETION' // Loeschung
| 'INCIDENT' // Incident Response
| 'SUBPROCESSOR' // Unterauftragnehmer
| 'TOM' // Tech/Org Massnahmen
| 'CONTRACT' // Vertragliche Grundlagen
| 'DATA_SUBJECT' // Betroffenenrechte
| 'SECURITY' // Sicherheit
| 'GOVERNANCE' // Governance
export type ControlStatus =
| 'PASS'
| 'PARTIAL'
| 'FAIL'
| 'NOT_APPLICABLE'
| 'PLANNED'
export type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
export type EntityType = 'VENDOR' | 'PROCESSING_ACTIVITY' | 'CONTRACT'
export type EvidenceType = 'DOCUMENT' | 'SCREENSHOT' | 'LINK' | 'ATTESTATION'
// ==========================================
// ENUMS - EXPORT
// ==========================================
export type ReportType =
| 'VVT_EXPORT'
| 'VENDOR_AUDIT'
| 'ROPA'
| 'MANAGEMENT_SUMMARY'
| 'DPIA_INPUT'
export type ExportFormat = 'PDF' | 'DOCX' | 'XLSX' | 'JSON'

View File

@@ -0,0 +1,50 @@
// ==========================================
// INTERFACES - FINDINGS
// ==========================================
import type { LocalizedText } from './common'
import type { FindingType, FindingCategory, FindingSeverity, FindingStatus } from './enums'
export interface Citation {
documentId: string
versionId?: string
page: number
startChar: number
endChar: number
quotedText: string
quoteHash: string // SHA-256 zur Verifizierung
}
export interface Finding {
id: string
tenantId: string
contractId: string
vendorId: string
// Klassifikation
type: FindingType
category: FindingCategory
severity: FindingSeverity
// Inhalt
title: LocalizedText
description: LocalizedText
recommendation?: LocalizedText
// Citations (Textstellen-Belege)
citations: Citation[]
// Verknuepfung
affectedRequirement?: string // z.B. "Art. 28 Abs. 3 lit. a DSGVO"
triggeredControls: string[] // Control-IDs
// Workflow
status: FindingStatus
assignee?: string
dueDate?: Date
resolution?: string
resolvedAt?: Date
createdAt: Date
updatedAt: Date
}

View File

@@ -0,0 +1,79 @@
// ==========================================
// FORM TYPES
// ==========================================
import type { LocalizedText, ResponsibleParty, Contact, Address } from './common'
import type {
DataSubjectCategory,
PersonalDataCategory,
ProtectionLevel,
VendorRole,
ServiceCategory,
DataAccessLevel,
TransferMechanismType,
DocumentType,
ReviewFrequency,
} from './enums'
import type {
LegalBasis,
RecipientCategory,
ThirdCountryTransfer,
RetentionPeriod,
DataSource,
SystemReference,
DataFlow,
} from './vvt-interfaces'
import type { ProcessingLocation, Certification } from './vendor-interfaces'
export interface ProcessingActivityFormData {
vvtId: string
name: LocalizedText
responsible: ResponsibleParty
dpoContact?: Contact
purposes: LocalizedText[]
dataSubjectCategories: DataSubjectCategory[]
personalDataCategories: PersonalDataCategory[]
recipientCategories: RecipientCategory[]
thirdCountryTransfers: ThirdCountryTransfer[]
retentionPeriod: RetentionPeriod
technicalMeasures: string[]
legalBasis: LegalBasis[]
dataSources: DataSource[]
systems: SystemReference[]
dataFlows: DataFlow[]
protectionLevel: ProtectionLevel
dpiaRequired: boolean
dpiaJustification?: string
subProcessors: string[]
owner: string
}
export interface VendorFormData {
name: string
legalForm?: string
country: string
address: Address
website?: string
role: VendorRole
serviceDescription: string
serviceCategory: ServiceCategory
dataAccessLevel: DataAccessLevel
processingLocations: ProcessingLocation[]
transferMechanisms: TransferMechanismType[]
certifications: Certification[]
primaryContact: Contact
dpoContact?: Contact
securityContact?: Contact
contractTypes: DocumentType[]
reviewFrequency: ReviewFrequency
notes?: string
}
export interface ContractUploadData {
vendorId: string
documentType: DocumentType
version: string
effectiveDate?: Date
expirationDate?: Date
autoRenewal?: boolean
}

View File

@@ -0,0 +1,126 @@
// ==========================================
// HELPER FUNCTIONS
// ==========================================
import type {
RiskLevel,
PersonalDataCategory,
FindingSeverity,
VendorStatus,
ProcessingActivityStatus,
ContractStatus,
} from './enums'
/**
* Calculate risk level from score
*/
export function getRiskLevelFromScore(score: number): RiskLevel {
if (score <= 4) return 'LOW'
if (score <= 9) return 'MEDIUM'
if (score <= 16) return 'HIGH'
return 'CRITICAL'
}
/**
* Calculate risk score from likelihood and impact
*/
export function calculateRiskScore(likelihood: number, impact: number): number {
return likelihood * impact
}
/**
* Check if data category is special (Art. 9 DSGVO)
*/
export function isSpecialCategory(category: PersonalDataCategory): boolean {
const specialCategories: PersonalDataCategory[] = [
'HEALTH_DATA',
'GENETIC_DATA',
'BIOMETRIC_DATA',
'RACIAL_ETHNIC',
'POLITICAL_OPINIONS',
'RELIGIOUS_BELIEFS',
'TRADE_UNION',
'SEX_LIFE',
'CRIMINAL_DATA',
]
return specialCategories.includes(category)
}
/**
* Check if country has adequacy decision
*/
export function hasAdequacyDecision(countryCode: string): boolean {
const adequateCountries = [
'AD', 'AR', 'CA', 'FO', 'GG', 'IL', 'IM', 'JP', 'JE', 'NZ', 'KR', 'CH', 'GB', 'UY',
// EU/EEA countries
'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU',
'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE',
'IS', 'LI', 'NO',
]
return adequateCountries.includes(countryCode.toUpperCase())
}
/**
* Generate VVT ID
*/
export function generateVVTId(existingIds: string[]): string {
const year = new Date().getFullYear()
const prefix = `VVT-${year}-`
const existingNumbers = existingIds
.filter(id => id.startsWith(prefix))
.map(id => parseInt(id.replace(prefix, ''), 10))
.filter(n => !isNaN(n))
const nextNumber = existingNumbers.length > 0 ? Math.max(...existingNumbers) + 1 : 1
return `${prefix}${nextNumber.toString().padStart(3, '0')}`
}
/**
* Format date for display
*/
export function formatDate(date: Date | string | undefined): string {
if (!date) return '-'
const d = typeof date === 'string' ? new Date(date) : date
return d.toLocaleDateString('de-DE', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
})
}
/**
* Get severity color class
*/
export function getSeverityColor(severity: FindingSeverity): string {
switch (severity) {
case 'LOW': return 'text-blue-600 bg-blue-100'
case 'MEDIUM': return 'text-yellow-600 bg-yellow-100'
case 'HIGH': return 'text-orange-600 bg-orange-100'
case 'CRITICAL': return 'text-red-600 bg-red-100'
}
}
/**
* Get status color class
*/
export function getStatusColor(status: VendorStatus | ProcessingActivityStatus | ContractStatus): string {
switch (status) {
case 'ACTIVE':
case 'APPROVED':
case 'SIGNED':
return 'text-green-600 bg-green-100'
case 'DRAFT':
case 'PENDING_REVIEW':
return 'text-yellow-600 bg-yellow-100'
case 'REVIEW':
case 'INACTIVE':
return 'text-blue-600 bg-blue-100'
case 'ARCHIVED':
case 'EXPIRED':
case 'TERMINATED':
return 'text-gray-600 bg-gray-100'
default:
return 'text-gray-600 bg-gray-100'
}
}

View File

@@ -0,0 +1,19 @@
/**
* Vendor & Contract Compliance Module (VVT/RoPA)
*
* Barrel re-export of all domain modules.
*/
export * from './common'
export * from './enums'
export * from './vvt-interfaces'
export * from './vendor-interfaces'
export * from './contract-interfaces'
export * from './finding-interfaces'
export * from './risk-control-interfaces'
export * from './audit-reports'
export * from './state-management'
export * from './statistics-api'
export * from './forms'
export * from './helpers'
export * from './constants'

View File

@@ -0,0 +1,116 @@
// ==========================================
// INTERFACES - RISK & CONTROLS
// ==========================================
import type { LocalizedText } from './common'
import type {
RiskLevel,
EntityType,
EvidenceType,
ControlDomain,
ControlStatus,
ReviewFrequency,
} from './enums'
export interface RiskFactor {
id: string
name: LocalizedText
category: string
weight: number
value: number // 1-5
rationale?: string
}
export interface RiskScore {
likelihood: 1 | 2 | 3 | 4 | 5
impact: 1 | 2 | 3 | 4 | 5
score: number // likelihood * impact (1-25)
level: RiskLevel
rationale: string
}
export interface RiskAssessment {
id: string
tenantId: string
entityType: EntityType
entityId: string
// Bewertung
inherentRisk: RiskScore
residualRisk: RiskScore
// Faktoren
riskFactors: RiskFactor[]
mitigatingControls: string[] // Control-IDs
// Workflow
assessedBy: string
assessedAt: Date
approvedBy?: string
approvedAt?: Date
nextAssessmentDate: Date
}
export interface Control {
id: string // z.B. VND-TRF-01
domain: ControlDomain
title: LocalizedText
description: LocalizedText
passCriteria: LocalizedText
// Mapping
requirements: string[] // Art. 28 Abs. 3 lit. a, ISO 27001 A.15.1.2
// Standard
isRequired: boolean
defaultFrequency: ReviewFrequency
}
export interface ControlInstance {
id: string
tenantId: string
controlId: string
entityType: EntityType
entityId: string
// Status
status: ControlStatus
// Evidenz
evidenceIds: string[]
// Workflow
lastAssessedAt: Date
lastAssessedBy: string
nextAssessmentDate: Date
notes?: string
}
export interface Evidence {
id: string
tenantId: string
controlInstanceId: string
type: EvidenceType
title: string
description?: string
// Fuer Dokumente
storagePath?: string
fileName?: string
// Fuer Links
url?: string
// Fuer Attestation
attestedBy?: string
attestedAt?: Date
validFrom: Date
validUntil?: Date
createdAt: Date
}

View File

@@ -0,0 +1,73 @@
// ==========================================
// STATE MANAGEMENT - ACTIONS & STATE
// ==========================================
import type { ExportFormat } from './enums'
import type { ProcessingActivity } from './vvt-interfaces'
import type { Vendor } from './vendor-interfaces'
import type { ContractDocument } from './contract-interfaces'
import type { Finding } from './finding-interfaces'
import type { Control, ControlInstance, RiskAssessment } from './risk-control-interfaces'
// ==========================================
// ACTIONS
// ==========================================
export type VendorComplianceAction =
// Processing Activities
| { type: 'SET_PROCESSING_ACTIVITIES'; payload: ProcessingActivity[] }
| { type: 'ADD_PROCESSING_ACTIVITY'; payload: ProcessingActivity }
| { type: 'UPDATE_PROCESSING_ACTIVITY'; payload: { id: string; data: Partial<ProcessingActivity> } }
| { type: 'DELETE_PROCESSING_ACTIVITY'; payload: string }
// Vendors
| { type: 'SET_VENDORS'; payload: Vendor[] }
| { type: 'ADD_VENDOR'; payload: Vendor }
| { type: 'UPDATE_VENDOR'; payload: { id: string; data: Partial<Vendor> } }
| { type: 'DELETE_VENDOR'; payload: string }
// Contracts
| { type: 'SET_CONTRACTS'; payload: ContractDocument[] }
| { type: 'ADD_CONTRACT'; payload: ContractDocument }
| { type: 'UPDATE_CONTRACT'; payload: { id: string; data: Partial<ContractDocument> } }
| { type: 'DELETE_CONTRACT'; payload: string }
// Findings
| { type: 'SET_FINDINGS'; payload: Finding[] }
| { type: 'ADD_FINDINGS'; payload: Finding[] }
| { type: 'UPDATE_FINDING'; payload: { id: string; data: Partial<Finding> } }
// Controls
| { type: 'SET_CONTROLS'; payload: Control[] }
| { type: 'SET_CONTROL_INSTANCES'; payload: ControlInstance[] }
| { type: 'UPDATE_CONTROL_INSTANCE'; payload: { id: string; data: Partial<ControlInstance> } }
// Risk Assessments
| { type: 'SET_RISK_ASSESSMENTS'; payload: RiskAssessment[] }
| { type: 'UPDATE_RISK_ASSESSMENT'; payload: { id: string; data: Partial<RiskAssessment> } }
// UI State
| { type: 'SET_LOADING'; payload: boolean }
| { type: 'SET_ERROR'; payload: string | null }
| { type: 'SET_SELECTED_VENDOR'; payload: string | null }
| { type: 'SET_SELECTED_ACTIVITY'; payload: string | null }
| { type: 'SET_ACTIVE_TAB'; payload: string }
// ==========================================
// STATE
// ==========================================
export interface VendorComplianceState {
// Data
processingActivities: ProcessingActivity[]
vendors: Vendor[]
contracts: ContractDocument[]
findings: Finding[]
controls: Control[]
controlInstances: ControlInstance[]
riskAssessments: RiskAssessment[]
// UI State
isLoading: boolean
error: string | null
selectedVendorId: string | null
selectedActivityId: string | null
activeTab: string
// Metadata
lastModified: Date | null
}

View File

@@ -0,0 +1,104 @@
// ==========================================
// CONTEXT VALUE
// ==========================================
import type { ExportFormat, VendorStatus, VendorRole, RiskLevel, FindingType, FindingSeverity } from './enums'
import type { ProcessingActivity } from './vvt-interfaces'
import type { Vendor } from './vendor-interfaces'
import type { ContractDocument } from './contract-interfaces'
import type { Finding } from './finding-interfaces'
import type { ControlInstance } from './risk-control-interfaces'
import type { VendorComplianceAction, VendorComplianceState } from './state-management'
export interface VendorComplianceContextValue extends VendorComplianceState {
// Dispatch
dispatch: React.Dispatch<VendorComplianceAction>
// Computed
vendorStats: VendorStatistics
complianceStats: ComplianceStatistics
riskOverview: RiskOverview
// Actions - Processing Activities
createProcessingActivity: (data: Omit<ProcessingActivity, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>) => Promise<ProcessingActivity>
updateProcessingActivity: (id: string, data: Partial<ProcessingActivity>) => Promise<void>
deleteProcessingActivity: (id: string) => Promise<void>
duplicateProcessingActivity: (id: string) => Promise<ProcessingActivity>
// Actions - Vendors
createVendor: (data: Omit<Vendor, 'id' | 'tenantId' | 'createdAt' | 'updatedAt'>) => Promise<Vendor>
updateVendor: (id: string, data: Partial<Vendor>) => Promise<void>
deleteVendor: (id: string) => Promise<void>
// Actions - Contracts
uploadContract: (vendorId: string, file: File, metadata: Partial<ContractDocument>) => Promise<ContractDocument>
updateContract: (id: string, data: Partial<ContractDocument>) => Promise<void>
deleteContract: (id: string) => Promise<void>
startContractReview: (contractId: string) => Promise<void>
// Actions - Findings
updateFinding: (id: string, data: Partial<Finding>) => Promise<void>
resolveFinding: (id: string, resolution: string) => Promise<void>
// Actions - Controls
updateControlInstance: (id: string, data: Partial<ControlInstance>) => Promise<void>
// Actions - Export
exportVVT: (format: ExportFormat, activityIds?: string[]) => Promise<string>
exportVendorAuditPack: (vendorId: string, format: ExportFormat) => Promise<string>
exportRoPA: (format: ExportFormat) => Promise<string>
// Data Loading
loadData: () => Promise<void>
refresh: () => Promise<void>
}
// ==========================================
// STATISTICS INTERFACES
// ==========================================
export interface VendorStatistics {
total: number
byStatus: Record<VendorStatus, number>
byRole: Record<VendorRole, number>
byRiskLevel: Record<RiskLevel, number>
pendingReviews: number
withExpiredContracts: number
}
export interface ComplianceStatistics {
averageComplianceScore: number
findingsByType: Record<FindingType, number>
findingsBySeverity: Record<FindingSeverity, number>
openFindings: number
resolvedFindings: number
controlPassRate: number
}
export interface RiskOverview {
averageInherentRisk: number
averageResidualRisk: number
highRiskVendors: number
criticalFindings: number
transfersToThirdCountries: number
}
// ==========================================
// API RESPONSE TYPES
// ==========================================
export interface ApiResponse<T> {
success: boolean
data?: T
error?: string
timestamp: string
}
export interface PaginatedResponse<T> extends ApiResponse<T[]> {
pagination: {
page: number
pageSize: number
total: number
totalPages: number
}
}

View File

@@ -0,0 +1,93 @@
// ==========================================
// INTERFACES - VENDOR
// ==========================================
import type { Address, Contact } from './common'
import type {
VendorRole,
ServiceCategory,
DataAccessLevel,
TransferMechanismType,
DocumentType,
ReviewFrequency,
VendorStatus,
} from './enums'
export interface ProcessingLocation {
country: string // ISO 3166-1 alpha-2
region?: string
city?: string
dataCenter?: string
isEU: boolean
isAdequate: boolean // Angemessenheitsbeschluss
type?: string // e.g., 'primary', 'backup', 'disaster-recovery'
description?: string
isPrimary?: boolean
}
export interface Certification {
type: string // ISO 27001, SOC2, TISAX, C5, etc.
issuer?: string
issuedDate?: Date
expirationDate?: Date
scope?: string
certificateNumber?: string
documentId?: string // Referenz zum hochgeladenen Zertifikat
}
export interface Vendor {
id: string
tenantId: string
// Stammdaten
name: string
legalForm?: string
country: string
address: Address
website?: string
// Rolle
role: VendorRole
serviceDescription: string
serviceCategory: ServiceCategory
// Datenzugriff
dataAccessLevel: DataAccessLevel
processingLocations: ProcessingLocation[]
transferMechanisms: TransferMechanismType[]
// Zertifizierungen
certifications: Certification[]
// Kontakte
primaryContact: Contact
dpoContact?: Contact
securityContact?: Contact
// Vertraege
contractTypes: DocumentType[]
contracts: string[] // Contract-IDs
// Risiko
inherentRiskScore: number // 0-100 (auto-berechnet)
residualRiskScore: number // 0-100 (nach Controls)
manualRiskAdjustment?: number
riskJustification?: string
// Review
reviewFrequency: ReviewFrequency
lastReviewDate?: Date
nextReviewDate?: Date
// Workflow
status: VendorStatus
// Linked Processing Activities
processingActivityIds: string[]
// Notes
notes?: string
createdAt: Date
updatedAt: Date
}

View File

@@ -0,0 +1,104 @@
// ==========================================
// INTERFACES - VVT / PROCESSING ACTIVITIES
// ==========================================
import type { LocalizedText, ResponsibleParty, Contact } from './common'
import type {
LegalBasisType,
RecipientCategoryType,
TransferMechanismType,
DataSourceType,
PersonalDataCategory,
DataSubjectCategory,
ProtectionLevel,
ProcessingActivityStatus,
} from './enums'
export interface LegalBasis {
type: LegalBasisType
description?: string
reference?: string // z.B. "§ 26 BDSG"
}
export interface RecipientCategory {
type: RecipientCategoryType
name: string
description?: string
isThirdCountry?: boolean
country?: string
}
export interface ThirdCountryTransfer {
country: string // ISO 3166-1 alpha-2
recipient: string
transferMechanism: TransferMechanismType
sccVersion?: string
tiaCompleted?: boolean
tiaDate?: Date
additionalMeasures?: string[]
}
export interface RetentionPeriod {
duration?: number // in Monaten
durationUnit?: 'DAYS' | 'MONTHS' | 'YEARS'
description: LocalizedText
legalBasis?: string // z.B. "HGB § 257", "AO § 147"
deletionProcedure?: string
}
export interface DataSource {
type: DataSourceType
description?: string
}
export interface SystemReference {
systemId: string
name: string
description?: string
type?: string // CRM, ERP, etc.
}
export interface DataFlow {
sourceSystem?: string
targetSystem?: string
description: string
dataCategories: PersonalDataCategory[]
}
export interface ProcessingActivity {
id: string
tenantId: string
// Pflichtfelder Art. 30(1) DSGVO
vvtId: string // Eindeutige VVT-Nummer (z.B. VVT-2024-001)
name: LocalizedText
responsible: ResponsibleParty
dpoContact?: Contact
purposes: LocalizedText[]
dataSubjectCategories: DataSubjectCategory[]
personalDataCategories: PersonalDataCategory[]
recipientCategories: RecipientCategory[]
thirdCountryTransfers: ThirdCountryTransfer[]
retentionPeriod: RetentionPeriod
technicalMeasures: string[] // TOM-Referenzen
// Empfohlene Zusatzfelder
legalBasis: LegalBasis[]
dataSources: DataSource[]
systems: SystemReference[]
dataFlows: DataFlow[]
protectionLevel: ProtectionLevel
dpiaRequired: boolean
dpiaJustification?: string
subProcessors: string[] // Vendor-IDs
legalRetentionBasis?: string
// Workflow
status: ProcessingActivityStatus
owner: string
lastReviewDate?: Date
nextReviewDate?: Date
createdAt: Date
updatedAt: Date
}