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

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

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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