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:
File diff suppressed because it is too large
Load Diff
98
admin-compliance/lib/sdk/dsfa/types/api-types.ts
Normal file
98
admin-compliance/lib/sdk/dsfa/types/api-types.ts
Normal 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
|
||||
}
|
||||
171
admin-compliance/lib/sdk/dsfa/types/authority-resources.ts
Normal file
171
admin-compliance/lib/sdk/dsfa/types/authority-resources.ts
Normal 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' },
|
||||
],
|
||||
},
|
||||
]
|
||||
84
admin-compliance/lib/sdk/dsfa/types/dsk-references.ts
Normal file
84
admin-compliance/lib/sdk/dsfa/types/dsk-references.ts
Normal 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,
|
||||
},
|
||||
]
|
||||
52
admin-compliance/lib/sdk/dsfa/types/enums-constants.ts
Normal file
52
admin-compliance/lib/sdk/dsfa/types/enums-constants.ts
Normal 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' },
|
||||
]
|
||||
162
admin-compliance/lib/sdk/dsfa/types/helper-functions.ts
Normal file
162
admin-compliance/lib/sdk/dsfa/types/helper-functions.ts
Normal 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,
|
||||
})),
|
||||
},
|
||||
]
|
||||
}
|
||||
17
admin-compliance/lib/sdk/dsfa/types/index.ts
Normal file
17
admin-compliance/lib/sdk/dsfa/types/index.ts
Normal 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'
|
||||
116
admin-compliance/lib/sdk/dsfa/types/main-dsfa.ts
Normal file
116
admin-compliance/lib/sdk/dsfa/types/main-dsfa.ts
Normal 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
|
||||
}
|
||||
35
admin-compliance/lib/sdk/dsfa/types/risk-matrix.ts
Normal file
35
admin-compliance/lib/sdk/dsfa/types/risk-matrix.ts
Normal 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 }
|
||||
}
|
||||
50
admin-compliance/lib/sdk/dsfa/types/sdm-goals.ts
Normal file
50
admin-compliance/lib/sdk/dsfa/types/sdm-goals.ts
Normal 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',
|
||||
},
|
||||
}
|
||||
136
admin-compliance/lib/sdk/dsfa/types/sub-types.ts
Normal file
136
admin-compliance/lib/sdk/dsfa/types/sub-types.ts
Normal 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
|
||||
}
|
||||
97
admin-compliance/lib/sdk/dsfa/types/ui-helpers.ts
Normal file
97
admin-compliance/lib/sdk/dsfa/types/ui-helpers.ts
Normal 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,
|
||||
},
|
||||
]
|
||||
91
admin-compliance/lib/sdk/dsfa/types/wp248-criteria.ts
Normal file
91
admin-compliance/lib/sdk/dsfa/types/wp248-criteria.ts
Normal 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',
|
||||
},
|
||||
]
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
259
admin-compliance/lib/sdk/einwilligungen/types/constants.ts
Normal file
259
admin-compliance/lib/sdk/einwilligungen/types/constants.ts
Normal 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'
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
72
admin-compliance/lib/sdk/einwilligungen/types/data-point.ts
Normal file
72
admin-compliance/lib/sdk/einwilligungen/types/data-point.ts
Normal 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[]
|
||||
}
|
||||
85
admin-compliance/lib/sdk/einwilligungen/types/enums.ts
Normal file
85
admin-compliance/lib/sdk/einwilligungen/types/enums.ts
Normal 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'
|
||||
18
admin-compliance/lib/sdk/einwilligungen/types/helpers.ts
Normal file
18
admin-compliance/lib/sdk/einwilligungen/types/helpers.ts
Normal 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
|
||||
}
|
||||
17
admin-compliance/lib/sdk/einwilligungen/types/index.ts
Normal file
17
admin-compliance/lib/sdk/einwilligungen/types/index.ts
Normal 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'
|
||||
@@ -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
|
||||
}
|
||||
@@ -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' }
|
||||
123
admin-compliance/lib/sdk/einwilligungen/types/warnings.ts
Normal file
123
admin-compliance/lib/sdk/einwilligungen/types/warnings.ts
Normal 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'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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'],
|
||||
}
|
||||
77
admin-compliance/lib/sdk/tom-generator/types/api.ts
Normal file
77
admin-compliance/lib/sdk/tom-generator/types/api.ts
Normal 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
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
]
|
||||
@@ -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[]
|
||||
}
|
||||
141
admin-compliance/lib/sdk/tom-generator/types/data-metadata.ts
Normal file
141
admin-compliance/lib/sdk/tom-generator/types/data-metadata.ts
Normal 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,
|
||||
},
|
||||
]
|
||||
23
admin-compliance/lib/sdk/tom-generator/types/derived-tom.ts
Normal file
23
admin-compliance/lib/sdk/tom-generator/types/derived-tom.ts
Normal 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[]
|
||||
}
|
||||
115
admin-compliance/lib/sdk/tom-generator/types/enums.ts
Normal file
115
admin-compliance/lib/sdk/tom-generator/types/enums.ts
Normal 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'
|
||||
39
admin-compliance/lib/sdk/tom-generator/types/evidence.ts
Normal file
39
admin-compliance/lib/sdk/tom-generator/types/evidence.ts
Normal 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
|
||||
}
|
||||
28
admin-compliance/lib/sdk/tom-generator/types/gap-analysis.ts
Normal file
28
admin-compliance/lib/sdk/tom-generator/types/gap-analysis.ts
Normal 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
|
||||
}
|
||||
131
admin-compliance/lib/sdk/tom-generator/types/helpers.ts
Normal file
131
admin-compliance/lib/sdk/tom-generator/types/helpers.ts
Normal 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
|
||||
20
admin-compliance/lib/sdk/tom-generator/types/index.ts
Normal file
20
admin-compliance/lib/sdk/tom-generator/types/index.ts
Normal 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'
|
||||
99
admin-compliance/lib/sdk/tom-generator/types/profiles.ts
Normal file
99
admin-compliance/lib/sdk/tom-generator/types/profiles.ts
Normal 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
|
||||
}
|
||||
63
admin-compliance/lib/sdk/tom-generator/types/sdm.ts
Normal file
63
admin-compliance/lib/sdk/tom-generator/types/sdm.ts
Normal 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'],
|
||||
}
|
||||
76
admin-compliance/lib/sdk/tom-generator/types/state.ts
Normal file
76
admin-compliance/lib/sdk/tom-generator/types/state.ts
Normal 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
|
||||
}
|
||||
93
admin-compliance/lib/sdk/tom-generator/types/step-config.ts
Normal file
93
admin-compliance/lib/sdk/tom-generator/types/step-config.ts
Normal 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
@@ -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
|
||||
}
|
||||
47
admin-compliance/lib/sdk/vendor-compliance/types/common.ts
Normal file
47
admin-compliance/lib/sdk/vendor-compliance/types/common.ts
Normal 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
|
||||
}
|
||||
140
admin-compliance/lib/sdk/vendor-compliance/types/constants.ts
Normal file
140
admin-compliance/lib/sdk/vendor-compliance/types/constants.ts
Normal 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' },
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
262
admin-compliance/lib/sdk/vendor-compliance/types/enums.ts
Normal file
262
admin-compliance/lib/sdk/vendor-compliance/types/enums.ts
Normal 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'
|
||||
@@ -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
|
||||
}
|
||||
79
admin-compliance/lib/sdk/vendor-compliance/types/forms.ts
Normal file
79
admin-compliance/lib/sdk/vendor-compliance/types/forms.ts
Normal 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
|
||||
}
|
||||
126
admin-compliance/lib/sdk/vendor-compliance/types/helpers.ts
Normal file
126
admin-compliance/lib/sdk/vendor-compliance/types/helpers.ts
Normal 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'
|
||||
}
|
||||
}
|
||||
19
admin-compliance/lib/sdk/vendor-compliance/types/index.ts
Normal file
19
admin-compliance/lib/sdk/vendor-compliance/types/index.ts
Normal 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'
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user