From 91063f09b8d414e7326bcc9048dec694d72f5bde Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com> Date: Sat, 18 Apr 2026 00:07:03 +0200 Subject: [PATCH] refactor(admin): split lib document generators and data catalogs into domain barrels obligations-document, tom-document, loeschfristen-document, compliance-scope-triggers, sdk-flow/flow-data, processing-activities, loeschfristen-baseline-catalog, catalog-registry, dsfa mitigation-library + risk-catalog, vvt-baseline-catalog, vendor contract-review checklists + findings, demo-data, tom-compliance. Co-Authored-By: Claude Sonnet 4.6 --- .../app/sdk/sdk-flow/flow-data.ts | 903 +---------------- .../app/sdk/sdk-flow/steps-analyse.ts | 155 +++ .../app/sdk/sdk-flow/steps-betrieb.ts | 253 +++++ .../app/sdk/sdk-flow/steps-dokumentation.ts | 260 +++++ .../app/sdk/sdk-flow/steps-vorbereitung.ts | 147 +++ admin-compliance/app/sdk/sdk-flow/types.ts | 75 ++ .../sdk/catalog-manager/catalog-registry.ts | 738 +------------- .../catalog-manager/registry/registry-api.ts | 190 ++++ .../catalog-manager/registry/registry-dsfa.ts | 250 +++++ .../registry/registry-reference.ts | 127 +++ .../registry/registry-vendor.ts | 159 +++ .../lib/sdk/compliance-scope-triggers.ts | 824 +--------------- .../compliance-scope-triggers/triggers-a-e.ts | 359 +++++++ .../compliance-scope-triggers/triggers-f-m.ts | 467 +++++++++ .../lib/sdk/demo-data/demo-state.ts | 217 +++++ admin-compliance/lib/sdk/demo-data/index.ts | 419 +------- .../lib/sdk/dsfa/mitigation-library.ts | 698 +------------ .../sdk/dsfa/mitigations/access-integrity.ts | 176 ++++ .../mitigations/availability-minimization.ts | 165 ++++ .../lib/sdk/dsfa/mitigations/helpers.ts | 61 ++ .../transparency-intervention-org.ts | 267 +++++ .../lib/sdk/dsfa/mitigations/types.ts | 17 + admin-compliance/lib/sdk/dsfa/risk-catalog.ts | 618 +----------- .../risks/availability-rights-auto-org.ts | 310 ++++++ .../dsfa/risks/confidentiality-integrity.ts | 206 ++++ .../lib/sdk/dsfa/risks/helpers.ts | 64 ++ admin-compliance/lib/sdk/dsfa/risks/types.ts | 19 + .../lib/sdk/loeschfristen-baseline-catalog.ts | 763 +-------------- .../finance-legal.ts | 202 ++++ .../loeschfristen-baseline-catalog/helpers.ts | 69 ++ .../sdk/loeschfristen-baseline-catalog/hr.ts | 178 ++++ .../it-security.ts | 105 ++ .../marketing-crm.ts | 154 +++ .../loeschfristen-baseline-catalog/types.ts | 32 + .../lib/sdk/loeschfristen-document.ts | 879 +---------------- .../lib/sdk/loeschfristen-document/helpers.ts | 26 + .../loeschfristen-document/html-builder.ts | 603 ++++++++++++ .../loeschfristen-document/types-defaults.ts | 60 ++ .../lib/sdk/obligations-document.ts | 915 +----------------- .../lib/sdk/obligations-document/helpers.ts | 31 + .../sdk/obligations-document/html-builder.ts | 620 ++++++++++++ .../obligations-document/html-sections-1-5.ts | 207 ++++ .../sdk/obligations-document/html-styles.ts | 211 ++++ .../obligations-document/types-defaults.ts | 70 ++ .../lib/sdk/tom-compliance-checks.ts | 328 +++++++ admin-compliance/lib/sdk/tom-compliance.ts | 414 +------- admin-compliance/lib/sdk/tom-document.ts | 906 +---------------- .../lib/sdk/tom-document/helpers.ts | 26 + .../lib/sdk/tom-document/html-builder.ts | 82 ++ .../lib/sdk/tom-document/html-sections-1-6.ts | 306 ++++++ .../sdk/tom-document/html-sections-7-11.ts | 241 +++++ .../lib/sdk/tom-document/html-styles.ts | 85 ++ .../lib/sdk/tom-document/types-defaults.ts | 98 ++ .../catalog/processing-activities.ts | 815 +--------------- .../catalog/processing-activities/helpers.ts | 87 ++ .../catalog/processing-activities/hr-sales.ts | 200 ++++ .../it-customer-web-general.ts | 363 +++++++ .../marketing-finance.ts | 137 +++ .../catalog/processing-activities/types.ts | 48 + .../contract-review/checklists-data.ts | 322 ++++++ .../contract-review/checklists.ts | 396 +------- .../contract-review/findings-templates.ts | 331 +++++++ .../contract-review/findings.ts | 383 +------- .../sdk/vvt-baseline-catalog/hr-finance.ts | 191 ++++ .../lib/sdk/vvt-baseline-catalog/types.ts | 30 + 65 files changed, 9514 insertions(+), 9544 deletions(-) create mode 100644 admin-compliance/app/sdk/sdk-flow/steps-analyse.ts create mode 100644 admin-compliance/app/sdk/sdk-flow/steps-betrieb.ts create mode 100644 admin-compliance/app/sdk/sdk-flow/steps-dokumentation.ts create mode 100644 admin-compliance/app/sdk/sdk-flow/steps-vorbereitung.ts create mode 100644 admin-compliance/app/sdk/sdk-flow/types.ts create mode 100644 admin-compliance/lib/sdk/catalog-manager/registry/registry-api.ts create mode 100644 admin-compliance/lib/sdk/catalog-manager/registry/registry-dsfa.ts create mode 100644 admin-compliance/lib/sdk/catalog-manager/registry/registry-reference.ts create mode 100644 admin-compliance/lib/sdk/catalog-manager/registry/registry-vendor.ts create mode 100644 admin-compliance/lib/sdk/compliance-scope-triggers/triggers-a-e.ts create mode 100644 admin-compliance/lib/sdk/compliance-scope-triggers/triggers-f-m.ts create mode 100644 admin-compliance/lib/sdk/demo-data/demo-state.ts create mode 100644 admin-compliance/lib/sdk/dsfa/mitigations/access-integrity.ts create mode 100644 admin-compliance/lib/sdk/dsfa/mitigations/availability-minimization.ts create mode 100644 admin-compliance/lib/sdk/dsfa/mitigations/helpers.ts create mode 100644 admin-compliance/lib/sdk/dsfa/mitigations/transparency-intervention-org.ts create mode 100644 admin-compliance/lib/sdk/dsfa/mitigations/types.ts create mode 100644 admin-compliance/lib/sdk/dsfa/risks/availability-rights-auto-org.ts create mode 100644 admin-compliance/lib/sdk/dsfa/risks/confidentiality-integrity.ts create mode 100644 admin-compliance/lib/sdk/dsfa/risks/helpers.ts create mode 100644 admin-compliance/lib/sdk/dsfa/risks/types.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-baseline-catalog/finance-legal.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-baseline-catalog/helpers.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-baseline-catalog/hr.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-baseline-catalog/it-security.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-baseline-catalog/marketing-crm.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-baseline-catalog/types.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-document/helpers.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-document/html-builder.ts create mode 100644 admin-compliance/lib/sdk/loeschfristen-document/types-defaults.ts create mode 100644 admin-compliance/lib/sdk/obligations-document/helpers.ts create mode 100644 admin-compliance/lib/sdk/obligations-document/html-builder.ts create mode 100644 admin-compliance/lib/sdk/obligations-document/html-sections-1-5.ts create mode 100644 admin-compliance/lib/sdk/obligations-document/html-styles.ts create mode 100644 admin-compliance/lib/sdk/obligations-document/types-defaults.ts create mode 100644 admin-compliance/lib/sdk/tom-compliance-checks.ts create mode 100644 admin-compliance/lib/sdk/tom-document/helpers.ts create mode 100644 admin-compliance/lib/sdk/tom-document/html-builder.ts create mode 100644 admin-compliance/lib/sdk/tom-document/html-sections-1-6.ts create mode 100644 admin-compliance/lib/sdk/tom-document/html-sections-7-11.ts create mode 100644 admin-compliance/lib/sdk/tom-document/html-styles.ts create mode 100644 admin-compliance/lib/sdk/tom-document/types-defaults.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/helpers.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/hr-sales.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/it-customer-web-general.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/marketing-finance.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/types.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists-data.ts create mode 100644 admin-compliance/lib/sdk/vendor-compliance/contract-review/findings-templates.ts create mode 100644 admin-compliance/lib/sdk/vvt-baseline-catalog/hr-finance.ts create mode 100644 admin-compliance/lib/sdk/vvt-baseline-catalog/types.ts diff --git a/admin-compliance/app/sdk/sdk-flow/flow-data.ts b/admin-compliance/app/sdk/sdk-flow/flow-data.ts index 5e64922..4b7e13a 100644 --- a/admin-compliance/app/sdk/sdk-flow/flow-data.ts +++ b/admin-compliance/app/sdk/sdk-flow/flow-data.ts @@ -1,897 +1,28 @@ /** * SDK Flow Visualization - Step-Definitionen mit Datenfluss - * - * Beschreibt alle SDK-Steps mit: - * - Inputs/Outputs (SDKState-Properties) - * - DB-Tabellen und Modus - * - RAG-Collections und Verwendungszweck - * - Checkpoint-Informationen - * - Detaillierte Beschreibungen + * Barrel re-export — implementation split into sdk-flow/ subdirectory files */ -export interface SDKFlowStep { - id: string - name: string - nameShort: string - package: 'vorbereitung' | 'analyse' | 'dokumentation' | 'rechtliche-texte' | 'betrieb' - seq: number - checkpointId?: string - checkpointType?: 'REQUIRED' | 'RECOMMENDED' - checkpointReviewer?: 'NONE' | 'DSB' | 'LEGAL' +export type { SDKFlowStep } from './types' +export { FLOW_PACKAGES } from './types' - // Beschreibung - description: string - descriptionLong: string - legalBasis?: string +export { STEPS_VORBEREITUNG } from './steps-vorbereitung' +export { STEPS_ANALYSE } from './steps-analyse' +export { STEPS_DOKUMENTATION, STEPS_RECHTLICHE_TEXTE } from './steps-dokumentation' +export { STEPS_BETRIEB } from './steps-betrieb' - // Datenfluss - inputs: string[] - outputs: string[] - prerequisiteSteps: string[] - - // Infrastruktur - dbTables: string[] - dbMode: 'read' | 'write' | 'read/write' | 'none' - ragCollections: string[] - ragPurpose?: string - - // Generierung - generates?: string[] - isOptional?: boolean - url: string - - /** - * Fertigstellungsgrad in Prozent (0–100). - * Nur für Betrieb-Module gesetzt (außer academy/training). - * Berechnung: Frontend-Reifegrad + Backend-Persistenz + API-Abdeckung. - */ - completion?: number -} - -// ============================================================================= -// PACKAGE METADATA -// ============================================================================= - -export const FLOW_PACKAGES = { - vorbereitung: { - name: 'Vorbereitung', - nameShort: 'Vorb.', - icon: '🎯', - color: { bg: '#dbeafe', border: '#3b82f6', text: '#1e40af' }, - }, - analyse: { - name: 'Analyse', - nameShort: 'Analyse', - icon: '🔍', - color: { bg: '#fef3c7', border: '#f59e0b', text: '#92400e' }, - }, - dokumentation: { - name: 'Dokumentation', - nameShort: 'Doku', - icon: '📋', - color: { bg: '#ede9fe', border: '#7c3aed', text: '#5b21b6' }, - }, - 'rechtliche-texte': { - name: 'Rechtliche Texte', - nameShort: 'Legal', - icon: '📝', - color: { bg: '#d1fae5', border: '#10b981', text: '#065f46' }, - }, - betrieb: { - name: 'Betrieb', - nameShort: 'Betrieb', - icon: '⚙️', - color: { bg: '#f1f5f9', border: '#64748b', text: '#334155' }, - }, -} as const - -// ============================================================================= -// ALL SDK FLOW STEPS -// ============================================================================= +import { STEPS_VORBEREITUNG } from './steps-vorbereitung' +import { STEPS_ANALYSE } from './steps-analyse' +import { STEPS_DOKUMENTATION, STEPS_RECHTLICHE_TEXTE } from './steps-dokumentation' +import { STEPS_BETRIEB } from './steps-betrieb' +import type { SDKFlowStep } from './types' export const SDK_FLOW_STEPS: SDKFlowStep[] = [ - // ========================================================================= - // PAKET 1: VORBEREITUNG (seq 100-700) - // ========================================================================= - { - id: 'company-profile', - name: 'Unternehmensprofil', - nameShort: 'Profil', - package: 'vorbereitung', - seq: 100, - checkpointId: 'CP-PROF', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Erfassung aller Stammdaten des Unternehmens als Grundlage fuer die Compliance-Analyse.', - descriptionLong: 'Hier werden alle relevanten Unternehmensdaten erfasst: Firmenname, Rechtsform, Branche, Mitarbeiterzahl, Standorte, Datenschutzbeauftragter und Verantwortlicher. Diese Daten bilden die Basis fuer alle nachfolgenden Compliance-Schritte, da sie bestimmen, welche Regulierungen anwendbar sind (z.B. DSGVO, NIS2, AI Act). Nach Abschluss zeigt eine Summary-Seite alle erfassten Daten auf einen Blick. Ohne ein vollstaendiges Unternehmensprofil koennen keine weiteren Schritte durchgefuehrt werden.', - inputs: [], - outputs: ['companyProfile', 'complianceScope'], - prerequisiteSteps: [], - dbTables: ['sdk_states', 'compliance_company_profiles', 'compliance_company_profile_audit'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/company-profile', - }, - { - id: 'compliance-scope', - name: 'Compliance Scope', - nameShort: 'Scope', - package: 'vorbereitung', - seq: 200, - checkpointId: 'CP-SCOPE', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Bestimmung der Compliance-Tiefe und des Umfangs basierend auf Unternehmensprofil.', - descriptionLong: 'Basierend auf dem Unternehmensprofil wird automatisch ermittelt, wie tiefgehend die Compliance-Analyse sein muss. Kleine Unternehmen mit wenig Datenverarbeitung erhalten eine "BASIS"-Tiefe, waehrend grosse Unternehmen mit sensiblen Daten oder KI-Systemen eine "ERWEITERT" oder "VOLLSTAENDIG"-Tiefe erhalten. Der Compliance-Scope bestimmt, welche Module aktiviert werden und wie detailliert die Dokumentation sein muss. Zusaetzlich werden anwendbare Regulierungen (DSGVO, AI Act, NIS2 etc.) und zustaendige Aufsichtsbehoerden automatisch abgeleitet.', - inputs: ['companyProfile'], - outputs: ['complianceDepthLevel', 'applicableRegulations', 'supervisoryAuthorities'], - prerequisiteSteps: ['company-profile'], - dbTables: ['sdk_states'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/compliance-scope', - }, - { - id: 'use-case-assessment', - name: 'Anwendungsfall-Erfassung', - nameShort: 'Anwendung', - package: 'vorbereitung', - seq: 300, - checkpointId: 'CP-UC', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Systematische Erfassung aller Datenverarbeitungs- und KI-Anwendungsfaelle ueber einen 8-Schritte-Wizard mit Kachel-Auswahl.', - descriptionLong: 'In einem 8-Schritte-Wizard werden alle Use Cases erfasst: (1) Grundlegendes — Titel, Beschreibung, KI-Kategorie (21 Kacheln), Branche wird automatisch aus dem Profil abgeleitet. (2) Datenkategorien — ~60 Kategorien in 10 Gruppen als Kacheln (inkl. Art. 9 hervorgehoben). (3) Verarbeitungszweck — 16 Zweck-Kacheln, Rechtsgrundlage wird vom SDK automatisch ermittelt. (4) Automatisierungsgrad — assistiv/teilautomatisiert/vollautomatisiert. (5) Hosting & Modell — Provider, Region, Modellnutzung (Inferenz/RAG/Fine-Tuning/Training). (6) Datentransfer — Transferziele und Schutzmechanismen. (7) Datenhaltung — Aufbewahrungsfristen. (8) Vertraege — vorhandene Compliance-Dokumente. Die RAG-Collection bp_compliance_ce wird verwendet, um relevante CE-Regulierungen automatisch den Use Cases zuzuordnen (UCCA).', - legalBasis: 'Art. 30 DSGVO (Verzeichnis von Verarbeitungstaetigkeiten)', - inputs: ['companyProfile'], - outputs: ['useCases'], - prerequisiteSteps: ['company-profile'], - dbTables: ['ucca_assessments', 'ucca_findings', 'ucca_controls'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_ce'], - ragPurpose: 'CE-Regulierungen fuer Use-Case Matching', - isOptional: false, - url: '/sdk/use-cases', - }, - { - id: 'import', - name: 'Dokument-Import', - nameShort: 'Import', - package: 'vorbereitung', - seq: 400, - description: 'Import bestehender Compliance-Dokumente (Datenschutzerklaerungen, TOMs, VVTs).', - descriptionLong: 'Optionaler Schritt zum Import bereits vorhandener Compliance-Dokumente. Der Document Crawler analysiert hochgeladene PDFs, Word-Dokumente oder bestehende Datenschutzerklaerungen und extrahiert automatisch relevante Informationen wie bestehende TOMs, Verarbeitungsverzeichnisse oder Risikoanalysen. Diese importierten Daten werden als Grundlage fuer die nachfolgenden Schritte verwendet, damit nicht alles von Null aufgebaut werden muss.', - inputs: ['useCases'], - outputs: ['importedDocuments'], - prerequisiteSteps: ['use-case-assessment'], - dbTables: ['compliance_imported_documents', 'compliance_gap_analyses'], - dbMode: 'read/write', - ragCollections: [], - isOptional: true, - url: '/sdk/import', - }, - { - id: 'screening', - name: 'System Screening', - nameShort: 'Screening', - package: 'vorbereitung', - seq: 500, - checkpointId: 'CP-SCAN', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Technische Analyse der eingesetzten Software, Dienste und deren Abhaengigkeiten.', - descriptionLong: 'Das System Screening analysiert die technische Infrastruktur des Unternehmens. Es werden alle eingesetzten Software-Systeme, Cloud-Dienste, APIs und deren Abhaengigkeiten erfasst. Dabei wird auch eine SBOM (Software Bill of Materials) erstellt, die alle Drittanbieter-Komponenten und deren Lizenzen dokumentiert. Das Screening identifiziert potenzielle Compliance-Risiken wie Datentransfers in Drittlaender, unsichere Abhaengigkeiten oder fehlende Verschluesselung.', - inputs: ['useCases'], - outputs: ['screening', 'sbom'], - prerequisiteSteps: ['use-case-assessment'], - dbTables: ['compliance_screenings', 'compliance_security_issues'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/screening', - }, - { - id: 'modules', - name: 'Compliance Modules', - nameShort: 'Module', - package: 'vorbereitung', - seq: 600, - checkpointId: 'CP-MOD', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Aktivierung der relevanten Compliance-Module basierend auf Screening-Ergebnissen.', - descriptionLong: 'Basierend auf dem Unternehmensprofil und den Screening-Ergebnissen werden die relevanten Compliance-Module aktiviert. Module umfassen z.B. DSGVO-Grundschutz, AI Act, NIS2, ePrivacy, Whistleblower-Richtlinie usw. Die RAG-Collection bp_compliance_gesetze wird verwendet, um aktuelle Gesetzestexte den Modulen zuzuordnen. Nur aktivierte Module erzeugen in den nachfolgenden Schritten Anforderungen, Controls und Dokumentation.', - inputs: ['companyProfile', 'screening'], - outputs: ['modules'], - prerequisiteSteps: ['screening'], - dbTables: ['compliance_service_modules', 'sdk_states'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_gesetze'], - ragPurpose: 'Regulierungen den Modulen zuordnen', - isOptional: false, - url: '/sdk/modules', - }, - { - id: 'source-policy', - name: 'Source Policy', - nameShort: 'Quellen', - package: 'vorbereitung', - seq: 700, - checkpointId: 'CP-SPOL', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Festlegung der Rechtsquellen und Normen fuer die Compliance-Analyse.', - descriptionLong: 'Die Source Policy definiert, welche Rechtsquellen und Normen fuer die Compliance-Analyse herangezogen werden. Dies umfasst EU-Verordnungen (DSGVO, AI Act, NIS2), nationale Gesetze (BDSG, TTDSG), Branchenstandards (ISO 27001, BSI Grundschutz) und interne Richtlinien. Die Source Policy stellt sicher, dass alle nachfolgenden Schritte konsistent auf denselben Rechtsgrundlagen basieren.', - inputs: ['modules'], - outputs: ['sourcePolicy'], - prerequisiteSteps: ['modules'], - dbTables: ['compliance_allowed_sources', 'compliance_pii_rules', 'compliance_source_operations', 'compliance_source_policy_audit'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/source-policy', - }, - - // ========================================================================= - // PAKET 2: ANALYSE (seq 1000-1600) - // ========================================================================= - { - id: 'requirements', - name: 'Requirements', - nameShort: 'Anforderungen', - package: 'analyse', - seq: 1000, - checkpointId: 'CP-REQ', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Ableitung konkreter Compliance-Anforderungen aus den aktivierten Modulen, mit RAG-Anreicherung.', - descriptionLong: 'Aus den aktivierten Modulen und der Source Policy werden konkrete, umsetzbare Compliance-Anforderungen abgeleitet. Vollstaendige CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Loeschen) mit Backend-Persistenz. Die RAG-Collections bp_compliance_recht (DE-Gesetze) und bp_compliance_ce (EU-Verordnungen) liefern aktuelle Rechtstexte, aus denen spezifische Pflichten extrahiert werden. Die KI-gestuetzte Interpretation (interpret_requirement) und Control-Vorschlaege (suggest_controls) werden mit RAG-Kontext angereichert — die Collection wird automatisch anhand des Regulation-Codes gewaehlt (EU → bp_compliance_ce, DE → bp_compliance_recht). Status-Workflow: NOT_STARTED → IN_PROGRESS → IMPLEMENTED → VERIFIED mit automatischem Rollback bei Backend-Fehler. Filterung, Volltextsuche und Paginierung fuer grosse Datensaetze (500+ Anforderungen).', - legalBasis: 'Art. 5, 24, 25 DSGVO (Rechenschaftspflicht)', - inputs: ['modules', 'sourcePolicy'], - outputs: ['requirements'], - prerequisiteSteps: ['source-policy'], - dbTables: ['compliance_requirements'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_recht', 'bp_compliance_ce'], - ragPurpose: 'Rechtliche Anforderungen ableiten + AI-Interpretation mit Rechtskontext anreichern (Collection-Routing: EU→ce, DE→recht)', - isOptional: false, - url: '/sdk/requirements', - }, - { - id: 'controls', - name: 'Controls', - nameShort: 'Controls', - package: 'analyse', - seq: 1100, - checkpointId: 'CP-CTRL', - checkpointType: 'REQUIRED', - checkpointReviewer: 'DSB', - description: 'Definition technischer und organisatorischer Kontrollen zur Erfuellung der Anforderungen.', - descriptionLong: 'Fuer jede Compliance-Anforderung werden konkrete Controls (Kontrollmassnahmen) definiert. Controls sind technische oder organisatorische Massnahmen, die sicherstellen, dass eine Anforderung erfuellt wird. Beispiele: Zugriffskontrolle (RBAC), Verschluesselung (AES-256), Logging, Schulungspflichten. Evidence-Linking: Jeder Control zeigt verknuepfte Nachweise mit Gueltigkeits-Badge an. Navigation zur Evidence-Seite mit vorausgewaehltem Control. Domaenen-basierte Gruppierung (gov, priv, iam, crypto, sdlc, ops, ai, cra, aud). Review-Workflow mit Verantwortlichem und naechstem Review-Datum. Der DSB muss diesen Schritt freigeben.', - legalBasis: 'Art. 32 DSGVO (Sicherheit der Verarbeitung)', - inputs: ['requirements'], - outputs: ['controls'], - prerequisiteSteps: ['requirements'], - dbTables: ['compliance_controls'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/controls', - }, - { - id: 'evidence', - name: 'Evidence', - nameShort: 'Nachweise', - package: 'analyse', - seq: 1200, - checkpointId: 'CP-EVI', - checkpointType: 'RECOMMENDED', - checkpointReviewer: 'NONE', - description: 'Sammlung und Verwaltung von Nachweisen fuer die Umsetzung der Controls.', - descriptionLong: 'Fuer jeden Control wird dokumentiert, wie und wann er umgesetzt wurde. Evidence (Nachweise) koennen Screenshots, Konfigurationsdateien, Audit-Logs, Schulungszertifikate oder Testprotokolle sein. Server-seitige Pagination (page, limit Query-Parameter) fuer grosse Nachweis-Sammlungen. Gueltigkeits-Tracking (valid_from, valid_until) mit Status: valid, expired, pending, failed. Verknuepfung mit Controls und Upload von Dateien als Nachweise. Essentiell fuer Audits und Zertifizierungen.', - legalBasis: 'Art. 5 Abs. 2 DSGVO (Rechenschaftspflicht)', - inputs: ['controls'], - outputs: ['evidence'], - prerequisiteSteps: ['controls'], - dbTables: ['compliance_evidence'], - dbMode: 'write', - ragCollections: [], - isOptional: false, - url: '/sdk/evidence', - }, - { - id: 'risks', - name: 'Risk Matrix', - nameShort: 'Risiken', - package: 'analyse', - seq: 1300, - checkpointId: 'CP-RISK', - checkpointType: 'REQUIRED', - checkpointReviewer: 'DSB', - description: 'Bewertung aller Datenschutz- und Compliance-Risiken in einer Risikomatrix.', - descriptionLong: 'Die 5x5 Risikomatrix bewertet jedes Risiko nach Eintrittswahrscheinlichkeit und Schadenshoehe. Inherent Risk vs. Residual Risk mit visuellem Vergleich. Status-Workflow: IDENTIFIED → ASSESSED → MITIGATED → ACCEPTED → CLOSED. Expandierbare Mitigations-Sektion pro Risiko mit verknuepften Controls (Name, Status, Effectiveness). Automatische Risiko-Level-Berechnung: Score = Likelihood × Impact (LOW <6, MEDIUM 6-11, HIGH 12-19, CRITICAL ≥20). Der DSB muss die Risikobewertung freigeben.', - legalBasis: 'Art. 35 DSGVO (Datenschutz-Folgenabschaetzung)', - inputs: ['controls', 'modules'], - outputs: ['risks'], - prerequisiteSteps: ['evidence'], - dbTables: ['compliance_risks'], - dbMode: 'write', - ragCollections: [], - isOptional: false, - url: '/sdk/risks', - }, - { - id: 'ai-act', - name: 'AI Act Klassifizierung', - nameShort: 'AI Act', - package: 'analyse', - seq: 1400, - checkpointId: 'CP-AI', - checkpointType: 'REQUIRED', - checkpointReviewer: 'LEGAL', - description: 'Klassifizierung aller KI-Systeme nach EU AI Act Risikokategorien.', - descriptionLong: 'KI-System-Registrierung mit vollstaendiger Backend-Persistenz (CRUD). Risikopyramide: Minimal → Begrenzt → Hoch → Verboten. KI-gestuetzte Risikobewertung mit Rule-Based-Fallback: Der Assess-Endpoint analysiert Zweck, Sektor und Beschreibung und leitet Klassifizierung + Pflichten automatisch ab. Fuer Hochrisiko-Systeme werden 8 AI Act Pflichten abgeleitet (Risikomanagement, Daten-Governance, Dokumentation, Transparenz, menschliche Aufsicht, Genauigkeit, Robustheit, Cybersicherheit). Filterung nach Klassifizierung, Status und Sektor. Die Rechtsabteilung (LEGAL) muss die Klassifizierung freigeben.', - legalBasis: 'EU AI Act Art. 6-9 (Risikokategorien)', - inputs: ['useCases', 'companyProfile'], - outputs: ['aiActClassification', 'obligations'], - prerequisiteSteps: ['risks'], - dbTables: ['compliance_ai_systems'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_ce'], - ragPurpose: 'EU AI Act Regulierungstexte', - isOptional: false, - url: '/sdk/ai-act', - }, - { - id: 'audit-checklist', - name: 'Audit Checklist', - nameShort: 'Checklist', - package: 'analyse', - seq: 1500, - checkpointId: 'CP-CHK', - checkpointType: 'RECOMMENDED', - checkpointReviewer: 'NONE', - description: 'Erstellung einer pruefbaren Checkliste fuer interne und externe Audits.', - descriptionLong: 'Aus den Requirements und Controls wird eine strukturierte Audit-Checkliste generiert. Session-Management: Draft → In Progress → Completed → Archived. Interaktiver Sign-Off-Workflow mit digitalem Signatur-Hash (SHA-256). PDF-Download in Deutsch oder Englisch. Session-History: Anzeige vergangener Audit-Sitzungen mit Status-Badges. JSON-Export der Checkliste. Die Checkliste kann fuer interne Self-Assessments oder als Vorbereitung auf externe Audits (ISO 27001, BSI Grundschutz) verwendet werden.', - inputs: ['requirements', 'controls'], - outputs: ['checklist'], - prerequisiteSteps: ['ai-act'], - dbTables: ['compliance_audit_sessions', 'compliance_audit_signoffs'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/audit-checklist', - }, - { - id: 'audit-report', - name: 'Audit Report', - nameShort: 'Report', - package: 'analyse', - seq: 1600, - checkpointId: 'CP-AREP', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Generierung eines vollstaendigen Audit-Reports mit Findings und Empfehlungen.', - descriptionLong: 'Der Audit Report fasst alle Ergebnisse der Analyse-Phase zusammen. Uebersicht aller Audit-Sitzungen mit Status-Badges. Detail-Seite pro Sitzung mit Session-Metadaten (Auditor, Zeitraum, Status), Fortschrittsbalken (konform/nicht konform/ausstehend), interaktiven Checklist-Items mit Sign-Off, Notizen-Bearbeitung pro Pruefpunkt und PDF-Download mit Sprachauswahl (DE/EN). Click-Navigation von der Uebersicht zur Detail-Seite. Dient als Nachweis gegenueber Aufsichtsbehoerden.', - inputs: ['checklist', 'controls', 'evidence'], - outputs: ['auditReport'], - prerequisiteSteps: ['audit-checklist'], - dbTables: ['compliance_audit_sessions'], - dbMode: 'write', - ragCollections: [], - generates: ['Audit-Report (PDF)'], - isOptional: false, - url: '/sdk/audit-report', - }, - - // ========================================================================= - // PAKET 3: DOKUMENTATION (seq 2000-2400) - // ========================================================================= - { - id: 'obligations', - name: 'Pflichtenuebersicht', - nameShort: 'Pflichten', - package: 'dokumentation', - seq: 2000, - checkpointId: 'CP-OBL', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Zusammenfassung aller gesetzlichen Pflichten aus DSGVO, AI Act, NIS2.', - descriptionLong: 'Die Pflichtenuebersicht konsolidiert alle gesetzlichen Pflichten, die sich aus den Requirements, der AI-Act-Klassifizierung und den aktivierten Modulen ergeben. Wenn applicableRegulations aus dem Scope-Profiling vorliegen, werden diese direkt als Vorfilter verwendet. Fuer jede Pflicht wird angegeben: Welches Gesetz (DSGVO, AI Act, NIS2), welcher Artikel, welche Frist, wer verantwortlich ist und welche Massnahmen erforderlich sind. Die RAG-Collection bp_compliance_recht liefert aktuelle Pflichtentexte und Auslegungshinweise.', - legalBasis: 'Art. 5 Abs. 2 DSGVO, Art. 9 AI Act', - inputs: ['requirements', 'aiActClassification', 'modules', 'applicableRegulations'], - outputs: ['obligationsOverview'], - prerequisiteSteps: ['audit-report'], - dbTables: ['compliance_obligations'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_recht'], - ragPurpose: 'NIS2, DSGVO, AI Act Pflichtentexte', - isOptional: false, - url: '/sdk/obligations', - }, - { - id: 'dsfa', - name: 'DSFA', - nameShort: 'DSFA', - package: 'dokumentation', - seq: 2100, - checkpointId: 'CP-DSFA', - checkpointType: 'REQUIRED', - checkpointReviewer: 'DSB', - description: 'Datenschutz-Folgenabschaetzung fuer Hochrisiko-Verarbeitungen. Draft-Modus (v1 + v2) nutzt RAG fuer rechtliche Praezision.', - descriptionLong: 'Die Datenschutz-Folgenabschaetzung (DSFA) ist nach Art. 35 DSGVO fuer Verarbeitungen mit hohem Risiko vorgeschrieben. Sie bewertet systematisch die Notwendigkeit, Verhaeltnismaessigkeit und Risiken der Datenverarbeitung. Die DSFA enthaelt: Beschreibung der Verarbeitung, Bewertung der Notwendigkeit, Risikobewertung fuer die Betroffenen, geplante Abhilfemassnahmen. Der DSB muss die DSFA freigeben. Bei verbleibendem Hochrisiko muss die Aufsichtsbehoerde konsultiert werden. Sowohl der v1- als auch der v2-Draft-Modus werden mit rechtlichem Kontext aus dem RAG-Corpus (bp_dsfa_corpus) angereichert. Die shared queryRAG-Utility (rag-query.ts) wird von Chat- und Draft-Pipelines gemeinsam genutzt.', - legalBasis: 'Art. 35, 36 DSGVO (DSFA und vorherige Konsultation)', - inputs: ['risks', 'aiActClassification', 'modules'], - outputs: ['dsfa'], - prerequisiteSteps: ['obligations'], - dbTables: [], - dbMode: 'none', - ragCollections: ['bp_dsfa_corpus'], - ragPurpose: 'DSFA-Vorlagen, Bewertungskriterien und Art. 35 DSGVO Rechtstexte. v1-Pipeline haengt RAG-Kontext an System-Prompt an, v2-Pipeline injiziert ihn pro Block als RECHTSKONTEXT-Referenz.', - generates: ['DSFA-Report'], - isOptional: true, - url: '/sdk/dsfa', - }, - { - id: 'tom', - name: 'TOMs', - nameShort: 'TOMs', - package: 'dokumentation', - seq: 2200, - checkpointId: 'CP-TOM', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Dokumentation aller Technisch-Organisatorischen Massnahmen nach Art. 32 DSGVO.', - descriptionLong: 'Die Technisch-Organisatorischen Massnahmen (TOMs) dokumentieren alle Sicherheitsmassnahmen, die zum Schutz personenbezogener Daten implementiert sind. TOMs umfassen: Zutrittskontrolle, Zugangskontrolle, Zugriffskontrolle, Weitergabekontrolle, Eingabekontrolle, Auftragskontrolle, Verfuegbarkeitskontrolle und Trennungsgebot. Jede Massnahme wird mit Implementierungsstatus, Verantwortlichem und Pruefintervall dokumentiert. Die bestehenden Controls werden als Basis verwendet.', - legalBasis: 'Art. 32 DSGVO (Sicherheit der Verarbeitung)', - inputs: ['dsfa', 'controls', 'risks'], - outputs: ['toms'], - prerequisiteSteps: ['obligations'], - dbTables: ['compliance_controls'], - dbMode: 'read', - ragCollections: ['bp_compliance_datenschutz'], - ragPurpose: 'TOM-Massnahmenkataloge', - isOptional: false, - url: '/sdk/tom', - }, - { - id: 'loeschfristen', - name: 'Loeschfristen', - nameShort: 'Loeschfristen', - package: 'dokumentation', - seq: 2300, - checkpointId: 'CP-RET', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Festlegung von Aufbewahrungs- und Loeschfristen fuer alle Datenkategorien.', - descriptionLong: 'Fuer jede Datenkategorie werden gesetzliche Aufbewahrungsfristen und Loeschzeitpunkte definiert. Dabei werden gesetzliche Mindestaufbewahrungsfristen (z.B. 10 Jahre Steuerrecht, 6 Jahre Handelsrecht, 3 Jahre Verjaehrung) mit dem Grundsatz der Datenminimierung abgewogen. Das Loeschkonzept definiert: Welche Daten, wann geloescht, wie geloescht (Anonymisierung vs. physische Loeschung) und wer verantwortlich ist.', - legalBasis: 'Art. 5 Abs. 1e DSGVO (Speicherbegrenzung), Art. 17 DSGVO (Recht auf Loeschung)', - inputs: ['vvt', 'dataMapping'], - outputs: ['retentionPolicies'], - prerequisiteSteps: ['tom'], - dbTables: ['compliance_loeschfristen'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_recht'], - ragPurpose: 'Aufbewahrungsfristen nach Gesetz', - isOptional: false, - url: '/sdk/loeschfristen', - }, - { - id: 'vvt', - name: 'Verarbeitungsverzeichnis', - nameShort: 'VVT', - package: 'dokumentation', - seq: 2400, - checkpointId: 'CP-VVT', - checkpointType: 'REQUIRED', - checkpointReviewer: 'DSB', - description: 'Erstellung des Verzeichnisses aller Verarbeitungstaetigkeiten nach Art. 30 DSGVO — vollstaendig backend-persistent.', - descriptionLong: 'Das VVT (Verzeichnis von Verarbeitungstaetigkeiten) ist eine gesetzliche Pflichtdokumentation nach Art. 30 DSGVO. Fuer jede Verarbeitungstaetigkeit wird dokumentiert: Zweck, Rechtsgrundlage, Kategorien betroffener Personen, Datenkategorien, Empfaenger, Drittlandtransfers, Loeschfristen und TOMs. Jede Aktivitaet wird mit einem eindeutigen VVT-ID versehen und in der Datenbank gespeichert (compliance_vvt_activities). Organisationsweite Metadaten (DSB-Kontakt, Branche, Standorte) werden separat verwaltet (compliance_vvt_organization). Alle Aenderungen werden in einem Audit-Log protokolliert (compliance_vvt_audit_log). Das VVT wird via FastAPI-Backend (backend-compliance:8002) persistent gespeichert. Der DSB muss das VVT freigeben.', - legalBasis: 'Art. 30 DSGVO (Verzeichnis von Verarbeitungstaetigkeiten)', - inputs: ['modules', 'toms', 'dataMapping'], - outputs: ['vvt'], - prerequisiteSteps: ['loeschfristen'], - dbTables: ['compliance_vvt_organization', 'compliance_vvt_activities', 'compliance_vvt_audit_log'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_gesetze'], - ragPurpose: 'Art. 30 DSGVO Vorlage', - isOptional: false, - url: '/sdk/vvt', - }, - - // ========================================================================= - // PAKET 4: RECHTLICHE TEXTE (seq 3000-3400) - // ========================================================================= - { - id: 'einwilligungen', - name: 'Einwilligungen', - nameShort: 'Einwilligungen', - package: 'rechtliche-texte', - seq: 3000, - checkpointId: 'CP-CONS', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Definition aller Einwilligungserklaerungen — vollstaendig backend-persistent mit Nachweis-Tracking.', - descriptionLong: 'Basierend auf dem VVT und den aktivierten Modulen werden alle Verarbeitungen identifiziert, die eine Einwilligung erfordern (Art. 6 Abs. 1a DSGVO). Der Datenkatalog definiert einwilligungspflichtige Datenpunkte. Erteilte und widerrufene Einwilligungen werden mit vollstaendigem Audit-Trail gespeichert: Zeitpunkt, Version, IP-Adresse, User-Agent, Quelle. Widerruf setzt `revoked_at` ohne den urspruenglichen Eintrag zu loeschen (Nachweispflicht). Cookie-Banner-Konfiguration ist ebenfalls hier zentral verwaltet.', - legalBasis: 'Art. 6 Abs. 1a, Art. 7 DSGVO (Einwilligung)', - inputs: ['vvt', 'modules'], - outputs: ['consents'], - prerequisiteSteps: ['vvt'], - dbTables: ['compliance_einwilligungen_catalog', 'compliance_einwilligungen_company', 'compliance_einwilligungen_consents', 'compliance_einwilligungen_cookies'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_datenschutz'], - ragPurpose: 'Einwilligungsvorlagen DSGVO', - isOptional: false, - url: '/sdk/einwilligungen', - completion: 100, - }, - { - id: 'consent', - name: 'Rechtliche Vorlagen', - nameShort: 'Vorlagen', - package: 'rechtliche-texte', - seq: 3100, - checkpointId: 'CP-DOC', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Verwaltung von Datenschutzerklaerung, AGB und Nutzungsbedingungen — vollstaendig backend-persistent.', - descriptionLong: 'In diesem Schritt werden die zentralen rechtlichen Dokumente verwaltet: Datenschutzerklaerung (Art. 13/14 DSGVO), AGB, Cookie-Richtlinie, Impressum und AVV. Jedes Dokument wird in `compliance_legal_documents` gespeichert. Ueber den Vorschau-Button kann die aktuell veroffentlichte HTML-Version im Browser angezeigt werden. Per Bearbeiten-Button gelangt man direkt in den Document Workflow. Schnellaktionen navigieren zum Dokumentengenerator fuer KI-gestuetzte Template-Generierung.', - legalBasis: 'Art. 13, 14 DSGVO (Informationspflichten)', - inputs: ['companyProfile', 'vvt', 'consents'], - outputs: ['documents'], - prerequisiteSteps: ['einwilligungen'], - dbTables: ['compliance_legal_documents', 'compliance_legal_document_versions'], - dbMode: 'read/write', - ragCollections: ['bp_legal_templates'], - ragPurpose: 'AGB, DSE, Nutzungsbedingungen Templates', - generates: ['Datenschutzerklaerung', 'AGB', 'Nutzungsbedingungen'], - isOptional: false, - url: '/sdk/consent', - completion: 100, - }, - { - id: 'cookie-banner', - name: 'Cookie Banner', - nameShort: 'Cookies', - package: 'rechtliche-texte', - seq: 3200, - checkpointId: 'CP-COOK', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Konfiguration eines rechtskonformen Cookie-Banners — Texte und Kategorien persistent in DB.', - descriptionLong: 'Der Cookie-Banner wird basierend auf den definierten Einwilligungen konfiguriert. Alle Einstellungen (Position, Stil, Farbe, Texte) und Kategorien werden in `compliance_einwilligungen_cookies` gespeichert. Banner-Texte (Ueberschrift, Beschreibung, Datenschutz-Link) sind Controlled Inputs und werden beim Speichern persistiert. Die Live-Vorschau aktualisiert sich in Echtzeit. Der Embed-Code wird beim Export aus der DB-Konfiguration generiert — kein In-Memory-Speicher, kein Datenverlust bei Neustart. Implementiert "Privacy by Default": nur notwendige Cookies sind vorausgewaehlt.', - legalBasis: 'Art. 5 Abs. 3 ePrivacy-RL, TTDSG § 25', - inputs: ['consents', 'companyProfile'], - outputs: ['cookieBanner'], - prerequisiteSteps: ['consent'], - dbTables: ['compliance_einwilligungen_cookies'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_datenschutz'], - ragPurpose: 'Cookie-Consent Richtlinien', - isOptional: false, - url: '/sdk/cookie-banner', - completion: 100, - }, - { - id: 'document-generator', - name: 'Dokumentengenerator', - nameShort: 'Generator', - package: 'rechtliche-texte', - seq: 3300, - checkpointId: 'CP-DOCGEN', - checkpointType: 'RECOMMENDED', - checkpointReviewer: 'NONE', - description: 'Generierung weiterer rechtlicher Dokumente (Impressum, AVV, Auftragsverarbeitung) mit PDF-Export.', - descriptionLong: 'Der Dokumentengenerator erstellt zusaetzliche rechtliche Dokumente, die ueber die Pflichtdokumente hinausgehen: Impressum (nach TMG/DDG), Auftragsverarbeitungsvertraege (AVV nach Art. 28 DSGVO), Vertraulichkeitsvereinbarungen, Betriebsvereinbarungen zum Datenschutz und Datenschutz-Folgenabschaetzungs-Berichte. Die Templates werden aus bp_legal_templates geladen und mit den unternehmensspezifischen Daten befuellt. PDF-Export ist direkt im Browser via window.print() moeglich. Steht der Template-Service (breakpilot-core) nicht bereit, erscheint ein Fallback-Banner mit Hinweis.', - legalBasis: 'Art. 28 DSGVO (Auftragsverarbeitung), DDG § 5 (Impressum)', - inputs: ['companyProfile', 'toms', 'vvt'], - outputs: ['generatedDocuments'], - prerequisiteSteps: ['cookie-banner'], - dbTables: [], - dbMode: 'none', - ragCollections: ['bp_legal_templates'], - ragPurpose: 'Dokumenten-Templates', - generates: ['Impressum', 'Auftragsverarbeitungsvertrag'], - isOptional: true, - url: '/sdk/document-generator', - completion: 100, - }, - { - id: 'workflow', - name: 'Document Workflow', - nameShort: 'Workflow', - package: 'rechtliche-texte', - seq: 3400, - checkpointId: 'CP-WRKF', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Freigabe-Workflow fuer alle rechtlichen Dokumente — vollstaendig backend-persistent mit Versionierung.', - descriptionLong: 'Der Document Workflow steuert den Freigabeprozess fuer alle rechtlichen Dokumente. Split-View-Editor: linkes Panel zeigt die veroffentlichte Version, rechtes Panel den Entwurf. Status-Workflow: draft → review → approved → published (oder rejected). Alle Versionen werden in `compliance_legal_document_versions` gespeichert. Der Versions-Endpoint gibt ein direktes JSON-Array zurueck. DOCX-Import via multipart/form-data moeglich. Freigabe-Historie wird in `compliance_legal_document_approvals` protokolliert (Zeitstempel, Benutzer, Kommentar). Veroeffentlichte Versionen sind unveraenderlich — Aenderungen erzeugen stets eine neue Version.', - inputs: ['documents', 'generatedDocuments'], - outputs: ['approvedDocuments'], - prerequisiteSteps: ['cookie-banner'], - dbTables: ['compliance_legal_documents', 'compliance_legal_document_versions', 'compliance_legal_document_approvals'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/workflow', - completion: 100, - }, - - // ========================================================================= - // PAKET 5: BETRIEB (seq 4000+) - // ========================================================================= - { - id: 'dsr', - name: 'DSR Portal', - nameShort: 'DSR', - package: 'betrieb', - seq: 4000, - checkpointId: 'CP-DSR', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Einrichtung des Portals fuer Betroffenenrechte (Auskunft, Loeschung, Widerspruch).', - descriptionLong: 'Das DSR-Portal (Data Subject Rights) ermoeglicht es betroffenen Personen, ihre Rechte nach Art. 15-22 DSGVO auszuueben: Auskunftsrecht, Berichtigungsrecht, Loeschungsrecht ("Recht auf Vergessenwerden"), Einschraenkung der Verarbeitung, Datenportabilitaet und Widerspruchsrecht. Das Portal generiert automatisch Formulare, verwaltet Fristen (30 Tage) und dokumentiert die Bearbeitung jeder Anfrage fuer die Nachweispflicht.', - legalBasis: 'Art. 15-22 DSGVO (Betroffenenrechte)', - inputs: ['vvt', 'consents'], - outputs: ['dsrConfig'], - prerequisiteSteps: ['workflow'], - dbTables: [], - dbMode: 'none', - ragCollections: ['bp_compliance_recht'], - ragPurpose: 'Art. 15-21 DSGVO Betroffenenrechte', - isOptional: false, - url: '/sdk/dsr', - completion: 100, - }, - { - id: 'escalations', - name: 'Escalations', - nameShort: 'Eskalationen', - package: 'betrieb', - seq: 4100, - checkpointId: 'CP-ESC', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Definition von Eskalationspfaden bei Compliance-Verstoessen und Datenpannen — vollstaendig backend-persistent.', - descriptionLong: 'Das Eskalationsmanagement definiert klare Eskalationspfade fuer verschiedene Szenarien: Datenschutzverletzungen (Art. 33/34 DSGVO), Compliance-Verstoesse, Betroffenen-Beschwerden und Aufsichtsbehoerden-Anfragen. Fuer jedes Szenario werden Verantwortliche, Fristen (72h bei Datenpannen), Kommunikationswege und Massnahmen festgelegt. Eskalationen koennen aus DSR, Incidents und Whistleblower-Modulen heraus erstellt werden. Alle Daten werden in compliance_escalations gespeichert.', - legalBasis: 'Art. 33, 34 DSGVO (Meldepflichten bei Datenpannen)', - inputs: ['risks', 'controls'], - outputs: ['escalationWorkflows'], - prerequisiteSteps: ['dsr'], - dbTables: ['compliance_escalations'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/escalations', - completion: 100, - }, - { - id: 'vendor-compliance', - name: 'Vendor Compliance', - nameShort: 'Vendor', - package: 'dokumentation', - seq: 2500, - checkpointId: 'CP-VEND', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Pruefung und Verwaltung aller Auftragsverarbeiter und Drittanbieter — Cross-Modul-Integration mit VVT, Obligations, TOM und Loeschfristen.', - descriptionLong: 'Vendor Compliance verwaltet alle externen Dienstleister, die im Auftrag personenbezogene Daten verarbeiten (Auftragsverarbeiter nach Art. 28 DSGVO). Fuer jeden Vendor wird geprueft: Gibt es einen AVV? Wo werden Daten gespeichert (EU/Drittland)? Welche TOMs hat der Vendor? Gibt es Subunternehmer? Cross-Modul-Integration: VVT-Processor-Tab liest Vendors mit role=PROCESSOR direkt aus der Vendor-API, Obligations und Loeschfristen verknuepfen Vendors ueber linked_vendor_ids (JSONB), TOM zeigt Vendor-Controls als Querverweis.', - legalBasis: 'Art. 28 DSGVO (Auftragsverarbeiter), Art. 44-49 (Drittlandtransfer)', - inputs: ['modules', 'vvt'], - outputs: ['vendorAssessments', 'vendorControlInstances'], - prerequisiteSteps: ['vvt'], - dbTables: ['vendor_vendors', 'vendor_contracts', 'vendor_findings', 'vendor_control_instances', 'compliance_templates'], - dbMode: 'read/write', - ragCollections: ['bp_compliance_recht'], - ragPurpose: 'AVV-Vorlagen und Pruefkataloge', - isOptional: false, - url: '/sdk/vendor-compliance', - completion: 100, - }, - { - id: 'consent-management', - name: 'Consent Verwaltung', - nameShort: 'Consent Mgmt', - package: 'betrieb', - seq: 4300, - checkpointId: 'CP-CMGMT', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Laufende Verwaltung aller erteilten und widerrufenen Einwilligungen — E-Mail-Templates + DSGVO-Prozesse aus DB.', - descriptionLong: 'Das Consent Management System verwaltet im laufenden Betrieb alle erteilten Einwilligungen. E-Mail-Templates (Bestaetigungen, DSR-Antworten, etc.) und DSGVO-Prozesse (Art. 15-21) werden in der Datenbank gespeichert und koennen inline bearbeitet werden. Das System stellt sicher, dass Einwilligungen nachweisbar sind (Art. 7 Abs. 1 DSGVO), Widerrufe sofort wirksam werden und bei geaenderten Zwecken neue Einwilligungen eingeholt werden.', - legalBasis: 'Art. 7 DSGVO (Bedingungen fuer die Einwilligung)', - inputs: ['consents', 'documents'], - outputs: ['consentManagement'], - prerequisiteSteps: ['vendor-compliance'], - dbTables: ['compliance_consent_email_templates', 'compliance_consent_gdpr_processes'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/consent-management', - completion: 100, - }, - { - id: 'notfallplan', - name: 'Notfallplan & Breach Response', - nameShort: 'Notfallplan', - package: 'betrieb', - seq: 4400, - checkpointId: 'CP-NOTF', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Erstellung eines Notfallplans fuer Datenpannen und Sicherheitsvorfaelle — vollstaendig backend-persistent.', - descriptionLong: 'Der Notfallplan definiert das Vorgehen bei Datenschutzverletzungen (Data Breaches). Er enthaelt: Sofortmassnahmen zur Schadensbegrenzung, Meldeprozess an die Aufsichtsbehoerde (innerhalb 72h nach Art. 33 DSGVO), Benachrichtigung betroffener Personen (Art. 34 DSGVO), Dokumentation des Vorfalls und Massnahmen zur Verhinderung kuenftiger Vorfaelle. Alle Szenarien, Notfallkontakte, Checklisten und Uebungen werden in der Datenbank gespeichert — kein Mock-Data mehr.', - legalBasis: 'Art. 33, 34 DSGVO (Meldung von Datenpannen)', - inputs: ['risks', 'controls'], - outputs: ['incidentResponsePlan'], - prerequisiteSteps: ['consent-management'], - dbTables: ['compliance_notfallplan_scenarios', 'compliance_notfallplan_contacts', 'compliance_notfallplan_checklists', 'compliance_notfallplan_exercises'], - dbMode: 'read/write', - ragCollections: [], - generates: ['Notfallplan (PDF)'], - isOptional: false, - url: '/sdk/notfallplan', - completion: 100, - }, - { - id: 'incidents', - name: 'Incident Management', - nameShort: 'Incidents', - package: 'betrieb', - seq: 4500, - checkpointId: 'CP-INC', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Verwaltung und Dokumentation von Datenschutz-Vorfaellen und Sicherheitsereignissen.', - descriptionLong: 'Das Incident Management System ermoeglicht die strukturierte Erfassung, Bewertung und Bearbeitung von Datenschutzvorfaellen. Jeder Vorfall wird klassifiziert (Schweregrad, betroffene Daten, Anzahl Betroffener), der Notfallplan wird aktiviert und alle Massnahmen werden protokolliert. Das System berechnet automatisch, ob eine Meldepflicht an die Aufsichtsbehoerde oder eine Benachrichtigung der Betroffenen erforderlich ist. Historische Vorfaelle werden im Incident Registry archiviert.', - legalBasis: 'Art. 33 DSGVO (Meldung an Aufsichtsbehoerde)', - inputs: ['incidentResponsePlan'], - outputs: ['incidentRegistry'], - prerequisiteSteps: ['notfallplan'], - dbTables: [], - dbMode: 'none', - ragCollections: [], - isOptional: false, - url: '/sdk/incidents', - completion: 100, - }, - { - id: 'whistleblower', - name: 'Hinweisgebersystem', - nameShort: 'Whistleblower', - package: 'betrieb', - seq: 4600, - checkpointId: 'CP-WB', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Einrichtung eines anonymen Meldekanals nach HinSchG.', - descriptionLong: 'Das Hinweisgebersystem erfuellt die Anforderungen des Hinweisgeberschutzgesetzes (HinSchG). Es bietet Mitarbeitern und externen Personen einen sicheren, anonymen Kanal zur Meldung von Verstoessen gegen Compliance-Regeln, Datenschutzrecht oder andere Vorschriften. Das System schuetzt die Identitaet des Hinweisgebers, dokumentiert den Bearbeitungsprozess und stellt die Einhaltung der gesetzlichen Fristen (7 Tage Eingangsbestaetigung, 3 Monate Rueckmeldung) sicher.', - legalBasis: 'HinSchG (Hinweisgeberschutzgesetz)', - inputs: ['companyProfile'], - outputs: ['whistleblowerConfig'], - prerequisiteSteps: ['incidents'], - dbTables: [], - dbMode: 'none', - ragCollections: [], - isOptional: false, - url: '/sdk/whistleblower', - completion: 100, - }, - { - id: 'academy', - name: 'Compliance Academy', - nameShort: 'Academy', - package: 'betrieb', - seq: 4700, - checkpointId: 'CP-ACAD', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Erstellung eines Schulungsplans fuer Mitarbeiter zu Datenschutz und Compliance.', - descriptionLong: 'Die Compliance Academy erstellt basierend auf dem Unternehmensprofil und den aktivierten Modulen einen massgeschneiderten Schulungsplan. Verschiedene Mitarbeitergruppen erhalten unterschiedliche Schulungsinhalte: Grundlagen-Datenschutz fuer alle, vertiefte DSGVO-Schulung fuer die IT, AI-Act-Schulung fuer KI-Entwickler, Fuehrungskraefte-Schulung fuer das Management. Der Plan definiert Schulungsintervalle, Pflicht- und Wahlmodule und Erfolgskontrolle.', - inputs: ['companyProfile', 'modules'], - outputs: ['trainingPlan'], - prerequisiteSteps: ['whistleblower'], - dbTables: [], - dbMode: 'none', - ragCollections: [], - isOptional: false, - url: '/sdk/academy', - }, - { - id: 'training', - name: 'Training Engine', - nameShort: 'Training', - package: 'betrieb', - seq: 4800, - checkpointId: 'CP-TRAIN', - checkpointType: 'REQUIRED', - checkpointReviewer: 'NONE', - description: 'Durchfuehrung und Tracking von Compliance-Schulungen mit Quizzes und Zertifikaten — vollstaendig backend-persistent.', - descriptionLong: 'Die Training Engine setzt den Schulungsplan der Academy um. Sie bietet interaktive Schulungsmodule (DSGVO, AI Act, ISO 27001 etc.) mit Quizzes, automatisch generierten Inhalten und Zertifikaten. 28 vordefinierte Schulungsmodule sind hinterlegt. Jede abgeschlossene Schulung wird dokumentiert (Teilnehmer, Datum, Ergebnis, Quiz-Versuch) und dient als Evidence fuer Audits. Die Engine ueberwacht Faelligkeiten, sendet Erinnerungen bei ausstehenden Pflichtschulungen und generiert Compliance-Reports ueber den Schulungsstand aller Mitarbeiter. Backend: ai-compliance-sdk (Go, Port 8093) via /sdk/v1/training/*. Schulungsmatrix ordnet Rollen Pflichtmodulen zu.', - inputs: ['trainingPlan', 'modules'], - outputs: ['trainingContent'], - prerequisiteSteps: ['academy'], - dbTables: ['training_modules', 'training_assignments', 'training_quiz_questions', 'training_quiz_attempts', 'training_matrix_entries', 'training_audit_log'], - dbMode: 'read/write', - ragCollections: [], - isOptional: false, - url: '/sdk/training', - }, - { - id: 'security-backlog', - name: 'Security Backlog', - nameShort: 'Sec-Backlog', - package: 'betrieb', - seq: 4900, - checkpointId: 'CP-SEC', - checkpointType: 'RECOMMENDED', - checkpointReviewer: 'NONE', - description: 'Verwaltung offener Sicherheits-Findings: Schwachstellen, Fehlkonfigurationen und Haertungsmassnahmen.', - descriptionLong: 'Der Security Backlog erfasst alle identifizierten IT-Sicherheitsprobleme: CVE-Schwachstellen, Fehlkonfigurationen, Compliance-Luecken und Haertungsmassnahmen. Jeder Befund wird nach Schweregrad (critical/high/medium/low) klassifiziert, CVSS-Scores und betroffene Assets werden dokumentiert.', - legalBasis: 'Art. 32 DSGVO (Sicherheit der Verarbeitung), BSIG / IT-SiG 2.0', - inputs: ['risks', 'controls'], - outputs: ['securityBacklog'], - prerequisiteSteps: ['training'], - dbTables: ['compliance_security_backlog'], - dbMode: 'read/write', - ragCollections: [], - isOptional: true, - url: '/sdk/security-backlog', - completion: 100, - }, - { - id: 'quality', - name: 'KI-Qualitaetsmanagement', - nameShort: 'Quality', - package: 'betrieb', - seq: 5000, - checkpointId: 'CP-QUAL', - checkpointType: 'RECOMMENDED', - checkpointReviewer: 'NONE', - description: 'Kontinuierliches Monitoring von KI-Qualitaetsmetriken: Genauigkeit, Fairness, Erklaerbarkeit und Tests.', - descriptionLong: 'Das KI-Qualitaetsmanagement ueberwacht alle KI-Systeme auf Qualitaetsmetriken. Fuer jede Metrik wird ein Schwellenwert definiert; Ueberschreitungen loesen Warnungen aus. Qualitaetstests werden dokumentiert. Liefert Evidence fuer AI-Act High-Risk Anforderungen (Art. 9, Art. 15).', - legalBasis: 'Art. 9 AI Act (Risikomanagementsystem), Art. 15 AI Act (Genauigkeit)', - inputs: ['aiActClassification'], - outputs: ['qualityMetrics'], - prerequisiteSteps: ['security-backlog'], - dbTables: ['compliance_quality_metrics', 'compliance_quality_tests'], - dbMode: 'read/write', - ragCollections: [], - isOptional: true, - url: '/sdk/quality', - completion: 100, - }, - { - id: 'isms', - name: 'ISMS (ISO 27001)', - nameShort: 'ISMS', - package: 'betrieb', - seq: 5100, - checkpointId: 'CP-ISMS', - checkpointType: 'RECOMMENDED', - checkpointReviewer: 'DSB', - description: 'Informationssicherheits-Managementsystem: Scope, Policies, SoA, Audits, CAPA, Management-Reviews und Readiness-Check.', - descriptionLong: 'ISO 27001 Zertifizierungsvorbereitung. Verwaltet den ISMS-Scope (Kap. 4.3), Kontextanalyse (4.1/4.2), Sicherheitspolicies (5.2), Security Objectives mit SMART-KPIs (6.2), Statement of Applicability fuer alle 93 Annex-A-Controls, interne Audits (9.2), Management-Reviews (9.3), Audit-Findings mit CAPA-Workflow und einen automatischen Readiness-Check der potenzielle Major/Minor-Findings vor der externen Zertifizierung identifiziert.', - legalBasis: 'ISO/IEC 27001:2022, Art. 32 DSGVO (Sicherheit der Verarbeitung)', - inputs: ['risks', 'controls', 'requirements'], - outputs: ['ismsReadiness'], - prerequisiteSteps: ['quality'], - dbTables: [ - 'compliance_isms_scope', 'compliance_isms_context', 'compliance_isms_policy', - 'compliance_security_objectives', 'compliance_soa', - 'compliance_audit_findings', 'compliance_corrective_actions', - 'compliance_management_reviews', 'compliance_internal_audits', - 'compliance_audit_trail', 'compliance_isms_readiness_checks', - ], - dbMode: 'read/write', - ragCollections: [], - isOptional: true, - url: '/sdk/isms', - completion: 100, - }, + ...STEPS_VORBEREITUNG, + ...STEPS_ANALYSE, + ...STEPS_DOKUMENTATION, + ...STEPS_RECHTLICHE_TEXTE, + ...STEPS_BETRIEB, ] // ============================================================================= diff --git a/admin-compliance/app/sdk/sdk-flow/steps-analyse.ts b/admin-compliance/app/sdk/sdk-flow/steps-analyse.ts new file mode 100644 index 0000000..cef0056 --- /dev/null +++ b/admin-compliance/app/sdk/sdk-flow/steps-analyse.ts @@ -0,0 +1,155 @@ +/** + * SDK Flow Steps — Paket 2: Analyse (seq 1000–1600) + */ +import type { SDKFlowStep } from './types' + +export const STEPS_ANALYSE: SDKFlowStep[] = [ + { + id: 'requirements', + name: 'Requirements', + nameShort: 'Anforderungen', + package: 'analyse', + seq: 1000, + checkpointId: 'CP-REQ', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Ableitung konkreter Compliance-Anforderungen aus den aktivierten Modulen, mit RAG-Anreicherung.', + descriptionLong: 'Aus den aktivierten Modulen und der Source Policy werden konkrete, umsetzbare Compliance-Anforderungen abgeleitet. Vollstaendige CRUD-Operationen (Erstellen, Lesen, Aktualisieren, Loeschen) mit Backend-Persistenz. Die RAG-Collections bp_compliance_recht (DE-Gesetze) und bp_compliance_ce (EU-Verordnungen) liefern aktuelle Rechtstexte, aus denen spezifische Pflichten extrahiert werden. Die KI-gestuetzte Interpretation (interpret_requirement) und Control-Vorschlaege (suggest_controls) werden mit RAG-Kontext angereichert — die Collection wird automatisch anhand des Regulation-Codes gewaehlt (EU → bp_compliance_ce, DE → bp_compliance_recht). Status-Workflow: NOT_STARTED → IN_PROGRESS → IMPLEMENTED → VERIFIED mit automatischem Rollback bei Backend-Fehler. Filterung, Volltextsuche und Paginierung fuer grosse Datensaetze (500+ Anforderungen).', + legalBasis: 'Art. 5, 24, 25 DSGVO (Rechenschaftspflicht)', + inputs: ['modules', 'sourcePolicy'], + outputs: ['requirements'], + prerequisiteSteps: ['source-policy'], + dbTables: ['compliance_requirements'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_recht', 'bp_compliance_ce'], + ragPurpose: 'Rechtliche Anforderungen ableiten + AI-Interpretation mit Rechtskontext anreichern (Collection-Routing: EU→ce, DE→recht)', + isOptional: false, + url: '/sdk/requirements', + }, + { + id: 'controls', + name: 'Controls', + nameShort: 'Controls', + package: 'analyse', + seq: 1100, + checkpointId: 'CP-CTRL', + checkpointType: 'REQUIRED', + checkpointReviewer: 'DSB', + description: 'Definition technischer und organisatorischer Kontrollen zur Erfuellung der Anforderungen.', + descriptionLong: 'Fuer jede Compliance-Anforderung werden konkrete Controls (Kontrollmassnahmen) definiert. Controls sind technische oder organisatorische Massnahmen, die sicherstellen, dass eine Anforderung erfuellt wird. Beispiele: Zugriffskontrolle (RBAC), Verschluesselung (AES-256), Logging, Schulungspflichten. Evidence-Linking: Jeder Control zeigt verknuepfte Nachweise mit Gueltigkeits-Badge an. Navigation zur Evidence-Seite mit vorausgewaehltem Control. Domaenen-basierte Gruppierung (gov, priv, iam, crypto, sdlc, ops, ai, cra, aud). Review-Workflow mit Verantwortlichem und naechstem Review-Datum. Der DSB muss diesen Schritt freigeben.', + legalBasis: 'Art. 32 DSGVO (Sicherheit der Verarbeitung)', + inputs: ['requirements'], + outputs: ['controls'], + prerequisiteSteps: ['requirements'], + dbTables: ['compliance_controls'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/controls', + }, + { + id: 'evidence', + name: 'Evidence', + nameShort: 'Nachweise', + package: 'analyse', + seq: 1200, + checkpointId: 'CP-EVI', + checkpointType: 'RECOMMENDED', + checkpointReviewer: 'NONE', + description: 'Sammlung und Verwaltung von Nachweisen fuer die Umsetzung der Controls.', + descriptionLong: 'Fuer jeden Control wird dokumentiert, wie und wann er umgesetzt wurde. Evidence (Nachweise) koennen Screenshots, Konfigurationsdateien, Audit-Logs, Schulungszertifikate oder Testprotokolle sein. Server-seitige Pagination (page, limit Query-Parameter) fuer grosse Nachweis-Sammlungen. Gueltigkeits-Tracking (valid_from, valid_until) mit Status: valid, expired, pending, failed. Verknuepfung mit Controls und Upload von Dateien als Nachweise. Essentiell fuer Audits und Zertifizierungen.', + legalBasis: 'Art. 5 Abs. 2 DSGVO (Rechenschaftspflicht)', + inputs: ['controls'], + outputs: ['evidence'], + prerequisiteSteps: ['controls'], + dbTables: ['compliance_evidence'], + dbMode: 'write', + ragCollections: [], + isOptional: false, + url: '/sdk/evidence', + }, + { + id: 'risks', + name: 'Risk Matrix', + nameShort: 'Risiken', + package: 'analyse', + seq: 1300, + checkpointId: 'CP-RISK', + checkpointType: 'REQUIRED', + checkpointReviewer: 'DSB', + description: 'Bewertung aller Datenschutz- und Compliance-Risiken in einer Risikomatrix.', + descriptionLong: 'Die 5x5 Risikomatrix bewertet jedes Risiko nach Eintrittswahrscheinlichkeit und Schadenshoehe. Inherent Risk vs. Residual Risk mit visuellem Vergleich. Status-Workflow: IDENTIFIED → ASSESSED → MITIGATED → ACCEPTED → CLOSED. Expandierbare Mitigations-Sektion pro Risiko mit verknuepften Controls (Name, Status, Effectiveness). Automatische Risiko-Level-Berechnung: Score = Likelihood × Impact (LOW <6, MEDIUM 6-11, HIGH 12-19, CRITICAL ≥20). Der DSB muss die Risikobewertung freigeben.', + legalBasis: 'Art. 35 DSGVO (Datenschutz-Folgenabschaetzung)', + inputs: ['controls', 'modules'], + outputs: ['risks'], + prerequisiteSteps: ['evidence'], + dbTables: ['compliance_risks'], + dbMode: 'write', + ragCollections: [], + isOptional: false, + url: '/sdk/risks', + }, + { + id: 'ai-act', + name: 'AI Act Klassifizierung', + nameShort: 'AI Act', + package: 'analyse', + seq: 1400, + checkpointId: 'CP-AI', + checkpointType: 'REQUIRED', + checkpointReviewer: 'LEGAL', + description: 'Klassifizierung aller KI-Systeme nach EU AI Act Risikokategorien.', + descriptionLong: 'KI-System-Registrierung mit vollstaendiger Backend-Persistenz (CRUD). Risikopyramide: Minimal → Begrenzt → Hoch → Verboten. KI-gestuetzte Risikobewertung mit Rule-Based-Fallback: Der Assess-Endpoint analysiert Zweck, Sektor und Beschreibung und leitet Klassifizierung + Pflichten automatisch ab. Fuer Hochrisiko-Systeme werden 8 AI Act Pflichten abgeleitet (Risikomanagement, Daten-Governance, Dokumentation, Transparenz, menschliche Aufsicht, Genauigkeit, Robustheit, Cybersicherheit). Filterung nach Klassifizierung, Status und Sektor. Die Rechtsabteilung (LEGAL) muss die Klassifizierung freigeben.', + legalBasis: 'EU AI Act Art. 6-9 (Risikokategorien)', + inputs: ['useCases', 'companyProfile'], + outputs: ['aiActClassification', 'obligations'], + prerequisiteSteps: ['risks'], + dbTables: ['compliance_ai_systems'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_ce'], + ragPurpose: 'EU AI Act Regulierungstexte', + isOptional: false, + url: '/sdk/ai-act', + }, + { + id: 'audit-checklist', + name: 'Audit Checklist', + nameShort: 'Checklist', + package: 'analyse', + seq: 1500, + checkpointId: 'CP-CHK', + checkpointType: 'RECOMMENDED', + checkpointReviewer: 'NONE', + description: 'Erstellung einer pruefbaren Checkliste fuer interne und externe Audits.', + descriptionLong: 'Aus den Requirements und Controls wird eine strukturierte Audit-Checkliste generiert. Session-Management: Draft → In Progress → Completed → Archived. Interaktiver Sign-Off-Workflow mit digitalem Signatur-Hash (SHA-256). PDF-Download in Deutsch oder Englisch. Session-History: Anzeige vergangener Audit-Sitzungen mit Status-Badges. JSON-Export der Checkliste. Die Checkliste kann fuer interne Self-Assessments oder als Vorbereitung auf externe Audits (ISO 27001, BSI Grundschutz) verwendet werden.', + inputs: ['requirements', 'controls'], + outputs: ['checklist'], + prerequisiteSteps: ['ai-act'], + dbTables: ['compliance_audit_sessions', 'compliance_audit_signoffs'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/audit-checklist', + }, + { + id: 'audit-report', + name: 'Audit Report', + nameShort: 'Report', + package: 'analyse', + seq: 1600, + checkpointId: 'CP-AREP', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Generierung eines vollstaendigen Audit-Reports mit Findings und Empfehlungen.', + descriptionLong: 'Der Audit Report fasst alle Ergebnisse der Analyse-Phase zusammen. Uebersicht aller Audit-Sitzungen mit Status-Badges. Detail-Seite pro Sitzung mit Session-Metadaten (Auditor, Zeitraum, Status), Fortschrittsbalken (konform/nicht konform/ausstehend), interaktiven Checklist-Items mit Sign-Off, Notizen-Bearbeitung pro Pruefpunkt und PDF-Download mit Sprachauswahl (DE/EN). Click-Navigation von der Uebersicht zur Detail-Seite. Dient als Nachweis gegenueber Aufsichtsbehoerden.', + inputs: ['checklist', 'controls', 'evidence'], + outputs: ['auditReport'], + prerequisiteSteps: ['audit-checklist'], + dbTables: ['compliance_audit_sessions'], + dbMode: 'write', + ragCollections: [], + generates: ['Audit-Report (PDF)'], + isOptional: false, + url: '/sdk/audit-report', + }, +] diff --git a/admin-compliance/app/sdk/sdk-flow/steps-betrieb.ts b/admin-compliance/app/sdk/sdk-flow/steps-betrieb.ts new file mode 100644 index 0000000..2b4e2b4 --- /dev/null +++ b/admin-compliance/app/sdk/sdk-flow/steps-betrieb.ts @@ -0,0 +1,253 @@ +/** + * SDK Flow Steps — Paket 5: Betrieb (seq 4000+) + */ +import type { SDKFlowStep } from './types' + +export const STEPS_BETRIEB: SDKFlowStep[] = [ + { + id: 'dsr', + name: 'DSR Portal', + nameShort: 'DSR', + package: 'betrieb', + seq: 4000, + checkpointId: 'CP-DSR', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Einrichtung des Portals fuer Betroffenenrechte (Auskunft, Loeschung, Widerspruch).', + descriptionLong: 'Das DSR-Portal (Data Subject Rights) ermoeglicht es betroffenen Personen, ihre Rechte nach Art. 15-22 DSGVO auszuueben: Auskunftsrecht, Berichtigungsrecht, Loeschungsrecht ("Recht auf Vergessenwerden"), Einschraenkung der Verarbeitung, Datenportabilitaet und Widerspruchsrecht. Das Portal generiert automatisch Formulare, verwaltet Fristen (30 Tage) und dokumentiert die Bearbeitung jeder Anfrage fuer die Nachweispflicht.', + legalBasis: 'Art. 15-22 DSGVO (Betroffenenrechte)', + inputs: ['vvt', 'consents'], + outputs: ['dsrConfig'], + prerequisiteSteps: ['workflow'], + dbTables: [], + dbMode: 'none', + ragCollections: ['bp_compliance_recht'], + ragPurpose: 'Art. 15-21 DSGVO Betroffenenrechte', + isOptional: false, + url: '/sdk/dsr', + completion: 100, + }, + { + id: 'escalations', + name: 'Escalations', + nameShort: 'Eskalationen', + package: 'betrieb', + seq: 4100, + checkpointId: 'CP-ESC', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Definition von Eskalationspfaden bei Compliance-Verstoessen und Datenpannen — vollstaendig backend-persistent.', + descriptionLong: 'Das Eskalationsmanagement definiert klare Eskalationspfade fuer verschiedene Szenarien: Datenschutzverletzungen (Art. 33/34 DSGVO), Compliance-Verstoesse, Betroffenen-Beschwerden und Aufsichtsbehoerden-Anfragen. Fuer jedes Szenario werden Verantwortliche, Fristen (72h bei Datenpannen), Kommunikationswege und Massnahmen festgelegt. Eskalationen koennen aus DSR, Incidents und Whistleblower-Modulen heraus erstellt werden. Alle Daten werden in compliance_escalations gespeichert.', + legalBasis: 'Art. 33, 34 DSGVO (Meldepflichten bei Datenpannen)', + inputs: ['risks', 'controls'], + outputs: ['escalationWorkflows'], + prerequisiteSteps: ['dsr'], + dbTables: ['compliance_escalations'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/escalations', + completion: 100, + }, + { + id: 'consent-management', + name: 'Consent Verwaltung', + nameShort: 'Consent Mgmt', + package: 'betrieb', + seq: 4300, + checkpointId: 'CP-CMGMT', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Laufende Verwaltung aller erteilten und widerrufenen Einwilligungen — E-Mail-Templates + DSGVO-Prozesse aus DB.', + descriptionLong: 'Das Consent Management System verwaltet im laufenden Betrieb alle erteilten Einwilligungen. E-Mail-Templates (Bestaetigungen, DSR-Antworten, etc.) und DSGVO-Prozesse (Art. 15-21) werden in der Datenbank gespeichert und koennen inline bearbeitet werden. Das System stellt sicher, dass Einwilligungen nachweisbar sind (Art. 7 Abs. 1 DSGVO), Widerrufe sofort wirksam werden und bei geaenderten Zwecken neue Einwilligungen eingeholt werden.', + legalBasis: 'Art. 7 DSGVO (Bedingungen fuer die Einwilligung)', + inputs: ['consents', 'documents'], + outputs: ['consentManagement'], + prerequisiteSteps: ['vendor-compliance'], + dbTables: ['compliance_consent_email_templates', 'compliance_consent_gdpr_processes'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/consent-management', + completion: 100, + }, + { + id: 'notfallplan', + name: 'Notfallplan & Breach Response', + nameShort: 'Notfallplan', + package: 'betrieb', + seq: 4400, + checkpointId: 'CP-NOTF', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Erstellung eines Notfallplans fuer Datenpannen und Sicherheitsvorfaelle — vollstaendig backend-persistent.', + descriptionLong: 'Der Notfallplan definiert das Vorgehen bei Datenschutzverletzungen (Data Breaches). Er enthaelt: Sofortmassnahmen zur Schadensbegrenzung, Meldeprozess an die Aufsichtsbehoerde (innerhalb 72h nach Art. 33 DSGVO), Benachrichtigung betroffener Personen (Art. 34 DSGVO), Dokumentation des Vorfalls und Massnahmen zur Verhinderung kuenftiger Vorfaelle. Alle Szenarien, Notfallkontakte, Checklisten und Uebungen werden in der Datenbank gespeichert — kein Mock-Data mehr.', + legalBasis: 'Art. 33, 34 DSGVO (Meldung von Datenpannen)', + inputs: ['risks', 'controls'], + outputs: ['incidentResponsePlan'], + prerequisiteSteps: ['consent-management'], + dbTables: ['compliance_notfallplan_scenarios', 'compliance_notfallplan_contacts', 'compliance_notfallplan_checklists', 'compliance_notfallplan_exercises'], + dbMode: 'read/write', + ragCollections: [], + generates: ['Notfallplan (PDF)'], + isOptional: false, + url: '/sdk/notfallplan', + completion: 100, + }, + { + id: 'incidents', + name: 'Incident Management', + nameShort: 'Incidents', + package: 'betrieb', + seq: 4500, + checkpointId: 'CP-INC', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Verwaltung und Dokumentation von Datenschutz-Vorfaellen und Sicherheitsereignissen.', + descriptionLong: 'Das Incident Management System ermoeglicht die strukturierte Erfassung, Bewertung und Bearbeitung von Datenschutzvorfaellen. Jeder Vorfall wird klassifiziert (Schweregrad, betroffene Daten, Anzahl Betroffener), der Notfallplan wird aktiviert und alle Massnahmen werden protokolliert. Das System berechnet automatisch, ob eine Meldepflicht an die Aufsichtsbehoerde oder eine Benachrichtigung der Betroffenen erforderlich ist. Historische Vorfaelle werden im Incident Registry archiviert.', + legalBasis: 'Art. 33 DSGVO (Meldung an Aufsichtsbehoerde)', + inputs: ['incidentResponsePlan'], + outputs: ['incidentRegistry'], + prerequisiteSteps: ['notfallplan'], + dbTables: [], + dbMode: 'none', + ragCollections: [], + isOptional: false, + url: '/sdk/incidents', + completion: 100, + }, + { + id: 'whistleblower', + name: 'Hinweisgebersystem', + nameShort: 'Whistleblower', + package: 'betrieb', + seq: 4600, + checkpointId: 'CP-WB', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Einrichtung eines anonymen Meldekanals nach HinSchG.', + descriptionLong: 'Das Hinweisgebersystem erfuellt die Anforderungen des Hinweisgeberschutzgesetzes (HinSchG). Es bietet Mitarbeitern und externen Personen einen sicheren, anonymen Kanal zur Meldung von Verstoessen gegen Compliance-Regeln, Datenschutzrecht oder andere Vorschriften. Das System schuetzt die Identitaet des Hinweisgebers, dokumentiert den Bearbeitungsprozess und stellt die Einhaltung der gesetzlichen Fristen (7 Tage Eingangsbestaetigung, 3 Monate Rueckmeldung) sicher.', + legalBasis: 'HinSchG (Hinweisgeberschutzgesetz)', + inputs: ['companyProfile'], + outputs: ['whistleblowerConfig'], + prerequisiteSteps: ['incidents'], + dbTables: [], + dbMode: 'none', + ragCollections: [], + isOptional: false, + url: '/sdk/whistleblower', + completion: 100, + }, + { + id: 'academy', + name: 'Compliance Academy', + nameShort: 'Academy', + package: 'betrieb', + seq: 4700, + checkpointId: 'CP-ACAD', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Erstellung eines Schulungsplans fuer Mitarbeiter zu Datenschutz und Compliance.', + descriptionLong: 'Die Compliance Academy erstellt basierend auf dem Unternehmensprofil und den aktivierten Modulen einen massgeschneiderten Schulungsplan. Verschiedene Mitarbeitergruppen erhalten unterschiedliche Schulungsinhalte: Grundlagen-Datenschutz fuer alle, vertiefte DSGVO-Schulung fuer die IT, AI-Act-Schulung fuer KI-Entwickler, Fuehrungskraefte-Schulung fuer das Management. Der Plan definiert Schulungsintervalle, Pflicht- und Wahlmodule und Erfolgskontrolle.', + inputs: ['companyProfile', 'modules'], + outputs: ['trainingPlan'], + prerequisiteSteps: ['whistleblower'], + dbTables: [], + dbMode: 'none', + ragCollections: [], + isOptional: false, + url: '/sdk/academy', + }, + { + id: 'training', + name: 'Training Engine', + nameShort: 'Training', + package: 'betrieb', + seq: 4800, + checkpointId: 'CP-TRAIN', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Durchfuehrung und Tracking von Compliance-Schulungen mit Quizzes und Zertifikaten — vollstaendig backend-persistent.', + descriptionLong: 'Die Training Engine setzt den Schulungsplan der Academy um. Sie bietet interaktive Schulungsmodule (DSGVO, AI Act, ISO 27001 etc.) mit Quizzes, automatisch generierten Inhalten und Zertifikaten. 28 vordefinierte Schulungsmodule sind hinterlegt. Jede abgeschlossene Schulung wird dokumentiert (Teilnehmer, Datum, Ergebnis, Quiz-Versuch) und dient als Evidence fuer Audits. Die Engine ueberwacht Faelligkeiten, sendet Erinnerungen bei ausstehenden Pflichtschulungen und generiert Compliance-Reports ueber den Schulungsstand aller Mitarbeiter. Backend: ai-compliance-sdk (Go, Port 8093) via /sdk/v1/training/*. Schulungsmatrix ordnet Rollen Pflichtmodulen zu.', + inputs: ['trainingPlan', 'modules'], + outputs: ['trainingContent'], + prerequisiteSteps: ['academy'], + dbTables: ['training_modules', 'training_assignments', 'training_quiz_questions', 'training_quiz_attempts', 'training_matrix_entries', 'training_audit_log'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/training', + }, + { + id: 'security-backlog', + name: 'Security Backlog', + nameShort: 'Sec-Backlog', + package: 'betrieb', + seq: 4900, + checkpointId: 'CP-SEC', + checkpointType: 'RECOMMENDED', + checkpointReviewer: 'NONE', + description: 'Verwaltung offener Sicherheits-Findings: Schwachstellen, Fehlkonfigurationen und Haertungsmassnahmen.', + descriptionLong: 'Der Security Backlog erfasst alle identifizierten IT-Sicherheitsprobleme: CVE-Schwachstellen, Fehlkonfigurationen, Compliance-Luecken und Haertungsmassnahmen. Jeder Befund wird nach Schweregrad (critical/high/medium/low) klassifiziert, CVSS-Scores und betroffene Assets werden dokumentiert.', + legalBasis: 'Art. 32 DSGVO (Sicherheit der Verarbeitung), BSIG / IT-SiG 2.0', + inputs: ['risks', 'controls'], + outputs: ['securityBacklog'], + prerequisiteSteps: ['training'], + dbTables: ['compliance_security_backlog'], + dbMode: 'read/write', + ragCollections: [], + isOptional: true, + url: '/sdk/security-backlog', + completion: 100, + }, + { + id: 'quality', + name: 'KI-Qualitaetsmanagement', + nameShort: 'Quality', + package: 'betrieb', + seq: 5000, + checkpointId: 'CP-QUAL', + checkpointType: 'RECOMMENDED', + checkpointReviewer: 'NONE', + description: 'Kontinuierliches Monitoring von KI-Qualitaetsmetriken: Genauigkeit, Fairness, Erklaerbarkeit und Tests.', + descriptionLong: 'Das KI-Qualitaetsmanagement ueberwacht alle KI-Systeme auf Qualitaetsmetriken. Fuer jede Metrik wird ein Schwellenwert definiert; Ueberschreitungen loesen Warnungen aus. Qualitaetstests werden dokumentiert. Liefert Evidence fuer AI-Act High-Risk Anforderungen (Art. 9, Art. 15).', + legalBasis: 'Art. 9 AI Act (Risikomanagementsystem), Art. 15 AI Act (Genauigkeit)', + inputs: ['aiActClassification'], + outputs: ['qualityMetrics'], + prerequisiteSteps: ['security-backlog'], + dbTables: ['compliance_quality_metrics', 'compliance_quality_tests'], + dbMode: 'read/write', + ragCollections: [], + isOptional: true, + url: '/sdk/quality', + completion: 100, + }, + { + id: 'isms', + name: 'ISMS (ISO 27001)', + nameShort: 'ISMS', + package: 'betrieb', + seq: 5100, + checkpointId: 'CP-ISMS', + checkpointType: 'RECOMMENDED', + checkpointReviewer: 'DSB', + description: 'Informationssicherheits-Managementsystem: Scope, Policies, SoA, Audits, CAPA, Management-Reviews und Readiness-Check.', + descriptionLong: 'ISO 27001 Zertifizierungsvorbereitung. Verwaltet den ISMS-Scope (Kap. 4.3), Kontextanalyse (4.1/4.2), Sicherheitspolicies (5.2), Security Objectives mit SMART-KPIs (6.2), Statement of Applicability fuer alle 93 Annex-A-Controls, interne Audits (9.2), Management-Reviews (9.3), Audit-Findings mit CAPA-Workflow und einen automatischen Readiness-Check der potenzielle Major/Minor-Findings vor der externen Zertifizierung identifiziert.', + legalBasis: 'ISO/IEC 27001:2022, Art. 32 DSGVO (Sicherheit der Verarbeitung)', + inputs: ['risks', 'controls', 'requirements'], + outputs: ['ismsReadiness'], + prerequisiteSteps: ['quality'], + dbTables: [ + 'compliance_isms_scope', 'compliance_isms_context', 'compliance_isms_policy', + 'compliance_security_objectives', 'compliance_soa', + 'compliance_audit_findings', 'compliance_corrective_actions', + 'compliance_management_reviews', 'compliance_internal_audits', + 'compliance_audit_trail', 'compliance_isms_readiness_checks', + ], + dbMode: 'read/write', + ragCollections: [], + isOptional: true, + url: '/sdk/isms', + completion: 100, + }, +] diff --git a/admin-compliance/app/sdk/sdk-flow/steps-dokumentation.ts b/admin-compliance/app/sdk/sdk-flow/steps-dokumentation.ts new file mode 100644 index 0000000..13b11e4 --- /dev/null +++ b/admin-compliance/app/sdk/sdk-flow/steps-dokumentation.ts @@ -0,0 +1,260 @@ +/** + * SDK Flow Steps — Paket 3: Dokumentation (seq 2000–2500) + * + Paket 4: Rechtliche Texte (seq 3000–3400) + */ +import type { SDKFlowStep } from './types' + +export const STEPS_DOKUMENTATION: SDKFlowStep[] = [ + { + id: 'obligations', + name: 'Pflichtenuebersicht', + nameShort: 'Pflichten', + package: 'dokumentation', + seq: 2000, + checkpointId: 'CP-OBL', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Zusammenfassung aller gesetzlichen Pflichten aus DSGVO, AI Act, NIS2.', + descriptionLong: 'Die Pflichtenuebersicht konsolidiert alle gesetzlichen Pflichten, die sich aus den Requirements, der AI-Act-Klassifizierung und den aktivierten Modulen ergeben. Wenn applicableRegulations aus dem Scope-Profiling vorliegen, werden diese direkt als Vorfilter verwendet. Fuer jede Pflicht wird angegeben: Welches Gesetz (DSGVO, AI Act, NIS2), welcher Artikel, welche Frist, wer verantwortlich ist und welche Massnahmen erforderlich sind. Die RAG-Collection bp_compliance_recht liefert aktuelle Pflichtentexte und Auslegungshinweise.', + legalBasis: 'Art. 5 Abs. 2 DSGVO, Art. 9 AI Act', + inputs: ['requirements', 'aiActClassification', 'modules', 'applicableRegulations'], + outputs: ['obligationsOverview'], + prerequisiteSteps: ['audit-report'], + dbTables: ['compliance_obligations'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_recht'], + ragPurpose: 'NIS2, DSGVO, AI Act Pflichtentexte', + isOptional: false, + url: '/sdk/obligations', + }, + { + id: 'dsfa', + name: 'DSFA', + nameShort: 'DSFA', + package: 'dokumentation', + seq: 2100, + checkpointId: 'CP-DSFA', + checkpointType: 'REQUIRED', + checkpointReviewer: 'DSB', + description: 'Datenschutz-Folgenabschaetzung fuer Hochrisiko-Verarbeitungen. Draft-Modus (v1 + v2) nutzt RAG fuer rechtliche Praezision.', + descriptionLong: 'Die Datenschutz-Folgenabschaetzung (DSFA) ist nach Art. 35 DSGVO fuer Verarbeitungen mit hohem Risiko vorgeschrieben. Sie bewertet systematisch die Notwendigkeit, Verhaeltnismaessigkeit und Risiken der Datenverarbeitung. Die DSFA enthaelt: Beschreibung der Verarbeitung, Bewertung der Notwendigkeit, Risikobewertung fuer die Betroffenen, geplante Abhilfemassnahmen. Der DSB muss die DSFA freigeben. Bei verbleibendem Hochrisiko muss die Aufsichtsbehoerde konsultiert werden. Sowohl der v1- als auch der v2-Draft-Modus werden mit rechtlichem Kontext aus dem RAG-Corpus (bp_dsfa_corpus) angereichert. Die shared queryRAG-Utility (rag-query.ts) wird von Chat- und Draft-Pipelines gemeinsam genutzt.', + legalBasis: 'Art. 35, 36 DSGVO (DSFA und vorherige Konsultation)', + inputs: ['risks', 'aiActClassification', 'modules'], + outputs: ['dsfa'], + prerequisiteSteps: ['obligations'], + dbTables: [], + dbMode: 'none', + ragCollections: ['bp_dsfa_corpus'], + ragPurpose: 'DSFA-Vorlagen, Bewertungskriterien und Art. 35 DSGVO Rechtstexte. v1-Pipeline haengt RAG-Kontext an System-Prompt an, v2-Pipeline injiziert ihn pro Block als RECHTSKONTEXT-Referenz.', + generates: ['DSFA-Report'], + isOptional: true, + url: '/sdk/dsfa', + }, + { + id: 'tom', + name: 'TOMs', + nameShort: 'TOMs', + package: 'dokumentation', + seq: 2200, + checkpointId: 'CP-TOM', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Dokumentation aller Technisch-Organisatorischen Massnahmen nach Art. 32 DSGVO.', + descriptionLong: 'Die Technisch-Organisatorischen Massnahmen (TOMs) dokumentieren alle Sicherheitsmassnahmen, die zum Schutz personenbezogener Daten implementiert sind. TOMs umfassen: Zutrittskontrolle, Zugangskontrolle, Zugriffskontrolle, Weitergabekontrolle, Eingabekontrolle, Auftragskontrolle, Verfuegbarkeitskontrolle und Trennungsgebot. Jede Massnahme wird mit Implementierungsstatus, Verantwortlichem und Pruefintervall dokumentiert. Die bestehenden Controls werden als Basis verwendet.', + legalBasis: 'Art. 32 DSGVO (Sicherheit der Verarbeitung)', + inputs: ['dsfa', 'controls', 'risks'], + outputs: ['toms'], + prerequisiteSteps: ['obligations'], + dbTables: ['compliance_controls'], + dbMode: 'read', + ragCollections: ['bp_compliance_datenschutz'], + ragPurpose: 'TOM-Massnahmenkataloge', + isOptional: false, + url: '/sdk/tom', + }, + { + id: 'loeschfristen', + name: 'Loeschfristen', + nameShort: 'Loeschfristen', + package: 'dokumentation', + seq: 2300, + checkpointId: 'CP-RET', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Festlegung von Aufbewahrungs- und Loeschfristen fuer alle Datenkategorien.', + descriptionLong: 'Fuer jede Datenkategorie werden gesetzliche Aufbewahrungsfristen und Loeschzeitpunkte definiert. Dabei werden gesetzliche Mindestaufbewahrungsfristen (z.B. 10 Jahre Steuerrecht, 6 Jahre Handelsrecht, 3 Jahre Verjaehrung) mit dem Grundsatz der Datenminimierung abgewogen. Das Loeschkonzept definiert: Welche Daten, wann geloescht, wie geloescht (Anonymisierung vs. physische Loeschung) und wer verantwortlich ist.', + legalBasis: 'Art. 5 Abs. 1e DSGVO (Speicherbegrenzung), Art. 17 DSGVO (Recht auf Loeschung)', + inputs: ['vvt', 'dataMapping'], + outputs: ['retentionPolicies'], + prerequisiteSteps: ['tom'], + dbTables: ['compliance_loeschfristen'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_recht'], + ragPurpose: 'Aufbewahrungsfristen nach Gesetz', + isOptional: false, + url: '/sdk/loeschfristen', + }, + { + id: 'vvt', + name: 'Verarbeitungsverzeichnis', + nameShort: 'VVT', + package: 'dokumentation', + seq: 2400, + checkpointId: 'CP-VVT', + checkpointType: 'REQUIRED', + checkpointReviewer: 'DSB', + description: 'Erstellung des Verzeichnisses aller Verarbeitungstaetigkeiten nach Art. 30 DSGVO — vollstaendig backend-persistent.', + descriptionLong: 'Das VVT (Verzeichnis von Verarbeitungstaetigkeiten) ist eine gesetzliche Pflichtdokumentation nach Art. 30 DSGVO. Fuer jede Verarbeitungstaetigkeit wird dokumentiert: Zweck, Rechtsgrundlage, Kategorien betroffener Personen, Datenkategorien, Empfaenger, Drittlandtransfers, Loeschfristen und TOMs. Jede Aktivitaet wird mit einem eindeutigen VVT-ID versehen und in der Datenbank gespeichert (compliance_vvt_activities). Organisationsweite Metadaten (DSB-Kontakt, Branche, Standorte) werden separat verwaltet (compliance_vvt_organization). Alle Aenderungen werden in einem Audit-Log protokolliert (compliance_vvt_audit_log). Das VVT wird via FastAPI-Backend (backend-compliance:8002) persistent gespeichert. Der DSB muss das VVT freigeben.', + legalBasis: 'Art. 30 DSGVO (Verzeichnis von Verarbeitungstaetigkeiten)', + inputs: ['modules', 'toms', 'dataMapping'], + outputs: ['vvt'], + prerequisiteSteps: ['loeschfristen'], + dbTables: ['compliance_vvt_organization', 'compliance_vvt_activities', 'compliance_vvt_audit_log'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_gesetze'], + ragPurpose: 'Art. 30 DSGVO Vorlage', + isOptional: false, + url: '/sdk/vvt', + }, + { + id: 'vendor-compliance', + name: 'Vendor Compliance', + nameShort: 'Vendor', + package: 'dokumentation', + seq: 2500, + checkpointId: 'CP-VEND', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Pruefung und Verwaltung aller Auftragsverarbeiter und Drittanbieter — Cross-Modul-Integration mit VVT, Obligations, TOM und Loeschfristen.', + descriptionLong: 'Vendor Compliance verwaltet alle externen Dienstleister, die im Auftrag personenbezogene Daten verarbeiten (Auftragsverarbeiter nach Art. 28 DSGVO). Fuer jeden Vendor wird geprueft: Gibt es einen AVV? Wo werden Daten gespeichert (EU/Drittland)? Welche TOMs hat der Vendor? Gibt es Subunternehmer? Cross-Modul-Integration: VVT-Processor-Tab liest Vendors mit role=PROCESSOR direkt aus der Vendor-API, Obligations und Loeschfristen verknuepfen Vendors ueber linked_vendor_ids (JSONB), TOM zeigt Vendor-Controls als Querverweis.', + legalBasis: 'Art. 28 DSGVO (Auftragsverarbeiter), Art. 44-49 (Drittlandtransfer)', + inputs: ['modules', 'vvt'], + outputs: ['vendorAssessments', 'vendorControlInstances'], + prerequisiteSteps: ['vvt'], + dbTables: ['vendor_vendors', 'vendor_contracts', 'vendor_findings', 'vendor_control_instances', 'compliance_templates'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_recht'], + ragPurpose: 'AVV-Vorlagen und Pruefkataloge', + isOptional: false, + url: '/sdk/vendor-compliance', + completion: 100, + }, +] + +export const STEPS_RECHTLICHE_TEXTE: SDKFlowStep[] = [ + { + id: 'einwilligungen', + name: 'Einwilligungen', + nameShort: 'Einwilligungen', + package: 'rechtliche-texte', + seq: 3000, + checkpointId: 'CP-CONS', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Definition aller Einwilligungserklaerungen — vollstaendig backend-persistent mit Nachweis-Tracking.', + descriptionLong: 'Basierend auf dem VVT und den aktivierten Modulen werden alle Verarbeitungen identifiziert, die eine Einwilligung erfordern (Art. 6 Abs. 1a DSGVO). Der Datenkatalog definiert einwilligungspflichtige Datenpunkte. Erteilte und widerrufene Einwilligungen werden mit vollstaendigem Audit-Trail gespeichert: Zeitpunkt, Version, IP-Adresse, User-Agent, Quelle. Widerruf setzt `revoked_at` ohne den urspruenglichen Eintrag zu loeschen (Nachweispflicht). Cookie-Banner-Konfiguration ist ebenfalls hier zentral verwaltet.', + legalBasis: 'Art. 6 Abs. 1a, Art. 7 DSGVO (Einwilligung)', + inputs: ['vvt', 'modules'], + outputs: ['consents'], + prerequisiteSteps: ['vvt'], + dbTables: ['compliance_einwilligungen_catalog', 'compliance_einwilligungen_company', 'compliance_einwilligungen_consents', 'compliance_einwilligungen_cookies'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_datenschutz'], + ragPurpose: 'Einwilligungsvorlagen DSGVO', + isOptional: false, + url: '/sdk/einwilligungen', + completion: 100, + }, + { + id: 'consent', + name: 'Rechtliche Vorlagen', + nameShort: 'Vorlagen', + package: 'rechtliche-texte', + seq: 3100, + checkpointId: 'CP-DOC', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Verwaltung von Datenschutzerklaerung, AGB und Nutzungsbedingungen — vollstaendig backend-persistent.', + descriptionLong: 'In diesem Schritt werden die zentralen rechtlichen Dokumente verwaltet: Datenschutzerklaerung (Art. 13/14 DSGVO), AGB, Cookie-Richtlinie, Impressum und AVV. Jedes Dokument wird in `compliance_legal_documents` gespeichert. Ueber den Vorschau-Button kann die aktuell veroffentlichte HTML-Version im Browser angezeigt werden. Per Bearbeiten-Button gelangt man direkt in den Document Workflow. Schnellaktionen navigieren zum Dokumentengenerator fuer KI-gestuetzte Template-Generierung.', + legalBasis: 'Art. 13, 14 DSGVO (Informationspflichten)', + inputs: ['companyProfile', 'vvt', 'consents'], + outputs: ['documents'], + prerequisiteSteps: ['einwilligungen'], + dbTables: ['compliance_legal_documents', 'compliance_legal_document_versions'], + dbMode: 'read/write', + ragCollections: ['bp_legal_templates'], + ragPurpose: 'AGB, DSE, Nutzungsbedingungen Templates', + generates: ['Datenschutzerklaerung', 'AGB', 'Nutzungsbedingungen'], + isOptional: false, + url: '/sdk/consent', + completion: 100, + }, + { + id: 'cookie-banner', + name: 'Cookie Banner', + nameShort: 'Cookies', + package: 'rechtliche-texte', + seq: 3200, + checkpointId: 'CP-COOK', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Konfiguration eines rechtskonformen Cookie-Banners — Texte und Kategorien persistent in DB.', + descriptionLong: 'Der Cookie-Banner wird basierend auf den definierten Einwilligungen konfiguriert. Alle Einstellungen (Position, Stil, Farbe, Texte) und Kategorien werden in `compliance_einwilligungen_cookies` gespeichert. Banner-Texte (Ueberschrift, Beschreibung, Datenschutz-Link) sind Controlled Inputs und werden beim Speichern persistiert. Die Live-Vorschau aktualisiert sich in Echtzeit. Der Embed-Code wird beim Export aus der DB-Konfiguration generiert — kein In-Memory-Speicher, kein Datenverlust bei Neustart. Implementiert "Privacy by Default": nur notwendige Cookies sind vorausgewaehlt.', + legalBasis: 'Art. 5 Abs. 3 ePrivacy-RL, TTDSG § 25', + inputs: ['consents', 'companyProfile'], + outputs: ['cookieBanner'], + prerequisiteSteps: ['consent'], + dbTables: ['compliance_einwilligungen_cookies'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_datenschutz'], + ragPurpose: 'Cookie-Consent Richtlinien', + isOptional: false, + url: '/sdk/cookie-banner', + completion: 100, + }, + { + id: 'document-generator', + name: 'Dokumentengenerator', + nameShort: 'Generator', + package: 'rechtliche-texte', + seq: 3300, + checkpointId: 'CP-DOCGEN', + checkpointType: 'RECOMMENDED', + checkpointReviewer: 'NONE', + description: 'Generierung weiterer rechtlicher Dokumente (Impressum, AVV, Auftragsverarbeitung) mit PDF-Export.', + descriptionLong: 'Der Dokumentengenerator erstellt zusaetzliche rechtliche Dokumente, die ueber die Pflichtdokumente hinausgehen: Impressum (nach TMG/DDG), Auftragsverarbeitungsvertraege (AVV nach Art. 28 DSGVO), Vertraulichkeitsvereinbarungen, Betriebsvereinbarungen zum Datenschutz und Datenschutz-Folgenabschaetzungs-Berichte. Die Templates werden aus bp_legal_templates geladen und mit den unternehmensspezifischen Daten befuellt. PDF-Export ist direkt im Browser via window.print() moeglich. Steht der Template-Service (breakpilot-core) nicht bereit, erscheint ein Fallback-Banner mit Hinweis.', + legalBasis: 'Art. 28 DSGVO (Auftragsverarbeitung), DDG § 5 (Impressum)', + inputs: ['companyProfile', 'toms', 'vvt'], + outputs: ['generatedDocuments'], + prerequisiteSteps: ['cookie-banner'], + dbTables: [], + dbMode: 'none', + ragCollections: ['bp_legal_templates'], + ragPurpose: 'Dokumenten-Templates', + generates: ['Impressum', 'Auftragsverarbeitungsvertrag'], + isOptional: true, + url: '/sdk/document-generator', + completion: 100, + }, + { + id: 'workflow', + name: 'Document Workflow', + nameShort: 'Workflow', + package: 'rechtliche-texte', + seq: 3400, + checkpointId: 'CP-WRKF', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Freigabe-Workflow fuer alle rechtlichen Dokumente — vollstaendig backend-persistent mit Versionierung.', + descriptionLong: 'Der Document Workflow steuert den Freigabeprozess fuer alle rechtlichen Dokumente. Split-View-Editor: linkes Panel zeigt die veroffentlichte Version, rechtes Panel den Entwurf. Status-Workflow: draft → review → approved → published (oder rejected). Alle Versionen werden in `compliance_legal_document_versions` gespeichert. Der Versions-Endpoint gibt ein direktes JSON-Array zurueck. DOCX-Import via multipart/form-data moeglich. Freigabe-Historie wird in `compliance_legal_document_approvals` protokolliert (Zeitstempel, Benutzer, Kommentar). Veroeffentlichte Versionen sind unveraenderlich — Aenderungen erzeugen stets eine neue Version.', + inputs: ['documents', 'generatedDocuments'], + outputs: ['approvedDocuments'], + prerequisiteSteps: ['cookie-banner'], + dbTables: ['compliance_legal_documents', 'compliance_legal_document_versions', 'compliance_legal_document_approvals'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/workflow', + completion: 100, + }, +] diff --git a/admin-compliance/app/sdk/sdk-flow/steps-vorbereitung.ts b/admin-compliance/app/sdk/sdk-flow/steps-vorbereitung.ts new file mode 100644 index 0000000..00fd8ae --- /dev/null +++ b/admin-compliance/app/sdk/sdk-flow/steps-vorbereitung.ts @@ -0,0 +1,147 @@ +/** + * SDK Flow Steps — Paket 1: Vorbereitung (seq 100–700) + */ +import type { SDKFlowStep } from './types' + +export const STEPS_VORBEREITUNG: SDKFlowStep[] = [ + { + id: 'company-profile', + name: 'Unternehmensprofil', + nameShort: 'Profil', + package: 'vorbereitung', + seq: 100, + checkpointId: 'CP-PROF', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Erfassung aller Stammdaten des Unternehmens als Grundlage fuer die Compliance-Analyse.', + descriptionLong: 'Hier werden alle relevanten Unternehmensdaten erfasst: Firmenname, Rechtsform, Branche, Mitarbeiterzahl, Standorte, Datenschutzbeauftragter und Verantwortlicher. Diese Daten bilden die Basis fuer alle nachfolgenden Compliance-Schritte, da sie bestimmen, welche Regulierungen anwendbar sind (z.B. DSGVO, NIS2, AI Act). Nach Abschluss zeigt eine Summary-Seite alle erfassten Daten auf einen Blick. Ohne ein vollstaendiges Unternehmensprofil koennen keine weiteren Schritte durchgefuehrt werden.', + inputs: [], + outputs: ['companyProfile', 'complianceScope'], + prerequisiteSteps: [], + dbTables: ['sdk_states', 'compliance_company_profiles', 'compliance_company_profile_audit'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/company-profile', + }, + { + id: 'compliance-scope', + name: 'Compliance Scope', + nameShort: 'Scope', + package: 'vorbereitung', + seq: 200, + checkpointId: 'CP-SCOPE', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Bestimmung der Compliance-Tiefe und des Umfangs basierend auf Unternehmensprofil.', + descriptionLong: 'Basierend auf dem Unternehmensprofil wird automatisch ermittelt, wie tiefgehend die Compliance-Analyse sein muss. Kleine Unternehmen mit wenig Datenverarbeitung erhalten eine "BASIS"-Tiefe, waehrend grosse Unternehmen mit sensiblen Daten oder KI-Systemen eine "ERWEITERT" oder "VOLLSTAENDIG"-Tiefe erhalten. Der Compliance-Scope bestimmt, welche Module aktiviert werden und wie detailliert die Dokumentation sein muss. Zusaetzlich werden anwendbare Regulierungen (DSGVO, AI Act, NIS2 etc.) und zustaendige Aufsichtsbehoerden automatisch abgeleitet.', + inputs: ['companyProfile'], + outputs: ['complianceDepthLevel', 'applicableRegulations', 'supervisoryAuthorities'], + prerequisiteSteps: ['company-profile'], + dbTables: ['sdk_states'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/compliance-scope', + }, + { + id: 'use-case-assessment', + name: 'Anwendungsfall-Erfassung', + nameShort: 'Anwendung', + package: 'vorbereitung', + seq: 300, + checkpointId: 'CP-UC', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Systematische Erfassung aller Datenverarbeitungs- und KI-Anwendungsfaelle ueber einen 8-Schritte-Wizard mit Kachel-Auswahl.', + descriptionLong: 'In einem 8-Schritte-Wizard werden alle Use Cases erfasst: (1) Grundlegendes — Titel, Beschreibung, KI-Kategorie (21 Kacheln), Branche wird automatisch aus dem Profil abgeleitet. (2) Datenkategorien — ~60 Kategorien in 10 Gruppen als Kacheln (inkl. Art. 9 hervorgehoben). (3) Verarbeitungszweck — 16 Zweck-Kacheln, Rechtsgrundlage wird vom SDK automatisch ermittelt. (4) Automatisierungsgrad — assistiv/teilautomatisiert/vollautomatisiert. (5) Hosting & Modell — Provider, Region, Modellnutzung (Inferenz/RAG/Fine-Tuning/Training). (6) Datentransfer — Transferziele und Schutzmechanismen. (7) Datenhaltung — Aufbewahrungsfristen. (8) Vertraege — vorhandene Compliance-Dokumente. Die RAG-Collection bp_compliance_ce wird verwendet, um relevante CE-Regulierungen automatisch den Use Cases zuzuordnen (UCCA).', + legalBasis: 'Art. 30 DSGVO (Verzeichnis von Verarbeitungstaetigkeiten)', + inputs: ['companyProfile'], + outputs: ['useCases'], + prerequisiteSteps: ['company-profile'], + dbTables: ['ucca_assessments', 'ucca_findings', 'ucca_controls'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_ce'], + ragPurpose: 'CE-Regulierungen fuer Use-Case Matching', + isOptional: false, + url: '/sdk/use-cases', + }, + { + id: 'import', + name: 'Dokument-Import', + nameShort: 'Import', + package: 'vorbereitung', + seq: 400, + description: 'Import bestehender Compliance-Dokumente (Datenschutzerklaerungen, TOMs, VVTs).', + descriptionLong: 'Optionaler Schritt zum Import bereits vorhandener Compliance-Dokumente. Der Document Crawler analysiert hochgeladene PDFs, Word-Dokumente oder bestehende Datenschutzerklaerungen und extrahiert automatisch relevante Informationen wie bestehende TOMs, Verarbeitungsverzeichnisse oder Risikoanalysen. Diese importierten Daten werden als Grundlage fuer die nachfolgenden Schritte verwendet, damit nicht alles von Null aufgebaut werden muss.', + inputs: ['useCases'], + outputs: ['importedDocuments'], + prerequisiteSteps: ['use-case-assessment'], + dbTables: ['compliance_imported_documents', 'compliance_gap_analyses'], + dbMode: 'read/write', + ragCollections: [], + isOptional: true, + url: '/sdk/import', + }, + { + id: 'screening', + name: 'System Screening', + nameShort: 'Screening', + package: 'vorbereitung', + seq: 500, + checkpointId: 'CP-SCAN', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Technische Analyse der eingesetzten Software, Dienste und deren Abhaengigkeiten.', + descriptionLong: 'Das System Screening analysiert die technische Infrastruktur des Unternehmens. Es werden alle eingesetzten Software-Systeme, Cloud-Dienste, APIs und deren Abhaengigkeiten erfasst. Dabei wird auch eine SBOM (Software Bill of Materials) erstellt, die alle Drittanbieter-Komponenten und deren Lizenzen dokumentiert. Das Screening identifiziert potenzielle Compliance-Risiken wie Datentransfers in Drittlaender, unsichere Abhaengigkeiten oder fehlende Verschluesselung.', + inputs: ['useCases'], + outputs: ['screening', 'sbom'], + prerequisiteSteps: ['use-case-assessment'], + dbTables: ['compliance_screenings', 'compliance_security_issues'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/screening', + }, + { + id: 'modules', + name: 'Compliance Modules', + nameShort: 'Module', + package: 'vorbereitung', + seq: 600, + checkpointId: 'CP-MOD', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Aktivierung der relevanten Compliance-Module basierend auf Screening-Ergebnissen.', + descriptionLong: 'Basierend auf dem Unternehmensprofil und den Screening-Ergebnissen werden die relevanten Compliance-Module aktiviert. Module umfassen z.B. DSGVO-Grundschutz, AI Act, NIS2, ePrivacy, Whistleblower-Richtlinie usw. Die RAG-Collection bp_compliance_gesetze wird verwendet, um aktuelle Gesetzestexte den Modulen zuzuordnen. Nur aktivierte Module erzeugen in den nachfolgenden Schritten Anforderungen, Controls und Dokumentation.', + inputs: ['companyProfile', 'screening'], + outputs: ['modules'], + prerequisiteSteps: ['screening'], + dbTables: ['compliance_service_modules', 'sdk_states'], + dbMode: 'read/write', + ragCollections: ['bp_compliance_gesetze'], + ragPurpose: 'Regulierungen den Modulen zuordnen', + isOptional: false, + url: '/sdk/modules', + }, + { + id: 'source-policy', + name: 'Source Policy', + nameShort: 'Quellen', + package: 'vorbereitung', + seq: 700, + checkpointId: 'CP-SPOL', + checkpointType: 'REQUIRED', + checkpointReviewer: 'NONE', + description: 'Festlegung der Rechtsquellen und Normen fuer die Compliance-Analyse.', + descriptionLong: 'Die Source Policy definiert, welche Rechtsquellen und Normen fuer die Compliance-Analyse herangezogen werden. Dies umfasst EU-Verordnungen (DSGVO, AI Act, NIS2), nationale Gesetze (BDSG, TTDSG), Branchenstandards (ISO 27001, BSI Grundschutz) und interne Richtlinien. Die Source Policy stellt sicher, dass alle nachfolgenden Schritte konsistent auf denselben Rechtsgrundlagen basieren.', + inputs: ['modules'], + outputs: ['sourcePolicy'], + prerequisiteSteps: ['modules'], + dbTables: ['compliance_allowed_sources', 'compliance_pii_rules', 'compliance_source_operations', 'compliance_source_policy_audit'], + dbMode: 'read/write', + ragCollections: [], + isOptional: false, + url: '/sdk/source-policy', + }, +] diff --git a/admin-compliance/app/sdk/sdk-flow/types.ts b/admin-compliance/app/sdk/sdk-flow/types.ts new file mode 100644 index 0000000..97653ef --- /dev/null +++ b/admin-compliance/app/sdk/sdk-flow/types.ts @@ -0,0 +1,75 @@ +/** + * SDK Flow — Shared Types and Package Metadata + */ + +export interface SDKFlowStep { + id: string + name: string + nameShort: string + package: 'vorbereitung' | 'analyse' | 'dokumentation' | 'rechtliche-texte' | 'betrieb' + seq: number + checkpointId?: string + checkpointType?: 'REQUIRED' | 'RECOMMENDED' + checkpointReviewer?: 'NONE' | 'DSB' | 'LEGAL' + + // Beschreibung + description: string + descriptionLong: string + legalBasis?: string + + // Datenfluss + inputs: string[] + outputs: string[] + prerequisiteSteps: string[] + + // Infrastruktur + dbTables: string[] + dbMode: 'read' | 'write' | 'read/write' | 'none' + ragCollections: string[] + ragPurpose?: string + + // Generierung + generates?: string[] + isOptional?: boolean + url: string + + /** + * Fertigstellungsgrad in Prozent (0–100). + * Nur für Betrieb-Module gesetzt (außer academy/training). + * Berechnung: Frontend-Reifegrad + Backend-Persistenz + API-Abdeckung. + */ + completion?: number +} + +export const FLOW_PACKAGES = { + vorbereitung: { + name: 'Vorbereitung', + nameShort: 'Vorb.', + icon: '🎯', + color: { bg: '#dbeafe', border: '#3b82f6', text: '#1e40af' }, + }, + analyse: { + name: 'Analyse', + nameShort: 'Analyse', + icon: '🔍', + color: { bg: '#fef3c7', border: '#f59e0b', text: '#92400e' }, + }, + dokumentation: { + name: 'Dokumentation', + nameShort: 'Doku', + icon: '📋', + color: { bg: '#ede9fe', border: '#7c3aed', text: '#5b21b6' }, + }, + 'rechtliche-texte': { + name: 'Rechtliche Texte', + nameShort: 'Legal', + icon: '📝', + color: { bg: '#d1fae5', border: '#10b981', text: '#065f46' }, + }, + betrieb: { + name: 'Betrieb', + nameShort: 'Betrieb', + icon: '⚙️', + color: { bg: '#f1f5f9', border: '#64748b', text: '#334155' }, + }, +} as const diff --git a/admin-compliance/lib/sdk/catalog-manager/catalog-registry.ts b/admin-compliance/lib/sdk/catalog-manager/catalog-registry.ts index 5306524..648a655 100644 --- a/admin-compliance/lib/sdk/catalog-manager/catalog-registry.ts +++ b/admin-compliance/lib/sdk/catalog-manager/catalog-registry.ts @@ -1,734 +1,12 @@ /** * SDK Catalog Manager - Central Registry - * - * Maps all SDK catalogs to a unified interface for browsing, searching, and CRUD. + * + * Barrel re-export — split into domain modules under registry/. + * Do NOT import directly from registry/ sub-files in consumers; + * always import from this barrel to preserve the stable public path. */ -import type { - CatalogId, - CatalogMeta, - CatalogModule, - CatalogEntry, - CatalogStats, - CatalogOverviewStats, - CustomCatalogEntry, - CustomCatalogs, -} from './types' - -// ============================================================================= -// CATALOG DATA IMPORTS -// ============================================================================= - -import { RISK_CATALOG } from '../dsfa/risk-catalog' -import { MITIGATION_LIBRARY } from '../dsfa/mitigation-library' -import { AI_RISK_CATALOG } from '../dsfa/ai-risk-catalog' -import { AI_MITIGATION_LIBRARY } from '../dsfa/ai-mitigation-library' -import { PROHIBITED_AI_PRACTICES } from '../dsfa/prohibited-ai-practices' -import { EU_BASE_FRAMEWORKS, NATIONAL_FRAMEWORKS } from '../dsfa/eu-legal-frameworks' -import { GDPR_ENFORCEMENT_CASES } from '../dsfa/gdpr-enforcement-cases' -import { WP248_CRITERIA, SDM_GOALS, DSFA_AUTHORITY_RESOURCES } from '../dsfa/types' -import { VVT_BASELINE_CATALOG } from '../vvt-baseline-catalog' -import { BASELINE_TEMPLATES } from '../loeschfristen-baseline-catalog' -import { VENDOR_TEMPLATES, COUNTRY_RISK_PROFILES } from '../vendor-compliance/catalog/vendor-templates' -import { LEGAL_BASIS_INFO, STANDARD_RETENTION_PERIODS } from '../vendor-compliance/catalog/legal-basis' - -// ============================================================================= -// HELPER: Resolve localized text fields -// ============================================================================= - -function resolveField(value: unknown): string { - if (value === null || value === undefined) return '' - if (typeof value === 'string') return value - if (typeof value === 'number') return String(value) - if (typeof value === 'object' && 'de' in (value as Record)) { - return String((value as Record).de || '') - } - return String(value) -} - -// ============================================================================= -// SDM_GOALS as entries array (it's a Record, not an array) -// ============================================================================= - -const SDM_GOALS_ENTRIES = Object.entries(SDM_GOALS).map(([key, val]) => ({ - id: key, - name: val.name, - description: val.description, - article: val.article, -})) - -// ============================================================================= -// CATALOG REGISTRY -// ============================================================================= - -export const CATALOG_REGISTRY: Record = { - 'dsfa-risks': { - id: 'dsfa-risks', - name: 'DSFA Risikokatalog', - description: 'Standardrisiken fuer Datenschutz-Folgenabschaetzungen', - module: 'dsfa', - icon: 'ShieldAlert', - systemCount: RISK_CATALOG.length, - allowCustom: true, - idField: 'id', - nameField: 'title', - descriptionField: 'description', - categoryField: 'category', - fields: [ - { key: 'id', label: 'Risiko-ID', type: 'text', required: true, placeholder: 'R-XXX-01' }, - { key: 'title', label: 'Titel', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'category', label: 'Kategorie', type: 'select', required: true, options: [ - { value: 'confidentiality', label: 'Vertraulichkeit' }, - { value: 'integrity', label: 'Integritaet' }, - { value: 'availability', label: 'Verfuegbarkeit' }, - { value: 'rights_freedoms', label: 'Rechte & Freiheiten' }, - ]}, - { key: 'typicalLikelihood', label: 'Typische Eintrittswahrscheinlichkeit', type: 'select', required: false, options: [ - { value: 'low', label: 'Niedrig' }, - { value: 'medium', label: 'Mittel' }, - { value: 'high', label: 'Hoch' }, - ]}, - { key: 'typicalImpact', label: 'Typische Auswirkung', type: 'select', required: false, options: [ - { value: 'low', label: 'Niedrig' }, - { value: 'medium', label: 'Mittel' }, - { value: 'high', label: 'Hoch' }, - ]}, - ], - searchableFields: ['id', 'title', 'description', 'category'], - }, - - 'dsfa-mitigations': { - id: 'dsfa-mitigations', - name: 'DSFA Massnahmenbibliothek', - description: 'Technische und organisatorische Massnahmen fuer DSFAs', - module: 'dsfa', - icon: 'Shield', - systemCount: MITIGATION_LIBRARY.length, - allowCustom: true, - idField: 'id', - nameField: 'title', - descriptionField: 'description', - categoryField: 'type', - fields: [ - { key: 'id', label: 'Massnahmen-ID', type: 'text', required: true, placeholder: 'M-XXX-01' }, - { key: 'title', label: 'Titel', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'type', label: 'Typ', type: 'select', required: true, options: [ - { value: 'technical', label: 'Technisch' }, - { value: 'organizational', label: 'Organisatorisch' }, - { value: 'legal', label: 'Rechtlich' }, - ]}, - { key: 'effectiveness', label: 'Wirksamkeit', type: 'select', required: false, options: [ - { value: 'low', label: 'Niedrig' }, - { value: 'medium', label: 'Mittel' }, - { value: 'high', label: 'Hoch' }, - ]}, - { key: 'legalBasis', label: 'Rechtsgrundlage', type: 'text', required: false }, - ], - searchableFields: ['id', 'title', 'description', 'type', 'legalBasis'], - }, - - 'ai-risks': { - id: 'ai-risks', - name: 'KI-Risikokatalog', - description: 'Spezifische Risiken fuer KI-Systeme', - module: 'ai_act', - icon: 'Bot', - systemCount: AI_RISK_CATALOG.length, - allowCustom: true, - idField: 'id', - nameField: 'title', - descriptionField: 'description', - categoryField: 'category', - fields: [ - { key: 'id', label: 'Risiko-ID', type: 'text', required: true, placeholder: 'R-AI-XXX-01' }, - { key: 'title', label: 'Titel', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'category', label: 'Kategorie', type: 'select', required: true, options: [ - { value: 'confidentiality', label: 'Vertraulichkeit' }, - { value: 'integrity', label: 'Integritaet' }, - { value: 'availability', label: 'Verfuegbarkeit' }, - { value: 'rights_freedoms', label: 'Rechte & Freiheiten' }, - ]}, - { key: 'typicalLikelihood', label: 'Eintrittswahrscheinlichkeit', type: 'select', required: false, options: [ - { value: 'low', label: 'Niedrig' }, - { value: 'medium', label: 'Mittel' }, - { value: 'high', label: 'Hoch' }, - ]}, - { key: 'typicalImpact', label: 'Auswirkung', type: 'select', required: false, options: [ - { value: 'low', label: 'Niedrig' }, - { value: 'medium', label: 'Mittel' }, - { value: 'high', label: 'Hoch' }, - ]}, - ], - searchableFields: ['id', 'title', 'description', 'category'], - }, - - 'ai-mitigations': { - id: 'ai-mitigations', - name: 'KI-Massnahmenbibliothek', - description: 'Massnahmen fuer KI-spezifische Risiken', - module: 'ai_act', - icon: 'ShieldCheck', - systemCount: AI_MITIGATION_LIBRARY.length, - allowCustom: true, - idField: 'id', - nameField: 'title', - descriptionField: 'description', - categoryField: 'type', - fields: [ - { key: 'id', label: 'Massnahmen-ID', type: 'text', required: true }, - { key: 'title', label: 'Titel', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'type', label: 'Typ', type: 'select', required: true, options: [ - { value: 'technical', label: 'Technisch' }, - { value: 'organizational', label: 'Organisatorisch' }, - { value: 'legal', label: 'Rechtlich' }, - ]}, - { key: 'effectiveness', label: 'Wirksamkeit', type: 'select', required: false, options: [ - { value: 'low', label: 'Niedrig' }, - { value: 'medium', label: 'Mittel' }, - { value: 'high', label: 'Hoch' }, - ]}, - ], - searchableFields: ['id', 'title', 'description', 'type'], - }, - - 'prohibited-ai-practices': { - id: 'prohibited-ai-practices', - name: 'Verbotene KI-Praktiken', - description: 'Absolut und bedingt verbotene KI-Anwendungen nach AI Act', - module: 'ai_act', - icon: 'Ban', - systemCount: PROHIBITED_AI_PRACTICES.length, - allowCustom: false, - idField: 'id', - nameField: 'title', - descriptionField: 'description', - categoryField: 'severity', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'title', label: 'Titel', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'severity', label: 'Schwere', type: 'select', required: true, options: [ - { value: 'absolute', label: 'Absolutes Verbot' }, - { value: 'conditional', label: 'Bedingtes Verbot' }, - ]}, - { key: 'legalBasis', label: 'Rechtsgrundlage', type: 'text', required: false }, - ], - searchableFields: ['id', 'title', 'description', 'severity', 'legalBasis'], - }, - - 'vvt-templates': { - id: 'vvt-templates', - name: 'VVT Baseline-Vorlagen', - description: 'Vorlagen fuer Verarbeitungstaetigkeiten', - module: 'vvt', - icon: 'FileText', - systemCount: VVT_BASELINE_CATALOG.length, - allowCustom: true, - idField: 'templateId', - nameField: 'name', - descriptionField: 'description', - categoryField: 'businessFunction', - fields: [ - { key: 'templateId', label: 'Vorlagen-ID', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'businessFunction', label: 'Geschaeftsbereich', type: 'select', required: true, options: [ - { value: 'hr', label: 'Personal' }, - { value: 'finance', label: 'Finanzen' }, - { value: 'sales', label: 'Vertrieb' }, - { value: 'marketing', label: 'Marketing' }, - { value: 'support', label: 'Support' }, - { value: 'it', label: 'IT' }, - { value: 'other', label: 'Sonstige' }, - ]}, - { key: 'protectionLevel', label: 'Schutzniveau', type: 'select', required: false, options: [ - { value: 'LOW', label: 'Niedrig' }, - { value: 'MEDIUM', label: 'Mittel' }, - { value: 'HIGH', label: 'Hoch' }, - ]}, - ], - searchableFields: ['templateId', 'name', 'description', 'businessFunction'], - }, - - 'loeschfristen-templates': { - id: 'loeschfristen-templates', - name: 'Loeschfristen-Vorlagen', - description: 'Baseline-Vorlagen fuer Aufbewahrungsfristen', - module: 'vvt', - icon: 'Clock', - systemCount: BASELINE_TEMPLATES.length, - allowCustom: true, - idField: 'templateId', - nameField: 'dataObjectName', - descriptionField: 'description', - categoryField: 'retentionDriver', - fields: [ - { key: 'templateId', label: 'Vorlagen-ID', type: 'text', required: true }, - { key: 'dataObjectName', label: 'Datenobjekt', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'retentionDuration', label: 'Aufbewahrungsdauer', type: 'number', required: true, min: 0 }, - { key: 'retentionUnit', label: 'Einheit', type: 'select', required: true, options: [ - { value: 'days', label: 'Tage' }, - { value: 'months', label: 'Monate' }, - { value: 'years', label: 'Jahre' }, - ]}, - { key: 'deletionMethod', label: 'Loeschmethode', type: 'text', required: false }, - { key: 'responsibleRole', label: 'Verantwortlich', type: 'text', required: false }, - ], - searchableFields: ['templateId', 'dataObjectName', 'description', 'retentionDriver'], - }, - - 'vendor-templates': { - id: 'vendor-templates', - name: 'AV-Vorlagen', - description: 'Vorlagen fuer Auftragsverarbeitungsvertraege', - module: 'vendor', - icon: 'Building2', - systemCount: VENDOR_TEMPLATES.length, - allowCustom: true, - idField: 'id', - nameField: 'name', - descriptionField: 'description', - categoryField: 'serviceCategory', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'serviceCategory', label: 'Dienstleistungskategorie', type: 'select', required: true, options: [ - { value: 'HOSTING', label: 'Hosting' }, - { value: 'CLOUD_INFRASTRUCTURE', label: 'Cloud-Infrastruktur' }, - { value: 'ANALYTICS', label: 'Analyse' }, - { value: 'CRM', label: 'CRM' }, - { value: 'ERP', label: 'ERP' }, - { value: 'HR_SOFTWARE', label: 'HR-Software' }, - { value: 'PAYMENT', label: 'Zahlungsdienstleister' }, - { value: 'EMAIL', label: 'E-Mail' }, - { value: 'MARKETING', label: 'Marketing' }, - { value: 'SUPPORT', label: 'Support' }, - { value: 'SECURITY', label: 'Sicherheit' }, - { value: 'COMMUNICATION', label: 'Kommunikation' }, - { value: 'STORAGE', label: 'Speicher' }, - { value: 'BACKUP', label: 'Backup' }, - { value: 'CDN', label: 'CDN' }, - { value: 'ACCOUNTING', label: 'Buchhaltung' }, - { value: 'CONSULTING', label: 'Beratung' }, - { value: 'OTHER', label: 'Sonstige' }, - ]}, - { key: 'suggestedRole', label: 'Vorgeschlagene Rolle', type: 'select', required: false, options: [ - { value: 'PROCESSOR', label: 'Auftragsverarbeiter' }, - { value: 'JOINT_CONTROLLER', label: 'Gemeinsam Verantwortlicher' }, - { value: 'CONTROLLER', label: 'Eigenstaendiger Verantwortlicher' }, - { value: 'SUB_PROCESSOR', label: 'Unterauftragnehmer' }, - { value: 'THIRD_PARTY', label: 'Dritter' }, - ]}, - { key: 'suggestedDataAccess', label: 'Datenzugriff', type: 'select', required: false, options: [ - { value: 'NONE', label: 'Kein Zugriff' }, - { value: 'POTENTIAL', label: 'Potenzieller Zugriff' }, - { value: 'ADMINISTRATIVE', label: 'Administrativer Zugriff' }, - { value: 'CONTENT', label: 'Inhaltlicher Zugriff' }, - ]}, - { key: 'suggestedTransferMechanisms', label: 'Transfer-Mechanismen', type: 'multiselect', required: false, options: [ - { value: 'ADEQUACY_DECISION', label: 'Angemessenheitsbeschluss' }, - { value: 'SCC_CONTROLLER', label: 'SCC Controller-to-Controller' }, - { value: 'SCC_PROCESSOR', label: 'SCC Controller-to-Processor' }, - { value: 'BCR', label: 'Binding Corporate Rules' }, - { value: 'DEROGATION_CONSENT', label: 'Einwilligung' }, - { value: 'DEROGATION_CONTRACT', label: 'Vertragserfuellung' }, - { value: 'CERTIFICATION', label: 'Zertifizierung' }, - { value: 'CODE_OF_CONDUCT', label: 'Verhaltensregeln' }, - ]}, - { key: 'suggestedContractTypes', label: 'Vertragstypen', type: 'multiselect', required: false, options: [ - { value: 'AVV', label: 'AVV (Auftragsverarbeitung)' }, - { value: 'MSA', label: 'MSA (Master Service)' }, - { value: 'SLA', label: 'SLA (Service Level)' }, - { value: 'SCC', label: 'SCC (Standardvertragsklauseln)' }, - { value: 'NDA', label: 'NDA (Geheimhaltung)' }, - { value: 'TOM_ANNEX', label: 'TOM-Anlage' }, - { value: 'CERTIFICATION', label: 'Zertifikat' }, - { value: 'SUB_PROCESSOR_LIST', label: 'Unterauftragnehmer-Liste' }, - ]}, - { key: 'typicalDataCategories', label: 'Typische Datenkategorien', type: 'multiselect', required: false, options: [ - { value: 'NAME', label: 'Name' }, - { value: 'CONTACT', label: 'Kontaktdaten' }, - { value: 'ADDRESS', label: 'Adressdaten' }, - { value: 'DOB', label: 'Geburtsdatum' }, - { value: 'BANK_ACCOUNT', label: 'Bankverbindung' }, - { value: 'PAYMENT_DATA', label: 'Zahlungsdaten' }, - { value: 'EMPLOYMENT_DATA', label: 'Beschaeftigungsdaten' }, - { value: 'SALARY_DATA', label: 'Gehaltsdaten' }, - { value: 'HEALTH_DATA', label: 'Gesundheitsdaten' }, - { value: 'IP_ADDRESS', label: 'IP-Adresse' }, - { value: 'USAGE_DATA', label: 'Nutzungsdaten' }, - { value: 'LOCATION_DATA', label: 'Standortdaten' }, - { value: 'COMMUNICATION_DATA', label: 'Kommunikationsdaten' }, - ]}, - { key: 'typicalCertifications', label: 'Typische Zertifizierungen', type: 'tags', required: false, placeholder: 'z.B. ISO 27001, SOC 2, C5' }, - { key: 'commonProviders', label: 'Typische Anbieter', type: 'tags', required: false, placeholder: 'z.B. AWS, Azure, GCP' }, - ], - searchableFields: ['id', 'name', 'description', 'serviceCategory', 'suggestedRole', 'commonProviders'], - }, - - 'country-risk-profiles': { - id: 'country-risk-profiles', - name: 'Laenderrisikoprofile', - description: 'Datenschutz-Risikobewertung nach Laendern', - module: 'vendor', - icon: 'Globe', - systemCount: COUNTRY_RISK_PROFILES.length, - allowCustom: false, - idField: 'code', - nameField: 'name', - categoryField: 'riskLevel', - fields: [ - { key: 'code', label: 'Laendercode', type: 'text', required: true }, - { key: 'name', label: 'Land', type: 'text', required: true }, - { key: 'riskLevel', label: 'Risikostufe', type: 'select', required: true, options: [ - { value: 'LOW', label: 'Niedrig' }, - { value: 'MEDIUM', label: 'Mittel' }, - { value: 'HIGH', label: 'Hoch' }, - { value: 'VERY_HIGH', label: 'Sehr hoch' }, - ]}, - { key: 'isEU', label: 'EU-Mitglied', type: 'boolean', required: false }, - { key: 'isEEA', label: 'EWR-Mitglied', type: 'boolean', required: false }, - { key: 'hasAdequacyDecision', label: 'Angemessenheitsbeschluss', type: 'boolean', required: false }, - ], - searchableFields: ['code', 'name', 'riskLevel'], - }, - - 'legal-bases': { - id: 'legal-bases', - name: 'Rechtsgrundlagen', - description: 'DSGVO Art. 6 und Art. 9 Rechtsgrundlagen', - module: 'reference', - icon: 'Scale', - systemCount: LEGAL_BASIS_INFO.length, - allowCustom: false, - idField: 'type', - nameField: 'name', - descriptionField: 'description', - categoryField: 'article', - fields: [ - { key: 'type', label: 'Typ', type: 'text', required: true }, - { key: 'article', label: 'Artikel', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'isSpecialCategory', label: 'Besondere Kategorie (Art. 9)', type: 'boolean', required: false }, - ], - searchableFields: ['type', 'article', 'name', 'description'], - }, - - 'retention-periods': { - id: 'retention-periods', - name: 'Aufbewahrungsfristen', - description: 'Gesetzliche Standard-Aufbewahrungsfristen', - module: 'reference', - icon: 'Timer', - systemCount: STANDARD_RETENTION_PERIODS.length, - allowCustom: false, - idField: 'id', - nameField: 'name', - descriptionField: 'description', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'legalBasis', label: 'Rechtsgrundlage', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - ], - searchableFields: ['id', 'name', 'legalBasis', 'description'], - }, - - 'eu-legal-frameworks': { - id: 'eu-legal-frameworks', - name: 'EU-Rechtsrahmen', - description: 'EU-weite Datenschutzgesetze und -verordnungen', - module: 'reference', - icon: 'Landmark', - systemCount: EU_BASE_FRAMEWORKS.length, - allowCustom: false, - idField: 'id', - nameField: 'name', - descriptionField: 'description', - categoryField: 'type', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'fullName', label: 'Vollstaendiger Name', type: 'text', required: true }, - { key: 'type', label: 'Typ', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - ], - searchableFields: ['id', 'name', 'fullName', 'description', 'type'], - }, - - 'national-legal-frameworks': { - id: 'national-legal-frameworks', - name: 'Nationale Rechtsrahmen', - description: 'Nationale Datenschutzgesetze der EU/EWR-Staaten', - module: 'reference', - icon: 'Flag', - systemCount: NATIONAL_FRAMEWORKS.length, - allowCustom: false, - idField: 'id', - nameField: 'name', - descriptionField: 'description', - categoryField: 'countryCode', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'countryCode', label: 'Land', type: 'text', required: true }, - { key: 'type', label: 'Typ', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - ], - searchableFields: ['id', 'name', 'countryCode', 'description', 'type'], - }, - - 'gdpr-enforcement-cases': { - id: 'gdpr-enforcement-cases', - name: 'DSGVO-Bussgeldentscheidungen', - description: 'Relevante Bussgeldentscheidungen als Referenz', - module: 'reference', - icon: 'Gavel', - systemCount: GDPR_ENFORCEMENT_CASES.length, - allowCustom: false, - idField: 'id', - nameField: 'company', - descriptionField: 'description', - categoryField: 'country', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'company', label: 'Unternehmen', type: 'text', required: true }, - { key: 'country', label: 'Land', type: 'text', required: true }, - { key: 'year', label: 'Jahr', type: 'number', required: true }, - { key: 'fineOriginal', label: 'Bussgeld (EUR)', type: 'number', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - ], - searchableFields: ['id', 'company', 'country', 'description'], - }, - - 'wp248-criteria': { - id: 'wp248-criteria', - name: 'WP248 Kriterien', - description: 'Kriterien zur DSFA-Pflichtpruefung nach WP248', - module: 'dsfa', - icon: 'ClipboardCheck', - systemCount: WP248_CRITERIA.length, - allowCustom: false, - idField: 'code', - nameField: 'title', - descriptionField: 'description', - fields: [ - { key: 'code', label: 'Code', type: 'text', required: true }, - { key: 'title', label: 'Titel', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'gdprRef', label: 'DSGVO-Referenz', type: 'text', required: false }, - ], - searchableFields: ['code', 'title', 'description', 'gdprRef'], - }, - - 'sdm-goals': { - id: 'sdm-goals', - name: 'SDM Gewaehrleistungsziele', - description: 'Standard-Datenschutzmodell Gewaehrleistungsziele', - module: 'dsfa', - icon: 'Target', - systemCount: SDM_GOALS_ENTRIES.length, - allowCustom: false, - idField: 'id', - nameField: 'name', - descriptionField: 'description', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'name', label: 'Name', type: 'text', required: true }, - { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, - { key: 'article', label: 'DSGVO-Artikel', type: 'text', required: false }, - ], - searchableFields: ['id', 'name', 'description', 'article'], - }, - - 'dsfa-authority-resources': { - id: 'dsfa-authority-resources', - name: 'Aufsichtsbehoerden-Ressourcen', - description: 'DSFA-Ressourcen der deutschen Aufsichtsbehoerden', - module: 'dsfa', - icon: 'Building', - systemCount: DSFA_AUTHORITY_RESOURCES.length, - allowCustom: false, - idField: 'id', - nameField: 'shortName', - descriptionField: 'name', - categoryField: 'state', - fields: [ - { key: 'id', label: 'ID', type: 'text', required: true }, - { key: 'shortName', label: 'Kurzname', type: 'text', required: true }, - { key: 'name', label: 'Voller Name', type: 'text', required: true }, - { key: 'state', label: 'Bundesland', type: 'text', required: true }, - ], - searchableFields: ['id', 'shortName', 'name', 'state'], - }, -} - -// ============================================================================= -// SYSTEM ENTRIES MAP -// ============================================================================= - -const SYSTEM_ENTRIES_MAP: Record[]> = { - 'dsfa-risks': RISK_CATALOG as unknown as Record[], - 'dsfa-mitigations': MITIGATION_LIBRARY as unknown as Record[], - 'ai-risks': AI_RISK_CATALOG as unknown as Record[], - 'ai-mitigations': AI_MITIGATION_LIBRARY as unknown as Record[], - 'prohibited-ai-practices': PROHIBITED_AI_PRACTICES as unknown as Record[], - 'vvt-templates': VVT_BASELINE_CATALOG as unknown as Record[], - 'loeschfristen-templates': BASELINE_TEMPLATES as unknown as Record[], - 'vendor-templates': VENDOR_TEMPLATES as unknown as Record[], - 'country-risk-profiles': COUNTRY_RISK_PROFILES as unknown as Record[], - 'legal-bases': LEGAL_BASIS_INFO as unknown as Record[], - 'retention-periods': STANDARD_RETENTION_PERIODS as unknown as Record[], - 'eu-legal-frameworks': EU_BASE_FRAMEWORKS as unknown as Record[], - 'national-legal-frameworks': NATIONAL_FRAMEWORKS as unknown as Record[], - 'gdpr-enforcement-cases': GDPR_ENFORCEMENT_CASES as unknown as Record[], - 'wp248-criteria': WP248_CRITERIA as unknown as Record[], - 'sdm-goals': SDM_GOALS_ENTRIES as unknown as Record[], - 'dsfa-authority-resources': DSFA_AUTHORITY_RESOURCES as unknown as Record[], -} - -// ============================================================================= -// ENTRY CONVERTERS -// ============================================================================= - -function systemEntryToCatalogEntry( - catalogId: CatalogId, - data: Record, -): CatalogEntry { - const meta = CATALOG_REGISTRY[catalogId] - const idValue = resolveField(data[meta.idField]) - const nameValue = resolveField(data[meta.nameField]) - const descValue = meta.descriptionField ? resolveField(data[meta.descriptionField]) : undefined - const catValue = meta.categoryField ? resolveField(data[meta.categoryField]) : undefined - - return { - id: idValue || crypto.randomUUID(), - catalogId, - source: 'system', - data, - displayName: nameValue || idValue || '(Unbenannt)', - displayDescription: descValue, - category: catValue, - } -} - -function customEntryToCatalogEntry( - catalogId: CatalogId, - entry: CustomCatalogEntry, -): CatalogEntry { - const meta = CATALOG_REGISTRY[catalogId] - const nameValue = resolveField(entry.data[meta.nameField]) - const descValue = meta.descriptionField ? resolveField(entry.data[meta.descriptionField]) : undefined - const catValue = meta.categoryField ? resolveField(entry.data[meta.categoryField]) : undefined - - return { - id: entry.id, - catalogId, - source: 'custom', - data: entry.data, - displayName: nameValue || '(Unbenannt)', - displayDescription: descValue, - category: catValue, - } -} - -// ============================================================================= -// PUBLIC API -// ============================================================================= - -export function getSystemEntries(catalogId: CatalogId): CatalogEntry[] { - const raw = SYSTEM_ENTRIES_MAP[catalogId] || [] - return raw.map(data => systemEntryToCatalogEntry(catalogId, data)) -} - -export function getAllEntries( - catalogId: CatalogId, - customEntries: CustomCatalogEntry[] = [], -): CatalogEntry[] { - const system = getSystemEntries(catalogId) - const custom = customEntries.map(e => customEntryToCatalogEntry(catalogId, e)) - return [...system, ...custom] -} - -export function getCatalogsByModule(module: CatalogModule): CatalogMeta[] { - return Object.values(CATALOG_REGISTRY).filter(c => c.module === module) -} - -export function getCatalogStats( - catalogId: CatalogId, - customEntries: CustomCatalogEntry[] = [], -): CatalogStats { - const meta = CATALOG_REGISTRY[catalogId] - return { - catalogId, - systemCount: meta.systemCount, - customCount: customEntries.length, - totalCount: meta.systemCount + customEntries.length, - } -} - -export function getOverviewStats(customCatalogs: CustomCatalogs): CatalogOverviewStats { - const modules: CatalogModule[] = ['dsfa', 'vvt', 'vendor', 'ai_act', 'reference'] - const byModule = {} as Record - - let totalSystemEntries = 0 - let totalCustomEntries = 0 - - for (const mod of modules) { - const cats = getCatalogsByModule(mod) - let entries = 0 - for (const cat of cats) { - const customCount = customCatalogs[cat.id]?.length ?? 0 - entries += cat.systemCount + customCount - totalSystemEntries += cat.systemCount - totalCustomEntries += customCount - } - byModule[mod] = { catalogs: cats.length, entries } - } - - return { - totalCatalogs: Object.keys(CATALOG_REGISTRY).length, - totalSystemEntries, - totalCustomEntries, - totalEntries: totalSystemEntries + totalCustomEntries, - byModule, - } -} - -export function searchCatalog( - catalogId: CatalogId, - query: string, - customEntries: CustomCatalogEntry[] = [], -): CatalogEntry[] { - const allEntries = getAllEntries(catalogId, customEntries) - const meta = CATALOG_REGISTRY[catalogId] - const q = query.toLowerCase().trim() - - if (!q) return allEntries - - return allEntries - .map(entry => { - let score = 0 - for (const field of meta.searchableFields) { - const value = resolveField(entry.data[field]).toLowerCase() - if (value.includes(q)) { - score += value.startsWith(q) ? 10 : 5 - } - } - // Also search display name - if (entry.displayName.toLowerCase().includes(q)) { - score += 15 - } - return { entry, score } - }) - .filter(r => r.score > 0) - .sort((a, b) => b.score - a.score) - .map(r => r.entry) -} +export * from './registry/registry-dsfa' +export * from './registry/registry-vendor' +export * from './registry/registry-reference' +export * from './registry/registry-api' diff --git a/admin-compliance/lib/sdk/catalog-manager/registry/registry-api.ts b/admin-compliance/lib/sdk/catalog-manager/registry/registry-api.ts new file mode 100644 index 0000000..fd3f206 --- /dev/null +++ b/admin-compliance/lib/sdk/catalog-manager/registry/registry-api.ts @@ -0,0 +1,190 @@ +/** + * Catalog Registry — Public API, Entry Converters & Registry Assembly + */ + +import type { + CatalogId, + CatalogMeta, + CatalogModule, + CatalogEntry, + CatalogStats, + CatalogOverviewStats, + CustomCatalogEntry, + CustomCatalogs, +} from '../types' +import { DSFA_AI_CATALOG_META, DSFA_AI_SYSTEM_ENTRIES } from './registry-dsfa' +import { VENDOR_VVT_CATALOG_META, VENDOR_VVT_SYSTEM_ENTRIES } from './registry-vendor' +import { REFERENCE_CATALOG_META, REFERENCE_SYSTEM_ENTRIES } from './registry-reference' + +// ============================================================================= +// CATALOG REGISTRY (assembled from sub-registries) +// ============================================================================= + +export const CATALOG_REGISTRY: Record = { + ...DSFA_AI_CATALOG_META, + ...VENDOR_VVT_CATALOG_META, + ...REFERENCE_CATALOG_META, +} as Record + +// ============================================================================= +// SYSTEM ENTRIES MAP (assembled from sub-registries) +// ============================================================================= + +const SYSTEM_ENTRIES_MAP: Record[]> = { + ...DSFA_AI_SYSTEM_ENTRIES, + ...VENDOR_VVT_SYSTEM_ENTRIES, + ...REFERENCE_SYSTEM_ENTRIES, +} as Record[]> + +// ============================================================================= +// HELPER: Resolve localized text fields +// ============================================================================= + +function resolveField(value: unknown): string { + if (value === null || value === undefined) return '' + if (typeof value === 'string') return value + if (typeof value === 'number') return String(value) + if (typeof value === 'object' && 'de' in (value as Record)) { + return String((value as Record).de || '') + } + return String(value) +} + +// ============================================================================= +// ENTRY CONVERTERS +// ============================================================================= + +function systemEntryToCatalogEntry( + catalogId: CatalogId, + data: Record, +): CatalogEntry { + const meta = CATALOG_REGISTRY[catalogId] + const idValue = resolveField(data[meta.idField]) + const nameValue = resolveField(data[meta.nameField]) + const descValue = meta.descriptionField ? resolveField(data[meta.descriptionField]) : undefined + const catValue = meta.categoryField ? resolveField(data[meta.categoryField]) : undefined + + return { + id: idValue || crypto.randomUUID(), + catalogId, + source: 'system', + data, + displayName: nameValue || idValue || '(Unbenannt)', + displayDescription: descValue, + category: catValue, + } +} + +function customEntryToCatalogEntry( + catalogId: CatalogId, + entry: CustomCatalogEntry, +): CatalogEntry { + const meta = CATALOG_REGISTRY[catalogId] + const nameValue = resolveField(entry.data[meta.nameField]) + const descValue = meta.descriptionField ? resolveField(entry.data[meta.descriptionField]) : undefined + const catValue = meta.categoryField ? resolveField(entry.data[meta.categoryField]) : undefined + + return { + id: entry.id, + catalogId, + source: 'custom', + data: entry.data, + displayName: nameValue || '(Unbenannt)', + displayDescription: descValue, + category: catValue, + } +} + +// ============================================================================= +// PUBLIC API +// ============================================================================= + +export function getSystemEntries(catalogId: CatalogId): CatalogEntry[] { + const raw = SYSTEM_ENTRIES_MAP[catalogId] || [] + return raw.map(data => systemEntryToCatalogEntry(catalogId, data)) +} + +export function getAllEntries( + catalogId: CatalogId, + customEntries: CustomCatalogEntry[] = [], +): CatalogEntry[] { + const system = getSystemEntries(catalogId) + const custom = customEntries.map(e => customEntryToCatalogEntry(catalogId, e)) + return [...system, ...custom] +} + +export function getCatalogsByModule(module: CatalogModule): CatalogMeta[] { + return Object.values(CATALOG_REGISTRY).filter(c => c.module === module) +} + +export function getCatalogStats( + catalogId: CatalogId, + customEntries: CustomCatalogEntry[] = [], +): CatalogStats { + const meta = CATALOG_REGISTRY[catalogId] + return { + catalogId, + systemCount: meta.systemCount, + customCount: customEntries.length, + totalCount: meta.systemCount + customEntries.length, + } +} + +export function getOverviewStats(customCatalogs: CustomCatalogs): CatalogOverviewStats { + const modules: CatalogModule[] = ['dsfa', 'vvt', 'vendor', 'ai_act', 'reference'] + const byModule = {} as Record + + let totalSystemEntries = 0 + let totalCustomEntries = 0 + + for (const mod of modules) { + const cats = getCatalogsByModule(mod) + let entries = 0 + for (const cat of cats) { + const customCount = customCatalogs[cat.id]?.length ?? 0 + entries += cat.systemCount + customCount + totalSystemEntries += cat.systemCount + totalCustomEntries += customCount + } + byModule[mod] = { catalogs: cats.length, entries } + } + + return { + totalCatalogs: Object.keys(CATALOG_REGISTRY).length, + totalSystemEntries, + totalCustomEntries, + totalEntries: totalSystemEntries + totalCustomEntries, + byModule, + } +} + +export function searchCatalog( + catalogId: CatalogId, + query: string, + customEntries: CustomCatalogEntry[] = [], +): CatalogEntry[] { + const allEntries = getAllEntries(catalogId, customEntries) + const meta = CATALOG_REGISTRY[catalogId] + const q = query.toLowerCase().trim() + + if (!q) return allEntries + + return allEntries + .map(entry => { + let score = 0 + for (const field of meta.searchableFields) { + const value = resolveField(entry.data[field]).toLowerCase() + if (value.includes(q)) { + score += value.startsWith(q) ? 10 : 5 + } + } + // Also search display name + if (entry.displayName.toLowerCase().includes(q)) { + score += 15 + } + return { entry, score } + }) + .filter(r => r.score > 0) + .sort((a, b) => b.score - a.score) + .map(r => r.entry) +} diff --git a/admin-compliance/lib/sdk/catalog-manager/registry/registry-dsfa.ts b/admin-compliance/lib/sdk/catalog-manager/registry/registry-dsfa.ts new file mode 100644 index 0000000..7f6acaf --- /dev/null +++ b/admin-compliance/lib/sdk/catalog-manager/registry/registry-dsfa.ts @@ -0,0 +1,250 @@ +/** + * Catalog Registry — DSFA & AI Act Catalogs + */ + +import type { CatalogId, CatalogMeta } from '../types' +import { RISK_CATALOG } from '../../dsfa/risk-catalog' +import { MITIGATION_LIBRARY } from '../../dsfa/mitigation-library' +import { AI_RISK_CATALOG } from '../../dsfa/ai-risk-catalog' +import { AI_MITIGATION_LIBRARY } from '../../dsfa/ai-mitigation-library' +import { PROHIBITED_AI_PRACTICES } from '../../dsfa/prohibited-ai-practices' +import { WP248_CRITERIA, SDM_GOALS, DSFA_AUTHORITY_RESOURCES } from '../../dsfa/types' + +export const SDM_GOALS_ENTRIES = Object.entries(SDM_GOALS).map(([key, val]) => ({ + id: key, + name: val.name, + description: val.description, + article: val.article, +})) + +export const DSFA_AI_CATALOG_META: Partial> = { + 'dsfa-risks': { + id: 'dsfa-risks', + name: 'DSFA Risikokatalog', + description: 'Standardrisiken fuer Datenschutz-Folgenabschaetzungen', + module: 'dsfa', + icon: 'ShieldAlert', + systemCount: RISK_CATALOG.length, + allowCustom: true, + idField: 'id', + nameField: 'title', + descriptionField: 'description', + categoryField: 'category', + fields: [ + { key: 'id', label: 'Risiko-ID', type: 'text', required: true, placeholder: 'R-XXX-01' }, + { key: 'title', label: 'Titel', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'category', label: 'Kategorie', type: 'select', required: true, options: [ + { value: 'confidentiality', label: 'Vertraulichkeit' }, + { value: 'integrity', label: 'Integritaet' }, + { value: 'availability', label: 'Verfuegbarkeit' }, + { value: 'rights_freedoms', label: 'Rechte & Freiheiten' }, + ]}, + { key: 'typicalLikelihood', label: 'Typische Eintrittswahrscheinlichkeit', type: 'select', required: false, options: [ + { value: 'low', label: 'Niedrig' }, + { value: 'medium', label: 'Mittel' }, + { value: 'high', label: 'Hoch' }, + ]}, + { key: 'typicalImpact', label: 'Typische Auswirkung', type: 'select', required: false, options: [ + { value: 'low', label: 'Niedrig' }, + { value: 'medium', label: 'Mittel' }, + { value: 'high', label: 'Hoch' }, + ]}, + ], + searchableFields: ['id', 'title', 'description', 'category'], + }, + + 'dsfa-mitigations': { + id: 'dsfa-mitigations', + name: 'DSFA Massnahmenbibliothek', + description: 'Technische und organisatorische Massnahmen fuer DSFAs', + module: 'dsfa', + icon: 'Shield', + systemCount: MITIGATION_LIBRARY.length, + allowCustom: true, + idField: 'id', + nameField: 'title', + descriptionField: 'description', + categoryField: 'type', + fields: [ + { key: 'id', label: 'Massnahmen-ID', type: 'text', required: true, placeholder: 'M-XXX-01' }, + { key: 'title', label: 'Titel', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'type', label: 'Typ', type: 'select', required: true, options: [ + { value: 'technical', label: 'Technisch' }, + { value: 'organizational', label: 'Organisatorisch' }, + { value: 'legal', label: 'Rechtlich' }, + ]}, + { key: 'effectiveness', label: 'Wirksamkeit', type: 'select', required: false, options: [ + { value: 'low', label: 'Niedrig' }, + { value: 'medium', label: 'Mittel' }, + { value: 'high', label: 'Hoch' }, + ]}, + { key: 'legalBasis', label: 'Rechtsgrundlage', type: 'text', required: false }, + ], + searchableFields: ['id', 'title', 'description', 'type', 'legalBasis'], + }, + + 'ai-risks': { + id: 'ai-risks', + name: 'KI-Risikokatalog', + description: 'Spezifische Risiken fuer KI-Systeme', + module: 'ai_act', + icon: 'Bot', + systemCount: AI_RISK_CATALOG.length, + allowCustom: true, + idField: 'id', + nameField: 'title', + descriptionField: 'description', + categoryField: 'category', + fields: [ + { key: 'id', label: 'Risiko-ID', type: 'text', required: true, placeholder: 'R-AI-XXX-01' }, + { key: 'title', label: 'Titel', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'category', label: 'Kategorie', type: 'select', required: true, options: [ + { value: 'confidentiality', label: 'Vertraulichkeit' }, + { value: 'integrity', label: 'Integritaet' }, + { value: 'availability', label: 'Verfuegbarkeit' }, + { value: 'rights_freedoms', label: 'Rechte & Freiheiten' }, + ]}, + { key: 'typicalLikelihood', label: 'Eintrittswahrscheinlichkeit', type: 'select', required: false, options: [ + { value: 'low', label: 'Niedrig' }, + { value: 'medium', label: 'Mittel' }, + { value: 'high', label: 'Hoch' }, + ]}, + { key: 'typicalImpact', label: 'Auswirkung', type: 'select', required: false, options: [ + { value: 'low', label: 'Niedrig' }, + { value: 'medium', label: 'Mittel' }, + { value: 'high', label: 'Hoch' }, + ]}, + ], + searchableFields: ['id', 'title', 'description', 'category'], + }, + + 'ai-mitigations': { + id: 'ai-mitigations', + name: 'KI-Massnahmenbibliothek', + description: 'Massnahmen fuer KI-spezifische Risiken', + module: 'ai_act', + icon: 'ShieldCheck', + systemCount: AI_MITIGATION_LIBRARY.length, + allowCustom: true, + idField: 'id', + nameField: 'title', + descriptionField: 'description', + categoryField: 'type', + fields: [ + { key: 'id', label: 'Massnahmen-ID', type: 'text', required: true }, + { key: 'title', label: 'Titel', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'type', label: 'Typ', type: 'select', required: true, options: [ + { value: 'technical', label: 'Technisch' }, + { value: 'organizational', label: 'Organisatorisch' }, + { value: 'legal', label: 'Rechtlich' }, + ]}, + { key: 'effectiveness', label: 'Wirksamkeit', type: 'select', required: false, options: [ + { value: 'low', label: 'Niedrig' }, + { value: 'medium', label: 'Mittel' }, + { value: 'high', label: 'Hoch' }, + ]}, + ], + searchableFields: ['id', 'title', 'description', 'type'], + }, + + 'prohibited-ai-practices': { + id: 'prohibited-ai-practices', + name: 'Verbotene KI-Praktiken', + description: 'Absolut und bedingt verbotene KI-Anwendungen nach AI Act', + module: 'ai_act', + icon: 'Ban', + systemCount: PROHIBITED_AI_PRACTICES.length, + allowCustom: false, + idField: 'id', + nameField: 'title', + descriptionField: 'description', + categoryField: 'severity', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'title', label: 'Titel', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'severity', label: 'Schwere', type: 'select', required: true, options: [ + { value: 'absolute', label: 'Absolutes Verbot' }, + { value: 'conditional', label: 'Bedingtes Verbot' }, + ]}, + { key: 'legalBasis', label: 'Rechtsgrundlage', type: 'text', required: false }, + ], + searchableFields: ['id', 'title', 'description', 'severity', 'legalBasis'], + }, + + 'wp248-criteria': { + id: 'wp248-criteria', + name: 'WP248 Kriterien', + description: 'Kriterien zur DSFA-Pflichtpruefung nach WP248', + module: 'dsfa', + icon: 'ClipboardCheck', + systemCount: WP248_CRITERIA.length, + allowCustom: false, + idField: 'code', + nameField: 'title', + descriptionField: 'description', + fields: [ + { key: 'code', label: 'Code', type: 'text', required: true }, + { key: 'title', label: 'Titel', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'gdprRef', label: 'DSGVO-Referenz', type: 'text', required: false }, + ], + searchableFields: ['code', 'title', 'description', 'gdprRef'], + }, + + 'sdm-goals': { + id: 'sdm-goals', + name: 'SDM Gewaehrleistungsziele', + description: 'Standard-Datenschutzmodell Gewaehrleistungsziele', + module: 'dsfa', + icon: 'Target', + systemCount: SDM_GOALS_ENTRIES.length, + allowCustom: false, + idField: 'id', + nameField: 'name', + descriptionField: 'description', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'article', label: 'DSGVO-Artikel', type: 'text', required: false }, + ], + searchableFields: ['id', 'name', 'description', 'article'], + }, + + 'dsfa-authority-resources': { + id: 'dsfa-authority-resources', + name: 'Aufsichtsbehoerden-Ressourcen', + description: 'DSFA-Ressourcen der deutschen Aufsichtsbehoerden', + module: 'dsfa', + icon: 'Building', + systemCount: DSFA_AUTHORITY_RESOURCES.length, + allowCustom: false, + idField: 'id', + nameField: 'shortName', + descriptionField: 'name', + categoryField: 'state', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'shortName', label: 'Kurzname', type: 'text', required: true }, + { key: 'name', label: 'Voller Name', type: 'text', required: true }, + { key: 'state', label: 'Bundesland', type: 'text', required: true }, + ], + searchableFields: ['id', 'shortName', 'name', 'state'], + }, +} + +export const DSFA_AI_SYSTEM_ENTRIES: Partial[]>> = { + 'dsfa-risks': RISK_CATALOG as unknown as Record[], + 'dsfa-mitigations': MITIGATION_LIBRARY as unknown as Record[], + 'ai-risks': AI_RISK_CATALOG as unknown as Record[], + 'ai-mitigations': AI_MITIGATION_LIBRARY as unknown as Record[], + 'prohibited-ai-practices': PROHIBITED_AI_PRACTICES as unknown as Record[], + 'wp248-criteria': WP248_CRITERIA as unknown as Record[], + 'sdm-goals': SDM_GOALS_ENTRIES as unknown as Record[], + 'dsfa-authority-resources': DSFA_AUTHORITY_RESOURCES as unknown as Record[], +} diff --git a/admin-compliance/lib/sdk/catalog-manager/registry/registry-reference.ts b/admin-compliance/lib/sdk/catalog-manager/registry/registry-reference.ts new file mode 100644 index 0000000..c986e30 --- /dev/null +++ b/admin-compliance/lib/sdk/catalog-manager/registry/registry-reference.ts @@ -0,0 +1,127 @@ +/** + * Catalog Registry — Reference Catalogs (Legal Bases, Frameworks, Enforcement) + */ + +import type { CatalogId, CatalogMeta } from '../types' +import { EU_BASE_FRAMEWORKS, NATIONAL_FRAMEWORKS } from '../../dsfa/eu-legal-frameworks' +import { GDPR_ENFORCEMENT_CASES } from '../../dsfa/gdpr-enforcement-cases' +import { LEGAL_BASIS_INFO, STANDARD_RETENTION_PERIODS } from '../../vendor-compliance/catalog/legal-basis' + +export const REFERENCE_CATALOG_META: Partial> = { + 'legal-bases': { + id: 'legal-bases', + name: 'Rechtsgrundlagen', + description: 'DSGVO Art. 6 und Art. 9 Rechtsgrundlagen', + module: 'reference', + icon: 'Scale', + systemCount: LEGAL_BASIS_INFO.length, + allowCustom: false, + idField: 'type', + nameField: 'name', + descriptionField: 'description', + categoryField: 'article', + fields: [ + { key: 'type', label: 'Typ', type: 'text', required: true }, + { key: 'article', label: 'Artikel', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'isSpecialCategory', label: 'Besondere Kategorie (Art. 9)', type: 'boolean', required: false }, + ], + searchableFields: ['type', 'article', 'name', 'description'], + }, + + 'retention-periods': { + id: 'retention-periods', + name: 'Aufbewahrungsfristen', + description: 'Gesetzliche Standard-Aufbewahrungsfristen', + module: 'reference', + icon: 'Timer', + systemCount: STANDARD_RETENTION_PERIODS.length, + allowCustom: false, + idField: 'id', + nameField: 'name', + descriptionField: 'description', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'legalBasis', label: 'Rechtsgrundlage', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + ], + searchableFields: ['id', 'name', 'legalBasis', 'description'], + }, + + 'eu-legal-frameworks': { + id: 'eu-legal-frameworks', + name: 'EU-Rechtsrahmen', + description: 'EU-weite Datenschutzgesetze und -verordnungen', + module: 'reference', + icon: 'Landmark', + systemCount: EU_BASE_FRAMEWORKS.length, + allowCustom: false, + idField: 'id', + nameField: 'name', + descriptionField: 'description', + categoryField: 'type', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'fullName', label: 'Vollstaendiger Name', type: 'text', required: true }, + { key: 'type', label: 'Typ', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + ], + searchableFields: ['id', 'name', 'fullName', 'description', 'type'], + }, + + 'national-legal-frameworks': { + id: 'national-legal-frameworks', + name: 'Nationale Rechtsrahmen', + description: 'Nationale Datenschutzgesetze der EU/EWR-Staaten', + module: 'reference', + icon: 'Flag', + systemCount: NATIONAL_FRAMEWORKS.length, + allowCustom: false, + idField: 'id', + nameField: 'name', + descriptionField: 'description', + categoryField: 'countryCode', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'countryCode', label: 'Land', type: 'text', required: true }, + { key: 'type', label: 'Typ', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + ], + searchableFields: ['id', 'name', 'countryCode', 'description', 'type'], + }, + + 'gdpr-enforcement-cases': { + id: 'gdpr-enforcement-cases', + name: 'DSGVO-Bussgeldentscheidungen', + description: 'Relevante Bussgeldentscheidungen als Referenz', + module: 'reference', + icon: 'Gavel', + systemCount: GDPR_ENFORCEMENT_CASES.length, + allowCustom: false, + idField: 'id', + nameField: 'company', + descriptionField: 'description', + categoryField: 'country', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'company', label: 'Unternehmen', type: 'text', required: true }, + { key: 'country', label: 'Land', type: 'text', required: true }, + { key: 'year', label: 'Jahr', type: 'number', required: true }, + { key: 'fineOriginal', label: 'Bussgeld (EUR)', type: 'number', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + ], + searchableFields: ['id', 'company', 'country', 'description'], + }, +} + +export const REFERENCE_SYSTEM_ENTRIES: Partial[]>> = { + 'legal-bases': LEGAL_BASIS_INFO as unknown as Record[], + 'retention-periods': STANDARD_RETENTION_PERIODS as unknown as Record[], + 'eu-legal-frameworks': EU_BASE_FRAMEWORKS as unknown as Record[], + 'national-legal-frameworks': NATIONAL_FRAMEWORKS as unknown as Record[], + 'gdpr-enforcement-cases': GDPR_ENFORCEMENT_CASES as unknown as Record[], +} diff --git a/admin-compliance/lib/sdk/catalog-manager/registry/registry-vendor.ts b/admin-compliance/lib/sdk/catalog-manager/registry/registry-vendor.ts new file mode 100644 index 0000000..e841d63 --- /dev/null +++ b/admin-compliance/lib/sdk/catalog-manager/registry/registry-vendor.ts @@ -0,0 +1,159 @@ +/** + * Catalog Registry — Vendor, VVT & Loeschfristen Catalogs + */ + +import type { CatalogId, CatalogMeta } from '../types' +import { VVT_BASELINE_CATALOG } from '../../vvt-baseline-catalog' +import { BASELINE_TEMPLATES } from '../../loeschfristen-baseline-catalog' +import { VENDOR_TEMPLATES, COUNTRY_RISK_PROFILES } from '../../vendor-compliance/catalog/vendor-templates' + +export const VENDOR_VVT_CATALOG_META: Partial> = { + 'vvt-templates': { + id: 'vvt-templates', + name: 'VVT Baseline-Vorlagen', + description: 'Vorlagen fuer Verarbeitungstaetigkeiten', + module: 'vvt', + icon: 'FileText', + systemCount: VVT_BASELINE_CATALOG.length, + allowCustom: true, + idField: 'templateId', + nameField: 'name', + descriptionField: 'description', + categoryField: 'businessFunction', + fields: [ + { key: 'templateId', label: 'Vorlagen-ID', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'businessFunction', label: 'Geschaeftsbereich', type: 'select', required: true, options: [ + { value: 'hr', label: 'Personal' }, + { value: 'finance', label: 'Finanzen' }, + { value: 'sales', label: 'Vertrieb' }, + { value: 'marketing', label: 'Marketing' }, + { value: 'support', label: 'Support' }, + { value: 'it', label: 'IT' }, + { value: 'other', label: 'Sonstige' }, + ]}, + { key: 'protectionLevel', label: 'Schutzniveau', type: 'select', required: false, options: [ + { value: 'LOW', label: 'Niedrig' }, + { value: 'MEDIUM', label: 'Mittel' }, + { value: 'HIGH', label: 'Hoch' }, + ]}, + ], + searchableFields: ['templateId', 'name', 'description', 'businessFunction'], + }, + + 'loeschfristen-templates': { + id: 'loeschfristen-templates', + name: 'Loeschfristen-Vorlagen', + description: 'Baseline-Vorlagen fuer Aufbewahrungsfristen', + module: 'vvt', + icon: 'Clock', + systemCount: BASELINE_TEMPLATES.length, + allowCustom: true, + idField: 'templateId', + nameField: 'dataObjectName', + descriptionField: 'description', + categoryField: 'retentionDriver', + fields: [ + { key: 'templateId', label: 'Vorlagen-ID', type: 'text', required: true }, + { key: 'dataObjectName', label: 'Datenobjekt', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'retentionDuration', label: 'Aufbewahrungsdauer', type: 'number', required: true, min: 0 }, + { key: 'retentionUnit', label: 'Einheit', type: 'select', required: true, options: [ + { value: 'days', label: 'Tage' }, + { value: 'months', label: 'Monate' }, + { value: 'years', label: 'Jahre' }, + ]}, + { key: 'deletionMethod', label: 'Loeschmethode', type: 'text', required: false }, + { key: 'responsibleRole', label: 'Verantwortlich', type: 'text', required: false }, + ], + searchableFields: ['templateId', 'dataObjectName', 'description', 'retentionDriver'], + }, + + 'vendor-templates': { + id: 'vendor-templates', + name: 'AV-Vorlagen', + description: 'Vorlagen fuer Auftragsverarbeitungsvertraege', + module: 'vendor', + icon: 'Building2', + systemCount: VENDOR_TEMPLATES.length, + allowCustom: true, + idField: 'id', + nameField: 'name', + descriptionField: 'description', + categoryField: 'serviceCategory', + fields: [ + { key: 'id', label: 'ID', type: 'text', required: true }, + { key: 'name', label: 'Name', type: 'text', required: true }, + { key: 'description', label: 'Beschreibung', type: 'textarea', required: true }, + { key: 'serviceCategory', label: 'Dienstleistungskategorie', type: 'select', required: true, options: [ + { value: 'HOSTING', label: 'Hosting' }, + { value: 'CLOUD_INFRASTRUCTURE', label: 'Cloud-Infrastruktur' }, + { value: 'ANALYTICS', label: 'Analyse' }, + { value: 'CRM', label: 'CRM' }, + { value: 'ERP', label: 'ERP' }, + { value: 'HR_SOFTWARE', label: 'HR-Software' }, + { value: 'PAYMENT', label: 'Zahlungsdienstleister' }, + { value: 'EMAIL', label: 'E-Mail' }, + { value: 'MARKETING', label: 'Marketing' }, + { value: 'SUPPORT', label: 'Support' }, + { value: 'SECURITY', label: 'Sicherheit' }, + { value: 'COMMUNICATION', label: 'Kommunikation' }, + { value: 'STORAGE', label: 'Speicher' }, + { value: 'BACKUP', label: 'Backup' }, + { value: 'CDN', label: 'CDN' }, + { value: 'ACCOUNTING', label: 'Buchhaltung' }, + { value: 'CONSULTING', label: 'Beratung' }, + { value: 'OTHER', label: 'Sonstige' }, + ]}, + { key: 'suggestedRole', label: 'Vorgeschlagene Rolle', type: 'select', required: false, options: [ + { value: 'PROCESSOR', label: 'Auftragsverarbeiter' }, + { value: 'JOINT_CONTROLLER', label: 'Gemeinsam Verantwortlicher' }, + { value: 'CONTROLLER', label: 'Eigenstaendiger Verantwortlicher' }, + { value: 'SUB_PROCESSOR', label: 'Unterauftragnehmer' }, + { value: 'THIRD_PARTY', label: 'Dritter' }, + ]}, + { key: 'suggestedDataAccess', label: 'Datenzugriff', type: 'select', required: false, options: [ + { value: 'NONE', label: 'Kein Zugriff' }, + { value: 'POTENTIAL', label: 'Potenzieller Zugriff' }, + { value: 'ADMINISTRATIVE', label: 'Administrativer Zugriff' }, + { value: 'CONTENT', label: 'Inhaltlicher Zugriff' }, + ]}, + ], + searchableFields: ['id', 'name', 'description', 'serviceCategory', 'suggestedRole', 'commonProviders'], + }, + + 'country-risk-profiles': { + id: 'country-risk-profiles', + name: 'Laenderrisikoprofile', + description: 'Datenschutz-Risikobewertung nach Laendern', + module: 'vendor', + icon: 'Globe', + systemCount: COUNTRY_RISK_PROFILES.length, + allowCustom: false, + idField: 'code', + nameField: 'name', + categoryField: 'riskLevel', + fields: [ + { key: 'code', label: 'Laendercode', type: 'text', required: true }, + { key: 'name', label: 'Land', type: 'text', required: true }, + { key: 'riskLevel', label: 'Risikostufe', type: 'select', required: true, options: [ + { value: 'LOW', label: 'Niedrig' }, + { value: 'MEDIUM', label: 'Mittel' }, + { value: 'HIGH', label: 'Hoch' }, + { value: 'VERY_HIGH', label: 'Sehr hoch' }, + ]}, + { key: 'isEU', label: 'EU-Mitglied', type: 'boolean', required: false }, + { key: 'isEEA', label: 'EWR-Mitglied', type: 'boolean', required: false }, + { key: 'hasAdequacyDecision', label: 'Angemessenheitsbeschluss', type: 'boolean', required: false }, + ], + searchableFields: ['code', 'name', 'riskLevel'], + }, +} + +export const VENDOR_VVT_SYSTEM_ENTRIES: Partial[]>> = { + 'vvt-templates': VVT_BASELINE_CATALOG as unknown as Record[], + 'loeschfristen-templates': BASELINE_TEMPLATES as unknown as Record[], + 'vendor-templates': VENDOR_TEMPLATES as unknown as Record[], + 'country-risk-profiles': COUNTRY_RISK_PROFILES as unknown as Record[], +} diff --git a/admin-compliance/lib/sdk/compliance-scope-triggers.ts b/admin-compliance/lib/sdk/compliance-scope-triggers.ts index 56539f2..522d7ca 100644 --- a/admin-compliance/lib/sdk/compliance-scope-triggers.ts +++ b/admin-compliance/lib/sdk/compliance-scope-triggers.ts @@ -1,823 +1,15 @@ /** - * 50 Hard Trigger Rules — data table. - * - * This file legitimately exceeds 500 LOC because it is a pure data - * definition with no logic. Splitting it further would hurt readability. + * 50 Hard Trigger Rules — barrel re-export. + * Implementation split into compliance-scope-triggers/ */ import type { HardTriggerRule } from './compliance-scope-types' +import { HARD_TRIGGER_RULES_A_E } from './compliance-scope-triggers/triggers-a-e' +import { HARD_TRIGGER_RULES_F_M } from './compliance-scope-triggers/triggers-f-m' -// ============================================================================ -// 50 HARD TRIGGER RULES -// ============================================================================ +export { HARD_TRIGGER_RULES_A_E } from './compliance-scope-triggers/triggers-a-e' +export { HARD_TRIGGER_RULES_F_M } from './compliance-scope-triggers/triggers-f-m' export const HARD_TRIGGER_RULES: HardTriggerRule[] = [ - // ========== A: Art. 9 Besondere Kategorien (9 rules) ========== - { - id: 'HT-A01', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'gesundheit', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung von Gesundheitsdaten', - }, - { - id: 'HT-A02', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'biometrie', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung biometrischer Daten zur eindeutigen Identifizierung', - }, - { - id: 'HT-A03', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'genetik', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung genetischer Daten', - }, - { - id: 'HT-A04', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'politisch', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung politischer Meinungen', - }, - { - id: 'HT-A05', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'religion', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung religiöser oder weltanschaulicher Überzeugungen', - }, - { - id: 'HT-A06', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'gewerkschaft', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung von Gewerkschaftszugehörigkeit', - }, - { - id: 'HT-A07', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'sexualleben', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung von Daten zum Sexualleben oder zur sexuellen Orientierung', - }, - { - id: 'HT-A08', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'strafrechtlich', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 10 DSGVO', - description: 'Verarbeitung strafrechtlicher Verurteilungen', - }, - { - id: 'HT-A09', - category: 'art9', - questionId: 'data_art9', - condition: 'CONTAINS', - conditionValue: 'ethnisch', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 Abs. 1 DSGVO', - description: 'Verarbeitung der rassischen oder ethnischen Herkunft', - }, - - // ========== B: Vulnerable Gruppen (3 rules) ========== - { - id: 'HT-B01', - category: 'vulnerable', - questionId: 'data_minors', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'DSE'], - legalReference: 'Art. 8 DSGVO', - description: 'Verarbeitung von Daten Minderjähriger', - }, - { - id: 'HT-B02', - category: 'vulnerable', - questionId: 'data_minors', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L4', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'DSE'], - legalReference: 'Art. 8 + Art. 9 DSGVO', - description: 'Verarbeitung besonderer Kategorien von Daten Minderjähriger', - combineWithArt9: true, - }, - { - id: 'HT-B03', - category: 'vulnerable', - questionId: 'data_minors', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L4', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'AI_ACT_DOKU'], - legalReference: 'Art. 8 DSGVO + AI Act', - description: 'KI-gestützte Verarbeitung von Daten Minderjähriger', - combineWithAI: true, - }, - - // ========== C: ADM/KI (6 rules) ========== - { - id: 'HT-C01', - category: 'adm', - questionId: 'proc_adm_scoring', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 22 DSGVO', - description: 'Automatisierte Einzelentscheidung mit Rechtswirkung oder erheblicher Beeinträchtigung', - }, - { - id: 'HT-C02', - category: 'adm', - questionId: 'proc_ai_usage', - condition: 'CONTAINS', - conditionValue: 'autonom', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'AI_ACT_DOKU'], - legalReference: 'Art. 22 DSGVO + AI Act', - description: 'Autonome KI-Systeme mit Entscheidungsbefugnis', - }, - { - id: 'HT-C03', - category: 'adm', - questionId: 'proc_ai_usage', - condition: 'CONTAINS', - conditionValue: 'scoring', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM'], - legalReference: 'Art. 22 DSGVO', - description: 'KI-gestütztes Scoring', - }, - { - id: 'HT-C04', - category: 'adm', - questionId: 'proc_ai_usage', - condition: 'CONTAINS', - conditionValue: 'profiling', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 22 DSGVO', - description: 'KI-gestütztes Profiling mit erheblicher Wirkung', - }, - { - id: 'HT-C05', - category: 'adm', - questionId: 'proc_ai_usage', - condition: 'CONTAINS', - conditionValue: 'generativ', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'AI_ACT_DOKU'], - legalReference: 'AI Act', - description: 'Generative KI-Systeme', - }, - { - id: 'HT-C06', - category: 'adm', - questionId: 'proc_ai_usage', - condition: 'CONTAINS', - conditionValue: 'chatbot', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'AI_ACT_DOKU'], - legalReference: 'AI Act', - description: 'Chatbots mit Personendatenverarbeitung', - }, - - // ========== D: Überwachung (5 rules) ========== - { - id: 'HT-D01', - category: 'surveillance', - questionId: 'proc_video_surveillance', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'DSE'], - legalReference: 'Art. 6 DSGVO', - description: 'Videoüberwachung', - }, - { - id: 'HT-D02', - category: 'surveillance', - questionId: 'proc_employee_monitoring', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 88 DSGVO + BetrVG', - description: 'Mitarbeiterüberwachung', - }, - { - id: 'HT-D03', - category: 'surveillance', - questionId: 'proc_tracking', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'COOKIE_BANNER', 'EINWILLIGUNGEN'], - legalReference: 'Art. 6 DSGVO + ePrivacy', - description: 'Online-Tracking', - }, - { - id: 'HT-D04', - category: 'surveillance', - questionId: 'proc_video_surveillance', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 35 Abs. 3 DSGVO', - description: 'Videoüberwachung kombiniert mit Mitarbeitermonitoring', - combineWithEmployeeMonitoring: true, - }, - { - id: 'HT-D05', - category: 'surveillance', - questionId: 'proc_video_surveillance', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 35 Abs. 3 DSGVO', - description: 'Videoüberwachung kombiniert mit automatisierter Bewertung', - combineWithADM: true, - }, - - // ========== E: Drittland (5 rules) ========== - { - id: 'HT-E01', - category: 'third_country', - questionId: 'tech_third_country', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TRANSFER_DOKU'], - legalReference: 'Art. 44 ff. DSGVO', - description: 'Datenübermittlung in Drittland', - }, - { - id: 'HT-E02', - category: 'third_country', - questionId: 'tech_hosting_location', - condition: 'EQUALS', - conditionValue: 'drittland', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'TRANSFER_DOKU'], - legalReference: 'Art. 44 ff. DSGVO', - description: 'Hosting in Drittland', - }, - { - id: 'HT-E03', - category: 'third_country', - questionId: 'tech_hosting_location', - condition: 'EQUALS', - conditionValue: 'us_adequacy', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TRANSFER_DOKU'], - legalReference: 'Art. 45 DSGVO', - description: 'Hosting in USA mit Angemessenheitsbeschluss', - }, - { - id: 'HT-E04', - category: 'third_country', - questionId: 'tech_third_country', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'TRANSFER_DOKU', 'DSFA'], - legalReference: 'Art. 44 ff. + Art. 9 DSGVO', - description: 'Drittlandtransfer besonderer Kategorien', - combineWithArt9: true, - }, - { - id: 'HT-E05', - category: 'third_country', - questionId: 'tech_third_country', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'TRANSFER_DOKU', 'DSFA'], - legalReference: 'Art. 44 ff. + Art. 8 DSGVO', - description: 'Drittlandtransfer von Daten Minderjähriger', - combineWithMinors: true, - }, - - // ========== F: Zertifizierung (5 rules) ========== - { - id: 'HT-F01', - category: 'certification', - questionId: 'org_cert_target', - condition: 'CONTAINS', - conditionValue: 'ISO27001', - minimumLevel: 'L4', - requiresDSFA: false, - mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST'], - legalReference: 'ISO/IEC 27001', - description: 'Angestrebte ISO 27001 Zertifizierung', - }, - { - id: 'HT-F02', - category: 'certification', - questionId: 'org_cert_target', - condition: 'CONTAINS', - conditionValue: 'ISO27701', - minimumLevel: 'L4', - requiresDSFA: false, - mandatoryDocuments: ['TOM', 'VVT', 'AUDIT_CHECKLIST'], - legalReference: 'ISO/IEC 27701', - description: 'Angestrebte ISO 27701 Zertifizierung', - }, - { - id: 'HT-F03', - category: 'certification', - questionId: 'org_cert_target', - condition: 'CONTAINS', - conditionValue: 'SOC2', - minimumLevel: 'L4', - requiresDSFA: false, - mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST'], - legalReference: 'SOC 2 Type II', - description: 'Angestrebte SOC 2 Zertifizierung', - }, - { - id: 'HT-F04', - category: 'certification', - questionId: 'org_cert_target', - condition: 'CONTAINS', - conditionValue: 'TISAX', - minimumLevel: 'L4', - requiresDSFA: false, - mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST', 'VENDOR_MANAGEMENT'], - legalReference: 'TISAX', - description: 'Angestrebte TISAX Zertifizierung', - }, - { - id: 'HT-F05', - category: 'certification', - questionId: 'org_cert_target', - condition: 'CONTAINS', - conditionValue: 'BSI-Grundschutz', - minimumLevel: 'L4', - requiresDSFA: false, - mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST'], - legalReference: 'BSI IT-Grundschutz', - description: 'Angestrebte BSI-Grundschutz Zertifizierung', - }, - - // ========== G: Volumen/Skala (5 rules) ========== - { - id: 'HT-G01', - category: 'scale', - questionId: 'data_volume', - condition: 'EQUALS', - conditionValue: '>1000000', - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'LOESCHKONZEPT'], - legalReference: 'Art. 35 Abs. 3 lit. b DSGVO', - description: 'Umfangreiche Verarbeitung personenbezogener Daten (>1 Mio. Datensätze)', - }, - { - id: 'HT-G02', - category: 'scale', - questionId: 'data_volume', - condition: 'EQUALS', - conditionValue: '100000-1000000', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM'], - legalReference: 'Art. 35 Abs. 3 lit. b DSGVO', - description: 'Großvolumige Datenverarbeitung (100k-1M Datensätze)', - }, - { - id: 'HT-G03', - category: 'scale', - questionId: 'org_customer_count', - condition: 'EQUALS', - conditionValue: '100000+', - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'DSR_PROZESS'], - legalReference: 'Art. 15-22 DSGVO', - description: 'Großer Kundenstamm (>100k) mit hoher Betroffenenanzahl', - }, - { - id: 'HT-G04', - category: 'scale', - questionId: 'org_employee_count', - condition: 'GREATER_THAN', - conditionValue: 249, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'LOESCHKONZEPT', 'NOTFALLPLAN'], - legalReference: 'Art. 37 DSGVO', - description: 'Große Organisation (>250 Mitarbeiter) mit erhöhten Compliance-Anforderungen', - }, - { - id: 'HT-G05', - category: 'scale', - questionId: 'org_employee_count', - condition: 'GREATER_THAN', - conditionValue: 999, - minimumLevel: 'L4', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'LOESCHKONZEPT'], - legalReference: 'Art. 35 + Art. 37 DSGVO', - description: 'Sehr große Organisation (>1000 Mitarbeiter) mit Art. 9 Daten', - combineWithArt9: true, - }, - - // ========== H: Produkt/Business (7 rules) ========== - { - id: 'HT-H01a', - category: 'product', - questionId: 'prod_webshop', - condition: 'EQUALS', - conditionValue: true, - excludeWhen: { questionId: 'org_business_model', value: 'B2B' }, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['DSE', 'AGB', 'COOKIE_BANNER', 'EINWILLIGUNGEN', - 'WIDERRUFSBELEHRUNG', 'PREISANGABEN', 'FERNABSATZ_INFO', 'STREITBEILEGUNG'], - legalReference: 'Art. 6 DSGVO + Fernabsatzrecht + PAngV + VSBG', - description: 'E-Commerce / Webshop (B2C) — Verbraucherschutzpflichten', - }, - { - id: 'HT-H01b', - category: 'product', - questionId: 'prod_webshop', - condition: 'EQUALS', - conditionValue: true, - requireWhen: { questionId: 'org_business_model', value: 'B2B' }, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['DSE', 'AGB', 'COOKIE_BANNER'], - legalReference: 'Art. 6 DSGVO + eCommerce', - description: 'E-Commerce / Webshop (B2B) — Basis-Pflichten', - }, - { - id: 'HT-H02', - category: 'product', - questionId: 'prod_data_broker', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'EINWILLIGUNGEN'], - legalReference: 'Art. 35 Abs. 3 DSGVO', - description: 'Datenhandel oder Datenmakler-Tätigkeit', - }, - { - id: 'HT-H03', - category: 'product', - questionId: 'prod_api_external', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TOM', 'AVV'], - legalReference: 'Art. 28 DSGVO', - description: 'Externe API mit Datenweitergabe', - }, - { - id: 'HT-H04', - category: 'product', - questionId: 'org_business_model', - condition: 'EQUALS', - conditionValue: 'b2c', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['DSE', 'COOKIE_BANNER', 'EINWILLIGUNGEN'], - legalReference: 'Art. 6 DSGVO', - description: 'B2C-Geschäftsmodell mit Endkundenkontakt', - }, - { - id: 'HT-H05', - category: 'product', - questionId: 'org_industry', - condition: 'EQUALS', - conditionValue: 'finance', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM'], - legalReference: 'Art. 6 DSGVO + Finanzaufsicht', - description: 'Finanzbranche mit erhöhten regulatorischen Anforderungen', - }, - { - id: 'HT-H06', - category: 'product', - questionId: 'org_industry', - condition: 'EQUALS', - conditionValue: 'healthcare', - minimumLevel: 'L3', - requiresDSFA: true, - mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], - legalReference: 'Art. 9 DSGVO + Gesundheitsrecht', - description: 'Gesundheitsbranche mit sensiblen Daten', - }, - { - id: 'HT-H07', - category: 'product', - questionId: 'org_industry', - condition: 'EQUALS', - conditionValue: 'public', - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM', 'DSR_PROZESS'], - legalReference: 'Art. 6 Abs. 1 lit. e DSGVO', - description: 'Öffentlicher Sektor', - }, - - // ========== I: Prozessreife - Gap Flags (5 rules) ========== - { - id: 'HT-I01', - category: 'process_maturity', - questionId: 'proc_dsar_process', - condition: 'EQUALS', - conditionValue: false, - minimumLevel: 'L1', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'Art. 15-22 DSGVO', - description: 'Fehlender Prozess für Betroffenenrechte', - }, - { - id: 'HT-I02', - category: 'process_maturity', - questionId: 'proc_deletion_concept', - condition: 'EQUALS', - conditionValue: false, - minimumLevel: 'L1', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'Art. 17 DSGVO', - description: 'Fehlendes Löschkonzept', - }, - { - id: 'HT-I03', - category: 'process_maturity', - questionId: 'proc_incident_response', - condition: 'EQUALS', - conditionValue: false, - minimumLevel: 'L1', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'Art. 33 DSGVO', - description: 'Fehlender Incident-Response-Prozess', - }, - { - id: 'HT-I04', - category: 'process_maturity', - questionId: 'proc_regular_audits', - condition: 'EQUALS', - conditionValue: false, - minimumLevel: 'L1', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'Art. 24 DSGVO', - description: 'Fehlende regelmäßige Audits', - }, - { - id: 'HT-I05', - category: 'process_maturity', - questionId: 'comp_training', - condition: 'EQUALS', - conditionValue: false, - minimumLevel: 'L1', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'Art. 39 Abs. 1 lit. b DSGVO', - description: 'Fehlende Schulungen zum Datenschutz', - }, - - // ========== J: IACE — AI Act Produkt-Triggers (3 rules) ========== - { - id: 'HT-J01', - category: 'iace_ai_act_product', - questionId: 'machineBuilder.containsAI', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM'], - legalReference: 'EU AI Act Annex I + EU Maschinenverordnung 2023/1230', - description: 'KI mit Sicherheitsfunktion in Maschine → AI Act High-Risk', - combineWithMachineBuilder: { field: 'hasSafetyFunction', value: true }, - riskWeight: 9, - }, - { - id: 'HT-J02', - category: 'iace_ai_act_product', - questionId: 'machineBuilder.containsAI', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM'], - legalReference: 'EU AI Act + EU Maschinenverordnung 2023/1230', - description: 'Autonome KI in Maschine → AI Act + Maschinenverordnung', - combineWithMachineBuilder: { field: 'autonomousBehavior', value: true }, - riskWeight: 8, - }, - { - id: 'HT-J03', - category: 'iace_ai_act_product', - questionId: 'machineBuilder.hasSafetyFunction', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['VVT', 'TOM'], - legalReference: 'EU AI Act Annex III', - description: 'KI-Bildverarbeitung mit Sicherheitsbezug', - combineWithMachineBuilder: { field: 'aiIntegrationType', includes: 'vision' }, - riskWeight: 8, - }, - - // ========== K: IACE — CRA Triggers (3 rules) ========== - { - id: 'HT-K01', - category: 'iace_cra', - questionId: 'machineBuilder.isNetworked', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TOM'], - legalReference: 'EU Cyber Resilience Act (CRA)', - description: 'Vernetztes Produkt → Cyber Resilience Act', - riskWeight: 6, - }, - { - id: 'HT-K02', - category: 'iace_cra', - questionId: 'machineBuilder.hasRemoteAccess', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TOM'], - legalReference: 'CRA + NIS2 Art. 21', - description: 'Remote-Zugriff → CRA + NIS2 Supply Chain', - riskWeight: 7, - }, - { - id: 'HT-K03', - category: 'iace_cra', - questionId: 'machineBuilder.hasOTAUpdates', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TOM'], - legalReference: 'CRA Art. 10 - Patch Management', - description: 'OTA-Updates → CRA Patch Management Pflicht', - riskWeight: 7, - }, - - // ========== L: IACE — NIS2 indirekt (2 rules) ========== - { - id: 'HT-L01', - category: 'iace_nis2_indirect', - questionId: 'machineBuilder.criticalSectorClients', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TOM'], - legalReference: 'NIS2 Art. 21 - Supply Chain', - description: 'Lieferant an KRITIS → NIS2 Supply Chain Anforderungen', - riskWeight: 7, - }, - { - id: 'HT-L02', - category: 'iace_nis2_indirect', - questionId: 'machineBuilder.oemClients', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'NIS2 + EU Maschinenverordnung', - description: 'OEM-Zulieferer → Compliance-Nachweispflicht', - riskWeight: 5, - }, - - // ========== M: IACE — Maschinenverordnung Triggers (4 rules) ========== - { - id: 'HT-M01', - category: 'iace_machinery_regulation', - questionId: 'machineBuilder.containsSoftware', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: ['TOM'], - legalReference: 'EU Maschinenverordnung 2023/1230 Anhang III', - description: 'Software als Sicherheitskomponente → Maschinenverordnung', - combineWithMachineBuilder: { field: 'hasSafetyFunction', value: true }, - riskWeight: 9, - }, - { - id: 'HT-M02', - category: 'iace_machinery_regulation', - questionId: 'machineBuilder.ceMarkingRequired', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'EU Maschinenverordnung 2023/1230', - description: 'CE-Kennzeichnung erforderlich', - riskWeight: 6, - }, - { - id: 'HT-M03', - category: 'iace_machinery_regulation', - questionId: 'machineBuilder.ceMarkingRequired', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L3', - requiresDSFA: false, - mandatoryDocuments: [], - legalReference: 'EU Maschinenverordnung 2023/1230 Art. 10', - description: 'CE ohne bestehende Risikobeurteilung → Dringend!', - combineWithMachineBuilder: { field: 'hasRiskAssessment', value: false }, - riskWeight: 9, - }, - { - id: 'HT-M04', - category: 'iace_machinery_regulation', - questionId: 'machineBuilder.containsFirmware', - condition: 'EQUALS', - conditionValue: true, - minimumLevel: 'L2', - requiresDSFA: false, - mandatoryDocuments: ['TOM'], - legalReference: 'EU Maschinenverordnung + CRA', - description: 'Firmware mit Remote-Update → Change Management Pflicht', - combineWithMachineBuilder: { field: 'hasOTAUpdates', value: true }, - riskWeight: 7, - }, + ...HARD_TRIGGER_RULES_A_E, + ...HARD_TRIGGER_RULES_F_M, ] diff --git a/admin-compliance/lib/sdk/compliance-scope-triggers/triggers-a-e.ts b/admin-compliance/lib/sdk/compliance-scope-triggers/triggers-a-e.ts new file mode 100644 index 0000000..8de578c --- /dev/null +++ b/admin-compliance/lib/sdk/compliance-scope-triggers/triggers-a-e.ts @@ -0,0 +1,359 @@ +/** + * Hard Trigger Rules A–E + * Groups: Art.9 (A), Vulnerable (B), ADM/KI (C), Ueberwachung (D), Drittland (E) + */ +import type { HardTriggerRule } from '../compliance-scope-types' + +export const HARD_TRIGGER_RULES_A_E: HardTriggerRule[] = [ + // ========== A: Art. 9 Besondere Kategorien (9 rules) ========== + { + id: 'HT-A01', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'gesundheit', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung von Gesundheitsdaten', + }, + { + id: 'HT-A02', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'biometrie', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung biometrischer Daten zur eindeutigen Identifizierung', + }, + { + id: 'HT-A03', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'genetik', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung genetischer Daten', + }, + { + id: 'HT-A04', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'politisch', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung politischer Meinungen', + }, + { + id: 'HT-A05', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'religion', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung religiöser oder weltanschaulicher Überzeugungen', + }, + { + id: 'HT-A06', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'gewerkschaft', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung von Gewerkschaftszugehörigkeit', + }, + { + id: 'HT-A07', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'sexualleben', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung von Daten zum Sexualleben oder zur sexuellen Orientierung', + }, + { + id: 'HT-A08', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'strafrechtlich', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 10 DSGVO', + description: 'Verarbeitung strafrechtlicher Verurteilungen', + }, + { + id: 'HT-A09', + category: 'art9', + questionId: 'data_art9', + condition: 'CONTAINS', + conditionValue: 'ethnisch', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 Abs. 1 DSGVO', + description: 'Verarbeitung der rassischen oder ethnischen Herkunft', + }, + + // ========== B: Vulnerable Gruppen (3 rules) ========== + { + id: 'HT-B01', + category: 'vulnerable', + questionId: 'data_minors', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'DSE'], + legalReference: 'Art. 8 DSGVO', + description: 'Verarbeitung von Daten Minderjähriger', + }, + { + id: 'HT-B02', + category: 'vulnerable', + questionId: 'data_minors', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L4', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'DSE'], + legalReference: 'Art. 8 + Art. 9 DSGVO', + description: 'Verarbeitung besonderer Kategorien von Daten Minderjähriger', + combineWithArt9: true, + }, + { + id: 'HT-B03', + category: 'vulnerable', + questionId: 'data_minors', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L4', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'AI_ACT_DOKU'], + legalReference: 'Art. 8 DSGVO + AI Act', + description: 'KI-gestützte Verarbeitung von Daten Minderjähriger', + combineWithAI: true, + }, + + // ========== C: ADM/KI (6 rules) ========== + { + id: 'HT-C01', + category: 'adm', + questionId: 'proc_adm_scoring', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 22 DSGVO', + description: 'Automatisierte Einzelentscheidung mit Rechtswirkung oder erheblicher Beeinträchtigung', + }, + { + id: 'HT-C02', + category: 'adm', + questionId: 'proc_ai_usage', + condition: 'CONTAINS', + conditionValue: 'autonom', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'AI_ACT_DOKU'], + legalReference: 'Art. 22 DSGVO + AI Act', + description: 'Autonome KI-Systeme mit Entscheidungsbefugnis', + }, + { + id: 'HT-C03', + category: 'adm', + questionId: 'proc_ai_usage', + condition: 'CONTAINS', + conditionValue: 'scoring', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM'], + legalReference: 'Art. 22 DSGVO', + description: 'KI-gestütztes Scoring', + }, + { + id: 'HT-C04', + category: 'adm', + questionId: 'proc_ai_usage', + condition: 'CONTAINS', + conditionValue: 'profiling', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 22 DSGVO', + description: 'KI-gestütztes Profiling mit erheblicher Wirkung', + }, + { + id: 'HT-C05', + category: 'adm', + questionId: 'proc_ai_usage', + condition: 'CONTAINS', + conditionValue: 'generativ', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'AI_ACT_DOKU'], + legalReference: 'AI Act', + description: 'Generative KI-Systeme', + }, + { + id: 'HT-C06', + category: 'adm', + questionId: 'proc_ai_usage', + condition: 'CONTAINS', + conditionValue: 'chatbot', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'AI_ACT_DOKU'], + legalReference: 'AI Act', + description: 'Chatbots mit Personendatenverarbeitung', + }, + + // ========== D: Überwachung (5 rules) ========== + { + id: 'HT-D01', + category: 'surveillance', + questionId: 'proc_video_surveillance', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'DSE'], + legalReference: 'Art. 6 DSGVO', + description: 'Videoüberwachung', + }, + { + id: 'HT-D02', + category: 'surveillance', + questionId: 'proc_employee_monitoring', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 88 DSGVO + BetrVG', + description: 'Mitarbeiterüberwachung', + }, + { + id: 'HT-D03', + category: 'surveillance', + questionId: 'proc_tracking', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'COOKIE_BANNER', 'EINWILLIGUNGEN'], + legalReference: 'Art. 6 DSGVO + ePrivacy', + description: 'Online-Tracking', + }, + { + id: 'HT-D04', + category: 'surveillance', + questionId: 'proc_video_surveillance', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 35 Abs. 3 DSGVO', + description: 'Videoüberwachung kombiniert mit Mitarbeitermonitoring', + combineWithEmployeeMonitoring: true, + }, + { + id: 'HT-D05', + category: 'surveillance', + questionId: 'proc_video_surveillance', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 35 Abs. 3 DSGVO', + description: 'Videoüberwachung kombiniert mit automatisierter Bewertung', + combineWithADM: true, + }, + + // ========== E: Drittland (5 rules) ========== + { + id: 'HT-E01', + category: 'third_country', + questionId: 'tech_third_country', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TRANSFER_DOKU'], + legalReference: 'Art. 44 ff. DSGVO', + description: 'Datenübermittlung in Drittland', + }, + { + id: 'HT-E02', + category: 'third_country', + questionId: 'tech_hosting_location', + condition: 'EQUALS', + conditionValue: 'drittland', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'TRANSFER_DOKU'], + legalReference: 'Art. 44 ff. DSGVO', + description: 'Hosting in Drittland', + }, + { + id: 'HT-E03', + category: 'third_country', + questionId: 'tech_hosting_location', + condition: 'EQUALS', + conditionValue: 'us_adequacy', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TRANSFER_DOKU'], + legalReference: 'Art. 45 DSGVO', + description: 'Hosting in USA mit Angemessenheitsbeschluss', + }, + { + id: 'HT-E04', + category: 'third_country', + questionId: 'tech_third_country', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'TRANSFER_DOKU', 'DSFA'], + legalReference: 'Art. 44 ff. + Art. 9 DSGVO', + description: 'Drittlandtransfer besonderer Kategorien', + combineWithArt9: true, + }, + { + id: 'HT-E05', + category: 'third_country', + questionId: 'tech_third_country', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'TRANSFER_DOKU', 'DSFA'], + legalReference: 'Art. 44 ff. + Art. 8 DSGVO', + description: 'Drittlandtransfer von Daten Minderjähriger', + combineWithMinors: true, + }, +] diff --git a/admin-compliance/lib/sdk/compliance-scope-triggers/triggers-f-m.ts b/admin-compliance/lib/sdk/compliance-scope-triggers/triggers-f-m.ts new file mode 100644 index 0000000..04b864d --- /dev/null +++ b/admin-compliance/lib/sdk/compliance-scope-triggers/triggers-f-m.ts @@ -0,0 +1,467 @@ +/** + * Hard Trigger Rules F–M + * Groups: Zertifizierung (F), Volumen/Skala (G), Produkt/Business (H), + * Prozessreife (I), IACE AI Act Produkt (J), IACE CRA (K), + * IACE NIS2 indirekt (L), IACE Maschinenverordnung (M) + */ +import type { HardTriggerRule } from '../compliance-scope-types' + +export const HARD_TRIGGER_RULES_F_M: HardTriggerRule[] = [ + // ========== F: Zertifizierung (5 rules) ========== + { + id: 'HT-F01', + category: 'certification', + questionId: 'org_cert_target', + condition: 'CONTAINS', + conditionValue: 'ISO27001', + minimumLevel: 'L4', + requiresDSFA: false, + mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST'], + legalReference: 'ISO/IEC 27001', + description: 'Angestrebte ISO 27001 Zertifizierung', + }, + { + id: 'HT-F02', + category: 'certification', + questionId: 'org_cert_target', + condition: 'CONTAINS', + conditionValue: 'ISO27701', + minimumLevel: 'L4', + requiresDSFA: false, + mandatoryDocuments: ['TOM', 'VVT', 'AUDIT_CHECKLIST'], + legalReference: 'ISO/IEC 27701', + description: 'Angestrebte ISO 27701 Zertifizierung', + }, + { + id: 'HT-F03', + category: 'certification', + questionId: 'org_cert_target', + condition: 'CONTAINS', + conditionValue: 'SOC2', + minimumLevel: 'L4', + requiresDSFA: false, + mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST'], + legalReference: 'SOC 2 Type II', + description: 'Angestrebte SOC 2 Zertifizierung', + }, + { + id: 'HT-F04', + category: 'certification', + questionId: 'org_cert_target', + condition: 'CONTAINS', + conditionValue: 'TISAX', + minimumLevel: 'L4', + requiresDSFA: false, + mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST', 'VENDOR_MANAGEMENT'], + legalReference: 'TISAX', + description: 'Angestrebte TISAX Zertifizierung', + }, + { + id: 'HT-F05', + category: 'certification', + questionId: 'org_cert_target', + condition: 'CONTAINS', + conditionValue: 'BSI-Grundschutz', + minimumLevel: 'L4', + requiresDSFA: false, + mandatoryDocuments: ['TOM', 'AUDIT_CHECKLIST'], + legalReference: 'BSI IT-Grundschutz', + description: 'Angestrebte BSI-Grundschutz Zertifizierung', + }, + + // ========== G: Volumen/Skala (5 rules) ========== + { + id: 'HT-G01', + category: 'scale', + questionId: 'data_volume', + condition: 'EQUALS', + conditionValue: '>1000000', + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'LOESCHKONZEPT'], + legalReference: 'Art. 35 Abs. 3 lit. b DSGVO', + description: 'Umfangreiche Verarbeitung personenbezogener Daten (>1 Mio. Datensätze)', + }, + { + id: 'HT-G02', + category: 'scale', + questionId: 'data_volume', + condition: 'EQUALS', + conditionValue: '100000-1000000', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM'], + legalReference: 'Art. 35 Abs. 3 lit. b DSGVO', + description: 'Großvolumige Datenverarbeitung (100k-1M Datensätze)', + }, + { + id: 'HT-G03', + category: 'scale', + questionId: 'org_customer_count', + condition: 'EQUALS', + conditionValue: '100000+', + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'DSR_PROZESS'], + legalReference: 'Art. 15-22 DSGVO', + description: 'Großer Kundenstamm (>100k) mit hoher Betroffenenanzahl', + }, + { + id: 'HT-G04', + category: 'scale', + questionId: 'org_employee_count', + condition: 'GREATER_THAN', + conditionValue: 249, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'LOESCHKONZEPT', 'NOTFALLPLAN'], + legalReference: 'Art. 37 DSGVO', + description: 'Große Organisation (>250 Mitarbeiter) mit erhöhten Compliance-Anforderungen', + }, + { + id: 'HT-G05', + category: 'scale', + questionId: 'org_employee_count', + condition: 'GREATER_THAN', + conditionValue: 999, + minimumLevel: 'L4', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'LOESCHKONZEPT'], + legalReference: 'Art. 35 + Art. 37 DSGVO', + description: 'Sehr große Organisation (>1000 Mitarbeiter) mit Art. 9 Daten', + combineWithArt9: true, + }, + + // ========== H: Produkt/Business (7 rules) ========== + { + id: 'HT-H01a', + category: 'product', + questionId: 'prod_webshop', + condition: 'EQUALS', + conditionValue: true, + excludeWhen: { questionId: 'org_business_model', value: 'B2B' }, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['DSE', 'AGB', 'COOKIE_BANNER', 'EINWILLIGUNGEN', + 'WIDERRUFSBELEHRUNG', 'PREISANGABEN', 'FERNABSATZ_INFO', 'STREITBEILEGUNG'], + legalReference: 'Art. 6 DSGVO + Fernabsatzrecht + PAngV + VSBG', + description: 'E-Commerce / Webshop (B2C) — Verbraucherschutzpflichten', + }, + { + id: 'HT-H01b', + category: 'product', + questionId: 'prod_webshop', + condition: 'EQUALS', + conditionValue: true, + requireWhen: { questionId: 'org_business_model', value: 'B2B' }, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['DSE', 'AGB', 'COOKIE_BANNER'], + legalReference: 'Art. 6 DSGVO + eCommerce', + description: 'E-Commerce / Webshop (B2B) — Basis-Pflichten', + }, + { + id: 'HT-H02', + category: 'product', + questionId: 'prod_data_broker', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA', 'EINWILLIGUNGEN'], + legalReference: 'Art. 35 Abs. 3 DSGVO', + description: 'Datenhandel oder Datenmakler-Tätigkeit', + }, + { + id: 'HT-H03', + category: 'product', + questionId: 'prod_api_external', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TOM', 'AVV'], + legalReference: 'Art. 28 DSGVO', + description: 'Externe API mit Datenweitergabe', + }, + { + id: 'HT-H04', + category: 'product', + questionId: 'org_business_model', + condition: 'EQUALS', + conditionValue: 'b2c', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['DSE', 'COOKIE_BANNER', 'EINWILLIGUNGEN'], + legalReference: 'Art. 6 DSGVO', + description: 'B2C-Geschäftsmodell mit Endkundenkontakt', + }, + { + id: 'HT-H05', + category: 'product', + questionId: 'org_industry', + condition: 'EQUALS', + conditionValue: 'finance', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM'], + legalReference: 'Art. 6 DSGVO + Finanzaufsicht', + description: 'Finanzbranche mit erhöhten regulatorischen Anforderungen', + }, + { + id: 'HT-H06', + category: 'product', + questionId: 'org_industry', + condition: 'EQUALS', + conditionValue: 'healthcare', + minimumLevel: 'L3', + requiresDSFA: true, + mandatoryDocuments: ['VVT', 'TOM', 'DSFA'], + legalReference: 'Art. 9 DSGVO + Gesundheitsrecht', + description: 'Gesundheitsbranche mit sensiblen Daten', + }, + { + id: 'HT-H07', + category: 'product', + questionId: 'org_industry', + condition: 'EQUALS', + conditionValue: 'public', + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM', 'DSR_PROZESS'], + legalReference: 'Art. 6 Abs. 1 lit. e DSGVO', + description: 'Öffentlicher Sektor', + }, + + // ========== I: Prozessreife - Gap Flags (5 rules) ========== + { + id: 'HT-I01', + category: 'process_maturity', + questionId: 'proc_dsar_process', + condition: 'EQUALS', + conditionValue: false, + minimumLevel: 'L1', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'Art. 15-22 DSGVO', + description: 'Fehlender Prozess für Betroffenenrechte', + }, + { + id: 'HT-I02', + category: 'process_maturity', + questionId: 'proc_deletion_concept', + condition: 'EQUALS', + conditionValue: false, + minimumLevel: 'L1', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'Art. 17 DSGVO', + description: 'Fehlendes Löschkonzept', + }, + { + id: 'HT-I03', + category: 'process_maturity', + questionId: 'proc_incident_response', + condition: 'EQUALS', + conditionValue: false, + minimumLevel: 'L1', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'Art. 33 DSGVO', + description: 'Fehlender Incident-Response-Prozess', + }, + { + id: 'HT-I04', + category: 'process_maturity', + questionId: 'proc_regular_audits', + condition: 'EQUALS', + conditionValue: false, + minimumLevel: 'L1', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'Art. 24 DSGVO', + description: 'Fehlende regelmäßige Audits', + }, + { + id: 'HT-I05', + category: 'process_maturity', + questionId: 'comp_training', + condition: 'EQUALS', + conditionValue: false, + minimumLevel: 'L1', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'Art. 39 Abs. 1 lit. b DSGVO', + description: 'Fehlende Schulungen zum Datenschutz', + }, + + // ========== J: IACE — AI Act Produkt-Triggers (3 rules) ========== + { + id: 'HT-J01', + category: 'iace_ai_act_product', + questionId: 'machineBuilder.containsAI', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM'], + legalReference: 'EU AI Act Annex I + EU Maschinenverordnung 2023/1230', + description: 'KI mit Sicherheitsfunktion in Maschine → AI Act High-Risk', + combineWithMachineBuilder: { field: 'hasSafetyFunction', value: true }, + riskWeight: 9, + }, + { + id: 'HT-J02', + category: 'iace_ai_act_product', + questionId: 'machineBuilder.containsAI', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM'], + legalReference: 'EU AI Act + EU Maschinenverordnung 2023/1230', + description: 'Autonome KI in Maschine → AI Act + Maschinenverordnung', + combineWithMachineBuilder: { field: 'autonomousBehavior', value: true }, + riskWeight: 8, + }, + { + id: 'HT-J03', + category: 'iace_ai_act_product', + questionId: 'machineBuilder.hasSafetyFunction', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['VVT', 'TOM'], + legalReference: 'EU AI Act Annex III', + description: 'KI-Bildverarbeitung mit Sicherheitsbezug', + combineWithMachineBuilder: { field: 'aiIntegrationType', includes: 'vision' }, + riskWeight: 8, + }, + + // ========== K: IACE — CRA Triggers (3 rules) ========== + { + id: 'HT-K01', + category: 'iace_cra', + questionId: 'machineBuilder.isNetworked', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TOM'], + legalReference: 'EU Cyber Resilience Act (CRA)', + description: 'Vernetztes Produkt → Cyber Resilience Act', + riskWeight: 6, + }, + { + id: 'HT-K02', + category: 'iace_cra', + questionId: 'machineBuilder.hasRemoteAccess', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TOM'], + legalReference: 'CRA + NIS2 Art. 21', + description: 'Remote-Zugriff → CRA + NIS2 Supply Chain', + riskWeight: 7, + }, + { + id: 'HT-K03', + category: 'iace_cra', + questionId: 'machineBuilder.hasOTAUpdates', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TOM'], + legalReference: 'CRA Art. 10 - Patch Management', + description: 'OTA-Updates → CRA Patch Management Pflicht', + riskWeight: 7, + }, + + // ========== L: IACE — NIS2 indirekt (2 rules) ========== + { + id: 'HT-L01', + category: 'iace_nis2_indirect', + questionId: 'machineBuilder.criticalSectorClients', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TOM'], + legalReference: 'NIS2 Art. 21 - Supply Chain', + description: 'Lieferant an KRITIS → NIS2 Supply Chain Anforderungen', + riskWeight: 7, + }, + { + id: 'HT-L02', + category: 'iace_nis2_indirect', + questionId: 'machineBuilder.oemClients', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'NIS2 + EU Maschinenverordnung', + description: 'OEM-Zulieferer → Compliance-Nachweispflicht', + riskWeight: 5, + }, + + // ========== M: IACE — Maschinenverordnung Triggers (4 rules) ========== + { + id: 'HT-M01', + category: 'iace_machinery_regulation', + questionId: 'machineBuilder.containsSoftware', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: ['TOM'], + legalReference: 'EU Maschinenverordnung 2023/1230 Anhang III', + description: 'Software als Sicherheitskomponente → Maschinenverordnung', + combineWithMachineBuilder: { field: 'hasSafetyFunction', value: true }, + riskWeight: 9, + }, + { + id: 'HT-M02', + category: 'iace_machinery_regulation', + questionId: 'machineBuilder.ceMarkingRequired', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'EU Maschinenverordnung 2023/1230', + description: 'CE-Kennzeichnung erforderlich', + riskWeight: 6, + }, + { + id: 'HT-M03', + category: 'iace_machinery_regulation', + questionId: 'machineBuilder.ceMarkingRequired', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L3', + requiresDSFA: false, + mandatoryDocuments: [], + legalReference: 'EU Maschinenverordnung 2023/1230 Art. 10', + description: 'CE ohne bestehende Risikobeurteilung → Dringend!', + combineWithMachineBuilder: { field: 'hasRiskAssessment', value: false }, + riskWeight: 9, + }, + { + id: 'HT-M04', + category: 'iace_machinery_regulation', + questionId: 'machineBuilder.containsFirmware', + condition: 'EQUALS', + conditionValue: true, + minimumLevel: 'L2', + requiresDSFA: false, + mandatoryDocuments: ['TOM'], + legalReference: 'EU Maschinenverordnung + CRA', + description: 'Firmware mit Remote-Update → Change Management Pflicht', + combineWithMachineBuilder: { field: 'hasOTAUpdates', value: true }, + riskWeight: 7, + }, +] diff --git a/admin-compliance/lib/sdk/demo-data/demo-state.ts b/admin-compliance/lib/sdk/demo-data/demo-state.ts new file mode 100644 index 0000000..104392d --- /dev/null +++ b/admin-compliance/lib/sdk/demo-data/demo-state.ts @@ -0,0 +1,217 @@ +/** + * Demo State Generator + * + * Generates a complete demo SDKState object for seeding. + * Barrel-split from index.ts. Do NOT import directly; use index.ts. + */ + +import { SDKState } from '../types' +import { getDemoUseCases } from './use-cases' +import { getDemoRisks } from './risks' +import { getDemoControls } from './controls' +import { getDemoDSFA } from './dsfa' +import { getDemoTOMs } from './toms' +import { getDemoProcessingActivities, getDemoRetentionPolicies } from './vvt' + +/** + * Generate a complete demo state object + * This is used as seed data for the API, not as runtime data + */ +export function generateDemoState(tenantId: string, userId: string): Partial { + const now = new Date() + + return { + // Metadata + version: '1.0.0', + projectVersion: 1, + lastModified: now, + + // Tenant & User + tenantId, + userId, + subscription: 'PROFESSIONAL', + + // Customer Type + customerType: 'new', + + // Company Profile (Demo: TechStart GmbH - SaaS-Startup aus Berlin) + companyProfile: { + companyName: 'TechStart GmbH', + legalForm: 'gmbh', + industry: ['Technologie / IT'], + industryOther: '', + foundedYear: 2022, + businessModel: 'B2B_B2C', + offerings: ['app_web', 'software_saas', 'services_consulting'], + companySize: 'small', + employeeCount: '10-49', + annualRevenue: '2-10 Mio', + headquartersCountry: 'DE', + headquartersCity: 'Berlin', + hasInternationalLocations: false, + internationalCountries: [], + targetMarkets: ['germany_only', 'dach'], + primaryJurisdiction: 'DE', + isDataController: true, + isDataProcessor: true, + dpoName: 'Max Mustermann', + dpoEmail: 'dsb@techstart.de', + legalContactName: null, + legalContactEmail: null, + isComplete: true, + completedAt: new Date('2026-01-14'), + }, + + // Progress - showing a realistic partially completed workflow + currentPhase: 2, + currentStep: 'tom', + completedSteps: [ + 'company-profile', + 'use-case-assessment', + 'screening', + 'modules', + 'requirements', + 'controls', + 'evidence', + 'audit-checklist', + 'risks', + 'ai-act', + 'obligations', + 'dsfa', + ], + checkpoints: { + 'CP-PROF': { checkpointId: 'CP-PROF', passed: true, validatedAt: new Date('2026-01-14'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-UC': { checkpointId: 'CP-UC', passed: true, validatedAt: new Date('2026-01-15'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-SCAN': { checkpointId: 'CP-SCAN', passed: true, validatedAt: new Date('2026-01-16'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-MOD': { checkpointId: 'CP-MOD', passed: true, validatedAt: new Date('2026-01-17'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-REQ': { checkpointId: 'CP-REQ', passed: true, validatedAt: new Date('2026-01-18'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-CTRL': { checkpointId: 'CP-CTRL', passed: true, validatedAt: new Date('2026-01-19'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-EVI': { checkpointId: 'CP-EVI', passed: true, validatedAt: new Date('2026-01-20'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-CHK': { checkpointId: 'CP-CHK', passed: true, validatedAt: new Date('2026-01-21'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-RISK': { checkpointId: 'CP-RISK', passed: true, validatedAt: new Date('2026-01-22'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-AI': { checkpointId: 'CP-AI', passed: true, validatedAt: new Date('2026-01-25'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-OBL': { checkpointId: 'CP-OBL', passed: true, validatedAt: new Date('2026-01-27'), validatedBy: 'demo-user', errors: [], warnings: [] }, + 'CP-DSFA': { checkpointId: 'CP-DSFA', passed: true, validatedAt: new Date('2026-01-30'), validatedBy: 'DSB', errors: [], warnings: [] }, + }, + + // Phase 1 Data + useCases: getDemoUseCases(), + activeUseCase: 'demo-uc-1', + screening: { + id: 'demo-scan-1', + status: 'COMPLETED', + startedAt: new Date('2026-01-16T09:00:00'), + completedAt: new Date('2026-01-16T09:15:00'), + sbom: { + format: 'CycloneDX', + version: '1.4', + components: [ + { name: 'tensorflow', version: '2.15.0', type: 'library', purl: 'pkg:pypi/tensorflow@2.15.0', licenses: ['Apache-2.0'], vulnerabilities: [] }, + { name: 'scikit-learn', version: '1.4.0', type: 'library', purl: 'pkg:pypi/scikit-learn@1.4.0', licenses: ['BSD-3-Clause'], vulnerabilities: [] }, + { name: 'pandas', version: '2.2.0', type: 'library', purl: 'pkg:pypi/pandas@2.2.0', licenses: ['BSD-3-Clause'], vulnerabilities: [] }, + ], + dependencies: [], + generatedAt: new Date('2026-01-16T09:10:00'), + }, + securityScan: { + totalIssues: 3, + critical: 0, + high: 1, + medium: 1, + low: 1, + issues: [ + { + id: 'sec-issue-1', severity: 'HIGH', title: 'Outdated cryptography library', + description: 'The cryptography library version 41.0.0 has known vulnerabilities', + cve: 'CVE-2024-1234', cvss: 7.5, affectedComponent: 'cryptography', + remediation: 'Upgrade to cryptography >= 42.0.0', status: 'RESOLVED', + }, + { + id: 'sec-issue-2', severity: 'MEDIUM', title: 'Insecure default configuration', + description: 'Debug mode enabled in production configuration', + cve: null, cvss: 5.3, affectedComponent: 'app-config', + remediation: 'Set DEBUG=false in production', status: 'RESOLVED', + }, + { + id: 'sec-issue-3', severity: 'LOW', title: 'Missing security headers', + description: 'X-Content-Type-Options header not set', + cve: null, cvss: 3.1, affectedComponent: 'web-server', + remediation: 'Add security headers middleware', status: 'RESOLVED', + }, + ], + }, + error: null, + }, + modules: [ + { id: 'demo-mod-1', name: 'Kundendaten-Modul', description: 'Verarbeitung von Kundendaten für Marketing und Analyse', regulations: ['DSGVO', 'TTDSG'], criticality: 'HIGH', processesPersonalData: true, hasAIComponents: true }, + { id: 'demo-mod-2', name: 'HR-Modul', description: 'Bewerbermanagement und Personalverwaltung', regulations: ['DSGVO', 'AGG', 'AI Act'], criticality: 'HIGH', processesPersonalData: true, hasAIComponents: true }, + { id: 'demo-mod-3', name: 'Support-Modul', description: 'Kundenservice und Chatbot-System', regulations: ['DSGVO', 'AI Act'], criticality: 'MEDIUM', processesPersonalData: true, hasAIComponents: true }, + ], + requirements: [ + { id: 'demo-req-1', regulation: 'DSGVO', article: 'Art. 5', title: 'Grundsätze der Verarbeitung', description: 'Einhaltung der Grundsätze für die Verarbeitung personenbezogener Daten', criticality: 'CRITICAL', applicableModules: ['demo-mod-1', 'demo-mod-2', 'demo-mod-3'], status: 'IMPLEMENTED', controls: ['demo-ctrl-1', 'demo-ctrl-2', 'demo-ctrl-9'] }, + { id: 'demo-req-2', regulation: 'DSGVO', article: 'Art. 32', title: 'Sicherheit der Verarbeitung', description: 'Geeignete technische und organisatorische Maßnahmen', criticality: 'CRITICAL', applicableModules: ['demo-mod-1', 'demo-mod-2', 'demo-mod-3'], status: 'IMPLEMENTED', controls: ['demo-ctrl-1', 'demo-ctrl-3', 'demo-ctrl-4'] }, + { id: 'demo-req-3', regulation: 'DSGVO', article: 'Art. 25', title: 'Datenschutz durch Technikgestaltung', description: 'Privacy by Design und Privacy by Default', criticality: 'HIGH', applicableModules: ['demo-mod-1', 'demo-mod-2'], status: 'IMPLEMENTED', controls: ['demo-ctrl-9', 'demo-ctrl-10'] }, + { id: 'demo-req-4', regulation: 'AI Act', article: 'Art. 13', title: 'Transparenz', description: 'Transparenzanforderungen für KI-Systeme', criticality: 'HIGH', applicableModules: ['demo-mod-1', 'demo-mod-2', 'demo-mod-3'], status: 'IMPLEMENTED', controls: ['demo-ctrl-7', 'demo-ctrl-8'] }, + { id: 'demo-req-5', regulation: 'AI Act', article: 'Art. 9', title: 'Risikomanagement', description: 'Risikomanagementsystem für Hochrisiko-KI', criticality: 'HIGH', applicableModules: ['demo-mod-2'], status: 'IMPLEMENTED', controls: ['demo-ctrl-5', 'demo-ctrl-6', 'demo-ctrl-11', 'demo-ctrl-12'] }, + ], + controls: getDemoControls(), + evidence: [ + { id: 'demo-evi-1', controlId: 'demo-ctrl-1', type: 'SCREENSHOT', name: 'MFA-Konfiguration Azure AD', description: 'Screenshot der MFA-Einstellungen im Azure AD Admin Portal', fileUrl: null, validFrom: new Date('2026-01-01'), validUntil: new Date('2027-01-01'), uploadedBy: 'IT-Security', uploadedAt: new Date('2026-01-10') }, + { id: 'demo-evi-2', controlId: 'demo-ctrl-2', type: 'DOCUMENT', name: 'Berechtigungskonzept v2.1', description: 'Dokumentiertes Berechtigungskonzept mit Rollenmatrix', fileUrl: null, validFrom: new Date('2026-01-01'), validUntil: null, uploadedBy: 'IT-Security', uploadedAt: new Date('2026-01-05') }, + { id: 'demo-evi-5', controlId: 'demo-ctrl-5', type: 'AUDIT_REPORT', name: 'Bias-Audit Q1/2026', description: 'Externer Audit-Bericht zur Fairness des KI-Modells', fileUrl: null, validFrom: new Date('2026-01-15'), validUntil: new Date('2026-04-15'), uploadedBy: 'Data Science Lead', uploadedAt: new Date('2026-01-20') }, + ], + checklist: [ + { id: 'demo-chk-1', requirementId: 'demo-req-1', title: 'Rechtmäßigkeit der Verarbeitung geprüft', description: 'Dokumentierte Prüfung der Rechtsgrundlagen', status: 'PASSED', notes: 'Geprüft durch DSB', verifiedBy: 'DSB', verifiedAt: new Date('2026-01-20') }, + { id: 'demo-chk-2', requirementId: 'demo-req-2', title: 'TOMs dokumentiert und umgesetzt', description: 'Technische und organisatorische Maßnahmen', status: 'PASSED', notes: 'Alle TOMs implementiert', verifiedBy: 'CISO', verifiedAt: new Date('2026-01-21') }, + ], + risks: getDemoRisks(), + + // Phase 2 Data + aiActClassification: { + riskCategory: 'HIGH', + systemType: 'Beschäftigungsbezogenes KI-System (Art. 6 Abs. 2 AI Act)', + obligations: [ + { id: 'demo-ai-obl-1', article: 'Art. 9', title: 'Risikomanagementsystem', description: 'Einrichtung eines KI-Risikomanagementsystems', deadline: new Date('2026-08-01'), status: 'IN_PROGRESS' }, + { id: 'demo-ai-obl-2', article: 'Art. 10', title: 'Daten-Governance', description: 'Anforderungen an Trainingsdaten', deadline: new Date('2026-08-01'), status: 'COMPLETED' }, + { id: 'demo-ai-obl-3', article: 'Art. 13', title: 'Transparenz', description: 'Dokumentation für Nutzer', deadline: new Date('2026-08-01'), status: 'COMPLETED' }, + ], + assessmentDate: new Date('2026-01-25'), + assessedBy: 'Compliance Team', + justification: 'Das System fällt unter Art. 6 Abs. 2 lit. a AI Act (Einstellung und Auswahl von Personen).', + }, + obligations: [ + { id: 'demo-obl-1', regulation: 'DSGVO', article: 'Art. 30', title: 'Verarbeitungsverzeichnis', description: 'Führung eines Verzeichnisses der Verarbeitungstätigkeiten', deadline: null, penalty: 'Bis zu 10 Mio. EUR oder 2% des Jahresumsatzes', status: 'COMPLETED', responsible: 'DSB' }, + { id: 'demo-obl-2', regulation: 'DSGVO', article: 'Art. 35', title: 'Datenschutz-Folgenabschätzung', description: 'Durchführung einer DSFA für Hochrisiko-Verarbeitungen', deadline: null, penalty: 'Bis zu 10 Mio. EUR oder 2% des Jahresumsatzes', status: 'COMPLETED', responsible: 'DSB' }, + { id: 'demo-obl-3', regulation: 'AI Act', article: 'Art. 49', title: 'CE-Kennzeichnung', description: 'CE-Kennzeichnung für Hochrisiko-KI-Systeme', deadline: new Date('2026-08-01'), penalty: 'Bis zu 35 Mio. EUR oder 7% des Jahresumsatzes', status: 'PENDING', responsible: 'Compliance' }, + ], + dsfa: getDemoDSFA(), + toms: getDemoTOMs(), + retentionPolicies: getDemoRetentionPolicies(), + vvt: getDemoProcessingActivities(), + + // Documents, Cookie Banner, etc. - partially filled + documents: [], + cookieBanner: null, + consents: [], + dsrConfig: null, + escalationWorkflows: [], + + // Security + sbom: null, + securityIssues: [], + securityBacklog: [], + + // UI State + commandBarHistory: [], + recentSearches: ['DSGVO Art. 5', 'Bias-Monitoring', 'TOM Verschlüsselung'], + preferences: { + language: 'de', + theme: 'light', + compactMode: false, + showHints: true, + autoSave: true, + autoValidate: true, + allowParallelWork: true, + }, + } +} diff --git a/admin-compliance/lib/sdk/demo-data/index.ts b/admin-compliance/lib/sdk/demo-data/index.ts index bf763b6..707e892 100644 --- a/admin-compliance/lib/sdk/demo-data/index.ts +++ b/admin-compliance/lib/sdk/demo-data/index.ts @@ -7,6 +7,8 @@ * * The seedDemoData() function writes data through the API, * and the data is then loaded from the database like any other data. + * + * generateDemoState lives in ./demo-state.ts (barrel split). */ import { SDKState } from '../types' @@ -39,420 +41,9 @@ export { DEMO_RETENTION_POLICIES, } -/** - * Generate a complete demo state object - * This is used as seed data for the API, not as runtime data - */ -export function generateDemoState(tenantId: string, userId: string): Partial { - const now = new Date() - - return { - // Metadata - version: '1.0.0', - projectVersion: 1, - lastModified: now, - - // Tenant & User - tenantId, - userId, - subscription: 'PROFESSIONAL', - - // Customer Type - customerType: 'new', - - // Company Profile (Demo: TechStart GmbH - SaaS-Startup aus Berlin) - companyProfile: { - companyName: 'TechStart GmbH', - legalForm: 'gmbh', - industry: ['Technologie / IT'], - industryOther: '', - foundedYear: 2022, - businessModel: 'B2B_B2C', - offerings: ['app_web', 'software_saas', 'services_consulting'], - companySize: 'small', - employeeCount: '10-49', - annualRevenue: '2-10 Mio', - headquartersCountry: 'DE', - headquartersCity: 'Berlin', - hasInternationalLocations: false, - internationalCountries: [], - targetMarkets: ['germany_only', 'dach'], - primaryJurisdiction: 'DE', - isDataController: true, - isDataProcessor: true, - dpoName: 'Max Mustermann', - dpoEmail: 'dsb@techstart.de', - legalContactName: null, - legalContactEmail: null, - isComplete: true, - completedAt: new Date('2026-01-14'), - }, - - // Progress - showing a realistic partially completed workflow - currentPhase: 2, - currentStep: 'tom', - completedSteps: [ - 'company-profile', - 'use-case-assessment', - 'screening', - 'modules', - 'requirements', - 'controls', - 'evidence', - 'audit-checklist', - 'risks', - 'ai-act', - 'obligations', - 'dsfa', - ], - checkpoints: { - 'CP-PROF': { checkpointId: 'CP-PROF', passed: true, validatedAt: new Date('2026-01-14'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-UC': { checkpointId: 'CP-UC', passed: true, validatedAt: new Date('2026-01-15'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-SCAN': { checkpointId: 'CP-SCAN', passed: true, validatedAt: new Date('2026-01-16'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-MOD': { checkpointId: 'CP-MOD', passed: true, validatedAt: new Date('2026-01-17'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-REQ': { checkpointId: 'CP-REQ', passed: true, validatedAt: new Date('2026-01-18'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-CTRL': { checkpointId: 'CP-CTRL', passed: true, validatedAt: new Date('2026-01-19'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-EVI': { checkpointId: 'CP-EVI', passed: true, validatedAt: new Date('2026-01-20'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-CHK': { checkpointId: 'CP-CHK', passed: true, validatedAt: new Date('2026-01-21'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-RISK': { checkpointId: 'CP-RISK', passed: true, validatedAt: new Date('2026-01-22'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-AI': { checkpointId: 'CP-AI', passed: true, validatedAt: new Date('2026-01-25'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-OBL': { checkpointId: 'CP-OBL', passed: true, validatedAt: new Date('2026-01-27'), validatedBy: 'demo-user', errors: [], warnings: [] }, - 'CP-DSFA': { checkpointId: 'CP-DSFA', passed: true, validatedAt: new Date('2026-01-30'), validatedBy: 'DSB', errors: [], warnings: [] }, - }, - - // Phase 1 Data - useCases: getDemoUseCases(), - activeUseCase: 'demo-uc-1', - screening: { - id: 'demo-scan-1', - status: 'COMPLETED', - startedAt: new Date('2026-01-16T09:00:00'), - completedAt: new Date('2026-01-16T09:15:00'), - sbom: { - format: 'CycloneDX', - version: '1.4', - components: [ - { - name: 'tensorflow', - version: '2.15.0', - type: 'library', - purl: 'pkg:pypi/tensorflow@2.15.0', - licenses: ['Apache-2.0'], - vulnerabilities: [], - }, - { - name: 'scikit-learn', - version: '1.4.0', - type: 'library', - purl: 'pkg:pypi/scikit-learn@1.4.0', - licenses: ['BSD-3-Clause'], - vulnerabilities: [], - }, - { - name: 'pandas', - version: '2.2.0', - type: 'library', - purl: 'pkg:pypi/pandas@2.2.0', - licenses: ['BSD-3-Clause'], - vulnerabilities: [], - }, - ], - dependencies: [], - generatedAt: new Date('2026-01-16T09:10:00'), - }, - securityScan: { - totalIssues: 3, - critical: 0, - high: 1, - medium: 1, - low: 1, - issues: [ - { - id: 'sec-issue-1', - severity: 'HIGH', - title: 'Outdated cryptography library', - description: 'The cryptography library version 41.0.0 has known vulnerabilities', - cve: 'CVE-2024-1234', - cvss: 7.5, - affectedComponent: 'cryptography', - remediation: 'Upgrade to cryptography >= 42.0.0', - status: 'RESOLVED', - }, - { - id: 'sec-issue-2', - severity: 'MEDIUM', - title: 'Insecure default configuration', - description: 'Debug mode enabled in production configuration', - cve: null, - cvss: 5.3, - affectedComponent: 'app-config', - remediation: 'Set DEBUG=false in production', - status: 'RESOLVED', - }, - { - id: 'sec-issue-3', - severity: 'LOW', - title: 'Missing security headers', - description: 'X-Content-Type-Options header not set', - cve: null, - cvss: 3.1, - affectedComponent: 'web-server', - remediation: 'Add security headers middleware', - status: 'RESOLVED', - }, - ], - }, - error: null, - }, - modules: [ - { - id: 'demo-mod-1', - name: 'Kundendaten-Modul', - description: 'Verarbeitung von Kundendaten für Marketing und Analyse', - regulations: ['DSGVO', 'TTDSG'], - criticality: 'HIGH', - processesPersonalData: true, - hasAIComponents: true, - }, - { - id: 'demo-mod-2', - name: 'HR-Modul', - description: 'Bewerbermanagement und Personalverwaltung', - regulations: ['DSGVO', 'AGG', 'AI Act'], - criticality: 'HIGH', - processesPersonalData: true, - hasAIComponents: true, - }, - { - id: 'demo-mod-3', - name: 'Support-Modul', - description: 'Kundenservice und Chatbot-System', - regulations: ['DSGVO', 'AI Act'], - criticality: 'MEDIUM', - processesPersonalData: true, - hasAIComponents: true, - }, - ], - requirements: [ - { - id: 'demo-req-1', - regulation: 'DSGVO', - article: 'Art. 5', - title: 'Grundsätze der Verarbeitung', - description: 'Einhaltung der Grundsätze für die Verarbeitung personenbezogener Daten', - criticality: 'CRITICAL', - applicableModules: ['demo-mod-1', 'demo-mod-2', 'demo-mod-3'], - status: 'IMPLEMENTED', - controls: ['demo-ctrl-1', 'demo-ctrl-2', 'demo-ctrl-9'], - }, - { - id: 'demo-req-2', - regulation: 'DSGVO', - article: 'Art. 32', - title: 'Sicherheit der Verarbeitung', - description: 'Geeignete technische und organisatorische Maßnahmen', - criticality: 'CRITICAL', - applicableModules: ['demo-mod-1', 'demo-mod-2', 'demo-mod-3'], - status: 'IMPLEMENTED', - controls: ['demo-ctrl-1', 'demo-ctrl-3', 'demo-ctrl-4'], - }, - { - id: 'demo-req-3', - regulation: 'DSGVO', - article: 'Art. 25', - title: 'Datenschutz durch Technikgestaltung', - description: 'Privacy by Design und Privacy by Default', - criticality: 'HIGH', - applicableModules: ['demo-mod-1', 'demo-mod-2'], - status: 'IMPLEMENTED', - controls: ['demo-ctrl-9', 'demo-ctrl-10'], - }, - { - id: 'demo-req-4', - regulation: 'AI Act', - article: 'Art. 13', - title: 'Transparenz', - description: 'Transparenzanforderungen für KI-Systeme', - criticality: 'HIGH', - applicableModules: ['demo-mod-1', 'demo-mod-2', 'demo-mod-3'], - status: 'IMPLEMENTED', - controls: ['demo-ctrl-7', 'demo-ctrl-8'], - }, - { - id: 'demo-req-5', - regulation: 'AI Act', - article: 'Art. 9', - title: 'Risikomanagement', - description: 'Risikomanagementsystem für Hochrisiko-KI', - criticality: 'HIGH', - applicableModules: ['demo-mod-2'], - status: 'IMPLEMENTED', - controls: ['demo-ctrl-5', 'demo-ctrl-6', 'demo-ctrl-11', 'demo-ctrl-12'], - }, - ], - controls: getDemoControls(), - evidence: [ - { - id: 'demo-evi-1', - controlId: 'demo-ctrl-1', - type: 'SCREENSHOT', - name: 'MFA-Konfiguration Azure AD', - description: 'Screenshot der MFA-Einstellungen im Azure AD Admin Portal', - fileUrl: null, - validFrom: new Date('2026-01-01'), - validUntil: new Date('2027-01-01'), - uploadedBy: 'IT-Security', - uploadedAt: new Date('2026-01-10'), - }, - { - id: 'demo-evi-2', - controlId: 'demo-ctrl-2', - type: 'DOCUMENT', - name: 'Berechtigungskonzept v2.1', - description: 'Dokumentiertes Berechtigungskonzept mit Rollenmatrix', - fileUrl: null, - validFrom: new Date('2026-01-01'), - validUntil: null, - uploadedBy: 'IT-Security', - uploadedAt: new Date('2026-01-05'), - }, - { - id: 'demo-evi-5', - controlId: 'demo-ctrl-5', - type: 'AUDIT_REPORT', - name: 'Bias-Audit Q1/2026', - description: 'Externer Audit-Bericht zur Fairness des KI-Modells', - fileUrl: null, - validFrom: new Date('2026-01-15'), - validUntil: new Date('2026-04-15'), - uploadedBy: 'Data Science Lead', - uploadedAt: new Date('2026-01-20'), - }, - ], - checklist: [ - { - id: 'demo-chk-1', - requirementId: 'demo-req-1', - title: 'Rechtmäßigkeit der Verarbeitung geprüft', - description: 'Dokumentierte Prüfung der Rechtsgrundlagen', - status: 'PASSED', - notes: 'Geprüft durch DSB', - verifiedBy: 'DSB', - verifiedAt: new Date('2026-01-20'), - }, - { - id: 'demo-chk-2', - requirementId: 'demo-req-2', - title: 'TOMs dokumentiert und umgesetzt', - description: 'Technische und organisatorische Maßnahmen', - status: 'PASSED', - notes: 'Alle TOMs implementiert', - verifiedBy: 'CISO', - verifiedAt: new Date('2026-01-21'), - }, - ], - risks: getDemoRisks(), - - // Phase 2 Data - aiActClassification: { - riskCategory: 'HIGH', - systemType: 'Beschäftigungsbezogenes KI-System (Art. 6 Abs. 2 AI Act)', - obligations: [ - { - id: 'demo-ai-obl-1', - article: 'Art. 9', - title: 'Risikomanagementsystem', - description: 'Einrichtung eines KI-Risikomanagementsystems', - deadline: new Date('2026-08-01'), - status: 'IN_PROGRESS', - }, - { - id: 'demo-ai-obl-2', - article: 'Art. 10', - title: 'Daten-Governance', - description: 'Anforderungen an Trainingsdaten', - deadline: new Date('2026-08-01'), - status: 'COMPLETED', - }, - { - id: 'demo-ai-obl-3', - article: 'Art. 13', - title: 'Transparenz', - description: 'Dokumentation für Nutzer', - deadline: new Date('2026-08-01'), - status: 'COMPLETED', - }, - ], - assessmentDate: new Date('2026-01-25'), - assessedBy: 'Compliance Team', - justification: 'Das System fällt unter Art. 6 Abs. 2 lit. a AI Act (Einstellung und Auswahl von Personen).', - }, - obligations: [ - { - id: 'demo-obl-1', - regulation: 'DSGVO', - article: 'Art. 30', - title: 'Verarbeitungsverzeichnis', - description: 'Führung eines Verzeichnisses der Verarbeitungstätigkeiten', - deadline: null, - penalty: 'Bis zu 10 Mio. EUR oder 2% des Jahresumsatzes', - status: 'COMPLETED', - responsible: 'DSB', - }, - { - id: 'demo-obl-2', - regulation: 'DSGVO', - article: 'Art. 35', - title: 'Datenschutz-Folgenabschätzung', - description: 'Durchführung einer DSFA für Hochrisiko-Verarbeitungen', - deadline: null, - penalty: 'Bis zu 10 Mio. EUR oder 2% des Jahresumsatzes', - status: 'COMPLETED', - responsible: 'DSB', - }, - { - id: 'demo-obl-3', - regulation: 'AI Act', - article: 'Art. 49', - title: 'CE-Kennzeichnung', - description: 'CE-Kennzeichnung für Hochrisiko-KI-Systeme', - deadline: new Date('2026-08-01'), - penalty: 'Bis zu 35 Mio. EUR oder 7% des Jahresumsatzes', - status: 'PENDING', - responsible: 'Compliance', - }, - ], - dsfa: getDemoDSFA(), - toms: getDemoTOMs(), - retentionPolicies: getDemoRetentionPolicies(), - vvt: getDemoProcessingActivities(), - - // Documents, Cookie Banner, etc. - partially filled - documents: [], - cookieBanner: null, - consents: [], - dsrConfig: null, - escalationWorkflows: [], - - // Security - sbom: null, - securityIssues: [], - securityBacklog: [], - - // UI State - commandBarHistory: [], - recentSearches: ['DSGVO Art. 5', 'Bias-Monitoring', 'TOM Verschlüsselung'], - preferences: { - language: 'de', - theme: 'light', - compactMode: false, - showHints: true, - autoSave: true, - autoValidate: true, - allowParallelWork: true, - }, - } -} +// Re-export generateDemoState from its own module +export { generateDemoState } from './demo-state' +import { generateDemoState } from './demo-state' /** * Seed demo data into the database via API diff --git a/admin-compliance/lib/sdk/dsfa/mitigation-library.ts b/admin-compliance/lib/sdk/dsfa/mitigation-library.ts index d462663..20431a2 100644 --- a/admin-compliance/lib/sdk/dsfa/mitigation-library.ts +++ b/admin-compliance/lib/sdk/dsfa/mitigation-library.ts @@ -1,694 +1,12 @@ /** - * DSFA Massnahmenbibliothek - Vordefinierte Massnahmen + * DSFA Massnahmenbibliothek — Barrel * - * ~50 Massnahmen gegliedert nach SDM-Gewaehrleistungszielen - * (Vertraulichkeit, Integritaet, Verfuegbarkeit, Datenminimierung, - * Transparenz, Nichtverkettung, Intervenierbarkeit) sowie - * Automatisierung/KI, Rechtlich/Organisatorisch. - * - * Quellen: Art. 25/32 DSGVO, SDM V2.0, BSI Grundschutz, - * Baseline-DSFA Katalog + * Split into domain modules under mitigations/. + * Import from this file to preserve the stable public path. */ -import type { DSFAMitigationType } from './types' -import type { SDMGoal } from './types' - -// ============================================================================= -// TYPES -// ============================================================================= - -export interface CatalogMitigation { - id: string - type: DSFAMitigationType - sdmGoals: SDMGoal[] - title: string - description: string - legalBasis: string - evidenceTypes: string[] - addressesRiskIds: string[] - effectiveness: 'low' | 'medium' | 'high' -} - -// ============================================================================= -// MASSNAHMENBIBLIOTHEK -// ============================================================================= - -export const MITIGATION_LIBRARY: CatalogMitigation[] = [ - // ========================================================================= - // VERTRAULICHKEIT (Access Control & Encryption) - // ========================================================================= - { - id: 'M-ACC-01', - type: 'technical', - sdmGoals: ['vertraulichkeit'], - title: 'Multi-Faktor-Authentifizierung (MFA) & Conditional Access', - description: 'Einfuehrung von MFA fuer alle Benutzerkonten mit Zugriff auf personenbezogene Daten. Conditional Access Policies beschraenken den Zugriff basierend auf Standort, Geraet und Risikobewertung.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['MFA-Policy-Screenshot', 'Conditional-Access-Regeln', 'Login-Statistiken'], - addressesRiskIds: ['R-CONF-02', 'R-CONF-06'], - effectiveness: 'high', - }, - { - id: 'M-ACC-02', - type: 'technical', - sdmGoals: ['vertraulichkeit'], - title: 'Passwort-Policy & Credential-Schutz', - description: 'Durchsetzung starker Passwort-Richtlinien, Credential-Rotation, Einsatz eines Passwort-Managers und Monitoring auf kompromittierte Zugangsdaten (Breach Detection).', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['Passwort-Policy-Dokument', 'Breach-Detection-Report'], - addressesRiskIds: ['R-CONF-02'], - effectiveness: 'medium', - }, - { - id: 'M-CONF-01', - type: 'technical', - sdmGoals: ['vertraulichkeit'], - title: 'Rollenbasierte Zugriffskontrolle (RBAC) & Least Privilege', - description: 'Implementierung eines RBAC-Systems mit dem Prinzip der minimalen Berechtigung. Jeder Benutzer erhaelt nur die Rechte, die fuer seine Aufgabe erforderlich sind.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO, Art. 25 Abs. 2 DSGVO', - evidenceTypes: ['Rollen-Matrix', 'Berechtigungs-Audit-Report', 'Access-Review-Protokoll'], - addressesRiskIds: ['R-CONF-01', 'R-CONF-03', 'R-INT-04'], - effectiveness: 'high', - }, - { - id: 'M-CONF-02', - type: 'technical', - sdmGoals: ['vertraulichkeit'], - title: 'Security Configuration Management', - description: 'Regelmaessige Ueberpruefung und Haertung der Systemkonfiguration. Automatisierte Konfigurationschecks (CIS Benchmarks) und Monitoring auf Konfigurationsaenderungen.', - legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', - evidenceTypes: ['CIS-Benchmark-Report', 'Konfigurationsaenderungs-Log'], - addressesRiskIds: ['R-CONF-01'], - effectiveness: 'high', - }, - { - id: 'M-CONF-03', - type: 'organizational', - sdmGoals: ['vertraulichkeit'], - title: 'Regelmaessige Zugriffsrechte-Ueberpruefung (Access Review)', - description: 'Quartalsweiser Review aller Zugriffsberechtigungen durch Vorgesetzte. Entzug nicht mehr benoetigter Rechte, Offboarding-Prozess bei Mitarbeiteraustritt.', - legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', - evidenceTypes: ['Access-Review-Protokoll', 'Offboarding-Checkliste'], - addressesRiskIds: ['R-CONF-01', 'R-CONF-03'], - effectiveness: 'medium', - }, - { - id: 'M-CONF-04', - type: 'technical', - sdmGoals: ['vertraulichkeit', 'integritaet'], - title: 'Privileged Access Management (PAM)', - description: 'Absicherung administrativer Zugriffe durch Just-in-Time-Elevation, Session-Recording und Break-Glass-Prozeduren fuer Notfallzugriffe.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['PAM-Policy', 'Session-Recording-Logs', 'Break-Glass-Protokolle'], - addressesRiskIds: ['R-CONF-03', 'R-INT-04'], - effectiveness: 'high', - }, - { - id: 'M-CONF-05', - type: 'organizational', - sdmGoals: ['vertraulichkeit'], - title: 'Vier-Augen-Prinzip fuer sensible Operationen', - description: 'Fuer den Zugriff auf besonders schutzwuerdige Daten oder kritische Systemoperationen ist die Genehmigung durch eine zweite Person erforderlich.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['Prozessbeschreibung', 'Genehmigungsprotokoll'], - addressesRiskIds: ['R-CONF-03'], - effectiveness: 'medium', - }, - { - id: 'M-CONF-06', - type: 'technical', - sdmGoals: ['vertraulichkeit'], - title: 'Verschluesselung at-rest und in-transit', - description: 'Vollstaendige Verschluesselung personenbezogener Daten bei Speicherung (AES-256) und Uebertragung (TLS 1.3). Verwaltung der Schluessel ueber ein zentrales Key-Management-System.', - legalBasis: 'Art. 32 Abs. 1 lit. a DSGVO', - evidenceTypes: ['Verschluesselungs-Policy', 'TLS-Konfigurationsreport', 'KMS-Audit'], - addressesRiskIds: ['R-CONF-04', 'R-TRANS-01', 'R-AUTO-05'], - effectiveness: 'high', - }, - { - id: 'M-CONF-07', - type: 'technical', - sdmGoals: ['vertraulichkeit'], - title: 'End-to-End-Verschluesselung fuer Kommunikation', - description: 'Einsatz von End-to-End-Verschluesselung fuer sensible Kommunikation (E-Mail, Messaging), sodass auch der Betreiber keinen Zugriff auf die Inhalte hat.', - legalBasis: 'Art. 32 Abs. 1 lit. a DSGVO', - evidenceTypes: ['E2E-Konfiguration', 'Testbericht'], - addressesRiskIds: ['R-CONF-04'], - effectiveness: 'high', - }, - { - id: 'M-CONF-08', - type: 'technical', - sdmGoals: ['vertraulichkeit', 'datenminimierung'], - title: 'Log-Sanitization & PII-Filtering', - description: 'Automatische Filterung personenbezogener Daten aus Logs, Fehlermeldungen und Debug-Ausgaben. Einsatz von Tokenisierung oder Maskierung.', - legalBasis: 'Art. 25 Abs. 1 DSGVO, Art. 32 Abs. 1 lit. a DSGVO', - evidenceTypes: ['Log-Policy', 'PII-Filter-Konfiguration', 'Stichproben-Audit'], - addressesRiskIds: ['R-CONF-07'], - effectiveness: 'medium', - }, - - // ========================================================================= - // INTEGRITAET (Audit, Monitoring, Integrity Checks) - // ========================================================================= - { - id: 'M-INT-01', - type: 'technical', - sdmGoals: ['integritaet'], - title: 'Input-Validierung & Injection-Schutz', - description: 'Konsequente Validierung aller Eingaben, Prepared Statements fuer Datenbankzugriffe, Content Security Policy und Output-Encoding zum Schutz vor Injection-Angriffen.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['SAST-Report', 'Penetrationstest-Bericht', 'WAF-Regeln'], - addressesRiskIds: ['R-INT-01'], - effectiveness: 'high', - }, - { - id: 'M-INT-02', - type: 'technical', - sdmGoals: ['integritaet', 'transparenz'], - title: 'Audit-Logging & SIEM-Integration', - description: 'Lueckenlose Protokollierung aller sicherheitsrelevanten Ereignisse mit Weiterleitung an ein SIEM-System. Manipulation-sichere Logs mit Integritaetspruefung.', - legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', - evidenceTypes: ['SIEM-Dashboard-Screenshot', 'Audit-Log-Beispiel', 'Alert-Regeln'], - addressesRiskIds: ['R-INT-01', 'R-INT-04', 'R-INT-05', 'R-CONF-03', 'R-ORG-04'], - effectiveness: 'high', - }, - { - id: 'M-INT-03', - type: 'technical', - sdmGoals: ['integritaet'], - title: 'Web Application Firewall (WAF) & API-Gateway', - description: 'Einsatz einer WAF zum Schutz vor OWASP Top 10 Angriffen und eines API-Gateways fuer Rate-Limiting, Schema-Validierung und Anomalie-Erkennung.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['WAF-Regelset', 'API-Gateway-Konfiguration', 'Blockierungs-Statistiken'], - addressesRiskIds: ['R-INT-01'], - effectiveness: 'medium', - }, - { - id: 'M-INT-04', - type: 'technical', - sdmGoals: ['integritaet'], - title: 'Daten-Synchronisations-Monitoring & Integritaetspruefung', - description: 'Automatische Ueberwachung von Synchronisationsprozessen mit Checksummen-Vergleich, Konflikterkennung und Alerting bei Inkonsistenzen.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['Sync-Monitoring-Dashboard', 'Checksummen-Report', 'Incident-Log'], - addressesRiskIds: ['R-INT-02'], - effectiveness: 'medium', - }, - { - id: 'M-INT-05', - type: 'technical', - sdmGoals: ['integritaet'], - title: 'Versionierung & Change-Tracking fuer personenbezogene Daten', - description: 'Alle Aenderungen an personenbezogenen Daten werden versioniert gespeichert (Audit-Trail). Wer hat wann was geaendert ist jederzeit nachvollziehbar.', - legalBasis: 'Art. 5 Abs. 1 lit. f DSGVO', - evidenceTypes: ['Versionierungs-Schema', 'Change-Log-Beispiel'], - addressesRiskIds: ['R-INT-02', 'R-INT-05'], - effectiveness: 'medium', - }, - - // ========================================================================= - // VERFUEGBARKEIT (Backup, Recovery, Redundancy) - // ========================================================================= - { - id: 'M-AVAIL-01', - type: 'technical', - sdmGoals: ['verfuegbarkeit'], - title: 'Backup-Strategie mit 3-2-1-Regel', - description: 'Implementierung einer Backup-Strategie nach der 3-2-1-Regel: 3 Kopien, 2 verschiedene Medien, 1 Offsite. Verschluesselte Backups mit regelmaessiger Integritaetspruefung.', - legalBasis: 'Art. 32 Abs. 1 lit. c DSGVO', - evidenceTypes: ['Backup-Policy', 'Backup-Monitoring-Report', 'Offsite-Nachweis'], - addressesRiskIds: ['R-AVAIL-01', 'R-AVAIL-03', 'R-INT-03'], - effectiveness: 'high', - }, - { - id: 'M-AVAIL-02', - type: 'organizational', - sdmGoals: ['verfuegbarkeit'], - title: 'Regelmaessige Restore-Tests & Disaster Recovery Uebungen', - description: 'Mindestens quartalsweise Durchfuehrung von Restore-Tests und jaehrliche Disaster-Recovery-Uebungen. Dokumentation der Ergebnisse und Lessons Learned.', - legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', - evidenceTypes: ['Restore-Test-Protokoll', 'DR-Uebungs-Dokumentation', 'RTO/RPO-Nachweis'], - addressesRiskIds: ['R-AVAIL-01', 'R-AVAIL-03', 'R-INT-03'], - effectiveness: 'high', - }, - { - id: 'M-AVAIL-03', - type: 'technical', - sdmGoals: ['verfuegbarkeit'], - title: 'Endpoint Protection & Anti-Ransomware', - description: 'Einsatz von Endpoint-Detection-and-Response (EDR) Loesungen mit spezifischem Ransomware-Schutz, Verhaltensanalyse und automatischer Isolation kompromittierter Systeme.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['EDR-Dashboard', 'Threat-Detection-Statistiken', 'Incident-Response-Plan'], - addressesRiskIds: ['R-AVAIL-01'], - effectiveness: 'high', - }, - { - id: 'M-AVAIL-04', - type: 'technical', - sdmGoals: ['verfuegbarkeit'], - title: 'Redundanz & High-Availability-Architektur', - description: 'Redundante Systemauslegung mit automatischem Failover, Load-Balancing und geo-redundanter Datenhaltung zur Sicherstellung der Verfuegbarkeit.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['HA-Architekturdiagramm', 'Failover-Testprotokoll', 'SLA-Dokumentation'], - addressesRiskIds: ['R-AVAIL-02', 'R-AVAIL-04'], - effectiveness: 'high', - }, - { - id: 'M-AVAIL-05', - type: 'organizational', - sdmGoals: ['verfuegbarkeit', 'intervenierbarkeit'], - title: 'Exit-Strategie & Datenportabilitaetsplan', - description: 'Dokumentierte Exit-Strategie fuer jeden kritischen Anbieter mit Datenexport-Verfahren, Migrationsplan und Uebergangsfristen. Regelmaessiger Export-Test.', - legalBasis: 'Art. 28 Abs. 3 lit. g DSGVO, Art. 20 DSGVO', - evidenceTypes: ['Exit-Plan-Dokument', 'Export-Test-Protokoll', 'Vertragliche-Regelung'], - addressesRiskIds: ['R-AVAIL-02', 'R-AVAIL-05'], - effectiveness: 'medium', - }, - { - id: 'M-AVAIL-06', - type: 'technical', - sdmGoals: ['verfuegbarkeit'], - title: 'DDoS-Schutz & Rate-Limiting', - description: 'Einsatz von DDoS-Mitigation-Services, CDN-basiertem Schutz und anwendungsspezifischem Rate-Limiting zur Abwehr von Verfuegbarkeitsangriffen.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['DDoS-Schutz-Konfiguration', 'Rate-Limit-Regeln', 'Traffic-Analyse'], - addressesRiskIds: ['R-AVAIL-04'], - effectiveness: 'high', - }, - - // ========================================================================= - // DATENMINIMIERUNG (Retention, Anonymization, Purpose Limitation) - // ========================================================================= - { - id: 'M-DMIN-01', - type: 'technical', - sdmGoals: ['datenminimierung'], - title: 'Privacy by Design: Datenerhebung auf das Minimum beschraenken', - description: 'Technische Massnahmen zur Beschraenkung der Datenerhebung: Pflichtfelder minimieren, optionale Felder deutlich kennzeichnen, Default-Einstellungen datenschutzfreundlich.', - legalBasis: 'Art. 25 Abs. 1 DSGVO', - evidenceTypes: ['Formular-Review', 'Default-Settings-Dokumentation'], - addressesRiskIds: ['R-RIGHTS-07', 'R-CONF-07'], - effectiveness: 'medium', - }, - { - id: 'M-DMIN-02', - type: 'technical', - sdmGoals: ['datenminimierung', 'nichtverkettung'], - title: 'Pseudonymisierung & Anonymisierung', - description: 'Einsatz von Pseudonymisierungsverfahren (Token-basiert, Hash-basiert) und k-Anonymity/Differential Privacy bei der Weitergabe oder Analyse von Daten.', - legalBasis: 'Art. 25 Abs. 1 DSGVO, Art. 32 Abs. 1 lit. a DSGVO', - evidenceTypes: ['Pseudonymisierungs-Konzept', 'Re-Identifizierungs-Risiko-Analyse'], - addressesRiskIds: ['R-RIGHTS-04', 'R-RIGHTS-07'], - effectiveness: 'high', - }, - { - id: 'M-DMIN-03', - type: 'technical', - sdmGoals: ['datenminimierung'], - title: 'Automatisiertes Loeschkonzept mit Aufbewahrungsfristen', - description: 'Implementierung automatischer Loeschroutinen basierend auf definierten Aufbewahrungsfristen. Monitoring der Loeschvorgaenge und Nachweis der Loeschung.', - legalBasis: 'Art. 5 Abs. 1 lit. e DSGVO, Art. 17 DSGVO', - evidenceTypes: ['Loeschkonzept-Dokument', 'Loeschfrist-Uebersicht', 'Loeschprotokoll'], - addressesRiskIds: ['R-RIGHTS-07', 'R-ORG-02'], - effectiveness: 'high', - }, - { - id: 'M-DMIN-04', - type: 'organizational', - sdmGoals: ['datenminimierung'], - title: 'Regelmaessige Ueberpruefung der Datenbestaende', - description: 'Jaehrlicher Review aller gespeicherten personenbezogenen Daten auf Erforderlichkeit. Identifikation und Bereinigung von Altbestaenden, verwaisten Datensaetzen und redundanten Kopien.', - legalBasis: 'Art. 5 Abs. 1 lit. e DSGVO', - evidenceTypes: ['Datenbestand-Review-Bericht', 'Bereinigungs-Protokoll'], - addressesRiskIds: ['R-ORG-02'], - effectiveness: 'medium', - }, - - // ========================================================================= - // TRANSPARENZ (Information, Documentation, Auditability) - // ========================================================================= - { - id: 'M-TRANS-01', - type: 'organizational', - sdmGoals: ['transparenz'], - title: 'Datenschutzhinweise & Privacy Notices', - description: 'Umfassende, verstaendliche Datenschutzhinweise gemaess Art. 13/14 DSGVO an allen Erhebungsstellen. Layered-Approach fuer unterschiedliche Detailstufen.', - legalBasis: 'Art. 13, Art. 14 DSGVO', - evidenceTypes: ['Privacy-Notice-Review', 'Zustellungs-Nachweis', 'Usability-Test'], - addressesRiskIds: ['R-CONF-05', 'R-RIGHTS-02', 'R-RIGHTS-03', 'R-RIGHTS-06', 'R-TRANS-03', 'R-SPEC-02'], - effectiveness: 'medium', - }, - { - id: 'M-TRANS-02', - type: 'technical', - sdmGoals: ['transparenz'], - title: 'Vollstaendiger Audit-Trail fuer personenbezogene Daten', - description: 'Lueckenloser, manipulationssicherer Audit-Trail fuer alle Verarbeitungsvorgaenge personenbezogener Daten. Wer hat wann auf welche Daten zugegriffen oder sie veraendert.', - legalBasis: 'Art. 5 Abs. 2 DSGVO (Rechenschaftspflicht)', - evidenceTypes: ['Audit-Trail-Architektur', 'Log-Integritaets-Nachweis', 'Beispiel-Audit-Export'], - addressesRiskIds: ['R-INT-05'], - effectiveness: 'high', - }, - { - id: 'M-TRANS-03', - type: 'technical', - sdmGoals: ['transparenz'], - title: 'Erklaerbarkeit von KI-Entscheidungen (Explainability)', - description: 'Implementierung von Erklaerungsverfahren (SHAP, LIME, Feature-Importance) fuer automatisierte Entscheidungen. Bereitstellung verstaendlicher Begruendungen fuer Betroffene.', - legalBasis: 'Art. 22 Abs. 3 DSGVO, Art. 13 Abs. 2 lit. f DSGVO', - evidenceTypes: ['XAI-Konzept', 'Erklaerbarkeits-Beispiel', 'Betroffenen-Information'], - addressesRiskIds: ['R-AUTO-01', 'R-AUTO-03', 'R-RIGHTS-01'], - effectiveness: 'medium', - }, - { - id: 'M-TRANS-04', - type: 'organizational', - sdmGoals: ['transparenz'], - title: 'Ueberwachungs-Folgenabschaetzung & Informationspflicht', - description: 'Bei systematischer Ueberwachung: Gesonderte Folgenabschaetzung, klare Beschilderung/Information, Verhaeltnismaessigkeitspruefung und zeitliche Begrenzung.', - legalBasis: 'Art. 35 Abs. 3 lit. c DSGVO, Art. 13 DSGVO', - evidenceTypes: ['Ueberwachungs-DSFA', 'Beschilderungs-Nachweis', 'Verhaeltnismaessigkeits-Bewertung'], - addressesRiskIds: ['R-RIGHTS-03'], - effectiveness: 'medium', - }, - { - id: 'M-TRANS-05', - type: 'organizational', - sdmGoals: ['transparenz'], - title: 'Verzeichnis von Verarbeitungstaetigkeiten (VVT) pflegen', - description: 'Vollstaendiges und aktuelles VVT gemaess Art. 30 DSGVO fuer alle Verarbeitungstaetigkeiten. Regelmaessige Aktualisierung bei Aenderungen.', - legalBasis: 'Art. 30 DSGVO', - evidenceTypes: ['VVT-Export', 'Aktualisierungs-Log'], - addressesRiskIds: ['R-RIGHTS-06'], - effectiveness: 'medium', - }, - { - id: 'M-TRANS-06', - type: 'legal', - sdmGoals: ['transparenz', 'vertraulichkeit'], - title: 'Transfer Impact Assessment (TIA) fuer Drittlandtransfer', - description: 'Durchfuehrung eines Transfer Impact Assessments vor jedem Drittlandtransfer. Bewertung des Schutzniveaus im Empfaengerland und Festlegung zusaetzlicher Garantien.', - legalBasis: 'Art. 46 DSGVO, Schrems-II-Urteil', - evidenceTypes: ['TIA-Dokument', 'Schutzniveau-Analyse', 'Zusaetzliche-Garantien-Vereinbarung'], - addressesRiskIds: ['R-TRANS-01', 'R-TRANS-02'], - effectiveness: 'high', - }, - { - id: 'M-TRANS-07', - type: 'legal', - sdmGoals: ['vertraulichkeit'], - title: 'Standardvertragsklauseln (SCC) & Supplementary Measures', - description: 'Abschluss aktueller EU-Standardvertragsklauseln (2021/914) mit Auftragsverarbeitern im Drittland. Ergaenzende technische und organisatorische Massnahmen (Verschluesselung, Pseudonymisierung).', - legalBasis: 'Art. 46 Abs. 2 lit. c DSGVO', - evidenceTypes: ['Unterzeichnete SCC', 'Supplementary-Measures-Dokumentation'], - addressesRiskIds: ['R-TRANS-01', 'R-TRANS-02'], - effectiveness: 'medium', - }, - - // ========================================================================= - // NICHTVERKETTUNG (Purpose Limitation, Data Separation, DLP) - // ========================================================================= - { - id: 'M-NONL-01', - type: 'technical', - sdmGoals: ['nichtverkettung'], - title: 'Zweckbindung & Consent-Management', - description: 'Technische Durchsetzung der Zweckbindung: Daten werden nur fuer den erhobenen Zweck verwendet. Consent-Management-System protokolliert und erzwingt Einwilligungen.', - legalBasis: 'Art. 5 Abs. 1 lit. b DSGVO, Art. 6 Abs. 1 lit. a DSGVO', - evidenceTypes: ['Consent-Management-System', 'Zweckbindungs-Matrix', 'Consent-Protokolle'], - addressesRiskIds: ['R-CONF-05', 'R-RIGHTS-02', 'R-RIGHTS-03'], - effectiveness: 'high', - }, - { - id: 'M-NONL-02', - type: 'technical', - sdmGoals: ['nichtverkettung'], - title: 'Data Loss Prevention (DLP) & Datenklassifikation', - description: 'Implementierung von DLP-Regeln zur Verhinderung unkontrollierter Datenweitergabe. Datenklassifikation (oeffentlich, intern, vertraulich, streng vertraulich) als Grundlage.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', - evidenceTypes: ['DLP-Policy', 'Datenklassifikations-Schema', 'DLP-Incident-Report'], - addressesRiskIds: ['R-RIGHTS-02'], - effectiveness: 'medium', - }, - { - id: 'M-NONL-03', - type: 'technical', - sdmGoals: ['nichtverkettung', 'datenminimierung'], - title: 'Differential Privacy & k-Anonymity bei Datenanalysen', - description: 'Einsatz von Differential Privacy oder k-Anonymity-Verfahren bei der Analyse personenbezogener Daten, um Re-Identifizierung zu verhindern.', - legalBasis: 'Art. 25 Abs. 1 DSGVO', - evidenceTypes: ['Anonymisierungs-Konzept', 'Privacy-Budget-Berechnung', 'k-Anonymity-Nachweis'], - addressesRiskIds: ['R-RIGHTS-04', 'R-AUTO-05'], - effectiveness: 'high', - }, - { - id: 'M-NONL-04', - type: 'technical', - sdmGoals: ['nichtverkettung'], - title: 'Mandantentrennung & Datenisolierung', - description: 'Strikte logische oder physische Trennung personenbezogener Daten verschiedener Mandanten/Zwecke. Verhinderung unbeabsichtigter Zusammenfuehrung.', - legalBasis: 'Art. 5 Abs. 1 lit. b DSGVO', - evidenceTypes: ['Mandantentrennungs-Konzept', 'Isolierungs-Test-Bericht'], - addressesRiskIds: ['R-RIGHTS-04'], - effectiveness: 'high', - }, - - // ========================================================================= - // INTERVENIERBARKEIT (Data Subject Rights, Correction, Deletion) - // ========================================================================= - { - id: 'M-INTERV-01', - type: 'technical', - sdmGoals: ['intervenierbarkeit'], - title: 'DSAR-Workflow (Data Subject Access Request)', - description: 'Automatisierter Workflow fuer Betroffenenanfragen (Auskunft, Loeschung, Berichtigung, Export). Fristenmanagement (1 Monat), Identitaetspruefung und Dokumentation.', - legalBasis: 'Art. 15-22 DSGVO, Art. 12 Abs. 3 DSGVO', - evidenceTypes: ['DSAR-Workflow-Dokumentation', 'Bearbeitungszeiten-Statistik', 'Audit-Trail'], - addressesRiskIds: ['R-RIGHTS-05', 'R-AVAIL-05'], - effectiveness: 'high', - }, - { - id: 'M-INTERV-02', - type: 'technical', - sdmGoals: ['intervenierbarkeit'], - title: 'Self-Service Datenverwaltung fuer Betroffene', - description: 'Bereitstellung eines Self-Service-Portals, ueber das Betroffene ihre Daten einsehen, korrigieren, exportieren und die Loeschung beantragen koennen.', - legalBasis: 'Art. 15-20 DSGVO', - evidenceTypes: ['Portal-Screenshot', 'Funktions-Testprotokoll', 'Nutzungs-Statistik'], - addressesRiskIds: ['R-RIGHTS-05'], - effectiveness: 'high', - }, - { - id: 'M-INTERV-03', - type: 'organizational', - sdmGoals: ['intervenierbarkeit'], - title: 'Widerspruchs- und Einschraenkungsprozess', - description: 'Definierter Prozess fuer die Bearbeitung von Widerspruechen (Art. 21) und Einschraenkungsersuchen (Art. 18). Technische Moeglichkeit zur Sperrung einzelner Datensaetze.', - legalBasis: 'Art. 18, Art. 21 DSGVO', - evidenceTypes: ['Prozessbeschreibung', 'Sperr-Funktionalitaets-Nachweis'], - addressesRiskIds: ['R-RIGHTS-05'], - effectiveness: 'medium', - }, - { - id: 'M-INTERV-04', - type: 'organizational', - sdmGoals: ['intervenierbarkeit'], - title: 'Human-in-the-Loop bei automatisierten Entscheidungen', - description: 'Sicherstellung menschlicher Ueberpruefung bei automatisierten Entscheidungen mit erheblicher Auswirkung. Eskalationsprozess und Einspruchsmoeglichkeit fuer Betroffene.', - legalBasis: 'Art. 22 Abs. 3 DSGVO', - evidenceTypes: ['HITL-Prozessbeschreibung', 'Eskalations-Statistik', 'Einspruchs-Protokoll'], - addressesRiskIds: ['R-AUTO-04'], - effectiveness: 'high', - }, - - // ========================================================================= - // AUTOMATISIERUNG / KI - // ========================================================================= - { - id: 'M-AUTO-01', - type: 'technical', - sdmGoals: ['nichtverkettung', 'transparenz'], - title: 'Bias-Monitoring & Fairness-Tests', - description: 'Regelmaessige Ueberpruefung von KI-Modellen auf Bias und Diskriminierung. Fairness-Metriken (Demographic Parity, Equal Opportunity) und Korrekturmassnahmen bei Abweichungen.', - legalBasis: 'Art. 22 Abs. 3 DSGVO, AI Act Art. 10', - evidenceTypes: ['Bias-Audit-Report', 'Fairness-Metriken-Dashboard', 'Korrektur-Dokumentation'], - addressesRiskIds: ['R-RIGHTS-01', 'R-AUTO-01', 'R-AUTO-02'], - effectiveness: 'high', - }, - { - id: 'M-AUTO-02', - type: 'technical', - sdmGoals: ['transparenz'], - title: 'KI-Modell-Dokumentation & Model Cards', - description: 'Ausfuehrliche Dokumentation aller KI-Modelle: Trainingsdaten, Architektur, Performance-Metriken, bekannte Einschraenkungen, Einsatzzweck (Model Cards).', - legalBasis: 'Art. 13 Abs. 2 lit. f DSGVO, AI Act Art. 11', - evidenceTypes: ['Model-Card', 'Performance-Report', 'Einsatzbereich-Dokumentation'], - addressesRiskIds: ['R-AUTO-01', 'R-AUTO-03'], - effectiveness: 'medium', - }, - { - id: 'M-AUTO-03', - type: 'organizational', - sdmGoals: ['intervenierbarkeit', 'transparenz'], - title: 'KI-Governance-Framework & Human Oversight Board', - description: 'Etablierung eines KI-Governance-Frameworks mit einem Human Oversight Board, das alle KI-Systeme mit hohem Risiko ueberwacht und Interventionsmoeglichkeiten hat.', - legalBasis: 'Art. 22 DSGVO, AI Act Art. 14', - evidenceTypes: ['Governance-Policy', 'Oversight-Board-Protokolle', 'Interventions-Log'], - addressesRiskIds: ['R-AUTO-01', 'R-AUTO-04'], - effectiveness: 'high', - }, - { - id: 'M-AUTO-04', - type: 'technical', - sdmGoals: ['nichtverkettung', 'datenminimierung'], - title: 'Datenschutzkonformes KI-Training (Privacy-Preserving ML)', - description: 'Einsatz von Federated Learning, Differential Privacy beim Training oder synthetischen Trainingsdaten, um personenbezogene Daten im Modell zu schuetzen.', - legalBasis: 'Art. 25 Abs. 1 DSGVO', - evidenceTypes: ['Privacy-Preserving-ML-Konzept', 'Training-Daten-Analyse', 'Modell-Invertierbarkeiots-Test'], - addressesRiskIds: ['R-AUTO-02', 'R-AUTO-05'], - effectiveness: 'high', - }, - - // ========================================================================= - // ORGANISATORISCHE MASSNAHMEN - // ========================================================================= - { - id: 'M-ORG-01', - type: 'organizational', - sdmGoals: ['vertraulichkeit', 'integritaet'], - title: 'Datenschutz-Schulungen & Awareness-Programm', - description: 'Regelmaessige verpflichtende Datenschutz-Schulungen fuer alle Mitarbeiter. Awareness-Kampagnen zu Phishing, Social Engineering und sicherem Datenumgang.', - legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO, Art. 39 Abs. 1 lit. a DSGVO', - evidenceTypes: ['Schulungsplan', 'Teilnahmequoten', 'Phishing-Simulations-Ergebnis'], - addressesRiskIds: ['R-CONF-06', 'R-ORG-03'], - effectiveness: 'medium', - }, - { - id: 'M-ORG-02', - type: 'organizational', - sdmGoals: ['integritaet'], - title: 'Verpflichtung auf Vertraulichkeit & Datenschutz-Policy', - description: 'Schriftliche Verpflichtung aller Mitarbeiter und externen Dienstleister auf Vertraulichkeit und Einhaltung der Datenschutz-Policies.', - legalBasis: 'Art. 28 Abs. 3 lit. b DSGVO, Art. 29 DSGVO', - evidenceTypes: ['Unterzeichnete-Verpflichtungserklaerung', 'Datenschutz-Policy'], - addressesRiskIds: ['R-ORG-03'], - effectiveness: 'medium', - }, - { - id: 'M-ORG-03', - type: 'organizational', - sdmGoals: ['transparenz'], - title: 'Datenpannen-Erkennungs- und Meldeprozess (Incident Response)', - description: 'Definierter Incident-Response-Prozess mit klaren Eskalationswegen, 72h-Meldepflicht-Tracking, Klassifizierungsschema und Kommunikationsplan.', - legalBasis: 'Art. 33, Art. 34 DSGVO', - evidenceTypes: ['Incident-Response-Plan', 'Melde-Template', 'Uebungs-Protokoll'], - addressesRiskIds: ['R-ORG-04'], - effectiveness: 'high', - }, - { - id: 'M-ORG-04', - type: 'technical', - sdmGoals: ['transparenz', 'verfuegbarkeit'], - title: 'Automatisiertes Breach-Detection & Alerting', - description: 'Automatische Erkennung von Datenpannen durch Anomalie-Detection, ungewoehnliche Zugriffsmuster und Datenexfiltrations-Erkennung mit sofortigem Alert an den Incident-Response-Team.', - legalBasis: 'Art. 33 Abs. 1 DSGVO', - evidenceTypes: ['Alert-Regeln', 'Detection-Dashboard', 'Reaktionszeiten-Statistik'], - addressesRiskIds: ['R-ORG-04'], - effectiveness: 'high', - }, - - // ========================================================================= - // RECHTLICHE MASSNAHMEN - // ========================================================================= - { - id: 'M-LEGAL-01', - type: 'legal', - sdmGoals: ['transparenz'], - title: 'Angemessenheitsbeschluss oder Binding Corporate Rules (BCR)', - description: 'Sicherstellung, dass Drittlandtransfers auf einem Angemessenheitsbeschluss oder genehmigten BCRs basieren. Laufende Ueberwachung des Schutzniveaus.', - legalBasis: 'Art. 45, Art. 47 DSGVO', - evidenceTypes: ['Angemessenheitsbeschluss-Referenz', 'BCR-Genehmigung'], - addressesRiskIds: ['R-TRANS-02'], - effectiveness: 'high', - }, - { - id: 'M-LEGAL-02', - type: 'legal', - sdmGoals: ['transparenz'], - title: 'Auftragsverarbeitungsvertrag (AVV) nach Art. 28 DSGVO', - description: 'Abschluss vollstaendiger AVVs mit allen Auftragsverarbeitern. Regelung von Zweck, Dauer, Datenkategorien, Weisungsbindung, Sub-Auftragsverarbeiter und Audit-Rechten.', - legalBasis: 'Art. 28 Abs. 3 DSGVO', - evidenceTypes: ['Unterzeichneter-AVV', 'Sub-Auftragsverarbeiter-Liste', 'Audit-Bericht'], - addressesRiskIds: ['R-ORG-01', 'R-TRANS-03'], - effectiveness: 'high', - }, - { - id: 'M-LEGAL-03', - type: 'legal', - sdmGoals: ['transparenz'], - title: 'Regelmaessige Auftragsverarbeiter-Audits', - description: 'Jaehrliche Ueberpruefung der Auftragsverarbeiter auf Einhaltung der AVV-Vorgaben. Dokumentierte Audits vor Ort oder anhand von Zertifizierungen (SOC 2, ISO 27001).', - legalBasis: 'Art. 28 Abs. 3 lit. h DSGVO', - evidenceTypes: ['Audit-Bericht', 'Zertifizierungs-Nachweis', 'Massnahmenplan'], - addressesRiskIds: ['R-ORG-01'], - effectiveness: 'medium', - }, - { - id: 'M-LEGAL-04', - type: 'legal', - sdmGoals: ['intervenierbarkeit', 'transparenz'], - title: 'Altersverifikation & Eltern-Einwilligung (Art. 8)', - description: 'Implementierung einer altersgerechten Verifikation und Einholung der Eltern-Einwilligung bei Minderjaehrigen unter 16 Jahren. Kindgerechte Datenschutzinformationen.', - legalBasis: 'Art. 8 DSGVO, EG 38 DSGVO', - evidenceTypes: ['Altersverifikations-Konzept', 'Eltern-Einwilligungs-Formular', 'Kindgerechte-Privacy-Notice'], - addressesRiskIds: ['R-SPEC-02'], - effectiveness: 'medium', - }, -] - -// ============================================================================= -// HELPER FUNCTIONS -// ============================================================================= - -export function getMitigationsBySDMGoal(goal: SDMGoal): CatalogMitigation[] { - return MITIGATION_LIBRARY.filter(m => m.sdmGoals.includes(goal)) -} - -export function getMitigationsByType(type: DSFAMitigationType): CatalogMitigation[] { - return MITIGATION_LIBRARY.filter(m => m.type === type) -} - -export function getMitigationsForRisk(riskId: string): CatalogMitigation[] { - return MITIGATION_LIBRARY.filter(m => m.addressesRiskIds.includes(riskId)) -} - -export function getCatalogMitigationById(id: string): CatalogMitigation | undefined { - return MITIGATION_LIBRARY.find(m => m.id === id) -} - -export function getMitigationsByEffectiveness(effectiveness: 'low' | 'medium' | 'high'): CatalogMitigation[] { - return MITIGATION_LIBRARY.filter(m => m.effectiveness === effectiveness) -} - -export const MITIGATION_TYPE_LABELS: Record = { - technical: 'Technisch', - organizational: 'Organisatorisch', - legal: 'Rechtlich', -} - -export const SDM_GOAL_LABELS: Record = { - datenminimierung: 'Datenminimierung', - verfuegbarkeit: 'Verfuegbarkeit', - integritaet: 'Integritaet', - vertraulichkeit: 'Vertraulichkeit', - nichtverkettung: 'Nichtverkettung', - transparenz: 'Transparenz', - intervenierbarkeit: 'Intervenierbarkeit', -} - -export const EFFECTIVENESS_LABELS: Record = { - low: 'Gering', - medium: 'Mittel', - high: 'Hoch', -} +export type { CatalogMitigation } from './mitigations/types' +export * from './mitigations/access-integrity' +export * from './mitigations/availability-minimization' +export * from './mitigations/transparency-intervention-org' +export * from './mitigations/helpers' diff --git a/admin-compliance/lib/sdk/dsfa/mitigations/access-integrity.ts b/admin-compliance/lib/sdk/dsfa/mitigations/access-integrity.ts new file mode 100644 index 0000000..5658cf8 --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/mitigations/access-integrity.ts @@ -0,0 +1,176 @@ +/** + * DSFA Massnahmenbibliothek — Vertraulichkeit / Zugriff & Integritaet + */ + +import type { CatalogMitigation } from './types' + +export const ACCESS_CONTROL_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-ACC-01', + type: 'technical', + sdmGoals: ['vertraulichkeit'], + title: 'Multi-Faktor-Authentifizierung (MFA) & Conditional Access', + description: 'Einfuehrung von MFA fuer alle Benutzerkonten mit Zugriff auf personenbezogene Daten. Conditional Access Policies beschraenken den Zugriff basierend auf Standort, Geraet und Risikobewertung.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['MFA-Policy-Screenshot', 'Conditional-Access-Regeln', 'Login-Statistiken'], + addressesRiskIds: ['R-CONF-02', 'R-CONF-06'], + effectiveness: 'high', + }, + { + id: 'M-ACC-02', + type: 'technical', + sdmGoals: ['vertraulichkeit'], + title: 'Passwort-Policy & Credential-Schutz', + description: 'Durchsetzung starker Passwort-Richtlinien, Credential-Rotation, Einsatz eines Passwort-Managers und Monitoring auf kompromittierte Zugangsdaten (Breach Detection).', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['Passwort-Policy-Dokument', 'Breach-Detection-Report'], + addressesRiskIds: ['R-CONF-02'], + effectiveness: 'medium', + }, + { + id: 'M-CONF-01', + type: 'technical', + sdmGoals: ['vertraulichkeit'], + title: 'Rollenbasierte Zugriffskontrolle (RBAC) & Least Privilege', + description: 'Implementierung eines RBAC-Systems mit dem Prinzip der minimalen Berechtigung. Jeder Benutzer erhaelt nur die Rechte, die fuer seine Aufgabe erforderlich sind.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO, Art. 25 Abs. 2 DSGVO', + evidenceTypes: ['Rollen-Matrix', 'Berechtigungs-Audit-Report', 'Access-Review-Protokoll'], + addressesRiskIds: ['R-CONF-01', 'R-CONF-03', 'R-INT-04'], + effectiveness: 'high', + }, + { + id: 'M-CONF-02', + type: 'technical', + sdmGoals: ['vertraulichkeit'], + title: 'Security Configuration Management', + description: 'Regelmaessige Ueberpruefung und Haertung der Systemkonfiguration. Automatisierte Konfigurationschecks (CIS Benchmarks) und Monitoring auf Konfigurationsaenderungen.', + legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', + evidenceTypes: ['CIS-Benchmark-Report', 'Konfigurationsaenderungs-Log'], + addressesRiskIds: ['R-CONF-01'], + effectiveness: 'high', + }, + { + id: 'M-CONF-03', + type: 'organizational', + sdmGoals: ['vertraulichkeit'], + title: 'Regelmaessige Zugriffsrechte-Ueberpruefung (Access Review)', + description: 'Quartalsweiser Review aller Zugriffsberechtigungen durch Vorgesetzte. Entzug nicht mehr benoetigter Rechte, Offboarding-Prozess bei Mitarbeiteraustritt.', + legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', + evidenceTypes: ['Access-Review-Protokoll', 'Offboarding-Checkliste'], + addressesRiskIds: ['R-CONF-01', 'R-CONF-03'], + effectiveness: 'medium', + }, + { + id: 'M-CONF-04', + type: 'technical', + sdmGoals: ['vertraulichkeit', 'integritaet'], + title: 'Privileged Access Management (PAM)', + description: 'Absicherung administrativer Zugriffe durch Just-in-Time-Elevation, Session-Recording und Break-Glass-Prozeduren fuer Notfallzugriffe.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['PAM-Policy', 'Session-Recording-Logs', 'Break-Glass-Protokolle'], + addressesRiskIds: ['R-CONF-03', 'R-INT-04'], + effectiveness: 'high', + }, + { + id: 'M-CONF-05', + type: 'organizational', + sdmGoals: ['vertraulichkeit'], + title: 'Vier-Augen-Prinzip fuer sensible Operationen', + description: 'Fuer den Zugriff auf besonders schutzwuerdige Daten oder kritische Systemoperationen ist die Genehmigung durch eine zweite Person erforderlich.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['Prozessbeschreibung', 'Genehmigungsprotokoll'], + addressesRiskIds: ['R-CONF-03'], + effectiveness: 'medium', + }, + { + id: 'M-CONF-06', + type: 'technical', + sdmGoals: ['vertraulichkeit'], + title: 'Verschluesselung at-rest und in-transit', + description: 'Vollstaendige Verschluesselung personenbezogener Daten bei Speicherung (AES-256) und Uebertragung (TLS 1.3). Verwaltung der Schluessel ueber ein zentrales Key-Management-System.', + legalBasis: 'Art. 32 Abs. 1 lit. a DSGVO', + evidenceTypes: ['Verschluesselungs-Policy', 'TLS-Konfigurationsreport', 'KMS-Audit'], + addressesRiskIds: ['R-CONF-04', 'R-TRANS-01', 'R-AUTO-05'], + effectiveness: 'high', + }, + { + id: 'M-CONF-07', + type: 'technical', + sdmGoals: ['vertraulichkeit'], + title: 'End-to-End-Verschluesselung fuer Kommunikation', + description: 'Einsatz von End-to-End-Verschluesselung fuer sensible Kommunikation (E-Mail, Messaging), sodass auch der Betreiber keinen Zugriff auf die Inhalte hat.', + legalBasis: 'Art. 32 Abs. 1 lit. a DSGVO', + evidenceTypes: ['E2E-Konfiguration', 'Testbericht'], + addressesRiskIds: ['R-CONF-04'], + effectiveness: 'high', + }, + { + id: 'M-CONF-08', + type: 'technical', + sdmGoals: ['vertraulichkeit', 'datenminimierung'], + title: 'Log-Sanitization & PII-Filtering', + description: 'Automatische Filterung personenbezogener Daten aus Logs, Fehlermeldungen und Debug-Ausgaben. Einsatz von Tokenisierung oder Maskierung.', + legalBasis: 'Art. 25 Abs. 1 DSGVO, Art. 32 Abs. 1 lit. a DSGVO', + evidenceTypes: ['Log-Policy', 'PII-Filter-Konfiguration', 'Stichproben-Audit'], + addressesRiskIds: ['R-CONF-07'], + effectiveness: 'medium', + }, +] + +export const INTEGRITY_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-INT-01', + type: 'technical', + sdmGoals: ['integritaet'], + title: 'Input-Validierung & Injection-Schutz', + description: 'Konsequente Validierung aller Eingaben, Prepared Statements fuer Datenbankzugriffe, Content Security Policy und Output-Encoding zum Schutz vor Injection-Angriffen.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['SAST-Report', 'Penetrationstest-Bericht', 'WAF-Regeln'], + addressesRiskIds: ['R-INT-01'], + effectiveness: 'high', + }, + { + id: 'M-INT-02', + type: 'technical', + sdmGoals: ['integritaet', 'transparenz'], + title: 'Audit-Logging & SIEM-Integration', + description: 'Lueckenlose Protokollierung aller sicherheitsrelevanten Ereignisse mit Weiterleitung an ein SIEM-System. Manipulation-sichere Logs mit Integritaetspruefung.', + legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', + evidenceTypes: ['SIEM-Dashboard-Screenshot', 'Audit-Log-Beispiel', 'Alert-Regeln'], + addressesRiskIds: ['R-INT-01', 'R-INT-04', 'R-INT-05', 'R-CONF-03', 'R-ORG-04'], + effectiveness: 'high', + }, + { + id: 'M-INT-03', + type: 'technical', + sdmGoals: ['integritaet'], + title: 'Web Application Firewall (WAF) & API-Gateway', + description: 'Einsatz einer WAF zum Schutz vor OWASP Top 10 Angriffen und eines API-Gateways fuer Rate-Limiting, Schema-Validierung und Anomalie-Erkennung.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['WAF-Regelset', 'API-Gateway-Konfiguration', 'Blockierungs-Statistiken'], + addressesRiskIds: ['R-INT-01'], + effectiveness: 'medium', + }, + { + id: 'M-INT-04', + type: 'technical', + sdmGoals: ['integritaet'], + title: 'Daten-Synchronisations-Monitoring & Integritaetspruefung', + description: 'Automatische Ueberwachung von Synchronisationsprozessen mit Checksummen-Vergleich, Konflikterkennung und Alerting bei Inkonsistenzen.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['Sync-Monitoring-Dashboard', 'Checksummen-Report', 'Incident-Log'], + addressesRiskIds: ['R-INT-02'], + effectiveness: 'medium', + }, + { + id: 'M-INT-05', + type: 'technical', + sdmGoals: ['integritaet'], + title: 'Versionierung & Change-Tracking fuer personenbezogene Daten', + description: 'Alle Aenderungen an personenbezogenen Daten werden versioniert gespeichert (Audit-Trail). Wer hat wann was geaendert ist jederzeit nachvollziehbar.', + legalBasis: 'Art. 5 Abs. 1 lit. f DSGVO', + evidenceTypes: ['Versionierungs-Schema', 'Change-Log-Beispiel'], + addressesRiskIds: ['R-INT-02', 'R-INT-05'], + effectiveness: 'medium', + }, +] diff --git a/admin-compliance/lib/sdk/dsfa/mitigations/availability-minimization.ts b/admin-compliance/lib/sdk/dsfa/mitigations/availability-minimization.ts new file mode 100644 index 0000000..ecc1567 --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/mitigations/availability-minimization.ts @@ -0,0 +1,165 @@ +/** + * DSFA Massnahmenbibliothek — Verfuegbarkeit, Datenminimierung & Nichtverkettung + */ + +import type { CatalogMitigation } from './types' + +export const AVAILABILITY_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-AVAIL-01', + type: 'technical', + sdmGoals: ['verfuegbarkeit'], + title: 'Backup-Strategie mit 3-2-1-Regel', + description: 'Implementierung einer Backup-Strategie nach der 3-2-1-Regel: 3 Kopien, 2 verschiedene Medien, 1 Offsite. Verschluesselte Backups mit regelmaessiger Integritaetspruefung.', + legalBasis: 'Art. 32 Abs. 1 lit. c DSGVO', + evidenceTypes: ['Backup-Policy', 'Backup-Monitoring-Report', 'Offsite-Nachweis'], + addressesRiskIds: ['R-AVAIL-01', 'R-AVAIL-03', 'R-INT-03'], + effectiveness: 'high', + }, + { + id: 'M-AVAIL-02', + type: 'organizational', + sdmGoals: ['verfuegbarkeit'], + title: 'Regelmaessige Restore-Tests & Disaster Recovery Uebungen', + description: 'Mindestens quartalsweise Durchfuehrung von Restore-Tests und jaehrliche Disaster-Recovery-Uebungen. Dokumentation der Ergebnisse und Lessons Learned.', + legalBasis: 'Art. 32 Abs. 1 lit. d DSGVO', + evidenceTypes: ['Restore-Test-Protokoll', 'DR-Uebungs-Dokumentation', 'RTO/RPO-Nachweis'], + addressesRiskIds: ['R-AVAIL-01', 'R-AVAIL-03', 'R-INT-03'], + effectiveness: 'high', + }, + { + id: 'M-AVAIL-03', + type: 'technical', + sdmGoals: ['verfuegbarkeit'], + title: 'Endpoint Protection & Anti-Ransomware', + description: 'Einsatz von Endpoint-Detection-and-Response (EDR) Loesungen mit spezifischem Ransomware-Schutz, Verhaltensanalyse und automatischer Isolation kompromittierter Systeme.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['EDR-Dashboard', 'Threat-Detection-Statistiken', 'Incident-Response-Plan'], + addressesRiskIds: ['R-AVAIL-01'], + effectiveness: 'high', + }, + { + id: 'M-AVAIL-04', + type: 'technical', + sdmGoals: ['verfuegbarkeit'], + title: 'Redundanz & High-Availability-Architektur', + description: 'Redundante Systemauslegung mit automatischem Failover, Load-Balancing und geo-redundanter Datenhaltung zur Sicherstellung der Verfuegbarkeit.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['HA-Architekturdiagramm', 'Failover-Testprotokoll', 'SLA-Dokumentation'], + addressesRiskIds: ['R-AVAIL-02', 'R-AVAIL-04'], + effectiveness: 'high', + }, + { + id: 'M-AVAIL-05', + type: 'organizational', + sdmGoals: ['verfuegbarkeit', 'intervenierbarkeit'], + title: 'Exit-Strategie & Datenportabilitaetsplan', + description: 'Dokumentierte Exit-Strategie fuer jeden kritischen Anbieter mit Datenexport-Verfahren, Migrationsplan und Uebergangsfristen. Regelmaessiger Export-Test.', + legalBasis: 'Art. 28 Abs. 3 lit. g DSGVO, Art. 20 DSGVO', + evidenceTypes: ['Exit-Plan-Dokument', 'Export-Test-Protokoll', 'Vertragliche-Regelung'], + addressesRiskIds: ['R-AVAIL-02', 'R-AVAIL-05'], + effectiveness: 'medium', + }, + { + id: 'M-AVAIL-06', + type: 'technical', + sdmGoals: ['verfuegbarkeit'], + title: 'DDoS-Schutz & Rate-Limiting', + description: 'Einsatz von DDoS-Mitigation-Services, CDN-basiertem Schutz und anwendungsspezifischem Rate-Limiting zur Abwehr von Verfuegbarkeitsangriffen.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['DDoS-Schutz-Konfiguration', 'Rate-Limit-Regeln', 'Traffic-Analyse'], + addressesRiskIds: ['R-AVAIL-04'], + effectiveness: 'high', + }, +] + +export const MINIMIZATION_NONLINKAGE_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-DMIN-01', + type: 'technical', + sdmGoals: ['datenminimierung'], + title: 'Privacy by Design: Datenerhebung auf das Minimum beschraenken', + description: 'Technische Massnahmen zur Beschraenkung der Datenerhebung: Pflichtfelder minimieren, optionale Felder deutlich kennzeichnen, Default-Einstellungen datenschutzfreundlich.', + legalBasis: 'Art. 25 Abs. 1 DSGVO', + evidenceTypes: ['Formular-Review', 'Default-Settings-Dokumentation'], + addressesRiskIds: ['R-RIGHTS-07', 'R-CONF-07'], + effectiveness: 'medium', + }, + { + id: 'M-DMIN-02', + type: 'technical', + sdmGoals: ['datenminimierung', 'nichtverkettung'], + title: 'Pseudonymisierung & Anonymisierung', + description: 'Einsatz von Pseudonymisierungsverfahren (Token-basiert, Hash-basiert) und k-Anonymity/Differential Privacy bei der Weitergabe oder Analyse von Daten.', + legalBasis: 'Art. 25 Abs. 1 DSGVO, Art. 32 Abs. 1 lit. a DSGVO', + evidenceTypes: ['Pseudonymisierungs-Konzept', 'Re-Identifizierungs-Risiko-Analyse'], + addressesRiskIds: ['R-RIGHTS-04', 'R-RIGHTS-07'], + effectiveness: 'high', + }, + { + id: 'M-DMIN-03', + type: 'technical', + sdmGoals: ['datenminimierung'], + title: 'Automatisiertes Loeschkonzept mit Aufbewahrungsfristen', + description: 'Implementierung automatischer Loeschroutinen basierend auf definierten Aufbewahrungsfristen. Monitoring der Loeschvorgaenge und Nachweis der Loeschung.', + legalBasis: 'Art. 5 Abs. 1 lit. e DSGVO, Art. 17 DSGVO', + evidenceTypes: ['Loeschkonzept-Dokument', 'Loeschfrist-Uebersicht', 'Loeschprotokoll'], + addressesRiskIds: ['R-RIGHTS-07', 'R-ORG-02'], + effectiveness: 'high', + }, + { + id: 'M-DMIN-04', + type: 'organizational', + sdmGoals: ['datenminimierung'], + title: 'Regelmaessige Ueberpruefung der Datenbestaende', + description: 'Jaehrlicher Review aller gespeicherten personenbezogenen Daten auf Erforderlichkeit. Identifikation und Bereinigung von Altbestaenden, verwaisten Datensaetzen und redundanten Kopien.', + legalBasis: 'Art. 5 Abs. 1 lit. e DSGVO', + evidenceTypes: ['Datenbestand-Review-Bericht', 'Bereinigungs-Protokoll'], + addressesRiskIds: ['R-ORG-02'], + effectiveness: 'medium', + }, + { + id: 'M-NONL-01', + type: 'technical', + sdmGoals: ['nichtverkettung'], + title: 'Zweckbindung & Consent-Management', + description: 'Technische Durchsetzung der Zweckbindung: Daten werden nur fuer den erhobenen Zweck verwendet. Consent-Management-System protokolliert und erzwingt Einwilligungen.', + legalBasis: 'Art. 5 Abs. 1 lit. b DSGVO, Art. 6 Abs. 1 lit. a DSGVO', + evidenceTypes: ['Consent-Management-System', 'Zweckbindungs-Matrix', 'Consent-Protokolle'], + addressesRiskIds: ['R-CONF-05', 'R-RIGHTS-02', 'R-RIGHTS-03'], + effectiveness: 'high', + }, + { + id: 'M-NONL-02', + type: 'technical', + sdmGoals: ['nichtverkettung'], + title: 'Data Loss Prevention (DLP) & Datenklassifikation', + description: 'Implementierung von DLP-Regeln zur Verhinderung unkontrollierter Datenweitergabe. Datenklassifikation (oeffentlich, intern, vertraulich, streng vertraulich) als Grundlage.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO', + evidenceTypes: ['DLP-Policy', 'Datenklassifikations-Schema', 'DLP-Incident-Report'], + addressesRiskIds: ['R-RIGHTS-02'], + effectiveness: 'medium', + }, + { + id: 'M-NONL-03', + type: 'technical', + sdmGoals: ['nichtverkettung', 'datenminimierung'], + title: 'Differential Privacy & k-Anonymity bei Datenanalysen', + description: 'Einsatz von Differential Privacy oder k-Anonymity-Verfahren bei der Analyse personenbezogener Daten, um Re-Identifizierung zu verhindern.', + legalBasis: 'Art. 25 Abs. 1 DSGVO', + evidenceTypes: ['Anonymisierungs-Konzept', 'Privacy-Budget-Berechnung', 'k-Anonymity-Nachweis'], + addressesRiskIds: ['R-RIGHTS-04', 'R-AUTO-05'], + effectiveness: 'high', + }, + { + id: 'M-NONL-04', + type: 'technical', + sdmGoals: ['nichtverkettung'], + title: 'Mandantentrennung & Datenisolierung', + description: 'Strikte logische oder physische Trennung personenbezogener Daten verschiedener Mandanten/Zwecke. Verhinderung unbeabsichtigter Zusammenfuehrung.', + legalBasis: 'Art. 5 Abs. 1 lit. b DSGVO', + evidenceTypes: ['Mandantentrennungs-Konzept', 'Isolierungs-Test-Bericht'], + addressesRiskIds: ['R-RIGHTS-04'], + effectiveness: 'high', + }, +] diff --git a/admin-compliance/lib/sdk/dsfa/mitigations/helpers.ts b/admin-compliance/lib/sdk/dsfa/mitigations/helpers.ts new file mode 100644 index 0000000..f398b53 --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/mitigations/helpers.ts @@ -0,0 +1,61 @@ +/** + * DSFA Massnahmenbibliothek — Helpers & Assembled Library + */ + +import type { DSFAMitigationType, SDMGoal } from '../types' +import type { CatalogMitigation } from './types' +import { ACCESS_CONTROL_MITIGATIONS, INTEGRITY_MITIGATIONS } from './access-integrity' +import { AVAILABILITY_MITIGATIONS, MINIMIZATION_NONLINKAGE_MITIGATIONS } from './availability-minimization' +import { TRANSPARENCY_MITIGATIONS, INTERVENTION_MITIGATIONS, AUTOMATION_ORG_LEGAL_MITIGATIONS } from './transparency-intervention-org' + +export const MITIGATION_LIBRARY: CatalogMitigation[] = [ + ...ACCESS_CONTROL_MITIGATIONS, + ...INTEGRITY_MITIGATIONS, + ...AVAILABILITY_MITIGATIONS, + ...MINIMIZATION_NONLINKAGE_MITIGATIONS, + ...TRANSPARENCY_MITIGATIONS, + ...INTERVENTION_MITIGATIONS, + ...AUTOMATION_ORG_LEGAL_MITIGATIONS, +] + +export function getMitigationsBySDMGoal(goal: SDMGoal): CatalogMitigation[] { + return MITIGATION_LIBRARY.filter(m => m.sdmGoals.includes(goal)) +} + +export function getMitigationsByType(type: DSFAMitigationType): CatalogMitigation[] { + return MITIGATION_LIBRARY.filter(m => m.type === type) +} + +export function getMitigationsForRisk(riskId: string): CatalogMitigation[] { + return MITIGATION_LIBRARY.filter(m => m.addressesRiskIds.includes(riskId)) +} + +export function getCatalogMitigationById(id: string): CatalogMitigation | undefined { + return MITIGATION_LIBRARY.find(m => m.id === id) +} + +export function getMitigationsByEffectiveness(effectiveness: 'low' | 'medium' | 'high'): CatalogMitigation[] { + return MITIGATION_LIBRARY.filter(m => m.effectiveness === effectiveness) +} + +export const MITIGATION_TYPE_LABELS: Record = { + technical: 'Technisch', + organizational: 'Organisatorisch', + legal: 'Rechtlich', +} + +export const SDM_GOAL_LABELS: Record = { + datenminimierung: 'Datenminimierung', + verfuegbarkeit: 'Verfuegbarkeit', + integritaet: 'Integritaet', + vertraulichkeit: 'Vertraulichkeit', + nichtverkettung: 'Nichtverkettung', + transparenz: 'Transparenz', + intervenierbarkeit: 'Intervenierbarkeit', +} + +export const EFFECTIVENESS_LABELS: Record = { + low: 'Gering', + medium: 'Mittel', + high: 'Hoch', +} diff --git a/admin-compliance/lib/sdk/dsfa/mitigations/transparency-intervention-org.ts b/admin-compliance/lib/sdk/dsfa/mitigations/transparency-intervention-org.ts new file mode 100644 index 0000000..847368b --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/mitigations/transparency-intervention-org.ts @@ -0,0 +1,267 @@ +/** + * DSFA Massnahmenbibliothek — Transparenz, Intervenierbarkeit, Automatisierung, Org & Legal + */ + +import type { CatalogMitigation } from './types' + +export const TRANSPARENCY_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-TRANS-01', + type: 'organizational', + sdmGoals: ['transparenz'], + title: 'Datenschutzhinweise & Privacy Notices', + description: 'Umfassende, verstaendliche Datenschutzhinweise gemaess Art. 13/14 DSGVO an allen Erhebungsstellen. Layered-Approach fuer unterschiedliche Detailstufen.', + legalBasis: 'Art. 13, Art. 14 DSGVO', + evidenceTypes: ['Privacy-Notice-Review', 'Zustellungs-Nachweis', 'Usability-Test'], + addressesRiskIds: ['R-CONF-05', 'R-RIGHTS-02', 'R-RIGHTS-03', 'R-RIGHTS-06', 'R-TRANS-03', 'R-SPEC-02'], + effectiveness: 'medium', + }, + { + id: 'M-TRANS-02', + type: 'technical', + sdmGoals: ['transparenz'], + title: 'Vollstaendiger Audit-Trail fuer personenbezogene Daten', + description: 'Lueckenloser, manipulationssicherer Audit-Trail fuer alle Verarbeitungsvorgaenge personenbezogener Daten. Wer hat wann auf welche Daten zugegriffen oder sie veraendert.', + legalBasis: 'Art. 5 Abs. 2 DSGVO (Rechenschaftspflicht)', + evidenceTypes: ['Audit-Trail-Architektur', 'Log-Integritaets-Nachweis', 'Beispiel-Audit-Export'], + addressesRiskIds: ['R-INT-05'], + effectiveness: 'high', + }, + { + id: 'M-TRANS-03', + type: 'technical', + sdmGoals: ['transparenz'], + title: 'Erklaerbarkeit von KI-Entscheidungen (Explainability)', + description: 'Implementierung von Erklaerungsverfahren (SHAP, LIME, Feature-Importance) fuer automatisierte Entscheidungen. Bereitstellung verstaendlicher Begruendungen fuer Betroffene.', + legalBasis: 'Art. 22 Abs. 3 DSGVO, Art. 13 Abs. 2 lit. f DSGVO', + evidenceTypes: ['XAI-Konzept', 'Erklaerbarkeits-Beispiel', 'Betroffenen-Information'], + addressesRiskIds: ['R-AUTO-01', 'R-AUTO-03', 'R-RIGHTS-01'], + effectiveness: 'medium', + }, + { + id: 'M-TRANS-04', + type: 'organizational', + sdmGoals: ['transparenz'], + title: 'Ueberwachungs-Folgenabschaetzung & Informationspflicht', + description: 'Bei systematischer Ueberwachung: Gesonderte Folgenabschaetzung, klare Beschilderung/Information, Verhaeltnismaessigkeitspruefung und zeitliche Begrenzung.', + legalBasis: 'Art. 35 Abs. 3 lit. c DSGVO, Art. 13 DSGVO', + evidenceTypes: ['Ueberwachungs-DSFA', 'Beschilderungs-Nachweis', 'Verhaeltnismaessigkeits-Bewertung'], + addressesRiskIds: ['R-RIGHTS-03'], + effectiveness: 'medium', + }, + { + id: 'M-TRANS-05', + type: 'organizational', + sdmGoals: ['transparenz'], + title: 'Verzeichnis von Verarbeitungstaetigkeiten (VVT) pflegen', + description: 'Vollstaendiges und aktuelles VVT gemaess Art. 30 DSGVO fuer alle Verarbeitungstaetigkeiten. Regelmaessige Aktualisierung bei Aenderungen.', + legalBasis: 'Art. 30 DSGVO', + evidenceTypes: ['VVT-Export', 'Aktualisierungs-Log'], + addressesRiskIds: ['R-RIGHTS-06'], + effectiveness: 'medium', + }, + { + id: 'M-TRANS-06', + type: 'legal', + sdmGoals: ['transparenz', 'vertraulichkeit'], + title: 'Transfer Impact Assessment (TIA) fuer Drittlandtransfer', + description: 'Durchfuehrung eines Transfer Impact Assessments vor jedem Drittlandtransfer. Bewertung des Schutzniveaus im Empfaengerland und Festlegung zusaetzlicher Garantien.', + legalBasis: 'Art. 46 DSGVO, Schrems-II-Urteil', + evidenceTypes: ['TIA-Dokument', 'Schutzniveau-Analyse', 'Zusaetzliche-Garantien-Vereinbarung'], + addressesRiskIds: ['R-TRANS-01', 'R-TRANS-02'], + effectiveness: 'high', + }, + { + id: 'M-TRANS-07', + type: 'legal', + sdmGoals: ['vertraulichkeit'], + title: 'Standardvertragsklauseln (SCC) & Supplementary Measures', + description: 'Abschluss aktueller EU-Standardvertragsklauseln (2021/914) mit Auftragsverarbeitern im Drittland. Ergaenzende technische und organisatorische Massnahmen (Verschluesselung, Pseudonymisierung).', + legalBasis: 'Art. 46 Abs. 2 lit. c DSGVO', + evidenceTypes: ['Unterzeichnete SCC', 'Supplementary-Measures-Dokumentation'], + addressesRiskIds: ['R-TRANS-01', 'R-TRANS-02'], + effectiveness: 'medium', + }, +] + +export const INTERVENTION_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-INTERV-01', + type: 'technical', + sdmGoals: ['intervenierbarkeit'], + title: 'DSAR-Workflow (Data Subject Access Request)', + description: 'Automatisierter Workflow fuer Betroffenenanfragen (Auskunft, Loeschung, Berichtigung, Export). Fristenmanagement (1 Monat), Identitaetspruefung und Dokumentation.', + legalBasis: 'Art. 15-22 DSGVO, Art. 12 Abs. 3 DSGVO', + evidenceTypes: ['DSAR-Workflow-Dokumentation', 'Bearbeitungszeiten-Statistik', 'Audit-Trail'], + addressesRiskIds: ['R-RIGHTS-05', 'R-AVAIL-05'], + effectiveness: 'high', + }, + { + id: 'M-INTERV-02', + type: 'technical', + sdmGoals: ['intervenierbarkeit'], + title: 'Self-Service Datenverwaltung fuer Betroffene', + description: 'Bereitstellung eines Self-Service-Portals, ueber das Betroffene ihre Daten einsehen, korrigieren, exportieren und die Loeschung beantragen koennen.', + legalBasis: 'Art. 15-20 DSGVO', + evidenceTypes: ['Portal-Screenshot', 'Funktions-Testprotokoll', 'Nutzungs-Statistik'], + addressesRiskIds: ['R-RIGHTS-05'], + effectiveness: 'high', + }, + { + id: 'M-INTERV-03', + type: 'organizational', + sdmGoals: ['intervenierbarkeit'], + title: 'Widerspruchs- und Einschraenkungsprozess', + description: 'Definierter Prozess fuer die Bearbeitung von Widerspruechen (Art. 21) und Einschraenkungsersuchen (Art. 18). Technische Moeglichkeit zur Sperrung einzelner Datensaetze.', + legalBasis: 'Art. 18, Art. 21 DSGVO', + evidenceTypes: ['Prozessbeschreibung', 'Sperr-Funktionalitaets-Nachweis'], + addressesRiskIds: ['R-RIGHTS-05'], + effectiveness: 'medium', + }, + { + id: 'M-INTERV-04', + type: 'organizational', + sdmGoals: ['intervenierbarkeit'], + title: 'Human-in-the-Loop bei automatisierten Entscheidungen', + description: 'Sicherstellung menschlicher Ueberpruefung bei automatisierten Entscheidungen mit erheblicher Auswirkung. Eskalationsprozess und Einspruchsmoeglichkeit fuer Betroffene.', + legalBasis: 'Art. 22 Abs. 3 DSGVO', + evidenceTypes: ['HITL-Prozessbeschreibung', 'Eskalations-Statistik', 'Einspruchs-Protokoll'], + addressesRiskIds: ['R-AUTO-04'], + effectiveness: 'high', + }, +] + +export const AUTOMATION_ORG_LEGAL_MITIGATIONS: CatalogMitigation[] = [ + { + id: 'M-AUTO-01', + type: 'technical', + sdmGoals: ['nichtverkettung', 'transparenz'], + title: 'Bias-Monitoring & Fairness-Tests', + description: 'Regelmaessige Ueberpruefung von KI-Modellen auf Bias und Diskriminierung. Fairness-Metriken (Demographic Parity, Equal Opportunity) und Korrekturmassnahmen bei Abweichungen.', + legalBasis: 'Art. 22 Abs. 3 DSGVO, AI Act Art. 10', + evidenceTypes: ['Bias-Audit-Report', 'Fairness-Metriken-Dashboard', 'Korrektur-Dokumentation'], + addressesRiskIds: ['R-RIGHTS-01', 'R-AUTO-01', 'R-AUTO-02'], + effectiveness: 'high', + }, + { + id: 'M-AUTO-02', + type: 'technical', + sdmGoals: ['transparenz'], + title: 'KI-Modell-Dokumentation & Model Cards', + description: 'Ausfuehrliche Dokumentation aller KI-Modelle: Trainingsdaten, Architektur, Performance-Metriken, bekannte Einschraenkungen, Einsatzzweck (Model Cards).', + legalBasis: 'Art. 13 Abs. 2 lit. f DSGVO, AI Act Art. 11', + evidenceTypes: ['Model-Card', 'Performance-Report', 'Einsatzbereich-Dokumentation'], + addressesRiskIds: ['R-AUTO-01', 'R-AUTO-03'], + effectiveness: 'medium', + }, + { + id: 'M-AUTO-03', + type: 'organizational', + sdmGoals: ['intervenierbarkeit', 'transparenz'], + title: 'KI-Governance-Framework & Human Oversight Board', + description: 'Etablierung eines KI-Governance-Frameworks mit einem Human Oversight Board, das alle KI-Systeme mit hohem Risiko ueberwacht und Interventionsmoeglichkeiten hat.', + legalBasis: 'Art. 22 DSGVO, AI Act Art. 14', + evidenceTypes: ['Governance-Policy', 'Oversight-Board-Protokolle', 'Interventions-Log'], + addressesRiskIds: ['R-AUTO-01', 'R-AUTO-04'], + effectiveness: 'high', + }, + { + id: 'M-AUTO-04', + type: 'technical', + sdmGoals: ['nichtverkettung', 'datenminimierung'], + title: 'Datenschutzkonformes KI-Training (Privacy-Preserving ML)', + description: 'Einsatz von Federated Learning, Differential Privacy beim Training oder synthetischen Trainingsdaten, um personenbezogene Daten im Modell zu schuetzen.', + legalBasis: 'Art. 25 Abs. 1 DSGVO', + evidenceTypes: ['Privacy-Preserving-ML-Konzept', 'Training-Daten-Analyse', 'Modell-Invertierbarkeiots-Test'], + addressesRiskIds: ['R-AUTO-02', 'R-AUTO-05'], + effectiveness: 'high', + }, + { + id: 'M-ORG-01', + type: 'organizational', + sdmGoals: ['vertraulichkeit', 'integritaet'], + title: 'Datenschutz-Schulungen & Awareness-Programm', + description: 'Regelmaessige verpflichtende Datenschutz-Schulungen fuer alle Mitarbeiter. Awareness-Kampagnen zu Phishing, Social Engineering und sicherem Datenumgang.', + legalBasis: 'Art. 32 Abs. 1 lit. b DSGVO, Art. 39 Abs. 1 lit. a DSGVO', + evidenceTypes: ['Schulungsplan', 'Teilnahmequoten', 'Phishing-Simulations-Ergebnis'], + addressesRiskIds: ['R-CONF-06', 'R-ORG-03'], + effectiveness: 'medium', + }, + { + id: 'M-ORG-02', + type: 'organizational', + sdmGoals: ['integritaet'], + title: 'Verpflichtung auf Vertraulichkeit & Datenschutz-Policy', + description: 'Schriftliche Verpflichtung aller Mitarbeiter und externen Dienstleister auf Vertraulichkeit und Einhaltung der Datenschutz-Policies.', + legalBasis: 'Art. 28 Abs. 3 lit. b DSGVO, Art. 29 DSGVO', + evidenceTypes: ['Unterzeichnete-Verpflichtungserklaerung', 'Datenschutz-Policy'], + addressesRiskIds: ['R-ORG-03'], + effectiveness: 'medium', + }, + { + id: 'M-ORG-03', + type: 'organizational', + sdmGoals: ['transparenz'], + title: 'Datenpannen-Erkennungs- und Meldeprozess (Incident Response)', + description: 'Definierter Incident-Response-Prozess mit klaren Eskalationswegen, 72h-Meldepflicht-Tracking, Klassifizierungsschema und Kommunikationsplan.', + legalBasis: 'Art. 33, Art. 34 DSGVO', + evidenceTypes: ['Incident-Response-Plan', 'Melde-Template', 'Uebungs-Protokoll'], + addressesRiskIds: ['R-ORG-04'], + effectiveness: 'high', + }, + { + id: 'M-ORG-04', + type: 'technical', + sdmGoals: ['transparenz', 'verfuegbarkeit'], + title: 'Automatisiertes Breach-Detection & Alerting', + description: 'Automatische Erkennung von Datenpannen durch Anomalie-Detection, ungewoehnliche Zugriffsmuster und Datenexfiltrations-Erkennung mit sofortigem Alert an den Incident-Response-Team.', + legalBasis: 'Art. 33 Abs. 1 DSGVO', + evidenceTypes: ['Alert-Regeln', 'Detection-Dashboard', 'Reaktionszeiten-Statistik'], + addressesRiskIds: ['R-ORG-04'], + effectiveness: 'high', + }, + { + id: 'M-LEGAL-01', + type: 'legal', + sdmGoals: ['transparenz'], + title: 'Angemessenheitsbeschluss oder Binding Corporate Rules (BCR)', + description: 'Sicherstellung, dass Drittlandtransfers auf einem Angemessenheitsbeschluss oder genehmigten BCRs basieren. Laufende Ueberwachung des Schutzniveaus.', + legalBasis: 'Art. 45, Art. 47 DSGVO', + evidenceTypes: ['Angemessenheitsbeschluss-Referenz', 'BCR-Genehmigung'], + addressesRiskIds: ['R-TRANS-02'], + effectiveness: 'high', + }, + { + id: 'M-LEGAL-02', + type: 'legal', + sdmGoals: ['transparenz'], + title: 'Auftragsverarbeitungsvertrag (AVV) nach Art. 28 DSGVO', + description: 'Abschluss vollstaendiger AVVs mit allen Auftragsverarbeitern. Regelung von Zweck, Dauer, Datenkategorien, Weisungsbindung, Sub-Auftragsverarbeiter und Audit-Rechten.', + legalBasis: 'Art. 28 Abs. 3 DSGVO', + evidenceTypes: ['Unterzeichneter-AVV', 'Sub-Auftragsverarbeiter-Liste', 'Audit-Bericht'], + addressesRiskIds: ['R-ORG-01', 'R-TRANS-03'], + effectiveness: 'high', + }, + { + id: 'M-LEGAL-03', + type: 'legal', + sdmGoals: ['transparenz'], + title: 'Regelmaessige Auftragsverarbeiter-Audits', + description: 'Jaehrliche Ueberpruefung der Auftragsverarbeiter auf Einhaltung der AVV-Vorgaben. Dokumentierte Audits vor Ort oder anhand von Zertifizierungen (SOC 2, ISO 27001).', + legalBasis: 'Art. 28 Abs. 3 lit. h DSGVO', + evidenceTypes: ['Audit-Bericht', 'Zertifizierungs-Nachweis', 'Massnahmenplan'], + addressesRiskIds: ['R-ORG-01'], + effectiveness: 'medium', + }, + { + id: 'M-LEGAL-04', + type: 'legal', + sdmGoals: ['intervenierbarkeit', 'transparenz'], + title: 'Altersverifikation & Eltern-Einwilligung (Art. 8)', + description: 'Implementierung einer altersgerechten Verifikation und Einholung der Eltern-Einwilligung bei Minderjaehrigen unter 16 Jahren. Kindgerechte Datenschutzinformationen.', + legalBasis: 'Art. 8 DSGVO, EG 38 DSGVO', + evidenceTypes: ['Altersverifikations-Konzept', 'Eltern-Einwilligungs-Formular', 'Kindgerechte-Privacy-Notice'], + addressesRiskIds: ['R-SPEC-02'], + effectiveness: 'medium', + }, +] diff --git a/admin-compliance/lib/sdk/dsfa/mitigations/types.ts b/admin-compliance/lib/sdk/dsfa/mitigations/types.ts new file mode 100644 index 0000000..3ebdbc7 --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/mitigations/types.ts @@ -0,0 +1,17 @@ +/** + * DSFA Massnahmenbibliothek — Types + */ + +import type { DSFAMitigationType, SDMGoal } from '../types' + +export interface CatalogMitigation { + id: string + type: DSFAMitigationType + sdmGoals: SDMGoal[] + title: string + description: string + legalBasis: string + evidenceTypes: string[] + addressesRiskIds: string[] + effectiveness: 'low' | 'medium' | 'high' +} diff --git a/admin-compliance/lib/sdk/dsfa/risk-catalog.ts b/admin-compliance/lib/sdk/dsfa/risk-catalog.ts index 4e99dcd..0edcd67 100644 --- a/admin-compliance/lib/sdk/dsfa/risk-catalog.ts +++ b/admin-compliance/lib/sdk/dsfa/risk-catalog.ts @@ -1,615 +1,11 @@ /** - * DSFA Risikokatalog - Vordefinierte Risikoszenarien + * DSFA Risikokatalog — Barrel * - * ~40 Risiken gegliedert nach Vertraulichkeit, Integritaet, Verfuegbarkeit, - * Rechte & Freiheiten, Drittlandtransfer und Automatisierung. - * - * Quellen: EG 75 DSGVO, Art. 32 DSGVO, Art. 28/46 DSGVO, Art. 22 DSGVO, - * Baseline-DSFA Katalog, SDM V2.0 + * Split into domain modules under risks/. + * Import from this file to preserve the stable public path. */ -import type { DSFARiskCategory } from './types' -import type { SDMGoal } from './types' - -// ============================================================================= -// TYPES -// ============================================================================= - -export interface CatalogRisk { - id: string - category: DSFARiskCategory - sdmGoal: SDMGoal - title: string - description: string - impactExamples: string[] - typicalLikelihood: 'low' | 'medium' | 'high' - typicalImpact: 'low' | 'medium' | 'high' - wp248Criteria: string[] - applicableTo: string[] - mitigationIds: string[] -} - -// ============================================================================= -// RISIKOKATALOG -// ============================================================================= - -export const RISK_CATALOG: CatalogRisk[] = [ - // ========================================================================= - // VERTRAULICHKEIT (Confidentiality) - // ========================================================================= - { - id: 'R-CONF-01', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Unbefugte Offenlegung durch Fehlkonfiguration', - description: 'Personenbezogene Daten werden durch fehlerhafte Systemkonfiguration (z.B. offene APIs, fehlerhafte Zugriffsrechte, oeffentliche Cloud-Speicher) unbefugt zugaenglich.', - impactExamples: ['Identitaetsdiebstahl', 'Reputationsschaden', 'Diskriminierung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K5'], - applicableTo: ['cloud_storage', 'web_application', 'api_service'], - mitigationIds: ['M-CONF-01', 'M-CONF-02', 'M-CONF-03'], - }, - { - id: 'R-CONF-02', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Account Takeover / Credential Stuffing', - description: 'Angreifer uebernehmen Benutzerkonten durch gestohlene Zugangsdaten, Brute-Force-Angriffe oder Phishing und erlangen Zugriff auf personenbezogene Daten.', - impactExamples: ['Kontrollverlust ueber eigene Daten', 'Finanzieller Schaden', 'Missbrauch der Identitaet'], - typicalLikelihood: 'high', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K7'], - applicableTo: ['identity', 'web_application', 'email_service'], - mitigationIds: ['M-ACC-01', 'M-ACC-02'], - }, - { - id: 'R-CONF-03', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Unbefugter Zugriff durch Support-/Administrationspersonal', - description: 'Administratoren oder Support-Mitarbeiter greifen ohne dienstliche Notwendigkeit auf personenbezogene Daten zu (Insider-Bedrohung).', - impactExamples: ['Verletzung der Privatsphaere', 'Datenmissbrauch', 'Vertrauensverlust'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K4'], - applicableTo: ['identity', 'crm', 'cloud_storage', 'support_system'], - mitigationIds: ['M-CONF-04', 'M-CONF-05', 'M-INT-02'], - }, - { - id: 'R-CONF-04', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Datenleck durch unzureichende Verschluesselung', - description: 'Personenbezogene Daten werden bei Uebertragung oder Speicherung nicht oder unzureichend verschluesselt und koennen abgefangen werden.', - impactExamples: ['Man-in-the-Middle-Angriff', 'Datendiebstahl bei Speichermedien-Verlust'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K8'], - applicableTo: ['cloud_storage', 'email_service', 'mobile_app', 'api_service'], - mitigationIds: ['M-CONF-06', 'M-CONF-07'], - }, - { - id: 'R-CONF-05', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Unkontrollierte Datenweitergabe an Dritte', - description: 'Personenbezogene Daten werden ohne Rechtsgrundlage oder ueber das vereinbarte Mass hinaus an Dritte weitergegeben (z.B. durch Tracking, Analyse-Tools, Sub-Auftragsverarbeiter).', - impactExamples: ['Unerwuenschte Werbung', 'Profiling ohne Wissen', 'Kontrollverlust'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K1', 'K6'], - applicableTo: ['web_application', 'analytics', 'marketing', 'crm'], - mitigationIds: ['M-NONL-01', 'M-TRANS-01'], - }, - { - id: 'R-CONF-06', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Social Engineering / Phishing gegen Betroffene', - description: 'Betroffene werden durch manipulative Kommunikation dazu verleitet, personenbezogene Daten preiszugeben oder Zugriff zu gewaehren.', - impactExamples: ['Identitaetsdiebstahl', 'Finanzieller Schaden', 'Uebernahme von Konten'], - typicalLikelihood: 'high', - typicalImpact: 'medium', - wp248Criteria: ['K7'], - applicableTo: ['email_service', 'web_application', 'identity'], - mitigationIds: ['M-ACC-01', 'M-ORG-01'], - }, - { - id: 'R-CONF-07', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Unbeabsichtigte Offenlegung in Logs/Debugging', - description: 'Personenbezogene Daten gelangen in Protokolldateien, Fehlermeldungen oder Debug-Ausgaben und werden dort nicht geschuetzt.', - impactExamples: ['Zugriff durch Unbefugte auf Logdaten', 'Langzeitspeicherung ohne Rechtsgrundlage'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K4'], - applicableTo: ['api_service', 'web_application', 'cloud_storage'], - mitigationIds: ['M-CONF-08', 'M-DMIN-01'], - }, - - // ========================================================================= - // INTEGRITAET (Integrity) - // ========================================================================= - { - id: 'R-INT-01', - category: 'integrity', - sdmGoal: 'integritaet', - title: 'Datenmanipulation durch externen Angriff', - description: 'Personenbezogene Daten werden durch einen Cyberangriff (SQL-Injection, API-Manipulation) veraendert, ohne dass dies erkannt wird.', - impactExamples: ['Falsche Entscheidungen auf Basis manipulierter Daten', 'Rufschaedigung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K8'], - applicableTo: ['api_service', 'web_application', 'database'], - mitigationIds: ['M-INT-01', 'M-INT-02', 'M-INT-03'], - }, - { - id: 'R-INT-02', - category: 'integrity', - sdmGoal: 'integritaet', - title: 'Fehlerhafte Synchronisation zwischen Systemen', - description: 'Bei der Synchronisation personenbezogener Daten zwischen verschiedenen Systemen kommt es zu Inkonsistenzen, Duplikaten oder Datenverlust.', - impactExamples: ['Falsche Kontaktdaten', 'Doppelte Verarbeitung', 'Falsche Auskuenfte'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K6'], - applicableTo: ['crm', 'cloud_storage', 'erp', 'identity'], - mitigationIds: ['M-INT-04', 'M-INT-05'], - }, - { - id: 'R-INT-03', - category: 'integrity', - sdmGoal: 'integritaet', - title: 'Backup-Korruption oder fehlerhafte Wiederherstellung', - description: 'Backups personenbezogener Daten sind beschaedigt, unvollstaendig oder veraltet, sodass eine zuverlaessige Wiederherstellung nicht moeglich ist.', - impactExamples: ['Datenverlust bei Wiederherstellung', 'Veraltete Datenbasis', 'Compliance-Verstoss'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K5'], - applicableTo: ['database', 'cloud_storage', 'erp'], - mitigationIds: ['M-AVAIL-01', 'M-AVAIL-02'], - }, - { - id: 'R-INT-04', - category: 'integrity', - sdmGoal: 'integritaet', - title: 'Unbemerkte Aenderung von Zugriffsrechten', - description: 'Zugriffsberechtigungen werden unbefugt oder fehlerhaft geaendert, wodurch unberechtigte Personen Zugang zu personenbezogenen Daten erhalten.', - impactExamples: ['Privilege Escalation', 'Unbefugter Datenzugriff'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K4'], - applicableTo: ['identity', 'cloud_storage', 'api_service'], - mitigationIds: ['M-INT-02', 'M-CONF-04'], - }, - { - id: 'R-INT-05', - category: 'integrity', - sdmGoal: 'integritaet', - title: 'Fehlende Nachvollziehbarkeit von Datenveraenderungen', - description: 'Aenderungen an personenbezogenen Daten werden nicht protokolliert, sodass Manipulationen oder Fehler nicht erkannt oder nachvollzogen werden koennen.', - impactExamples: ['Unmoeglich festzustellen wer/wann Daten geaendert hat', 'Audit-Versagen'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K3'], - applicableTo: ['database', 'crm', 'erp', 'web_application'], - mitigationIds: ['M-INT-02', 'M-TRANS-02'], - }, - - // ========================================================================= - // VERFUEGBARKEIT (Availability) - // ========================================================================= - { - id: 'R-AVAIL-01', - category: 'availability', - sdmGoal: 'verfuegbarkeit', - title: 'Ransomware-Angriff mit Datenverschluesselung', - description: 'Schadsoftware verschluesselt personenbezogene Daten und macht sie unzugaenglich. Die Wiederherstellung erfordert entweder Loesegeldzahlung oder Backup-Restore.', - impactExamples: ['Verlust des Zugangs zu eigenen Daten', 'Betriebsunterbrechung', 'Loesegeld-Erpressung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K5', 'K8'], - applicableTo: ['cloud_storage', 'database', 'erp', 'web_application'], - mitigationIds: ['M-AVAIL-01', 'M-AVAIL-02', 'M-AVAIL-03'], - }, - { - id: 'R-AVAIL-02', - category: 'availability', - sdmGoal: 'verfuegbarkeit', - title: 'Provider-Ausfall / Cloud-Service Nichtverfuegbarkeit', - description: 'Der Cloud-/Hosting-Provider faellt aus, was den Zugang zu personenbezogenen Daten verhindert. Betroffene koennen ihre Rechte nicht ausueben.', - impactExamples: ['Keine Auskunft moeglich', 'Vertragsverletzung', 'Geschaeftsunterbrechung'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K5', 'K9'], - applicableTo: ['cloud_storage', 'web_application', 'api_service'], - mitigationIds: ['M-AVAIL-04', 'M-AVAIL-05'], - }, - { - id: 'R-AVAIL-03', - category: 'availability', - sdmGoal: 'verfuegbarkeit', - title: 'Datenverlust durch fehlende oder ungetestete Backups', - description: 'Personenbezogene Daten gehen unwiederbringlich verloren, weil keine ausreichenden Backups existieren oder Restore-Prozesse nicht getestet werden.', - impactExamples: ['Unwiderruflicher Datenverlust', 'Verlust von Beweismitteln', 'Compliance-Verstoss'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K5'], - applicableTo: ['database', 'cloud_storage', 'erp'], - mitigationIds: ['M-AVAIL-01', 'M-AVAIL-02'], - }, - { - id: 'R-AVAIL-04', - category: 'availability', - sdmGoal: 'verfuegbarkeit', - title: 'DDoS-Angriff auf oeffentliche Dienste', - description: 'Ein Distributed-Denial-of-Service-Angriff verhindert den Zugang zu Systemen, die personenbezogene Daten verarbeiten.', - impactExamples: ['Betroffene koennen Rechte nicht ausueben', 'Geschaeftsausfall'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K5', 'K9'], - applicableTo: ['web_application', 'api_service'], - mitigationIds: ['M-AVAIL-06', 'M-AVAIL-04'], - }, - { - id: 'R-AVAIL-05', - category: 'availability', - sdmGoal: 'verfuegbarkeit', - title: 'Vendor Lock-in mit Kontrollverlust', - description: 'Abhaengigkeit von einem einzelnen Anbieter erschwert oder verhindert den Zugang zu personenbezogenen Daten bei Vertragsbeendigung oder Anbieterwechsel.', - impactExamples: ['Datenexport nicht moeglich', 'Erzwungene Weiternutzung', 'Datenverlust bei Kuendigung'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K9'], - applicableTo: ['cloud_storage', 'erp', 'crm'], - mitigationIds: ['M-AVAIL-05', 'M-INTERV-01'], - }, - - // ========================================================================= - // RECHTE & FREIHEITEN (Rights & Freedoms) - // ========================================================================= - { - id: 'R-RIGHTS-01', - category: 'rights_freedoms', - sdmGoal: 'nichtverkettung', - title: 'Diskriminierung durch automatisierte Verarbeitung', - description: 'Automatisierte Entscheidungssysteme fuehren zu einer diskriminierenden Behandlung bestimmter Personengruppen aufgrund von Merkmalen wie Alter, Geschlecht, Herkunft oder Gesundheitszustand.', - impactExamples: ['Benachteiligung bei Kreditvergabe', 'Ausschluss von Dienstleistungen', 'Ungleichbehandlung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K1', 'K2', 'K7'], - applicableTo: ['ai_ml', 'scoring', 'identity'], - mitigationIds: ['M-AUTO-01', 'M-AUTO-02', 'M-TRANS-03'], - }, - { - id: 'R-RIGHTS-02', - category: 'rights_freedoms', - sdmGoal: 'nichtverkettung', - title: 'Unzulaessiges Profiling ohne Einwilligung', - description: 'Nutzerverhalten wird systematisch analysiert und zu Profilen zusammengefuehrt, ohne dass eine Rechtsgrundlage oder Einwilligung vorliegt.', - impactExamples: ['Persoenlichkeitsprofile ohne Wissen', 'Gezielte Manipulation', 'Filterblase'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K1', 'K3', 'K6'], - applicableTo: ['analytics', 'marketing', 'web_application', 'ai_ml'], - mitigationIds: ['M-NONL-01', 'M-NONL-02', 'M-TRANS-01'], - }, - { - id: 'R-RIGHTS-03', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'Systematische Ueberwachung von Betroffenen', - description: 'Betroffene werden systematisch ueberwacht (z.B. durch Standorttracking, E-Mail-Monitoring, Videoueberwachung), ohne angemessene Transparenz oder Rechtsgrundlage.', - impactExamples: ['Einschuechterungseffekt (Chilling Effect)', 'Verletzung der Privatsphaere', 'Vertrauensverlust'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K3', 'K4', 'K7'], - applicableTo: ['monitoring', 'hr_system', 'mobile_app'], - mitigationIds: ['M-TRANS-01', 'M-TRANS-04', 'M-NONL-01'], - }, - { - id: 'R-RIGHTS-04', - category: 'rights_freedoms', - sdmGoal: 'nichtverkettung', - title: 'Re-Identifizierung pseudonymisierter Daten', - description: 'Pseudonymisierte oder anonymisierte Daten werden durch Zusammenfuehrung mit anderen Datenquellen re-identifiziert, wodurch der Schutz der Betroffenen aufgehoben wird.', - impactExamples: ['Verlust der Anonymitaet', 'Unerwuenschte Identifizierung', 'Zweckentfremdung'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K1', 'K6', 'K8'], - applicableTo: ['analytics', 'ai_ml', 'research'], - mitigationIds: ['M-NONL-03', 'M-NONL-04', 'M-DMIN-02'], - }, - { - id: 'R-RIGHTS-05', - category: 'rights_freedoms', - sdmGoal: 'intervenierbarkeit', - title: 'Hinderung bei Ausuebung von Betroffenenrechten', - description: 'Betroffene werden an der Ausuebung ihrer Rechte (Auskunft, Loeschung, Berichtigung, Widerspruch) gehindert — z.B. durch fehlende Prozesse, technische Huerden oder Verzoegerungen.', - impactExamples: ['Keine Loeschung moeglich', 'Verzoegerte Auskunft', 'Bussgeld gem. Art. 83'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K9'], - applicableTo: ['web_application', 'crm', 'identity', 'cloud_storage'], - mitigationIds: ['M-INTERV-01', 'M-INTERV-02', 'M-INTERV-03'], - }, - { - id: 'R-RIGHTS-06', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'Fehlende oder unzureichende Informationspflichten', - description: 'Betroffene werden nicht oder unzureichend ueber die Verarbeitung ihrer Daten informiert (Verstoss gegen Art. 13/14 DSGVO).', - impactExamples: ['Keine informierte Einwilligung moeglich', 'Vertrauensverlust', 'Bussgeld'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K9'], - applicableTo: ['web_application', 'mobile_app', 'marketing'], - mitigationIds: ['M-TRANS-01', 'M-TRANS-05'], - }, - { - id: 'R-RIGHTS-07', - category: 'rights_freedoms', - sdmGoal: 'datenminimierung', - title: 'Uebermassige Datenerhebung (Verstoss Datenminimierung)', - description: 'Es werden mehr personenbezogene Daten erhoben als fuer den Verarbeitungszweck notwendig (Verstoss gegen Art. 5 Abs. 1 lit. c DSGVO).', - impactExamples: ['Unnoetige Risikoexposition', 'Hoeherer Schaden bei Datenpanne'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K5'], - applicableTo: ['web_application', 'mobile_app', 'crm', 'hr_system'], - mitigationIds: ['M-DMIN-01', 'M-DMIN-02', 'M-DMIN-03'], - }, - - // ========================================================================= - // DRITTLANDTRANSFER - // ========================================================================= - { - id: 'R-TRANS-01', - category: 'rights_freedoms', - sdmGoal: 'vertraulichkeit', - title: 'Zugriff durch Drittland-Behoerden (FISA/CLOUD Act)', - description: 'Behoerden eines Drittlandes (z.B. USA) greifen auf personenbezogene Daten zu, die bei einem Cloud-Provider in der EU oder im Drittland gespeichert sind.', - impactExamples: ['Ueberwachung ohne Wissen', 'Kein Rechtsschutz', 'Schrems-II-Risiko'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K5', 'K7'], - applicableTo: ['cloud_storage', 'email_service', 'crm', 'analytics'], - mitigationIds: ['M-TRANS-06', 'M-TRANS-07', 'M-CONF-06'], - }, - { - id: 'R-TRANS-02', - category: 'rights_freedoms', - sdmGoal: 'vertraulichkeit', - title: 'Unzureichende Schutzgarantien bei Drittlandtransfer', - description: 'Personenbezogene Daten werden in Drittlaender uebermittelt, ohne dass angemessene Garantien (SCC, BCR, Angemessenheitsbeschluss) vorhanden sind.', - impactExamples: ['Rechtswidriger Transfer', 'Bussgeld', 'Untersagung der Verarbeitung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K5', 'K7'], - applicableTo: ['cloud_storage', 'email_service', 'crm', 'analytics'], - mitigationIds: ['M-TRANS-06', 'M-TRANS-07', 'M-LEGAL-01'], - }, - { - id: 'R-TRANS-03', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'Intransparente Sub-Auftragsverarbeiter-Kette', - description: 'Die Kette der Sub-Auftragsverarbeiter ist nicht transparent. Betroffene und Verantwortliche wissen nicht, wo ihre Daten tatsaechlich verarbeitet werden.', - impactExamples: ['Unkontrollierte Datenweitergabe', 'Unbekannter Verarbeitungsort'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K5'], - applicableTo: ['cloud_storage', 'crm', 'analytics'], - mitigationIds: ['M-TRANS-01', 'M-LEGAL-02'], - }, - - // ========================================================================= - // AUTOMATISIERUNG / KI - // ========================================================================= - { - id: 'R-AUTO-01', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'KI-Fehlentscheidung mit erheblicher Auswirkung', - description: 'Ein KI-System trifft eine fehlerhafte automatisierte Entscheidung (z.B. Ablehnung, Sperrung, Bewertung), die erhebliche Auswirkungen auf eine betroffene Person hat.', - impactExamples: ['Unrechtmaessige Ablehnung', 'Falsche Risikoeinstufung', 'Benachteiligung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K1', 'K2', 'K8'], - applicableTo: ['ai_ml', 'scoring', 'hr_system'], - mitigationIds: ['M-AUTO-01', 'M-AUTO-02', 'M-AUTO-03'], - }, - { - id: 'R-AUTO-02', - category: 'rights_freedoms', - sdmGoal: 'nichtverkettung', - title: 'Algorithmischer Bias in Trainingsdaten', - description: 'KI-Modelle spiegeln Vorurteile in den Trainingsdaten wider und treffen diskriminierende Entscheidungen bezueglich geschuetzter Merkmale.', - impactExamples: ['Diskriminierung nach Geschlecht/Herkunft', 'Systematische Benachteiligung'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K1', 'K2', 'K7', 'K8'], - applicableTo: ['ai_ml', 'scoring'], - mitigationIds: ['M-AUTO-01', 'M-AUTO-04'], - }, - { - id: 'R-AUTO-03', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'Fehlende Erklaerbarkeit automatisierter Entscheidungen', - description: 'Automatisierte Entscheidungen koennen den Betroffenen nicht erklaert werden ("Black Box"), sodass der Anspruch auf aussagekraeftige Informationen (Art. 22 Abs. 3) nicht erfuellt wird.', - impactExamples: ['Keine Anfechtbarkeit', 'Vertrauensverlust', 'Verstoss gegen Art. 22'], - typicalLikelihood: 'high', - typicalImpact: 'medium', - wp248Criteria: ['K2', 'K8'], - applicableTo: ['ai_ml', 'scoring'], - mitigationIds: ['M-AUTO-02', 'M-TRANS-03'], - }, - { - id: 'R-AUTO-04', - category: 'rights_freedoms', - sdmGoal: 'intervenierbarkeit', - title: 'Fehlende menschliche Aufsicht bei KI-Entscheidungen', - description: 'Automatisierte Entscheidungen werden ohne menschliche Ueberpruefung oder Interventionsmoeglichkeit getroffen, obwohl dies erforderlich waere.', - impactExamples: ['Keine Korrekturmoeglichkeit', 'Eskalation von Fehlern'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K2', 'K8'], - applicableTo: ['ai_ml', 'scoring', 'hr_system'], - mitigationIds: ['M-AUTO-03', 'M-INTERV-04'], - }, - { - id: 'R-AUTO-05', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Datenleck durch KI-Training mit personenbezogenen Daten', - description: 'Personenbezogene Daten, die fuer das Training von KI-Modellen verwendet werden, koennen durch das Modell reproduziert oder extrahiert werden (Model Inversion, Membership Inference).', - impactExamples: ['Offenlegung von Trainingsdaten', 'Re-Identifizierung'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K8'], - applicableTo: ['ai_ml'], - mitigationIds: ['M-CONF-06', 'M-NONL-03', 'M-AUTO-04'], - }, - - // ========================================================================= - // ORGANISATORISCHE RISIKEN - // ========================================================================= - { - id: 'R-ORG-01', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'Fehlende oder fehlerhafte Auftragsverarbeitungsvertraege', - description: 'Mit Auftragsverarbeitern existieren keine oder unzureichende Vertraege gemaess Art. 28 DSGVO, sodass Pflichten und Rechte nicht geregelt sind.', - impactExamples: ['Keine Kontrolle ueber Verarbeiter', 'Bussgeld', 'Datenmissbrauch durch Verarbeiter'], - typicalLikelihood: 'medium', - typicalImpact: 'medium', - wp248Criteria: ['K5'], - applicableTo: ['cloud_storage', 'crm', 'analytics', 'email_service'], - mitigationIds: ['M-LEGAL-02', 'M-LEGAL-03'], - }, - { - id: 'R-ORG-02', - category: 'rights_freedoms', - sdmGoal: 'datenminimierung', - title: 'Fehlende Loeschprozesse / Ueberschreitung von Aufbewahrungsfristen', - description: 'Personenbezogene Daten werden laenger als notwendig gespeichert, weil keine automatischen Loeschprozesse oder Aufbewahrungsfristen definiert sind.', - impactExamples: ['Unnoetige Risikoexposition', 'Verstoss gegen Speicherbegrenzung', 'Bussgeld'], - typicalLikelihood: 'high', - typicalImpact: 'medium', - wp248Criteria: ['K5'], - applicableTo: ['database', 'cloud_storage', 'crm', 'erp', 'email_service'], - mitigationIds: ['M-DMIN-03', 'M-DMIN-04'], - }, - { - id: 'R-ORG-03', - category: 'integrity', - sdmGoal: 'integritaet', - title: 'Unzureichende Schulung/Sensibilisierung der Mitarbeiter', - description: 'Mitarbeiter sind nicht ausreichend im Umgang mit personenbezogenen Daten geschult und verursachen durch Unkenntnis Datenpannen oder Verarbeitungsfehler.', - impactExamples: ['Versehentliche Datenweitergabe', 'Phishing-Erfolg', 'Fehlerhafte Verarbeitung'], - typicalLikelihood: 'high', - typicalImpact: 'medium', - wp248Criteria: ['K5', 'K7'], - applicableTo: ['hr_system', 'email_service', 'crm', 'web_application'], - mitigationIds: ['M-ORG-01', 'M-ORG-02'], - }, - { - id: 'R-ORG-04', - category: 'rights_freedoms', - sdmGoal: 'transparenz', - title: 'Fehlende Datenpannen-Erkennung und -Meldung', - description: 'Datenpannen werden nicht rechtzeitig erkannt oder nicht innerhalb der 72-Stunden-Frist (Art. 33 DSGVO) an die Aufsichtsbehoerde gemeldet.', - impactExamples: ['Verspaetete Meldung', 'Bussgeld', 'Verzoegerte Benachrichtigung Betroffener'], - typicalLikelihood: 'medium', - typicalImpact: 'high', - wp248Criteria: ['K5'], - applicableTo: ['web_application', 'cloud_storage', 'database', 'api_service'], - mitigationIds: ['M-ORG-03', 'M-ORG-04', 'M-INT-02'], - }, - - // ========================================================================= - // BESONDERE DATENKATEGORIEN - // ========================================================================= - { - id: 'R-SPEC-01', - category: 'confidentiality', - sdmGoal: 'vertraulichkeit', - title: 'Kompromittierung besonderer Datenkategorien (Art. 9)', - description: 'Besonders schutzwuerdige Daten (Gesundheit, Religion, Biometrie, Gewerkschaftszugehoerigkeit) werden offengelegt oder missbraucht.', - impactExamples: ['Schwerwiegende Diskriminierung', 'Existenzielle Bedrohung', 'Soziale Ausgrenzung'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K7'], - applicableTo: ['hr_system', 'health_system', 'identity'], - mitigationIds: ['M-CONF-06', 'M-CONF-01', 'M-CONF-04'], - }, - { - id: 'R-SPEC-02', - category: 'rights_freedoms', - sdmGoal: 'intervenierbarkeit', - title: 'Verarbeitung von Kinderdaten ohne angemessenen Schutz', - description: 'Daten von Minderjaehrigen werden verarbeitet, ohne die besonderen Schutzmassnahmen fuer Kinder (Art. 8, EG 38 DSGVO) zu beachten.', - impactExamples: ['Langzeitfolgen fuer Minderjaehrige', 'Einschraenkung der Entwicklung', 'Manipulation'], - typicalLikelihood: 'low', - typicalImpact: 'high', - wp248Criteria: ['K4', 'K7'], - applicableTo: ['web_application', 'mobile_app', 'education'], - mitigationIds: ['M-LEGAL-04', 'M-DMIN-01', 'M-TRANS-01'], - }, -] - -// ============================================================================= -// HELPER FUNCTIONS -// ============================================================================= - -export function getRisksByCategory(category: DSFARiskCategory): CatalogRisk[] { - return RISK_CATALOG.filter(r => r.category === category) -} - -export function getRisksBySDMGoal(goal: SDMGoal): CatalogRisk[] { - return RISK_CATALOG.filter(r => r.sdmGoal === goal) -} - -export function getRisksByWP248Criterion(criterionCode: string): CatalogRisk[] { - return RISK_CATALOG.filter(r => r.wp248Criteria.includes(criterionCode)) -} - -export function getRisksByComponent(component: string): CatalogRisk[] { - return RISK_CATALOG.filter(r => r.applicableTo.includes(component)) -} - -export function getCatalogRiskById(id: string): CatalogRisk | undefined { - return RISK_CATALOG.find(r => r.id === id) -} - -export const RISK_CATEGORY_LABELS: Record = { - confidentiality: 'Vertraulichkeit', - integrity: 'Integritaet', - availability: 'Verfuegbarkeit', - rights_freedoms: 'Rechte & Freiheiten', -} - -export const COMPONENT_FAMILY_LABELS: Record = { - identity: 'Identitaet & Zugang', - cloud_storage: 'Cloud-Speicher', - web_application: 'Web-Anwendung', - api_service: 'API-Service', - email_service: 'E-Mail-Dienst', - mobile_app: 'Mobile App', - database: 'Datenbank', - crm: 'CRM-System', - erp: 'ERP-System', - analytics: 'Analyse/Tracking', - marketing: 'Marketing', - ai_ml: 'KI / Machine Learning', - scoring: 'Scoring / Bewertung', - hr_system: 'HR-System', - health_system: 'Gesundheitssystem', - monitoring: 'Ueberwachungssystem', - support_system: 'Support-System', - education: 'Bildungsplattform', - research: 'Forschung', -} +export type { CatalogRisk } from './risks/types' +export * from './risks/confidentiality-integrity' +export * from './risks/availability-rights-auto-org' +export * from './risks/helpers' diff --git a/admin-compliance/lib/sdk/dsfa/risks/availability-rights-auto-org.ts b/admin-compliance/lib/sdk/dsfa/risks/availability-rights-auto-org.ts new file mode 100644 index 0000000..59a55dc --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/risks/availability-rights-auto-org.ts @@ -0,0 +1,310 @@ +/** + * DSFA Risikokatalog — Verfuegbarkeit, Rechte & Freiheiten, Drittlandtransfer, Auto/KI, Org + */ + +import type { CatalogRisk } from './types' + +export const AVAILABILITY_RISKS: CatalogRisk[] = [ + { + id: 'R-AVAIL-01', + category: 'availability', + sdmGoal: 'verfuegbarkeit', + title: 'Ransomware-Angriff mit Datenverschluesselung', + description: 'Schadsoftware verschluesselt personenbezogene Daten und macht sie unzugaenglich. Die Wiederherstellung erfordert entweder Loesegeldzahlung oder Backup-Restore.', + impactExamples: ['Verlust des Zugangs zu eigenen Daten', 'Betriebsunterbrechung', 'Loesegeld-Erpressung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K5', 'K8'], + applicableTo: ['cloud_storage', 'database', 'erp', 'web_application'], + mitigationIds: ['M-AVAIL-01', 'M-AVAIL-02', 'M-AVAIL-03'], + }, + { + id: 'R-AVAIL-02', + category: 'availability', + sdmGoal: 'verfuegbarkeit', + title: 'Provider-Ausfall / Cloud-Service Nichtverfuegbarkeit', + description: 'Der Cloud-/Hosting-Provider faellt aus, was den Zugang zu personenbezogenen Daten verhindert. Betroffene koennen ihre Rechte nicht ausueben.', + impactExamples: ['Keine Auskunft moeglich', 'Vertragsverletzung', 'Geschaeftsunterbrechung'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K5', 'K9'], + applicableTo: ['cloud_storage', 'web_application', 'api_service'], + mitigationIds: ['M-AVAIL-04', 'M-AVAIL-05'], + }, + { + id: 'R-AVAIL-03', + category: 'availability', + sdmGoal: 'verfuegbarkeit', + title: 'Datenverlust durch fehlende oder ungetestete Backups', + description: 'Personenbezogene Daten gehen unwiederbringlich verloren, weil keine ausreichenden Backups existieren oder Restore-Prozesse nicht getestet werden.', + impactExamples: ['Unwiderruflicher Datenverlust', 'Verlust von Beweismitteln', 'Compliance-Verstoss'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K5'], + applicableTo: ['database', 'cloud_storage', 'erp'], + mitigationIds: ['M-AVAIL-01', 'M-AVAIL-02'], + }, + { + id: 'R-AVAIL-04', + category: 'availability', + sdmGoal: 'verfuegbarkeit', + title: 'DDoS-Angriff auf oeffentliche Dienste', + description: 'Ein Distributed-Denial-of-Service-Angriff verhindert den Zugang zu Systemen, die personenbezogene Daten verarbeiten.', + impactExamples: ['Betroffene koennen Rechte nicht ausueben', 'Geschaeftsausfall'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K5', 'K9'], + applicableTo: ['web_application', 'api_service'], + mitigationIds: ['M-AVAIL-06', 'M-AVAIL-04'], + }, + { + id: 'R-AVAIL-05', + category: 'availability', + sdmGoal: 'verfuegbarkeit', + title: 'Vendor Lock-in mit Kontrollverlust', + description: 'Abhaengigkeit von einem einzelnen Anbieter erschwert oder verhindert den Zugang zu personenbezogenen Daten bei Vertragsbeendigung oder Anbieterwechsel.', + impactExamples: ['Datenexport nicht moeglich', 'Erzwungene Weiternutzung', 'Datenverlust bei Kuendigung'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K9'], + applicableTo: ['cloud_storage', 'erp', 'crm'], + mitigationIds: ['M-AVAIL-05', 'M-INTERV-01'], + }, +] + +export const RIGHTS_FREEDOMS_RISKS: CatalogRisk[] = [ + { + id: 'R-RIGHTS-01', + category: 'rights_freedoms', + sdmGoal: 'nichtverkettung', + title: 'Diskriminierung durch automatisierte Verarbeitung', + description: 'Automatisierte Entscheidungssysteme fuehren zu einer diskriminierenden Behandlung bestimmter Personengruppen aufgrund von Merkmalen wie Alter, Geschlecht, Herkunft oder Gesundheitszustand.', + impactExamples: ['Benachteiligung bei Kreditvergabe', 'Ausschluss von Dienstleistungen', 'Ungleichbehandlung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K1', 'K2', 'K7'], + applicableTo: ['ai_ml', 'scoring', 'identity'], + mitigationIds: ['M-AUTO-01', 'M-AUTO-02', 'M-TRANS-03'], + }, + { + id: 'R-RIGHTS-02', + category: 'rights_freedoms', + sdmGoal: 'nichtverkettung', + title: 'Unzulaessiges Profiling ohne Einwilligung', + description: 'Nutzerverhalten wird systematisch analysiert und zu Profilen zusammengefuehrt, ohne dass eine Rechtsgrundlage oder Einwilligung vorliegt.', + impactExamples: ['Persoenlichkeitsprofile ohne Wissen', 'Gezielte Manipulation', 'Filterblase'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K1', 'K3', 'K6'], + applicableTo: ['analytics', 'marketing', 'web_application', 'ai_ml'], + mitigationIds: ['M-NONL-01', 'M-NONL-02', 'M-TRANS-01'], + }, + { + id: 'R-RIGHTS-03', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'Systematische Ueberwachung von Betroffenen', + description: 'Betroffene werden systematisch ueberwacht (z.B. durch Standorttracking, E-Mail-Monitoring, Videoueberwachung), ohne angemessene Transparenz oder Rechtsgrundlage.', + impactExamples: ['Einschuechterungseffekt (Chilling Effect)', 'Verletzung der Privatsphaere', 'Vertrauensverlust'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K3', 'K4', 'K7'], + applicableTo: ['monitoring', 'hr_system', 'mobile_app'], + mitigationIds: ['M-TRANS-01', 'M-TRANS-04', 'M-NONL-01'], + }, + { + id: 'R-RIGHTS-04', + category: 'rights_freedoms', + sdmGoal: 'nichtverkettung', + title: 'Re-Identifizierung pseudonymisierter Daten', + description: 'Pseudonymisierte oder anonymisierte Daten werden durch Zusammenfuehrung mit anderen Datenquellen re-identifiziert, wodurch der Schutz der Betroffenen aufgehoben wird.', + impactExamples: ['Verlust der Anonymitaet', 'Unerwuenschte Identifizierung', 'Zweckentfremdung'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K1', 'K6', 'K8'], + applicableTo: ['analytics', 'ai_ml', 'research'], + mitigationIds: ['M-NONL-03', 'M-NONL-04', 'M-DMIN-02'], + }, + { + id: 'R-RIGHTS-05', + category: 'rights_freedoms', + sdmGoal: 'intervenierbarkeit', + title: 'Hinderung bei Ausuebung von Betroffenenrechten', + description: 'Betroffene werden an der Ausuebung ihrer Rechte (Auskunft, Loeschung, Berichtigung, Widerspruch) gehindert — z.B. durch fehlende Prozesse, technische Huerden oder Verzoegerungen.', + impactExamples: ['Keine Loeschung moeglich', 'Verzoegerte Auskunft', 'Bussgeld gem. Art. 83'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K9'], + applicableTo: ['web_application', 'crm', 'identity', 'cloud_storage'], + mitigationIds: ['M-INTERV-01', 'M-INTERV-02', 'M-INTERV-03'], + }, + { + id: 'R-RIGHTS-06', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'Fehlende oder unzureichende Informationspflichten', + description: 'Betroffene werden nicht oder unzureichend ueber die Verarbeitung ihrer Daten informiert (Verstoss gegen Art. 13/14 DSGVO).', + impactExamples: ['Keine informierte Einwilligung moeglich', 'Vertrauensverlust', 'Bussgeld'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K9'], + applicableTo: ['web_application', 'mobile_app', 'marketing'], + mitigationIds: ['M-TRANS-01', 'M-TRANS-05'], + }, + { + id: 'R-RIGHTS-07', + category: 'rights_freedoms', + sdmGoal: 'datenminimierung', + title: 'Uebermassige Datenerhebung (Verstoss Datenminimierung)', + description: 'Es werden mehr personenbezogene Daten erhoben als fuer den Verarbeitungszweck notwendig (Verstoss gegen Art. 5 Abs. 1 lit. c DSGVO).', + impactExamples: ['Unnoetige Risikoexposition', 'Hoeherer Schaden bei Datenpanne'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K5'], + applicableTo: ['web_application', 'mobile_app', 'crm', 'hr_system'], + mitigationIds: ['M-DMIN-01', 'M-DMIN-02', 'M-DMIN-03'], + }, + { + id: 'R-TRANS-01', + category: 'rights_freedoms', + sdmGoal: 'vertraulichkeit', + title: 'Zugriff durch Drittland-Behoerden (FISA/CLOUD Act)', + description: 'Behoerden eines Drittlandes (z.B. USA) greifen auf personenbezogene Daten zu, die bei einem Cloud-Provider in der EU oder im Drittland gespeichert sind.', + impactExamples: ['Ueberwachung ohne Wissen', 'Kein Rechtsschutz', 'Schrems-II-Risiko'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K5', 'K7'], + applicableTo: ['cloud_storage', 'email_service', 'crm', 'analytics'], + mitigationIds: ['M-TRANS-06', 'M-TRANS-07', 'M-CONF-06'], + }, + { + id: 'R-TRANS-02', + category: 'rights_freedoms', + sdmGoal: 'vertraulichkeit', + title: 'Unzureichende Schutzgarantien bei Drittlandtransfer', + description: 'Personenbezogene Daten werden in Drittlaender uebermittelt, ohne dass angemessene Garantien (SCC, BCR, Angemessenheitsbeschluss) vorhanden sind.', + impactExamples: ['Rechtswidriger Transfer', 'Bussgeld', 'Untersagung der Verarbeitung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K5', 'K7'], + applicableTo: ['cloud_storage', 'email_service', 'crm', 'analytics'], + mitigationIds: ['M-TRANS-06', 'M-TRANS-07', 'M-LEGAL-01'], + }, + { + id: 'R-TRANS-03', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'Intransparente Sub-Auftragsverarbeiter-Kette', + description: 'Die Kette der Sub-Auftragsverarbeiter ist nicht transparent. Betroffene und Verantwortliche wissen nicht, wo ihre Daten tatsaechlich verarbeitet werden.', + impactExamples: ['Unkontrollierte Datenweitergabe', 'Unbekannter Verarbeitungsort'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K5'], + applicableTo: ['cloud_storage', 'crm', 'analytics'], + mitigationIds: ['M-TRANS-01', 'M-LEGAL-02'], + }, + { + id: 'R-AUTO-01', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'KI-Fehlentscheidung mit erheblicher Auswirkung', + description: 'Ein KI-System trifft eine fehlerhafte automatisierte Entscheidung (z.B. Ablehnung, Sperrung, Bewertung), die erhebliche Auswirkungen auf eine betroffene Person hat.', + impactExamples: ['Unrechtmaessige Ablehnung', 'Falsche Risikoeinstufung', 'Benachteiligung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K1', 'K2', 'K8'], + applicableTo: ['ai_ml', 'scoring', 'hr_system'], + mitigationIds: ['M-AUTO-01', 'M-AUTO-02', 'M-AUTO-03'], + }, + { + id: 'R-AUTO-02', + category: 'rights_freedoms', + sdmGoal: 'nichtverkettung', + title: 'Algorithmischer Bias in Trainingsdaten', + description: 'KI-Modelle spiegeln Vorurteile in den Trainingsdaten wider und treffen diskriminierende Entscheidungen bezueglich geschuetzter Merkmale.', + impactExamples: ['Diskriminierung nach Geschlecht/Herkunft', 'Systematische Benachteiligung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K1', 'K2', 'K7', 'K8'], + applicableTo: ['ai_ml', 'scoring'], + mitigationIds: ['M-AUTO-01', 'M-AUTO-04'], + }, + { + id: 'R-AUTO-03', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'Fehlende Erklaerbarkeit automatisierter Entscheidungen', + description: 'Automatisierte Entscheidungen koennen den Betroffenen nicht erklaert werden ("Black Box"), sodass der Anspruch auf aussagekraeftige Informationen (Art. 22 Abs. 3) nicht erfuellt wird.', + impactExamples: ['Keine Anfechtbarkeit', 'Vertrauensverlust', 'Verstoss gegen Art. 22'], + typicalLikelihood: 'high', + typicalImpact: 'medium', + wp248Criteria: ['K2', 'K8'], + applicableTo: ['ai_ml', 'scoring'], + mitigationIds: ['M-AUTO-02', 'M-TRANS-03'], + }, + { + id: 'R-AUTO-04', + category: 'rights_freedoms', + sdmGoal: 'intervenierbarkeit', + title: 'Fehlende menschliche Aufsicht bei KI-Entscheidungen', + description: 'Automatisierte Entscheidungen werden ohne menschliche Ueberpruefung oder Interventionsmoeglichkeit getroffen, obwohl dies erforderlich waere.', + impactExamples: ['Keine Korrekturmoeglichkeit', 'Eskalation von Fehlern'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K2', 'K8'], + applicableTo: ['ai_ml', 'scoring', 'hr_system'], + mitigationIds: ['M-AUTO-03', 'M-INTERV-04'], + }, + { + id: 'R-ORG-01', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'Fehlende oder fehlerhafte Auftragsverarbeitungsvertraege', + description: 'Mit Auftragsverarbeitern existieren keine oder unzureichende Vertraege gemaess Art. 28 DSGVO, sodass Pflichten und Rechte nicht geregelt sind.', + impactExamples: ['Keine Kontrolle ueber Verarbeiter', 'Bussgeld', 'Datenmissbrauch durch Verarbeiter'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K5'], + applicableTo: ['cloud_storage', 'crm', 'analytics', 'email_service'], + mitigationIds: ['M-LEGAL-02', 'M-LEGAL-03'], + }, + { + id: 'R-ORG-02', + category: 'rights_freedoms', + sdmGoal: 'datenminimierung', + title: 'Fehlende Loeschprozesse / Ueberschreitung von Aufbewahrungsfristen', + description: 'Personenbezogene Daten werden laenger als notwendig gespeichert, weil keine automatischen Loeschprozesse oder Aufbewahrungsfristen definiert sind.', + impactExamples: ['Unnoetige Risikoexposition', 'Verstoss gegen Speicherbegrenzung', 'Bussgeld'], + typicalLikelihood: 'high', + typicalImpact: 'medium', + wp248Criteria: ['K5'], + applicableTo: ['database', 'cloud_storage', 'crm', 'erp', 'email_service'], + mitigationIds: ['M-DMIN-03', 'M-DMIN-04'], + }, + { + id: 'R-ORG-04', + category: 'rights_freedoms', + sdmGoal: 'transparenz', + title: 'Fehlende Datenpannen-Erkennung und -Meldung', + description: 'Datenpannen werden nicht rechtzeitig erkannt oder nicht innerhalb der 72-Stunden-Frist (Art. 33 DSGVO) an die Aufsichtsbehoerde gemeldet.', + impactExamples: ['Verspaetete Meldung', 'Bussgeld', 'Verzoegerte Benachrichtigung Betroffener'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K5'], + applicableTo: ['web_application', 'cloud_storage', 'database', 'api_service'], + mitigationIds: ['M-ORG-03', 'M-ORG-04', 'M-INT-02'], + }, + { + id: 'R-SPEC-02', + category: 'rights_freedoms', + sdmGoal: 'intervenierbarkeit', + title: 'Verarbeitung von Kinderdaten ohne angemessenen Schutz', + description: 'Daten von Minderjaehrigen werden verarbeitet, ohne die besonderen Schutzmassnahmen fuer Kinder (Art. 8, EG 38 DSGVO) zu beachten.', + impactExamples: ['Langzeitfolgen fuer Minderjaehrige', 'Einschraenkung der Entwicklung', 'Manipulation'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K7'], + applicableTo: ['web_application', 'mobile_app', 'education'], + mitigationIds: ['M-LEGAL-04', 'M-DMIN-01', 'M-TRANS-01'], + }, +] diff --git a/admin-compliance/lib/sdk/dsfa/risks/confidentiality-integrity.ts b/admin-compliance/lib/sdk/dsfa/risks/confidentiality-integrity.ts new file mode 100644 index 0000000..cb22ec2 --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/risks/confidentiality-integrity.ts @@ -0,0 +1,206 @@ +/** + * DSFA Risikokatalog — Vertraulichkeit & Integritaet + */ + +import type { CatalogRisk } from './types' + +export const CONFIDENTIALITY_RISKS: CatalogRisk[] = [ + { + id: 'R-CONF-01', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Unbefugte Offenlegung durch Fehlkonfiguration', + description: 'Personenbezogene Daten werden durch fehlerhafte Systemkonfiguration (z.B. offene APIs, fehlerhafte Zugriffsrechte, oeffentliche Cloud-Speicher) unbefugt zugaenglich.', + impactExamples: ['Identitaetsdiebstahl', 'Reputationsschaden', 'Diskriminierung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K5'], + applicableTo: ['cloud_storage', 'web_application', 'api_service'], + mitigationIds: ['M-CONF-01', 'M-CONF-02', 'M-CONF-03'], + }, + { + id: 'R-CONF-02', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Account Takeover / Credential Stuffing', + description: 'Angreifer uebernehmen Benutzerkonten durch gestohlene Zugangsdaten, Brute-Force-Angriffe oder Phishing und erlangen Zugriff auf personenbezogene Daten.', + impactExamples: ['Kontrollverlust ueber eigene Daten', 'Finanzieller Schaden', 'Missbrauch der Identitaet'], + typicalLikelihood: 'high', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K7'], + applicableTo: ['identity', 'web_application', 'email_service'], + mitigationIds: ['M-ACC-01', 'M-ACC-02'], + }, + { + id: 'R-CONF-03', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Unbefugter Zugriff durch Support-/Administrationspersonal', + description: 'Administratoren oder Support-Mitarbeiter greifen ohne dienstliche Notwendigkeit auf personenbezogene Daten zu (Insider-Bedrohung).', + impactExamples: ['Verletzung der Privatsphaere', 'Datenmissbrauch', 'Vertrauensverlust'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K4'], + applicableTo: ['identity', 'crm', 'cloud_storage', 'support_system'], + mitigationIds: ['M-CONF-04', 'M-CONF-05', 'M-INT-02'], + }, + { + id: 'R-CONF-04', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Datenleck durch unzureichende Verschluesselung', + description: 'Personenbezogene Daten werden bei Uebertragung oder Speicherung nicht oder unzureichend verschluesselt und koennen abgefangen werden.', + impactExamples: ['Man-in-the-Middle-Angriff', 'Datendiebstahl bei Speichermedien-Verlust'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K8'], + applicableTo: ['cloud_storage', 'email_service', 'mobile_app', 'api_service'], + mitigationIds: ['M-CONF-06', 'M-CONF-07'], + }, + { + id: 'R-CONF-05', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Unkontrollierte Datenweitergabe an Dritte', + description: 'Personenbezogene Daten werden ohne Rechtsgrundlage oder ueber das vereinbarte Mass hinaus an Dritte weitergegeben (z.B. durch Tracking, Analyse-Tools, Sub-Auftragsverarbeiter).', + impactExamples: ['Unerwuenschte Werbung', 'Profiling ohne Wissen', 'Kontrollverlust'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K1', 'K6'], + applicableTo: ['web_application', 'analytics', 'marketing', 'crm'], + mitigationIds: ['M-NONL-01', 'M-TRANS-01'], + }, + { + id: 'R-CONF-06', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Social Engineering / Phishing gegen Betroffene', + description: 'Betroffene werden durch manipulative Kommunikation dazu verleitet, personenbezogene Daten preiszugeben oder Zugriff zu gewaehren.', + impactExamples: ['Identitaetsdiebstahl', 'Finanzieller Schaden', 'Uebernahme von Konten'], + typicalLikelihood: 'high', + typicalImpact: 'medium', + wp248Criteria: ['K7'], + applicableTo: ['email_service', 'web_application', 'identity'], + mitigationIds: ['M-ACC-01', 'M-ORG-01'], + }, + { + id: 'R-CONF-07', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Unbeabsichtigte Offenlegung in Logs/Debugging', + description: 'Personenbezogene Daten gelangen in Protokolldateien, Fehlermeldungen oder Debug-Ausgaben und werden dort nicht geschuetzt.', + impactExamples: ['Zugriff durch Unbefugte auf Logdaten', 'Langzeitspeicherung ohne Rechtsgrundlage'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K4'], + applicableTo: ['api_service', 'web_application', 'cloud_storage'], + mitigationIds: ['M-CONF-08', 'M-DMIN-01'], + }, + { + id: 'R-SPEC-01', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Kompromittierung besonderer Datenkategorien (Art. 9)', + description: 'Besonders schutzwuerdige Daten (Gesundheit, Religion, Biometrie, Gewerkschaftszugehoerigkeit) werden offengelegt oder missbraucht.', + impactExamples: ['Schwerwiegende Diskriminierung', 'Existenzielle Bedrohung', 'Soziale Ausgrenzung'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K7'], + applicableTo: ['hr_system', 'health_system', 'identity'], + mitigationIds: ['M-CONF-06', 'M-CONF-01', 'M-CONF-04'], + }, + { + id: 'R-AUTO-05', + category: 'confidentiality', + sdmGoal: 'vertraulichkeit', + title: 'Datenleck durch KI-Training mit personenbezogenen Daten', + description: 'Personenbezogene Daten, die fuer das Training von KI-Modellen verwendet werden, koennen durch das Modell reproduziert oder extrahiert werden (Model Inversion, Membership Inference).', + impactExamples: ['Offenlegung von Trainingsdaten', 'Re-Identifizierung'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K8'], + applicableTo: ['ai_ml'], + mitigationIds: ['M-CONF-06', 'M-NONL-03', 'M-AUTO-04'], + }, +] + +export const INTEGRITY_RISKS: CatalogRisk[] = [ + { + id: 'R-INT-01', + category: 'integrity', + sdmGoal: 'integritaet', + title: 'Datenmanipulation durch externen Angriff', + description: 'Personenbezogene Daten werden durch einen Cyberangriff (SQL-Injection, API-Manipulation) veraendert, ohne dass dies erkannt wird.', + impactExamples: ['Falsche Entscheidungen auf Basis manipulierter Daten', 'Rufschaedigung'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K4', 'K8'], + applicableTo: ['api_service', 'web_application', 'database'], + mitigationIds: ['M-INT-01', 'M-INT-02', 'M-INT-03'], + }, + { + id: 'R-INT-02', + category: 'integrity', + sdmGoal: 'integritaet', + title: 'Fehlerhafte Synchronisation zwischen Systemen', + description: 'Bei der Synchronisation personenbezogener Daten zwischen verschiedenen Systemen kommt es zu Inkonsistenzen, Duplikaten oder Datenverlust.', + impactExamples: ['Falsche Kontaktdaten', 'Doppelte Verarbeitung', 'Falsche Auskuenfte'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K6'], + applicableTo: ['crm', 'cloud_storage', 'erp', 'identity'], + mitigationIds: ['M-INT-04', 'M-INT-05'], + }, + { + id: 'R-INT-03', + category: 'integrity', + sdmGoal: 'integritaet', + title: 'Backup-Korruption oder fehlerhafte Wiederherstellung', + description: 'Backups personenbezogener Daten sind beschaedigt, unvollstaendig oder veraltet, sodass eine zuverlaessige Wiederherstellung nicht moeglich ist.', + impactExamples: ['Datenverlust bei Wiederherstellung', 'Veraltete Datenbasis', 'Compliance-Verstoss'], + typicalLikelihood: 'low', + typicalImpact: 'high', + wp248Criteria: ['K5'], + applicableTo: ['database', 'cloud_storage', 'erp'], + mitigationIds: ['M-AVAIL-01', 'M-AVAIL-02'], + }, + { + id: 'R-INT-04', + category: 'integrity', + sdmGoal: 'integritaet', + title: 'Unbemerkte Aenderung von Zugriffsrechten', + description: 'Zugriffsberechtigungen werden unbefugt oder fehlerhaft geaendert, wodurch unberechtigte Personen Zugang zu personenbezogenen Daten erhalten.', + impactExamples: ['Privilege Escalation', 'Unbefugter Datenzugriff'], + typicalLikelihood: 'medium', + typicalImpact: 'high', + wp248Criteria: ['K4'], + applicableTo: ['identity', 'cloud_storage', 'api_service'], + mitigationIds: ['M-INT-02', 'M-CONF-04'], + }, + { + id: 'R-INT-05', + category: 'integrity', + sdmGoal: 'integritaet', + title: 'Fehlende Nachvollziehbarkeit von Datenveraenderungen', + description: 'Aenderungen an personenbezogenen Daten werden nicht protokolliert, sodass Manipulationen oder Fehler nicht erkannt oder nachvollzogen werden koennen.', + impactExamples: ['Unmoeglich festzustellen wer/wann Daten geaendert hat', 'Audit-Versagen'], + typicalLikelihood: 'medium', + typicalImpact: 'medium', + wp248Criteria: ['K3'], + applicableTo: ['database', 'crm', 'erp', 'web_application'], + mitigationIds: ['M-INT-02', 'M-TRANS-02'], + }, + { + id: 'R-ORG-03', + category: 'integrity', + sdmGoal: 'integritaet', + title: 'Unzureichende Schulung/Sensibilisierung der Mitarbeiter', + description: 'Mitarbeiter sind nicht ausreichend im Umgang mit personenbezogenen Daten geschult und verursachen durch Unkenntnis Datenpannen oder Verarbeitungsfehler.', + impactExamples: ['Versehentliche Datenweitergabe', 'Phishing-Erfolg', 'Fehlerhafte Verarbeitung'], + typicalLikelihood: 'high', + typicalImpact: 'medium', + wp248Criteria: ['K5', 'K7'], + applicableTo: ['hr_system', 'email_service', 'crm', 'web_application'], + mitigationIds: ['M-ORG-01', 'M-ORG-02'], + }, +] diff --git a/admin-compliance/lib/sdk/dsfa/risks/helpers.ts b/admin-compliance/lib/sdk/dsfa/risks/helpers.ts new file mode 100644 index 0000000..22f6b2b --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/risks/helpers.ts @@ -0,0 +1,64 @@ +/** + * DSFA Risikokatalog — Helpers & Assembled Catalog + */ + +import type { DSFARiskCategory, SDMGoal } from '../types' +import type { CatalogRisk } from './types' +import { CONFIDENTIALITY_RISKS, INTEGRITY_RISKS } from './confidentiality-integrity' +import { AVAILABILITY_RISKS, RIGHTS_FREEDOMS_RISKS } from './availability-rights-auto-org' + +export const RISK_CATALOG: CatalogRisk[] = [ + ...CONFIDENTIALITY_RISKS, + ...INTEGRITY_RISKS, + ...AVAILABILITY_RISKS, + ...RIGHTS_FREEDOMS_RISKS, +] + +export function getRisksByCategory(category: DSFARiskCategory): CatalogRisk[] { + return RISK_CATALOG.filter(r => r.category === category) +} + +export function getRisksBySDMGoal(goal: SDMGoal): CatalogRisk[] { + return RISK_CATALOG.filter(r => r.sdmGoal === goal) +} + +export function getRisksByWP248Criterion(criterionCode: string): CatalogRisk[] { + return RISK_CATALOG.filter(r => r.wp248Criteria.includes(criterionCode)) +} + +export function getRisksByComponent(component: string): CatalogRisk[] { + return RISK_CATALOG.filter(r => r.applicableTo.includes(component)) +} + +export function getCatalogRiskById(id: string): CatalogRisk | undefined { + return RISK_CATALOG.find(r => r.id === id) +} + +export const RISK_CATEGORY_LABELS: Record = { + confidentiality: 'Vertraulichkeit', + integrity: 'Integritaet', + availability: 'Verfuegbarkeit', + rights_freedoms: 'Rechte & Freiheiten', +} + +export const COMPONENT_FAMILY_LABELS: Record = { + identity: 'Identitaet & Zugang', + cloud_storage: 'Cloud-Speicher', + web_application: 'Web-Anwendung', + api_service: 'API-Service', + email_service: 'E-Mail-Dienst', + mobile_app: 'Mobile App', + database: 'Datenbank', + crm: 'CRM-System', + erp: 'ERP-System', + analytics: 'Analyse/Tracking', + marketing: 'Marketing', + ai_ml: 'KI / Machine Learning', + scoring: 'Scoring / Bewertung', + hr_system: 'HR-System', + health_system: 'Gesundheitssystem', + monitoring: 'Ueberwachungssystem', + support_system: 'Support-System', + education: 'Bildungsplattform', + research: 'Forschung', +} diff --git a/admin-compliance/lib/sdk/dsfa/risks/types.ts b/admin-compliance/lib/sdk/dsfa/risks/types.ts new file mode 100644 index 0000000..3c9945a --- /dev/null +++ b/admin-compliance/lib/sdk/dsfa/risks/types.ts @@ -0,0 +1,19 @@ +/** + * DSFA Risikokatalog — Types + */ + +import type { DSFARiskCategory, SDMGoal } from '../types' + +export interface CatalogRisk { + id: string + category: DSFARiskCategory + sdmGoal: SDMGoal + title: string + description: string + impactExamples: string[] + typicalLikelihood: 'low' | 'medium' | 'high' + typicalImpact: 'low' | 'medium' | 'high' + wp248Criteria: string[] + applicableTo: string[] + mitigationIds: string[] +} diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog.ts index 7c887c1..fe9c03b 100644 --- a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog.ts +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog.ts @@ -1,760 +1,13 @@ /** - * Loeschfristen Baseline-Katalog + * Loeschfristen Baseline-Katalog — Barrel * * 25 vordefinierte Aufbewahrungsfristen-Templates fuer gaengige - * Datenobjekte in deutschen Unternehmen. Basierend auf AO, HGB, - * UStG, BGB, ArbZG, AGG, BDSG, BSIG und ArbMedVV. - * - * Werden genutzt, um neue Loeschfrist-Policies schnell aus - * bewaehrten Vorlagen zu erstellen. + * Datenobjekte. Split into domain modules; re-exported here for backward compatibility. */ -import type { - LoeschfristPolicy, - RetentionDriverType, - DeletionMethodType, - StorageLocation, - PolicyStatus, - ReviewInterval, - RetentionUnit, - DeletionTriggerLevel, -} from './loeschfristen-types' - -import { createEmptyPolicy } from './loeschfristen-types' - -// ============================================================================= -// BASELINE TEMPLATE INTERFACE -// ============================================================================= - -export interface BaselineTemplate { - templateId: string - dataObjectName: string - description: string - affectedGroups: string[] - dataCategories: string[] - primaryPurpose: string - deletionTrigger: DeletionTriggerLevel - retentionDriver: RetentionDriverType | null - retentionDriverDetail: string - retentionDuration: number | null - retentionUnit: RetentionUnit | null - retentionDescription: string - startEvent: string - deletionMethod: DeletionMethodType - deletionMethodDetail: string - responsibleRole: string - reviewInterval: ReviewInterval - tags: string[] -} - -// ============================================================================= -// BASELINE TEMPLATES (25 Vorlagen) -// ============================================================================= - -export const BASELINE_TEMPLATES: BaselineTemplate[] = [ - // ==================== 1. Personalakten ==================== - { - templateId: 'personal-akten', - dataObjectName: 'Personalakten', - description: - 'Vollstaendige Personalakten inkl. Arbeitsvertraege, Zeugnisse, Abmahnungen und sonstige beschaeftigungsrelevante Dokumente.', - affectedGroups: ['Mitarbeiter'], - dataCategories: ['Stammdaten', 'Vertragsdaten', 'Gehaltsdaten', 'Zeugnisse'], - primaryPurpose: - 'Dokumentation und Nachweisfuehrung des Beschaeftigungsverhaeltnisses sowie Erfuellung steuerrechtlicher Aufbewahrungspflichten.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'AO_147', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 147 AO fuer steuerlich relevante Unterlagen der Personalakte.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre nach Ende des Beschaeftigungsverhaeltnisses', - startEvent: 'Ende des Beschaeftigungsverhaeltnisses', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung aller digitalen Personalakten-Dokumente nach Ablauf der Aufbewahrungsfrist. Papierakten werden datenschutzkonform vernichtet.', - responsibleRole: 'HR-Abteilung', - reviewInterval: 'ANNUAL', - tags: ['hr', 'steuer'], - }, - - // ==================== 2. Buchhaltungsbelege ==================== - { - templateId: 'buchhaltungsbelege', - dataObjectName: 'Buchhaltungsbelege', - description: - 'Buchungsbelege, Kontoauszuege, Kassenbuecher und sonstige Belege der laufenden Buchhaltung.', - affectedGroups: ['Kunden', 'Lieferanten'], - dataCategories: ['Finanzdaten', 'Transaktionsdaten', 'Kontodaten'], - primaryPurpose: - 'Ordnungsgemaesse Buchfuehrung und Erfuellung handelsrechtlicher Aufbewahrungspflichten nach HGB.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'HGB_257', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 257 HGB fuer Handelsbuecher und Buchungsbelege.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre nach Ende des Geschaeftsjahres', - startEvent: 'Ende des Geschaeftsjahres', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch die Buchhaltung vor Loeschung, um sicherzustellen, dass keine laufenden Pruefungen oder Rechtsstreitigkeiten bestehen.', - responsibleRole: 'Buchhaltung', - reviewInterval: 'ANNUAL', - tags: ['finanzen', 'hgb'], - }, - - // ==================== 3. Rechnungen ==================== - { - templateId: 'rechnungen', - dataObjectName: 'Rechnungen', - description: - 'Eingangs- und Ausgangsrechnungen inkl. Rechnungsanhaenge und rechnungsbegruendende Unterlagen.', - affectedGroups: ['Kunden', 'Lieferanten'], - dataCategories: ['Rechnungsdaten', 'Umsatzsteuerdaten', 'Adressdaten'], - primaryPurpose: - 'Dokumentation umsatzsteuerrelevanter Vorgaenge und Erfuellung der Aufbewahrungspflicht nach UStG.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'USTG_14B', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 14b UStG fuer Rechnungen und rechnungsbegruendende Unterlagen.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre ab Rechnungsdatum', - startEvent: 'Rechnungsdatum', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung nach Ablauf der 10-Jahres-Frist. Vor Loeschung wird geprueft, ob Rechnungen in laufenden Betriebspruefungen benoetigt werden.', - responsibleRole: 'Buchhaltung', - reviewInterval: 'ANNUAL', - tags: ['finanzen', 'ustg'], - }, - - // ==================== 4. Geschaeftsbriefe ==================== - { - templateId: 'geschaeftsbriefe', - dataObjectName: 'Geschaeftsbriefe', - description: - 'Empfangene und versandte Handelsbriefe, Geschaeftskorrespondenz und geschaeftsrelevante E-Mails.', - affectedGroups: ['Kunden', 'Lieferanten'], - dataCategories: ['Korrespondenz', 'Vertragskommunikation', 'Angebote'], - primaryPurpose: - 'Nachweisfuehrung geschaeftlicher Kommunikation und Erfuellung der handelsrechtlichen Aufbewahrungspflicht fuer Handelsbriefe.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'HGB_257', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 257 HGB fuer empfangene und versandte Handelsbriefe (6 Jahre).', - retentionDuration: 6, - retentionUnit: 'YEARS', - retentionDescription: '6 Jahre ab Eingang oder Versand des Geschaeftsbriefes', - startEvent: 'Eingang bzw. Versand des Geschaeftsbriefes', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch die Geschaeftsleitung, da Geschaeftsbriefe ggf. als Beweismittel in Rechtsstreitigkeiten dienen koennen.', - responsibleRole: 'Geschaeftsleitung', - reviewInterval: 'ANNUAL', - tags: ['kommunikation', 'hgb'], - }, - - // ==================== 5. Bewerbungsunterlagen ==================== - { - templateId: 'bewerbungsunterlagen', - dataObjectName: 'Bewerbungsunterlagen', - description: - 'Eingereichte Bewerbungsunterlagen inkl. Anschreiben, Lebenslauf, Zeugnisse und Korrespondenz mit Bewerbern.', - affectedGroups: ['Bewerber'], - dataCategories: ['Bewerbungsdaten', 'Qualifikationen', 'Kontaktdaten'], - primaryPurpose: - 'Durchfuehrung des Bewerbungsverfahrens und Absicherung gegen Entschaedigungsansprueche nach dem AGG.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'AGG_15', - retentionDriverDetail: - 'Aufbewahrung fuer 6 Monate nach Absage gemaess 15 Abs. 4 AGG (Frist fuer Geltendmachung von Entschaedigungsanspruechen).', - retentionDuration: 6, - retentionUnit: 'MONTHS', - retentionDescription: '6 Monate nach Absage oder Stellenbesetzung', - startEvent: 'Absage oder endgueltige Stellenbesetzung', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung aller Bewerbungsunterlagen und zugehoeriger Kommunikation nach Ablauf der 6-Monats-Frist.', - responsibleRole: 'HR-Abteilung', - reviewInterval: 'QUARTERLY', - tags: ['hr', 'bewerbung'], - }, - - // ==================== 6. Kundenstammdaten ==================== - { - templateId: 'kundenstammdaten', - dataObjectName: 'Kundenstammdaten', - description: - 'Stammdaten von Kunden inkl. Kontaktdaten, Anschrift, Kundennummer und Kommunikationspraeferenzen.', - affectedGroups: ['Kunden'], - dataCategories: ['Stammdaten', 'Kontaktdaten', 'Adressdaten'], - primaryPurpose: - 'Pflege der Kundenbeziehung, Vertragserfuellung und Absicherung gegen Verjaehrung vertraglicher Ansprueche.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BGB_195', - retentionDriverDetail: - 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB (3 Jahre).', - retentionDuration: 3, - retentionUnit: 'YEARS', - retentionDescription: '3 Jahre nach letzter geschaeftlicher Interaktion', - startEvent: 'Letzte geschaeftliche Interaktion mit dem Kunden', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch den Vertrieb vor Loeschung, um sicherzustellen, dass keine aktiven Geschaeftsbeziehungen oder offenen Forderungen bestehen.', - responsibleRole: 'Vertrieb', - reviewInterval: 'ANNUAL', - tags: ['crm', 'kunden'], - }, - - // ==================== 7. Newsletter-Einwilligungen ==================== - { - templateId: 'newsletter-einwilligungen', - dataObjectName: 'Newsletter-Einwilligungen', - description: - 'Einwilligungserklaerungen fuer den Newsletter-Versand inkl. Double-Opt-in-Nachweis und Abmeldezeitpunkt.', - affectedGroups: ['Abonnenten'], - dataCategories: ['Einwilligungsdaten', 'E-Mail-Adresse', 'Opt-in-Nachweis'], - primaryPurpose: - 'Nachweis der wirksamen Einwilligung zum Newsletter-Versand gemaess Art. 7 DSGVO und Dokumentation des Widerrufs.', - deletionTrigger: 'PURPOSE_END', - retentionDriver: null, - retentionDriverDetail: - 'Keine gesetzliche Aufbewahrungspflicht. Daten werden bis zum Widerruf der Einwilligung gespeichert.', - retentionDuration: null, - retentionUnit: null, - retentionDescription: 'Bis zum Widerruf der Einwilligung durch den Abonnenten', - startEvent: 'Widerruf der Einwilligung durch den Abonnenten', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung der personenbezogenen Daten nach Eingang des Widerrufs. Der Einwilligungsnachweis selbst wird fuer die Dauer der Nachweispflicht aufbewahrt.', - responsibleRole: 'Marketing', - reviewInterval: 'SEMI_ANNUAL', - tags: ['marketing', 'einwilligung'], - }, - - // ==================== 8. Webserver-Logs ==================== - { - templateId: 'webserver-logs', - dataObjectName: 'Webserver-Logs', - description: - 'Server-Zugriffsprotokolle inkl. IP-Adressen, Zeitstempel, aufgerufene URLs und HTTP-Statuscodes.', - affectedGroups: ['Website-Besucher'], - dataCategories: ['IP-Adressen', 'Zugriffszeitpunkte', 'User-Agent-Daten'], - primaryPurpose: - 'Sicherstellung der IT-Sicherheit, Erkennung von Angriffen und Stoerungen sowie Erfuellung der Protokollierungspflicht nach BSIG.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BSIG', - retentionDriverDetail: - 'Aufbewahrung gemaess BSI-Gesetz / IT-Sicherheitsgesetz 2.0 fuer die Analyse von Sicherheitsvorfaellen.', - retentionDuration: 7, - retentionUnit: 'DAYS', - retentionDescription: '7 Tage nach Zeitpunkt des Zugriffs', - startEvent: 'Zeitpunkt des Server-Zugriffs', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Rotation und Loeschung der Logdateien nach 7 Tagen durch den Webserver (logrotate).', - responsibleRole: 'IT-Abteilung', - reviewInterval: 'QUARTERLY', - tags: ['it', 'logs'], - }, - - // ==================== 9. Videoueberwachung ==================== - { - templateId: 'videoueberwachung', - dataObjectName: 'Videoueberwachung', - description: - 'Aufnahmen der Videoueberwachung in Geschaeftsraeumen, Eingangsbereichen und Parkplaetzen.', - affectedGroups: ['Besucher', 'Mitarbeiter'], - dataCategories: ['Videodaten', 'Bilddaten', 'Zeitstempel'], - primaryPurpose: - 'Schutz des Eigentums und der Sicherheit von Personen sowie Aufklaerung von Vorfaellen in den ueberwachten Bereichen.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BDSG_35', - retentionDriverDetail: - 'Unverzuegliche Loeschung nach Zweckwegfall gemaess 35 BDSG bzw. Art. 17 DSGVO. Maximale Speicherdauer 48 Stunden.', - retentionDuration: 2, - retentionUnit: 'DAYS', - retentionDescription: '48 Stunden (2 Tage) nach Aufnahmezeitpunkt', - startEvent: 'Aufnahmezeitpunkt der Videosequenz', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatisches Ueberschreiben der Aufnahmen durch das Videomanagementsystem nach Ablauf der 48-Stunden-Frist.', - responsibleRole: 'Facility Management', - reviewInterval: 'QUARTERLY', - tags: ['sicherheit', 'video'], - }, - - // ==================== 10. Gehaltsabrechnungen ==================== - { - templateId: 'gehaltsabrechnungen', - dataObjectName: 'Gehaltsabrechnungen', - description: - 'Monatliche Gehaltsabrechnungen, Lohnsteuerbescheinigungen und Sozialversicherungsmeldungen.', - affectedGroups: ['Mitarbeiter'], - dataCategories: ['Gehaltsdaten', 'Steuerdaten', 'Sozialversicherungsdaten'], - primaryPurpose: - 'Dokumentation der Lohn- und Gehaltszahlungen sowie Erfuellung steuerrechtlicher und sozialversicherungsrechtlicher Aufbewahrungspflichten.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'AO_147', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 147 AO fuer lohnsteuerrelevante Unterlagen und Gehaltsbuchungen.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre nach Ende des Geschaeftsjahres', - startEvent: 'Ende des Geschaeftsjahres der jeweiligen Abrechnung', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung der digitalen Gehaltsabrechnungen nach Ablauf der Aufbewahrungsfrist. Papierbelege werden datenschutzkonform vernichtet.', - responsibleRole: 'Lohnbuchhaltung', - reviewInterval: 'ANNUAL', - tags: ['hr', 'steuer'], - }, - - // ==================== 11. Vertraege ==================== - { - templateId: 'vertraege', - dataObjectName: 'Vertraege', - description: - 'Geschaeftsvertraege, Rahmenvereinbarungen, Dienstleistungsvertraege und zugehoerige Anlagen und Nachtraege.', - affectedGroups: ['Vertragspartner'], - dataCategories: ['Vertragsdaten', 'Kontaktdaten', 'Konditionen'], - primaryPurpose: - 'Dokumentation vertraglicher Vereinbarungen und Sicherung von Beweismitteln fuer die Dauer moeglicher Rechtsstreitigkeiten.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'HGB_257', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 257 HGB fuer handelsrechtlich relevante Vertragsunterlagen.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre nach Ende der Vertragslaufzeit', - startEvent: 'Ende der Vertragslaufzeit bzw. Vertragsbeendigung', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch die Rechtsabteilung vor Loeschung, um sicherzustellen, dass keine laufenden oder angedrohten Rechtsstreitigkeiten bestehen.', - responsibleRole: 'Rechtsabteilung', - reviewInterval: 'ANNUAL', - tags: ['recht', 'vertraege'], - }, - - // ==================== 12. Zeiterfassungsdaten ==================== - { - templateId: 'zeiterfassung', - dataObjectName: 'Zeiterfassungsdaten', - description: - 'Arbeitszeitaufzeichnungen inkl. Beginn, Ende, Pausen und Ueberstunden der Beschaeftigten.', - affectedGroups: ['Mitarbeiter'], - dataCategories: ['Arbeitszeiten', 'Pausenzeiten', 'Ueberstunden'], - primaryPurpose: - 'Erfuellung der gesetzlichen Aufzeichnungspflicht fuer Arbeitszeiten und Nachweis der Einhaltung des Arbeitszeitgesetzes.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'ARBZG_16', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 16 Abs. 2 ArbZG fuer Aufzeichnungen ueber die Arbeitszeit.', - retentionDuration: 2, - retentionUnit: 'YEARS', - retentionDescription: '2 Jahre nach Ende des Erfassungszeitraums', - startEvent: 'Ende des jeweiligen Erfassungszeitraums', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung der Zeiterfassungsdaten nach Ablauf der 2-Jahres-Frist im Zeiterfassungssystem.', - responsibleRole: 'HR-Abteilung', - reviewInterval: 'ANNUAL', - tags: ['hr', 'arbzg'], - }, - - // ==================== 13. Krankmeldungen ==================== - { - templateId: 'krankmeldungen', - dataObjectName: 'Krankmeldungen', - description: - 'Arbeitsunfaehigkeitsbescheinigungen, Krankmeldungen und zugehoerige Abwesenheitsdokumentationen.', - affectedGroups: ['Mitarbeiter'], - dataCategories: ['Gesundheitsdaten', 'Abwesenheitszeiten', 'AU-Bescheinigungen'], - primaryPurpose: - 'Dokumentation von Fehlzeiten, Entgeltfortzahlung im Krankheitsfall und Absicherung gegen Verjaehrung arbeitsrechtlicher Ansprueche.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BGB_195', - retentionDriverDetail: - 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB zur Absicherung von Erstattungsanspruechen.', - retentionDuration: 3, - retentionUnit: 'YEARS', - retentionDescription: '3 Jahre nach Ende des Beschaeftigungsverhaeltnisses', - startEvent: 'Ende des Beschaeftigungsverhaeltnisses', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch die HR-Abteilung vor Loeschung, da Krankmeldungen besondere Kategorien personenbezogener Daten (Gesundheitsdaten) enthalten.', - responsibleRole: 'HR-Abteilung', - reviewInterval: 'ANNUAL', - tags: ['hr', 'gesundheit'], - }, - - // ==================== 14. Steuererklaerungen ==================== - { - templateId: 'steuererklaerungen', - dataObjectName: 'Steuererklaerungen', - description: - 'Koerperschaftsteuer-, Gewerbesteuer- und Umsatzsteuererklaerungen inkl. Anlagen und Bescheide.', - affectedGroups: ['Unternehmen'], - dataCategories: ['Steuerdaten', 'Finanzkennzahlen', 'Bescheide'], - primaryPurpose: - 'Erfuellung steuerrechtlicher Dokumentationspflichten und Nachweisfuehrung gegenueber den Finanzbehoerden.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'AO_147', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 147 AO fuer Steuererklaerungen und zugehoerige Unterlagen.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre ab dem jeweiligen Steuerjahr', - startEvent: 'Ende des betreffenden Steuerjahres', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung nach Ablauf der 10-Jahres-Frist, sofern keine laufende Betriebspruefung oder Einspruchsverfahren vorliegen.', - responsibleRole: 'Steuerberater/Buchhaltung', - reviewInterval: 'ANNUAL', - tags: ['finanzen', 'steuer'], - }, - - // ==================== 15. Gesellschafterprotokolle ==================== - { - templateId: 'protokolle-gesellschafter', - dataObjectName: 'Gesellschafterprotokolle', - description: - 'Protokolle der Gesellschafterversammlungen, Beschluesse, Abstimmungsergebnisse und notarielle Urkunden.', - affectedGroups: ['Gesellschafter'], - dataCategories: ['Beschlussdaten', 'Abstimmungsergebnisse', 'Protokolle'], - primaryPurpose: - 'Dokumentation gesellschaftsrechtlicher Beschluesse und Erfuellung handelsrechtlicher Aufbewahrungspflichten.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'HGB_257', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 257 HGB fuer Eroeffnungsbilanzen, Jahresabschluesse und zugehoerige Beschluesse.', - retentionDuration: 10, - retentionUnit: 'YEARS', - retentionDescription: '10 Jahre ab Beschlussdatum', - startEvent: 'Datum des jeweiligen Gesellschafterbeschlusses', - deletionMethod: 'PHYSICAL_DESTROY', - deletionMethodDetail: - 'Physische Vernichtung der Papieroriginale durch zertifizierten Aktenvernichtungsdienstleister (DIN 66399, Sicherheitsstufe P-4). Digitale Kopien werden parallel geloescht.', - responsibleRole: 'Geschaeftsleitung', - reviewInterval: 'ANNUAL', - tags: ['recht', 'gesellschaft'], - }, - - // ==================== 16. CRM-Kontakthistorie ==================== - { - templateId: 'crm-kontakthistorie', - dataObjectName: 'CRM-Kontakthistorie', - description: - 'Kontaktverlauf im CRM-System inkl. Anrufe, E-Mails, Termine, Notizen und Angebotsverlauf.', - affectedGroups: ['Kunden', 'Interessenten'], - dataCategories: ['Kommunikationsdaten', 'Interaktionshistorie', 'Angebotsdaten'], - primaryPurpose: - 'Pflege der Kundenbeziehung und Nachverfolgung geschaeftlicher Interaktionen fuer Vertriebs- und Servicezwecke.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BGB_195', - retentionDriverDetail: - 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB zur Absicherung vertraglicher Ansprueche.', - retentionDuration: 3, - retentionUnit: 'YEARS', - retentionDescription: '3 Jahre nach letztem Kontakt mit dem Kunden oder Interessenten', - startEvent: 'Letzter dokumentierter Kontakt im CRM-System', - deletionMethod: 'ANONYMIZATION', - deletionMethodDetail: - 'Anonymisierung der personenbezogenen Daten im CRM-System, sodass statistische Auswertungen weiterhin moeglich sind, aber kein Personenbezug mehr hergestellt werden kann.', - responsibleRole: 'Vertrieb', - reviewInterval: 'SEMI_ANNUAL', - tags: ['crm', 'kunden'], - }, - - // ==================== 17. Backup-Daten ==================== - { - templateId: 'backup-daten', - dataObjectName: 'Backup-Daten', - description: - 'Vollstaendige und inkrementelle Sicherungskopien aller Systeme, Datenbanken und Dateisysteme.', - affectedGroups: ['Alle Betroffenengruppen'], - dataCategories: ['Systemsicherungen', 'Datenbankkopien', 'Dateisystemsicherungen'], - primaryPurpose: - 'Sicherstellung der Datenwiederherstellung im Katastrophenfall und Gewaehrleistung der Geschaeftskontinuitaet.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BSIG', - retentionDriverDetail: - 'Aufbewahrung von Backups fuer 90 Tage gemaess BSI-Grundschutz-Empfehlungen zur Sicherstellung der Wiederherstellbarkeit.', - retentionDuration: 90, - retentionUnit: 'DAYS', - retentionDescription: '90 Tage nach Erstellung des Backups', - startEvent: 'Erstellungsdatum des jeweiligen Backups', - deletionMethod: 'CRYPTO_ERASE', - deletionMethodDetail: - 'Kryptographische Loeschung durch Vernichtung der Verschluesselungsschluessel, sodass die verschluesselten Backup-Daten nicht mehr entschluesselt werden koennen.', - responsibleRole: 'IT-Abteilung', - reviewInterval: 'QUARTERLY', - tags: ['it', 'backup'], - }, - - // ==================== 18. Cookie-Consent-Nachweise ==================== - { - templateId: 'cookie-consent-logs', - dataObjectName: 'Cookie-Consent-Nachweise', - description: - 'Nachweise ueber Cookie-Einwilligungen der Website-Besucher inkl. Consent-ID, Zeitstempel, gesetzte Praeferenzen und IP-Adresse.', - affectedGroups: ['Website-Besucher'], - dataCategories: ['Consent-Daten', 'IP-Adressen', 'Zeitstempel', 'Praeferenzen'], - primaryPurpose: - 'Nachweisfuehrung der Einwilligung in die Cookie-Nutzung gemaess Art. 7 Abs. 1 DSGVO und ePrivacy-Richtlinie.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BGB_195', - retentionDriverDetail: - 'Aufbewahrung der Consent-Nachweise fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB zur Absicherung gegen Abmahnungen.', - retentionDuration: 3, - retentionUnit: 'YEARS', - retentionDescription: '3 Jahre nach Zeitpunkt der Einwilligung', - startEvent: 'Zeitpunkt der Cookie-Einwilligung (Consent-Zeitstempel)', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung der Consent-Nachweise nach Ablauf der 3-Jahres-Frist durch das Consent-Management-System.', - responsibleRole: 'Datenschutzbeauftragter', - reviewInterval: 'ANNUAL', - tags: ['datenschutz', 'consent'], - }, - - // ==================== 19. E-Mail-Archivierung ==================== - { - templateId: 'email-archivierung', - dataObjectName: 'E-Mail-Archivierung', - description: - 'Archivierte geschaeftliche E-Mails inkl. Anhaenge, die als Handelsbriefe oder steuerrelevante Korrespondenz einzustufen sind.', - affectedGroups: ['Mitarbeiter', 'Kunden', 'Lieferanten'], - dataCategories: ['E-Mail-Korrespondenz', 'Anhaenge', 'Metadaten'], - primaryPurpose: - 'Erfuellung der handelsrechtlichen Aufbewahrungspflicht fuer geschaeftliche Korrespondenz, die als Handelsbrief einzuordnen ist.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'HGB_257', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess 257 HGB fuer empfangene und versandte Handelsbriefe (6 Jahre) bzw. buchhalterisch relevante E-Mails (10 Jahre).', - retentionDuration: 6, - retentionUnit: 'YEARS', - retentionDescription: '6 Jahre nach Versand/Empfang der E-Mail', - startEvent: 'Versand- bzw. Empfangsdatum der E-Mail', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung durch das E-Mail-Archivierungssystem nach Ablauf der konfigurierten Aufbewahrungsfrist. Vor Loeschung wird geprueft, ob die E-Mail in laufenden Verfahren benoetigt wird.', - responsibleRole: 'IT-Abteilung', - reviewInterval: 'ANNUAL', - tags: ['kommunikation', 'hgb'], - }, - - // ==================== 20. Zutrittsprotokolle ==================== - { - templateId: 'zutrittsprotokolle', - dataObjectName: 'Zutrittsprotokolle', - description: - 'Protokolle des Zutrittskontrollsystems inkl. Zeitstempel, Kartennummer, Zutrittsort und Zugangsentscheidung (gewaehrt/verweigert).', - affectedGroups: ['Mitarbeiter', 'Besucher'], - dataCategories: ['Zutrittsdaten', 'Zeitstempel', 'Kartennummern', 'Standortdaten'], - primaryPurpose: - 'Sicherstellung der physischen Sicherheit, Nachvollziehbarkeit von Zutritten und Unterstuetzung bei der Aufklaerung von Sicherheitsvorfaellen.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BSIG', - retentionDriverDetail: - 'Aufbewahrung gemaess BSI-Grundschutz-Empfehlung fuer Zutrittsprotokolle zur Analyse von Sicherheitsvorfaellen (90 Tage).', - retentionDuration: 90, - retentionUnit: 'DAYS', - retentionDescription: '90 Tage nach Zeitpunkt des Zutritts', - startEvent: 'Zeitpunkt des protokollierten Zutrittsereignisses', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Rotation und Loeschung der Zutrittsprotokolle durch das Zutrittskontrollsystem nach Ablauf der 90-Tage-Frist.', - responsibleRole: 'Facility Management', - reviewInterval: 'QUARTERLY', - tags: ['sicherheit', 'zutritt'], - }, - - // ==================== 21. Schulungsnachweise ==================== - { - templateId: 'schulungsnachweise', - dataObjectName: 'Schulungsnachweise', - description: - 'Teilnahmebestaetigungen, Zertifikate und Protokolle von Mitarbeiterschulungen (Datenschutz, Arbeitssicherheit, Compliance).', - affectedGroups: ['Mitarbeiter'], - dataCategories: ['Schulungsdaten', 'Zertifikate', 'Teilnahmelisten'], - primaryPurpose: - 'Nachweis der Durchfuehrung gesetzlich vorgeschriebener Schulungen und Dokumentation der Mitarbeiterqualifikation.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'CUSTOM', - retentionDriverDetail: - 'Aufbewahrung fuer 3 Jahre nach Ende des Beschaeftigungsverhaeltnisses als Nachweis der ordnungsgemaessen Schulungsdurchfuehrung.', - retentionDuration: 3, - retentionUnit: 'YEARS', - retentionDescription: '3 Jahre nach Ende des Beschaeftigungsverhaeltnisses', - startEvent: 'Ende des Beschaeftigungsverhaeltnisses des geschulten Mitarbeiters', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch die HR-Abteilung vor Loeschung, da Schulungsnachweise als Compliance-Nachweis in Audits relevant sein koennen.', - responsibleRole: 'HR-Abteilung', - reviewInterval: 'ANNUAL', - tags: ['hr', 'schulung'], - }, - - // ==================== 22. Betriebsarzt-Dokumentation ==================== - { - templateId: 'betriebsarzt-doku', - dataObjectName: 'Betriebsarzt-Dokumentation', - description: - 'Ergebnisse arbeitsmedizinischer Vorsorgeuntersuchungen, Eignungsuntersuchungen und arbeitsmedizinische Empfehlungen.', - affectedGroups: ['Mitarbeiter'], - dataCategories: ['Gesundheitsdaten', 'Vorsorgeuntersuchungen', 'Eignungsbefunde'], - primaryPurpose: - 'Erfuellung der Dokumentationspflicht fuer arbeitsmedizinische Vorsorge gemaess ArbMedVV und Nachweisfuehrung gegenueber Berufsgenossenschaften.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'CUSTOM', - retentionDriverDetail: - 'Aufbewahrungspflicht gemaess ArbMedVV (Verordnung zur arbeitsmedizinischen Vorsorge) und Berufsgenossenschaftliche Grundsaetze: bis zu 40 Jahre bei Exposition gegenueber krebserzeugenden Gefahrstoffen.', - retentionDuration: 40, - retentionUnit: 'YEARS', - retentionDescription: '40 Jahre nach letzter Exposition (bei Gefahrstoffen), sonst 10 Jahre nach Ende der Taetigkeit', - startEvent: 'Ende der expositionsrelevanten Taetigkeit bzw. Ende des Beschaeftigungsverhaeltnisses', - deletionMethod: 'PHYSICAL_DESTROY', - deletionMethodDetail: - 'Physische Vernichtung der Papierunterlagen durch zertifizierten Aktenvernichtungsdienstleister (DIN 66399, Sicherheitsstufe P-5). Digitale Daten werden kryptographisch geloescht.', - responsibleRole: 'Betriebsarzt / Arbeitsmedizinischer Dienst', - reviewInterval: 'ANNUAL', - tags: ['hr', 'gesundheit'], - }, - - // ==================== 23. Kundenreklamationen ==================== - { - templateId: 'kundenreklamationen', - dataObjectName: 'Kundenreklamationen', - description: - 'Reklamationsvorgaenge inkl. Beschwerdeinhalt, Kommunikationsverlauf, Massnahmen und Ergebnis der Reklamationsbearbeitung.', - affectedGroups: ['Kunden'], - dataCategories: ['Reklamationsdaten', 'Kommunikation', 'Massnahmenprotokolle'], - primaryPurpose: - 'Dokumentation und Bearbeitung von Kundenreklamationen, Qualitaetssicherung und Absicherung gegen Gewaehrleistungsansprueche.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'BGB_195', - retentionDriverDetail: - 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB (3 Jahre) zur Absicherung gegen Gewaehrleistungs- und Schadensersatzansprueche.', - retentionDuration: 3, - retentionUnit: 'YEARS', - retentionDescription: '3 Jahre nach Abschluss des Reklamationsvorgangs', - startEvent: 'Abschluss des Reklamationsvorgangs (letzte Massnahme)', - deletionMethod: 'ANONYMIZATION', - deletionMethodDetail: - 'Anonymisierung der personenbezogenen Daten nach Ablauf der Frist. Anonymisierte Reklamationsstatistiken bleiben fuer die Qualitaetssicherung erhalten.', - responsibleRole: 'Qualitaetsmanagement', - reviewInterval: 'ANNUAL', - tags: ['kunden', 'qualitaet'], - }, - - // ==================== 24. Lieferantenbewertungen ==================== - { - templateId: 'lieferantenbewertungen', - dataObjectName: 'Lieferantenbewertungen', - description: - 'Bewertungen und Auditergebnisse von Lieferanten und Auftragsverarbeitern inkl. Qualitaets-, Compliance- und Datenschutz-Bewertungen.', - affectedGroups: ['Lieferanten', 'Auftragsverarbeiter'], - dataCategories: ['Bewertungsdaten', 'Auditberichte', 'Vertragsdaten'], - primaryPurpose: - 'Dokumentation der Sorgfaltspflicht bei der Auswahl und Ueberwachung von Auftragsverarbeitern gemaess Art. 28 DSGVO und Qualitaetssicherung in der Lieferkette.', - deletionTrigger: 'RETENTION_DRIVER', - retentionDriver: 'HGB_257', - retentionDriverDetail: - 'Aufbewahrung gemaess 257 HGB als handelsrelevante Unterlagen sowie zur Nachweisfuehrung der Sorgfaltspflicht bei der Auftragsverarbeitung.', - retentionDuration: 6, - retentionUnit: 'YEARS', - retentionDescription: '6 Jahre nach Ende der Geschaeftsbeziehung', - startEvent: 'Ende der Geschaeftsbeziehung mit dem Lieferanten/Auftragsverarbeiter', - deletionMethod: 'MANUAL_REVIEW_DELETE', - deletionMethodDetail: - 'Manuelle Pruefung durch den Einkauf/Compliance-Abteilung vor Loeschung, um sicherzustellen, dass keine Nachweispflichten aus laufenden Vertraegen oder Audits bestehen.', - responsibleRole: 'Einkauf / Compliance', - reviewInterval: 'ANNUAL', - tags: ['lieferanten', 'einkauf'], - }, - - // ==================== 25. Social-Media-Marketingdaten ==================== - { - templateId: 'social-media-daten', - dataObjectName: 'Social-Media-Marketingdaten', - description: - 'Personenbezogene Daten aus Social-Media-Kampagnen inkl. Nutzerinteraktionen, Custom Audiences, Retargeting-Listen und Kampagnen-Analytics.', - affectedGroups: ['Kunden', 'Interessenten', 'Website-Besucher'], - dataCategories: ['Interaktionsdaten', 'Zielgruppendaten', 'Tracking-Daten', 'Profilmerkmale'], - primaryPurpose: - 'Durchfuehrung zielgerichteter Marketing-Kampagnen auf Social-Media-Plattformen und Analyse der Kampagneneffektivitaet.', - deletionTrigger: 'PURPOSE_END', - retentionDriver: null, - retentionDriverDetail: - 'Keine gesetzliche Aufbewahrungspflicht. Daten werden bis zum Widerruf der Einwilligung bzw. bis zum Ende der Kampagne gespeichert (Art. 6 Abs. 1 lit. a DSGVO).', - retentionDuration: null, - retentionUnit: null, - retentionDescription: 'Bis zum Widerruf der Einwilligung oder Ende des Kampagnenzwecks', - startEvent: 'Widerruf der Einwilligung oder Ende der Marketing-Kampagne', - deletionMethod: 'AUTO_DELETE', - deletionMethodDetail: - 'Automatische Loeschung der personenbezogenen Daten in den Social-Media-Werbekonten und internen Systemen nach Zweckwegfall. Custom Audiences werden bei Plattformanbietern geloescht.', - responsibleRole: 'Marketing', - reviewInterval: 'SEMI_ANNUAL', - tags: ['marketing', 'social'], - }, -] - -// ============================================================================= -// HELPER FUNCTIONS -// ============================================================================= - -/** - * Erstellt eine vollstaendige LoeschfristPolicy aus einem BaselineTemplate. - * Nutzt createEmptyPolicy() als Basis und ueberlagert die Template-Felder. - */ -export function templateToPolicy(template: BaselineTemplate): LoeschfristPolicy { - const base = createEmptyPolicy() - - return { - ...base, - dataObjectName: template.dataObjectName, - description: template.description, - affectedGroups: [...template.affectedGroups], - dataCategories: [...template.dataCategories], - primaryPurpose: template.primaryPurpose, - deletionTrigger: template.deletionTrigger, - retentionDriver: template.retentionDriver, - retentionDriverDetail: template.retentionDriverDetail, - retentionDuration: template.retentionDuration, - retentionUnit: template.retentionUnit, - retentionDescription: template.retentionDescription, - startEvent: template.startEvent, - deletionMethod: template.deletionMethod, - deletionMethodDetail: template.deletionMethodDetail, - responsibleRole: template.responsibleRole, - reviewInterval: template.reviewInterval, - tags: [...template.tags], - } -} - -/** - * Gibt alle Templates zurueck, die einen bestimmten Tag enthalten. - */ -export function getTemplatesByTag(tag: string): BaselineTemplate[] { - return BASELINE_TEMPLATES.filter(t => t.tags.includes(tag)) -} - -/** - * Findet ein Template anhand seiner templateId. - */ -export function getTemplateById(templateId: string): BaselineTemplate | undefined { - return BASELINE_TEMPLATES.find(t => t.templateId === templateId) -} - -/** - * Gibt alle im Katalog verwendeten Tags als sortierte Liste zurueck. - */ -export function getAllTemplateTags(): string[] { - const tags = new Set() - BASELINE_TEMPLATES.forEach(t => t.tags.forEach(tag => tags.add(tag))) - return Array.from(tags).sort() -} +export * from './loeschfristen-baseline-catalog/types' +export * from './loeschfristen-baseline-catalog/finance-legal' +export * from './loeschfristen-baseline-catalog/hr' +export * from './loeschfristen-baseline-catalog/it-security' +export * from './loeschfristen-baseline-catalog/marketing-crm' +export * from './loeschfristen-baseline-catalog/helpers' diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/finance-legal.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/finance-legal.ts new file mode 100644 index 0000000..4068672 --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/finance-legal.ts @@ -0,0 +1,202 @@ +/** + * Loeschfristen — Finance & Legal Templates + * Buchhaltungsbelege, Rechnungen, Geschaeftsbriefe, Steuererklaerungen, + * Gesellschafterprotokolle, Vertraege, E-Mail-Archivierung, Lieferantenbewertungen + */ + +import { BaselineTemplate } from './types' + +export const FINANCE_LEGAL_TEMPLATES: BaselineTemplate[] = [ + { + templateId: 'buchhaltungsbelege', + dataObjectName: 'Buchhaltungsbelege', + description: + 'Buchungsbelege, Kontoauszuege, Kassenbuecher und sonstige Belege der laufenden Buchhaltung.', + affectedGroups: ['Kunden', 'Lieferanten'], + dataCategories: ['Finanzdaten', 'Transaktionsdaten', 'Kontodaten'], + primaryPurpose: + 'Ordnungsgemaesse Buchfuehrung und Erfuellung handelsrechtlicher Aufbewahrungspflichten nach HGB.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'HGB_257', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 257 HGB fuer Handelsbuecher und Buchungsbelege.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre nach Ende des Geschaeftsjahres', + startEvent: 'Ende des Geschaeftsjahres', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch die Buchhaltung vor Loeschung, um sicherzustellen, dass keine laufenden Pruefungen oder Rechtsstreitigkeiten bestehen.', + responsibleRole: 'Buchhaltung', + reviewInterval: 'ANNUAL', + tags: ['finanzen', 'hgb'], + }, + { + templateId: 'rechnungen', + dataObjectName: 'Rechnungen', + description: + 'Eingangs- und Ausgangsrechnungen inkl. Rechnungsanhaenge und rechnungsbegruendende Unterlagen.', + affectedGroups: ['Kunden', 'Lieferanten'], + dataCategories: ['Rechnungsdaten', 'Umsatzsteuerdaten', 'Adressdaten'], + primaryPurpose: + 'Dokumentation umsatzsteuerrelevanter Vorgaenge und Erfuellung der Aufbewahrungspflicht nach UStG.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'USTG_14B', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 14b UStG fuer Rechnungen und rechnungsbegruendende Unterlagen.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre ab Rechnungsdatum', + startEvent: 'Rechnungsdatum', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung nach Ablauf der 10-Jahres-Frist. Vor Loeschung wird geprueft, ob Rechnungen in laufenden Betriebspruefungen benoetigt werden.', + responsibleRole: 'Buchhaltung', + reviewInterval: 'ANNUAL', + tags: ['finanzen', 'ustg'], + }, + { + templateId: 'geschaeftsbriefe', + dataObjectName: 'Geschaeftsbriefe', + description: + 'Empfangene und versandte Handelsbriefe, Geschaeftskorrespondenz und geschaeftsrelevante E-Mails.', + affectedGroups: ['Kunden', 'Lieferanten'], + dataCategories: ['Korrespondenz', 'Vertragskommunikation', 'Angebote'], + primaryPurpose: + 'Nachweisfuehrung geschaeftlicher Kommunikation und Erfuellung der handelsrechtlichen Aufbewahrungspflicht fuer Handelsbriefe.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'HGB_257', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 257 HGB fuer empfangene und versandte Handelsbriefe (6 Jahre).', + retentionDuration: 6, + retentionUnit: 'YEARS', + retentionDescription: '6 Jahre ab Eingang oder Versand des Geschaeftsbriefes', + startEvent: 'Eingang bzw. Versand des Geschaeftsbriefes', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch die Geschaeftsleitung, da Geschaeftsbriefe ggf. als Beweismittel in Rechtsstreitigkeiten dienen koennen.', + responsibleRole: 'Geschaeftsleitung', + reviewInterval: 'ANNUAL', + tags: ['kommunikation', 'hgb'], + }, + { + templateId: 'steuererklaerungen', + dataObjectName: 'Steuererklaerungen', + description: + 'Koerperschaftsteuer-, Gewerbesteuer- und Umsatzsteuererklaerungen inkl. Anlagen und Bescheide.', + affectedGroups: ['Unternehmen'], + dataCategories: ['Steuerdaten', 'Finanzkennzahlen', 'Bescheide'], + primaryPurpose: + 'Erfuellung steuerrechtlicher Dokumentationspflichten und Nachweisfuehrung gegenueber den Finanzbehoerden.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'AO_147', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 147 AO fuer Steuererklaerungen und zugehoerige Unterlagen.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre ab dem jeweiligen Steuerjahr', + startEvent: 'Ende des betreffenden Steuerjahres', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung nach Ablauf der 10-Jahres-Frist, sofern keine laufende Betriebspruefung oder Einspruchsverfahren vorliegen.', + responsibleRole: 'Steuerberater/Buchhaltung', + reviewInterval: 'ANNUAL', + tags: ['finanzen', 'steuer'], + }, + { + templateId: 'protokolle-gesellschafter', + dataObjectName: 'Gesellschafterprotokolle', + description: + 'Protokolle der Gesellschafterversammlungen, Beschluesse, Abstimmungsergebnisse und notarielle Urkunden.', + affectedGroups: ['Gesellschafter'], + dataCategories: ['Beschlussdaten', 'Abstimmungsergebnisse', 'Protokolle'], + primaryPurpose: + 'Dokumentation gesellschaftsrechtlicher Beschluesse und Erfuellung handelsrechtlicher Aufbewahrungspflichten.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'HGB_257', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 257 HGB fuer Eroeffnungsbilanzen, Jahresabschluesse und zugehoerige Beschluesse.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre ab Beschlussdatum', + startEvent: 'Datum des jeweiligen Gesellschafterbeschlusses', + deletionMethod: 'PHYSICAL_DESTROY', + deletionMethodDetail: + 'Physische Vernichtung der Papieroriginale durch zertifizierten Aktenvernichtungsdienstleister (DIN 66399, Sicherheitsstufe P-4). Digitale Kopien werden parallel geloescht.', + responsibleRole: 'Geschaeftsleitung', + reviewInterval: 'ANNUAL', + tags: ['recht', 'gesellschaft'], + }, + { + templateId: 'vertraege', + dataObjectName: 'Vertraege', + description: + 'Geschaeftsvertraege, Rahmenvereinbarungen, Dienstleistungsvertraege und zugehoerige Anlagen und Nachtraege.', + affectedGroups: ['Vertragspartner'], + dataCategories: ['Vertragsdaten', 'Kontaktdaten', 'Konditionen'], + primaryPurpose: + 'Dokumentation vertraglicher Vereinbarungen und Sicherung von Beweismitteln fuer die Dauer moeglicher Rechtsstreitigkeiten.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'HGB_257', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 257 HGB fuer handelsrechtlich relevante Vertragsunterlagen.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre nach Ende der Vertragslaufzeit', + startEvent: 'Ende der Vertragslaufzeit bzw. Vertragsbeendigung', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch die Rechtsabteilung vor Loeschung, um sicherzustellen, dass keine laufenden oder angedrohten Rechtsstreitigkeiten bestehen.', + responsibleRole: 'Rechtsabteilung', + reviewInterval: 'ANNUAL', + tags: ['recht', 'vertraege'], + }, + { + templateId: 'email-archivierung', + dataObjectName: 'E-Mail-Archivierung', + description: + 'Archivierte geschaeftliche E-Mails inkl. Anhaenge, die als Handelsbriefe oder steuerrelevante Korrespondenz einzustufen sind.', + affectedGroups: ['Mitarbeiter', 'Kunden', 'Lieferanten'], + dataCategories: ['E-Mail-Korrespondenz', 'Anhaenge', 'Metadaten'], + primaryPurpose: + 'Erfuellung der handelsrechtlichen Aufbewahrungspflicht fuer geschaeftliche Korrespondenz, die als Handelsbrief einzuordnen ist.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'HGB_257', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 257 HGB fuer empfangene und versandte Handelsbriefe (6 Jahre) bzw. buchhalterisch relevante E-Mails (10 Jahre).', + retentionDuration: 6, + retentionUnit: 'YEARS', + retentionDescription: '6 Jahre nach Versand/Empfang der E-Mail', + startEvent: 'Versand- bzw. Empfangsdatum der E-Mail', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung durch das E-Mail-Archivierungssystem nach Ablauf der konfigurierten Aufbewahrungsfrist. Vor Loeschung wird geprueft, ob die E-Mail in laufenden Verfahren benoetigt wird.', + responsibleRole: 'IT-Abteilung', + reviewInterval: 'ANNUAL', + tags: ['kommunikation', 'hgb'], + }, + { + templateId: 'lieferantenbewertungen', + dataObjectName: 'Lieferantenbewertungen', + description: + 'Bewertungen und Auditergebnisse von Lieferanten und Auftragsverarbeitern inkl. Qualitaets-, Compliance- und Datenschutz-Bewertungen.', + affectedGroups: ['Lieferanten', 'Auftragsverarbeiter'], + dataCategories: ['Bewertungsdaten', 'Auditberichte', 'Vertragsdaten'], + primaryPurpose: + 'Dokumentation der Sorgfaltspflicht bei der Auswahl und Ueberwachung von Auftragsverarbeitern gemaess Art. 28 DSGVO und Qualitaetssicherung in der Lieferkette.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'HGB_257', + retentionDriverDetail: + 'Aufbewahrung gemaess 257 HGB als handelsrelevante Unterlagen sowie zur Nachweisfuehrung der Sorgfaltspflicht bei der Auftragsverarbeitung.', + retentionDuration: 6, + retentionUnit: 'YEARS', + retentionDescription: '6 Jahre nach Ende der Geschaeftsbeziehung', + startEvent: 'Ende der Geschaeftsbeziehung mit dem Lieferanten/Auftragsverarbeiter', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch den Einkauf/Compliance-Abteilung vor Loeschung, um sicherzustellen, dass keine Nachweispflichten aus laufenden Vertraegen oder Audits bestehen.', + responsibleRole: 'Einkauf / Compliance', + reviewInterval: 'ANNUAL', + tags: ['lieferanten', 'einkauf'], + }, +] diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/helpers.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/helpers.ts new file mode 100644 index 0000000..f11d110 --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/helpers.ts @@ -0,0 +1,69 @@ +/** + * Loeschfristen Baseline-Katalog — Helper Functions + */ + +import type { LoeschfristPolicy } from '../loeschfristen-types' +import { createEmptyPolicy } from '../loeschfristen-types' +import type { BaselineTemplate } from './types' +import { FINANCE_LEGAL_TEMPLATES } from './finance-legal' +import { HR_TEMPLATES } from './hr' +import { IT_SECURITY_TEMPLATES } from './it-security' +import { MARKETING_CRM_TEMPLATES } from './marketing-crm' + +export const BASELINE_TEMPLATES: BaselineTemplate[] = [ + ...HR_TEMPLATES, + ...FINANCE_LEGAL_TEMPLATES, + ...IT_SECURITY_TEMPLATES, + ...MARKETING_CRM_TEMPLATES, +] + +/** + * Erstellt eine vollstaendige LoeschfristPolicy aus einem BaselineTemplate. + */ +export function templateToPolicy(template: BaselineTemplate): LoeschfristPolicy { + const base = createEmptyPolicy() + + return { + ...base, + dataObjectName: template.dataObjectName, + description: template.description, + affectedGroups: [...template.affectedGroups], + dataCategories: [...template.dataCategories], + primaryPurpose: template.primaryPurpose, + deletionTrigger: template.deletionTrigger, + retentionDriver: template.retentionDriver, + retentionDriverDetail: template.retentionDriverDetail, + retentionDuration: template.retentionDuration, + retentionUnit: template.retentionUnit, + retentionDescription: template.retentionDescription, + startEvent: template.startEvent, + deletionMethod: template.deletionMethod, + deletionMethodDetail: template.deletionMethodDetail, + responsibleRole: template.responsibleRole, + reviewInterval: template.reviewInterval, + tags: [...template.tags], + } +} + +/** + * Gibt alle Templates zurueck, die einen bestimmten Tag enthalten. + */ +export function getTemplatesByTag(tag: string): BaselineTemplate[] { + return BASELINE_TEMPLATES.filter(t => t.tags.includes(tag)) +} + +/** + * Findet ein Template anhand seiner templateId. + */ +export function getTemplateById(templateId: string): BaselineTemplate | undefined { + return BASELINE_TEMPLATES.find(t => t.templateId === templateId) +} + +/** + * Gibt alle im Katalog verwendeten Tags als sortierte Liste zurueck. + */ +export function getAllTemplateTags(): string[] { + const tags = new Set() + BASELINE_TEMPLATES.forEach(t => t.tags.forEach(tag => tags.add(tag))) + return Array.from(tags).sort() +} diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/hr.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/hr.ts new file mode 100644 index 0000000..257fba4 --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/hr.ts @@ -0,0 +1,178 @@ +/** + * Loeschfristen — HR Templates + * Personalakten, Bewerbungsunterlagen, Gehaltsabrechnungen, Zeiterfassung, + * Krankmeldungen, Schulungsnachweise, Betriebsarzt-Dokumentation + */ + +import { BaselineTemplate } from './types' + +export const HR_TEMPLATES: BaselineTemplate[] = [ + { + templateId: 'personal-akten', + dataObjectName: 'Personalakten', + description: + 'Vollstaendige Personalakten inkl. Arbeitsvertraege, Zeugnisse, Abmahnungen und sonstige beschaeftigungsrelevante Dokumente.', + affectedGroups: ['Mitarbeiter'], + dataCategories: ['Stammdaten', 'Vertragsdaten', 'Gehaltsdaten', 'Zeugnisse'], + primaryPurpose: + 'Dokumentation und Nachweisfuehrung des Beschaeftigungsverhaeltnisses sowie Erfuellung steuerrechtlicher Aufbewahrungspflichten.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'AO_147', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 147 AO fuer steuerlich relevante Unterlagen der Personalakte.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre nach Ende des Beschaeftigungsverhaeltnisses', + startEvent: 'Ende des Beschaeftigungsverhaeltnisses', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung aller digitalen Personalakten-Dokumente nach Ablauf der Aufbewahrungsfrist. Papierakten werden datenschutzkonform vernichtet.', + responsibleRole: 'HR-Abteilung', + reviewInterval: 'ANNUAL', + tags: ['hr', 'steuer'], + }, + { + templateId: 'bewerbungsunterlagen', + dataObjectName: 'Bewerbungsunterlagen', + description: + 'Eingereichte Bewerbungsunterlagen inkl. Anschreiben, Lebenslauf, Zeugnisse und Korrespondenz mit Bewerbern.', + affectedGroups: ['Bewerber'], + dataCategories: ['Bewerbungsdaten', 'Qualifikationen', 'Kontaktdaten'], + primaryPurpose: + 'Durchfuehrung des Bewerbungsverfahrens und Absicherung gegen Entschaedigungsansprueche nach dem AGG.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'AGG_15', + retentionDriverDetail: + 'Aufbewahrung fuer 6 Monate nach Absage gemaess 15 Abs. 4 AGG (Frist fuer Geltendmachung von Entschaedigungsanspruechen).', + retentionDuration: 6, + retentionUnit: 'MONTHS', + retentionDescription: '6 Monate nach Absage oder Stellenbesetzung', + startEvent: 'Absage oder endgueltige Stellenbesetzung', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung aller Bewerbungsunterlagen und zugehoeriger Kommunikation nach Ablauf der 6-Monats-Frist.', + responsibleRole: 'HR-Abteilung', + reviewInterval: 'QUARTERLY', + tags: ['hr', 'bewerbung'], + }, + { + templateId: 'gehaltsabrechnungen', + dataObjectName: 'Gehaltsabrechnungen', + description: + 'Monatliche Gehaltsabrechnungen, Lohnsteuerbescheinigungen und Sozialversicherungsmeldungen.', + affectedGroups: ['Mitarbeiter'], + dataCategories: ['Gehaltsdaten', 'Steuerdaten', 'Sozialversicherungsdaten'], + primaryPurpose: + 'Dokumentation der Lohn- und Gehaltszahlungen sowie Erfuellung steuerrechtlicher und sozialversicherungsrechtlicher Aufbewahrungspflichten.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'AO_147', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 147 AO fuer lohnsteuerrelevante Unterlagen und Gehaltsbuchungen.', + retentionDuration: 10, + retentionUnit: 'YEARS', + retentionDescription: '10 Jahre nach Ende des Geschaeftsjahres', + startEvent: 'Ende des Geschaeftsjahres der jeweiligen Abrechnung', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung der digitalen Gehaltsabrechnungen nach Ablauf der Aufbewahrungsfrist. Papierbelege werden datenschutzkonform vernichtet.', + responsibleRole: 'Lohnbuchhaltung', + reviewInterval: 'ANNUAL', + tags: ['hr', 'steuer'], + }, + { + templateId: 'zeiterfassung', + dataObjectName: 'Zeiterfassungsdaten', + description: + 'Arbeitszeitaufzeichnungen inkl. Beginn, Ende, Pausen und Ueberstunden der Beschaeftigten.', + affectedGroups: ['Mitarbeiter'], + dataCategories: ['Arbeitszeiten', 'Pausenzeiten', 'Ueberstunden'], + primaryPurpose: + 'Erfuellung der gesetzlichen Aufzeichnungspflicht fuer Arbeitszeiten und Nachweis der Einhaltung des Arbeitszeitgesetzes.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'ARBZG_16', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess 16 Abs. 2 ArbZG fuer Aufzeichnungen ueber die Arbeitszeit.', + retentionDuration: 2, + retentionUnit: 'YEARS', + retentionDescription: '2 Jahre nach Ende des Erfassungszeitraums', + startEvent: 'Ende des jeweiligen Erfassungszeitraums', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung der Zeiterfassungsdaten nach Ablauf der 2-Jahres-Frist im Zeiterfassungssystem.', + responsibleRole: 'HR-Abteilung', + reviewInterval: 'ANNUAL', + tags: ['hr', 'arbzg'], + }, + { + templateId: 'krankmeldungen', + dataObjectName: 'Krankmeldungen', + description: + 'Arbeitsunfaehigkeitsbescheinigungen, Krankmeldungen und zugehoerige Abwesenheitsdokumentationen.', + affectedGroups: ['Mitarbeiter'], + dataCategories: ['Gesundheitsdaten', 'Abwesenheitszeiten', 'AU-Bescheinigungen'], + primaryPurpose: + 'Dokumentation von Fehlzeiten, Entgeltfortzahlung im Krankheitsfall und Absicherung gegen Verjaehrung arbeitsrechtlicher Ansprueche.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BGB_195', + retentionDriverDetail: + 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB zur Absicherung von Erstattungsanspruechen.', + retentionDuration: 3, + retentionUnit: 'YEARS', + retentionDescription: '3 Jahre nach Ende des Beschaeftigungsverhaeltnisses', + startEvent: 'Ende des Beschaeftigungsverhaeltnisses', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch die HR-Abteilung vor Loeschung, da Krankmeldungen besondere Kategorien personenbezogener Daten (Gesundheitsdaten) enthalten.', + responsibleRole: 'HR-Abteilung', + reviewInterval: 'ANNUAL', + tags: ['hr', 'gesundheit'], + }, + { + templateId: 'schulungsnachweise', + dataObjectName: 'Schulungsnachweise', + description: + 'Teilnahmebestaetigungen, Zertifikate und Protokolle von Mitarbeiterschulungen (Datenschutz, Arbeitssicherheit, Compliance).', + affectedGroups: ['Mitarbeiter'], + dataCategories: ['Schulungsdaten', 'Zertifikate', 'Teilnahmelisten'], + primaryPurpose: + 'Nachweis der Durchfuehrung gesetzlich vorgeschriebener Schulungen und Dokumentation der Mitarbeiterqualifikation.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'CUSTOM', + retentionDriverDetail: + 'Aufbewahrung fuer 3 Jahre nach Ende des Beschaeftigungsverhaeltnisses als Nachweis der ordnungsgemaessen Schulungsdurchfuehrung.', + retentionDuration: 3, + retentionUnit: 'YEARS', + retentionDescription: '3 Jahre nach Ende des Beschaeftigungsverhaeltnisses', + startEvent: 'Ende des Beschaeftigungsverhaeltnisses des geschulten Mitarbeiters', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch die HR-Abteilung vor Loeschung, da Schulungsnachweise als Compliance-Nachweis in Audits relevant sein koennen.', + responsibleRole: 'HR-Abteilung', + reviewInterval: 'ANNUAL', + tags: ['hr', 'schulung'], + }, + { + templateId: 'betriebsarzt-doku', + dataObjectName: 'Betriebsarzt-Dokumentation', + description: + 'Ergebnisse arbeitsmedizinischer Vorsorgeuntersuchungen, Eignungsuntersuchungen und arbeitsmedizinische Empfehlungen.', + affectedGroups: ['Mitarbeiter'], + dataCategories: ['Gesundheitsdaten', 'Vorsorgeuntersuchungen', 'Eignungsbefunde'], + primaryPurpose: + 'Erfuellung der Dokumentationspflicht fuer arbeitsmedizinische Vorsorge gemaess ArbMedVV und Nachweisfuehrung gegenueber Berufsgenossenschaften.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'CUSTOM', + retentionDriverDetail: + 'Aufbewahrungspflicht gemaess ArbMedVV (Verordnung zur arbeitsmedizinischen Vorsorge) und Berufsgenossenschaftliche Grundsaetze: bis zu 40 Jahre bei Exposition gegenueber krebserzeugenden Gefahrstoffen.', + retentionDuration: 40, + retentionUnit: 'YEARS', + retentionDescription: '40 Jahre nach letzter Exposition (bei Gefahrstoffen), sonst 10 Jahre nach Ende der Taetigkeit', + startEvent: 'Ende der expositionsrelevanten Taetigkeit bzw. Ende des Beschaeftigungsverhaeltnisses', + deletionMethod: 'PHYSICAL_DESTROY', + deletionMethodDetail: + 'Physische Vernichtung der Papierunterlagen durch zertifizierten Aktenvernichtungsdienstleister (DIN 66399, Sicherheitsstufe P-5). Digitale Daten werden kryptographisch geloescht.', + responsibleRole: 'Betriebsarzt / Arbeitsmedizinischer Dienst', + reviewInterval: 'ANNUAL', + tags: ['hr', 'gesundheit'], + }, +] diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/it-security.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/it-security.ts new file mode 100644 index 0000000..acdc744 --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/it-security.ts @@ -0,0 +1,105 @@ +/** + * Loeschfristen — IT & Security Templates + * Webserver-Logs, Videoueberwachung, Backup-Daten, Zutrittsprotokolle + */ + +import { BaselineTemplate } from './types' + +export const IT_SECURITY_TEMPLATES: BaselineTemplate[] = [ + { + templateId: 'webserver-logs', + dataObjectName: 'Webserver-Logs', + description: + 'Server-Zugriffsprotokolle inkl. IP-Adressen, Zeitstempel, aufgerufene URLs und HTTP-Statuscodes.', + affectedGroups: ['Website-Besucher'], + dataCategories: ['IP-Adressen', 'Zugriffszeitpunkte', 'User-Agent-Daten'], + primaryPurpose: + 'Sicherstellung der IT-Sicherheit, Erkennung von Angriffen und Stoerungen sowie Erfuellung der Protokollierungspflicht nach BSIG.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BSIG', + retentionDriverDetail: + 'Aufbewahrung gemaess BSI-Gesetz / IT-Sicherheitsgesetz 2.0 fuer die Analyse von Sicherheitsvorfaellen.', + retentionDuration: 7, + retentionUnit: 'DAYS', + retentionDescription: '7 Tage nach Zeitpunkt des Zugriffs', + startEvent: 'Zeitpunkt des Server-Zugriffs', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Rotation und Loeschung der Logdateien nach 7 Tagen durch den Webserver (logrotate).', + responsibleRole: 'IT-Abteilung', + reviewInterval: 'QUARTERLY', + tags: ['it', 'logs'], + }, + { + templateId: 'videoueberwachung', + dataObjectName: 'Videoueberwachung', + description: + 'Aufnahmen der Videoueberwachung in Geschaeftsraeumen, Eingangsbereichen und Parkplaetzen.', + affectedGroups: ['Besucher', 'Mitarbeiter'], + dataCategories: ['Videodaten', 'Bilddaten', 'Zeitstempel'], + primaryPurpose: + 'Schutz des Eigentums und der Sicherheit von Personen sowie Aufklaerung von Vorfaellen in den ueberwachten Bereichen.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BDSG_35', + retentionDriverDetail: + 'Unverzuegliche Loeschung nach Zweckwegfall gemaess 35 BDSG bzw. Art. 17 DSGVO. Maximale Speicherdauer 48 Stunden.', + retentionDuration: 2, + retentionUnit: 'DAYS', + retentionDescription: '48 Stunden (2 Tage) nach Aufnahmezeitpunkt', + startEvent: 'Aufnahmezeitpunkt der Videosequenz', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatisches Ueberschreiben der Aufnahmen durch das Videomanagementsystem nach Ablauf der 48-Stunden-Frist.', + responsibleRole: 'Facility Management', + reviewInterval: 'QUARTERLY', + tags: ['sicherheit', 'video'], + }, + { + templateId: 'backup-daten', + dataObjectName: 'Backup-Daten', + description: + 'Vollstaendige und inkrementelle Sicherungskopien aller Systeme, Datenbanken und Dateisysteme.', + affectedGroups: ['Alle Betroffenengruppen'], + dataCategories: ['Systemsicherungen', 'Datenbankkopien', 'Dateisystemsicherungen'], + primaryPurpose: + 'Sicherstellung der Datenwiederherstellung im Katastrophenfall und Gewaehrleistung der Geschaeftskontinuitaet.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BSIG', + retentionDriverDetail: + 'Aufbewahrung von Backups fuer 90 Tage gemaess BSI-Grundschutz-Empfehlungen zur Sicherstellung der Wiederherstellbarkeit.', + retentionDuration: 90, + retentionUnit: 'DAYS', + retentionDescription: '90 Tage nach Erstellung des Backups', + startEvent: 'Erstellungsdatum des jeweiligen Backups', + deletionMethod: 'CRYPTO_ERASE', + deletionMethodDetail: + 'Kryptographische Loeschung durch Vernichtung der Verschluesselungsschluessel, sodass die verschluesselten Backup-Daten nicht mehr entschluesselt werden koennen.', + responsibleRole: 'IT-Abteilung', + reviewInterval: 'QUARTERLY', + tags: ['it', 'backup'], + }, + { + templateId: 'zutrittsprotokolle', + dataObjectName: 'Zutrittsprotokolle', + description: + 'Protokolle des Zutrittskontrollsystems inkl. Zeitstempel, Kartennummer, Zutrittsort und Zugangsentscheidung (gewaehrt/verweigert).', + affectedGroups: ['Mitarbeiter', 'Besucher'], + dataCategories: ['Zutrittsdaten', 'Zeitstempel', 'Kartennummern', 'Standortdaten'], + primaryPurpose: + 'Sicherstellung der physischen Sicherheit, Nachvollziehbarkeit von Zutritten und Unterstuetzung bei der Aufklaerung von Sicherheitsvorfaellen.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BSIG', + retentionDriverDetail: + 'Aufbewahrung gemaess BSI-Grundschutz-Empfehlung fuer Zutrittsprotokolle zur Analyse von Sicherheitsvorfaellen (90 Tage).', + retentionDuration: 90, + retentionUnit: 'DAYS', + retentionDescription: '90 Tage nach Zeitpunkt des Zutritts', + startEvent: 'Zeitpunkt des protokollierten Zutrittsereignisses', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Rotation und Loeschung der Zutrittsprotokolle durch das Zutrittskontrollsystem nach Ablauf der 90-Tage-Frist.', + responsibleRole: 'Facility Management', + reviewInterval: 'QUARTERLY', + tags: ['sicherheit', 'zutritt'], + }, +] diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/marketing-crm.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/marketing-crm.ts new file mode 100644 index 0000000..f41a07a --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/marketing-crm.ts @@ -0,0 +1,154 @@ +/** + * Loeschfristen — Marketing & CRM Templates + * Newsletter-Einwilligungen, Kundenstammdaten, CRM-Kontakthistorie, + * Kundenreklamationen, Social-Media-Marketingdaten + */ + +import { BaselineTemplate } from './types' + +export const MARKETING_CRM_TEMPLATES: BaselineTemplate[] = [ + { + templateId: 'newsletter-einwilligungen', + dataObjectName: 'Newsletter-Einwilligungen', + description: + 'Einwilligungserklaerungen fuer den Newsletter-Versand inkl. Double-Opt-in-Nachweis und Abmeldezeitpunkt.', + affectedGroups: ['Abonnenten'], + dataCategories: ['Einwilligungsdaten', 'E-Mail-Adresse', 'Opt-in-Nachweis'], + primaryPurpose: + 'Nachweis der wirksamen Einwilligung zum Newsletter-Versand gemaess Art. 7 DSGVO und Dokumentation des Widerrufs.', + deletionTrigger: 'PURPOSE_END', + retentionDriver: null, + retentionDriverDetail: + 'Keine gesetzliche Aufbewahrungspflicht. Daten werden bis zum Widerruf der Einwilligung gespeichert.', + retentionDuration: null, + retentionUnit: null, + retentionDescription: 'Bis zum Widerruf der Einwilligung durch den Abonnenten', + startEvent: 'Widerruf der Einwilligung durch den Abonnenten', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung der personenbezogenen Daten nach Eingang des Widerrufs. Der Einwilligungsnachweis selbst wird fuer die Dauer der Nachweispflicht aufbewahrt.', + responsibleRole: 'Marketing', + reviewInterval: 'SEMI_ANNUAL', + tags: ['marketing', 'einwilligung'], + }, + { + templateId: 'kundenstammdaten', + dataObjectName: 'Kundenstammdaten', + description: + 'Stammdaten von Kunden inkl. Kontaktdaten, Anschrift, Kundennummer und Kommunikationspraeferenzen.', + affectedGroups: ['Kunden'], + dataCategories: ['Stammdaten', 'Kontaktdaten', 'Adressdaten'], + primaryPurpose: + 'Pflege der Kundenbeziehung, Vertragserfuellung und Absicherung gegen Verjaehrung vertraglicher Ansprueche.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BGB_195', + retentionDriverDetail: + 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB (3 Jahre).', + retentionDuration: 3, + retentionUnit: 'YEARS', + retentionDescription: '3 Jahre nach letzter geschaeftlicher Interaktion', + startEvent: 'Letzte geschaeftliche Interaktion mit dem Kunden', + deletionMethod: 'MANUAL_REVIEW_DELETE', + deletionMethodDetail: + 'Manuelle Pruefung durch den Vertrieb vor Loeschung, um sicherzustellen, dass keine aktiven Geschaeftsbeziehungen oder offenen Forderungen bestehen.', + responsibleRole: 'Vertrieb', + reviewInterval: 'ANNUAL', + tags: ['crm', 'kunden'], + }, + { + templateId: 'crm-kontakthistorie', + dataObjectName: 'CRM-Kontakthistorie', + description: + 'Kontaktverlauf im CRM-System inkl. Anrufe, E-Mails, Termine, Notizen und Angebotsverlauf.', + affectedGroups: ['Kunden', 'Interessenten'], + dataCategories: ['Kommunikationsdaten', 'Interaktionshistorie', 'Angebotsdaten'], + primaryPurpose: + 'Pflege der Kundenbeziehung und Nachverfolgung geschaeftlicher Interaktionen fuer Vertriebs- und Servicezwecke.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BGB_195', + retentionDriverDetail: + 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB zur Absicherung vertraglicher Ansprueche.', + retentionDuration: 3, + retentionUnit: 'YEARS', + retentionDescription: '3 Jahre nach letztem Kontakt mit dem Kunden oder Interessenten', + startEvent: 'Letzter dokumentierter Kontakt im CRM-System', + deletionMethod: 'ANONYMIZATION', + deletionMethodDetail: + 'Anonymisierung der personenbezogenen Daten im CRM-System, sodass statistische Auswertungen weiterhin moeglich sind, aber kein Personenbezug mehr hergestellt werden kann.', + responsibleRole: 'Vertrieb', + reviewInterval: 'SEMI_ANNUAL', + tags: ['crm', 'kunden'], + }, + { + templateId: 'kundenreklamationen', + dataObjectName: 'Kundenreklamationen', + description: + 'Reklamationsvorgaenge inkl. Beschwerdeinhalt, Kommunikationsverlauf, Massnahmen und Ergebnis der Reklamationsbearbeitung.', + affectedGroups: ['Kunden'], + dataCategories: ['Reklamationsdaten', 'Kommunikation', 'Massnahmenprotokolle'], + primaryPurpose: + 'Dokumentation und Bearbeitung von Kundenreklamationen, Qualitaetssicherung und Absicherung gegen Gewaehrleistungsansprueche.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BGB_195', + retentionDriverDetail: + 'Aufbewahrung fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB (3 Jahre) zur Absicherung gegen Gewaehrleistungs- und Schadensersatzansprueche.', + retentionDuration: 3, + retentionUnit: 'YEARS', + retentionDescription: '3 Jahre nach Abschluss des Reklamationsvorgangs', + startEvent: 'Abschluss des Reklamationsvorgangs (letzte Massnahme)', + deletionMethod: 'ANONYMIZATION', + deletionMethodDetail: + 'Anonymisierung der personenbezogenen Daten nach Ablauf der Frist. Anonymisierte Reklamationsstatistiken bleiben fuer die Qualitaetssicherung erhalten.', + responsibleRole: 'Qualitaetsmanagement', + reviewInterval: 'ANNUAL', + tags: ['kunden', 'qualitaet'], + }, + { + templateId: 'cookie-consent-logs', + dataObjectName: 'Cookie-Consent-Nachweise', + description: + 'Nachweise ueber Cookie-Einwilligungen der Website-Besucher inkl. Consent-ID, Zeitstempel, gesetzte Praeferenzen und IP-Adresse.', + affectedGroups: ['Website-Besucher'], + dataCategories: ['Consent-Daten', 'IP-Adressen', 'Zeitstempel', 'Praeferenzen'], + primaryPurpose: + 'Nachweisfuehrung der Einwilligung in die Cookie-Nutzung gemaess Art. 7 Abs. 1 DSGVO und ePrivacy-Richtlinie.', + deletionTrigger: 'RETENTION_DRIVER', + retentionDriver: 'BGB_195', + retentionDriverDetail: + 'Aufbewahrung der Consent-Nachweise fuer die Dauer der regelmaessigen Verjaehrungsfrist gemaess 195 BGB zur Absicherung gegen Abmahnungen.', + retentionDuration: 3, + retentionUnit: 'YEARS', + retentionDescription: '3 Jahre nach Zeitpunkt der Einwilligung', + startEvent: 'Zeitpunkt der Cookie-Einwilligung (Consent-Zeitstempel)', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung der Consent-Nachweise nach Ablauf der 3-Jahres-Frist durch das Consent-Management-System.', + responsibleRole: 'Datenschutzbeauftragter', + reviewInterval: 'ANNUAL', + tags: ['datenschutz', 'consent'], + }, + { + templateId: 'social-media-daten', + dataObjectName: 'Social-Media-Marketingdaten', + description: + 'Personenbezogene Daten aus Social-Media-Kampagnen inkl. Nutzerinteraktionen, Custom Audiences, Retargeting-Listen und Kampagnen-Analytics.', + affectedGroups: ['Kunden', 'Interessenten', 'Website-Besucher'], + dataCategories: ['Interaktionsdaten', 'Zielgruppendaten', 'Tracking-Daten', 'Profilmerkmale'], + primaryPurpose: + 'Durchfuehrung zielgerichteter Marketing-Kampagnen auf Social-Media-Plattformen und Analyse der Kampagneneffektivitaet.', + deletionTrigger: 'PURPOSE_END', + retentionDriver: null, + retentionDriverDetail: + 'Keine gesetzliche Aufbewahrungspflicht. Daten werden bis zum Widerruf der Einwilligung bzw. bis zum Ende der Kampagne gespeichert (Art. 6 Abs. 1 lit. a DSGVO).', + retentionDuration: null, + retentionUnit: null, + retentionDescription: 'Bis zum Widerruf der Einwilligung oder Ende des Kampagnenzwecks', + startEvent: 'Widerruf der Einwilligung oder Ende der Marketing-Kampagne', + deletionMethod: 'AUTO_DELETE', + deletionMethodDetail: + 'Automatische Loeschung der personenbezogenen Daten in den Social-Media-Werbekonten und internen Systemen nach Zweckwegfall. Custom Audiences werden bei Plattformanbietern geloescht.', + responsibleRole: 'Marketing', + reviewInterval: 'SEMI_ANNUAL', + tags: ['marketing', 'social'], + }, +] diff --git a/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/types.ts b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/types.ts new file mode 100644 index 0000000..5bc6c31 --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-baseline-catalog/types.ts @@ -0,0 +1,32 @@ +/** + * Loeschfristen Baseline-Katalog — Shared Types + */ + +import type { + RetentionDriverType, + DeletionMethodType, + ReviewInterval, + RetentionUnit, + DeletionTriggerLevel, +} from '../loeschfristen-types' + +export interface BaselineTemplate { + templateId: string + dataObjectName: string + description: string + affectedGroups: string[] + dataCategories: string[] + primaryPurpose: string + deletionTrigger: DeletionTriggerLevel + retentionDriver: RetentionDriverType | null + retentionDriverDetail: string + retentionDuration: number | null + retentionUnit: RetentionUnit | null + retentionDescription: string + startEvent: string + deletionMethod: DeletionMethodType + deletionMethodDetail: string + responsibleRole: string + reviewInterval: ReviewInterval + tags: string[] +} diff --git a/admin-compliance/lib/sdk/loeschfristen-document.ts b/admin-compliance/lib/sdk/loeschfristen-document.ts index bad7afd..128bfc8 100644 --- a/admin-compliance/lib/sdk/loeschfristen-document.ts +++ b/admin-compliance/lib/sdk/loeschfristen-document.ts @@ -1,879 +1,8 @@ // ============================================================================= // Loeschfristen Module - Loeschkonzept Document Generator -// Generates a printable, audit-ready HTML document according to DSGVO Art. 5/17/30 +// Barrel re-export — implementation split into loeschfristen-document/ // ============================================================================= -import type { - LoeschfristPolicy, - RetentionDriverType, -} from './loeschfristen-types' - -import { - RETENTION_DRIVER_META, - DELETION_METHOD_LABELS, - STATUS_LABELS, - TRIGGER_LABELS, - REVIEW_INTERVAL_LABELS, - formatRetentionDuration, - getEffectiveDeletionTrigger, - getActiveLegalHolds, -} from './loeschfristen-types' - -import type { ComplianceCheckResult, ComplianceIssueSeverity } from './loeschfristen-compliance' - -// ============================================================================= -// TYPES -// ============================================================================= - -export interface LoeschkonzeptOrgHeader { - organizationName: string - industry: string - dpoName: string - dpoContact: string - responsiblePerson: string - locations: string[] - employeeCount: string - loeschkonzeptVersion: string - lastReviewDate: string - nextReviewDate: string - reviewInterval: string -} - -export interface LoeschkonzeptRevision { - version: string - date: string - author: string - changes: string -} - -// ============================================================================= -// DEFAULTS -// ============================================================================= - -export function createDefaultLoeschkonzeptOrgHeader(): LoeschkonzeptOrgHeader { - const now = new Date() - const nextYear = new Date() - nextYear.setFullYear(nextYear.getFullYear() + 1) - - return { - organizationName: '', - industry: '', - dpoName: '', - dpoContact: '', - responsiblePerson: '', - locations: [], - employeeCount: '', - loeschkonzeptVersion: '1.0', - lastReviewDate: now.toISOString().split('T')[0], - nextReviewDate: nextYear.toISOString().split('T')[0], - reviewInterval: 'Jaehrlich', - } -} - -// ============================================================================= -// SEVERITY LABELS (for Compliance Status section) -// ============================================================================= - -const SEVERITY_LABELS_DE: Record = { - CRITICAL: 'Kritisch', - HIGH: 'Hoch', - MEDIUM: 'Mittel', - LOW: 'Niedrig', -} - -const SEVERITY_COLORS: Record = { - CRITICAL: '#dc2626', - HIGH: '#ea580c', - MEDIUM: '#d97706', - LOW: '#6b7280', -} - -// ============================================================================= -// HTML DOCUMENT BUILDER -// ============================================================================= - -export function buildLoeschkonzeptHtml( - policies: LoeschfristPolicy[], - orgHeader: LoeschkonzeptOrgHeader, - vvtActivities: Array<{ id: string; vvt_id?: string; vvtId?: string; name?: string; activity_name?: string }>, - complianceResult: ComplianceCheckResult | null, - revisions: LoeschkonzeptRevision[] -): string { - const today = new Date().toLocaleDateString('de-DE', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }) - - const activePolicies = policies.filter(p => p.status !== 'ARCHIVED') - const orgName = orgHeader.organizationName || 'Organisation' - - // Collect unique storage locations across all policies - const allStorageLocations = new Set() - for (const p of activePolicies) { - for (const loc of p.storageLocations) { - allStorageLocations.add(loc.name || loc.type) - } - } - - // Collect unique responsible roles - const roleMap = new Map() - for (const p of activePolicies) { - const role = p.responsibleRole || p.responsiblePerson || 'Nicht zugewiesen' - if (!roleMap.has(role)) roleMap.set(role, []) - roleMap.get(role)!.push(p.dataObjectName || p.policyId) - } - - // Collect active legal holds - const allActiveLegalHolds: Array<{ policy: string; hold: LoeschfristPolicy['legalHolds'][0] }> = [] - for (const p of activePolicies) { - for (const h of getActiveLegalHolds(p)) { - allActiveLegalHolds.push({ policy: p.dataObjectName || p.policyId, hold: h }) - } - } - - // Build VVT cross-reference data - const vvtRefs: Array<{ policyName: string; policyId: string; vvtId: string; vvtName: string }> = [] - for (const p of activePolicies) { - for (const linkedId of p.linkedVVTActivityIds) { - const activity = vvtActivities.find(a => a.id === linkedId) - if (activity) { - vvtRefs.push({ - policyName: p.dataObjectName || p.policyId, - policyId: p.policyId, - vvtId: activity.vvt_id || activity.vvtId || linkedId.substring(0, 8), - vvtName: activity.activity_name || activity.name || 'Unbenannte Verarbeitungstaetigkeit', - }) - } - } - } - - // Build vendor cross-reference data - const vendorRefs: Array<{ policyName: string; policyId: string; vendorId: string; duration: string }> = [] - for (const p of activePolicies) { - if (p.linkedVendorIds && p.linkedVendorIds.length > 0) { - for (const vendorId of p.linkedVendorIds) { - vendorRefs.push({ - policyName: p.dataObjectName || p.policyId, - policyId: p.policyId, - vendorId, - duration: formatRetentionDuration(p.retentionDuration, p.retentionUnit), - }) - } - } - } - - // ========================================================================= - // HTML Template - // ========================================================================= - - let html = ` - - - -Loeschkonzept — ${escHtml(orgName)} - - - -` - - // ========================================================================= - // Section 0: Cover Page - // ========================================================================= - html += ` -
-

Loeschkonzept

-
gemaess Art. 5 Abs. 1 lit. e, Art. 17, Art. 30 DSGVO
-
-
Organisation: ${escHtml(orgName)}
- ${orgHeader.industry ? `
Branche: ${escHtml(orgHeader.industry)}
` : ''} - ${orgHeader.dpoName ? `
Datenschutzbeauftragter: ${escHtml(orgHeader.dpoName)}
` : ''} - ${orgHeader.dpoContact ? `
DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
` : ''} - ${orgHeader.responsiblePerson ? `
Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
` : ''} - ${orgHeader.employeeCount ? `
Mitarbeiter: ${escHtml(orgHeader.employeeCount)}
` : ''} - ${orgHeader.locations.length > 0 ? `
Standorte: ${escHtml(orgHeader.locations.join(', '))}
` : ''} -
- -
-` - - // ========================================================================= - // Table of Contents - // ========================================================================= - const sections = [ - 'Ziel und Zweck', - 'Geltungsbereich', - 'Grundprinzipien der Datenspeicherung', - 'Loeschregeln-Uebersicht', - 'Detaillierte Loeschregeln', - 'VVT-Verknuepfung', - 'Auftragsverarbeiter mit Loeschpflichten', - 'Legal Hold Verfahren', - 'Verantwortlichkeiten', - 'Pruef- und Revisionszyklus', - 'Compliance-Status', - 'Aenderungshistorie', - ] - - html += ` -
-

Inhaltsverzeichnis

- ${sections.map((s, i) => `
${i + 1}. ${escHtml(s)}
`).join('\n ')} -
-` - - // ========================================================================= - // Section 1: Ziel und Zweck - // ========================================================================= - html += ` -
-
1. Ziel und Zweck
-
-

Dieses Loeschkonzept definiert die systematischen Regeln und Verfahren fuer die Loeschung - personenbezogener Daten bei ${escHtml(orgName)}. Es dient der Umsetzung - folgender DSGVO-Anforderungen:

- - - - - -
RechtsgrundlageInhalt
Art. 5 Abs. 1 lit. e DSGVOGrundsatz der Speicherbegrenzung — personenbezogene Daten duerfen nur so lange gespeichert werden, wie es fuer die Zwecke der Verarbeitung erforderlich ist.
Art. 17 DSGVORecht auf Loeschung („Recht auf Vergessenwerden“) — Betroffene haben das Recht, die Loeschung ihrer Daten zu verlangen.
Art. 30 DSGVOVerzeichnis von Verarbeitungstaetigkeiten — vorgesehene Fristen fuer die Loeschung der verschiedenen Datenkategorien muessen dokumentiert werden.
-

Das Loeschkonzept ist fester Bestandteil des Datenschutz-Managementsystems und wird - regelmaessig ueberprueft und aktualisiert.

-
-
-` - - // ========================================================================= - // Section 2: Geltungsbereich - // ========================================================================= - const storageListHtml = allStorageLocations.size > 0 - ? Array.from(allStorageLocations).map(s => `
  • ${escHtml(s)}
  • `).join('') - : '
  • Keine Speicherorte dokumentiert
  • ' - - html += ` -
    -
    2. Geltungsbereich
    -
    -

    Dieses Loeschkonzept gilt fuer alle personenbezogenen Daten, die von ${escHtml(orgName)} - verarbeitet werden. Es umfasst ${activePolicies.length} Loeschregeln fuer folgende Systeme und Speicherorte:

    -
      - ${storageListHtml} -
    -

    Saemtliche Verarbeitungstaetigkeiten, die im Verzeichnis von Verarbeitungstaetigkeiten (VVT) - erfasst sind, werden durch dieses Loeschkonzept abgedeckt.

    -
    -
    -` - - // ========================================================================= - // Section 3: Grundprinzipien - // ========================================================================= - html += ` -
    -
    3. Grundprinzipien der Datenspeicherung
    -
    -
    Speicherbegrenzung: Personenbezogene Daten werden nur so lange gespeichert, wie es fuer den jeweiligen Verarbeitungszweck erforderlich ist (Art. 5 Abs. 1 lit. e DSGVO).
    -
    3-Level-Loeschlogik: Die Loeschung folgt einer dreistufigen Priorisierung: (1) Zweckende, (2) gesetzliche Aufbewahrungspflichten, (3) Legal Hold — jeweils mit der laengsten Frist als massgeblich.
    -
    Dokumentationspflicht: Jede Loeschregel ist dokumentiert mit Rechtsgrundlage, Frist, Loeschmethode und Verantwortlichkeit.
    -
    Regelmaessige Ueberpruefung: Alle Loeschregeln werden im definierten Intervall ueberprueft und bei Bedarf angepasst.
    -
    Datenschutz durch Technikgestaltung: Loeschmechanismen werden moeglichst automatisiert, um menschliche Fehler zu minimieren (Art. 25 DSGVO).
    -
    -
    -` - - // ========================================================================= - // Section 4: Loeschregeln-Uebersicht - // ========================================================================= - html += ` -
    -
    4. Loeschregeln-Uebersicht
    -
    -

    Die folgende Tabelle zeigt eine Uebersicht aller ${activePolicies.length} aktiven Loeschregeln:

    - - - - - - - - - -` - for (const p of activePolicies) { - const trigger = TRIGGER_LABELS[getEffectiveDeletionTrigger(p)] - const duration = formatRetentionDuration(p.retentionDuration, p.retentionUnit) - const method = DELETION_METHOD_LABELS[p.deletionMethod] - const statusLabel = STATUS_LABELS[p.status] - const statusClass = p.status === 'ACTIVE' ? 'badge-active' : p.status === 'REVIEW_NEEDED' ? 'badge-review' : 'badge-draft' - - html += ` - - - - - - - -` - } - - html += `
    LF-Nr.DatenobjektLoeschtriggerAufbewahrungsfristLoeschmethodeStatus
    ${escHtml(p.policyId)}${escHtml(p.dataObjectName)}${escHtml(trigger)}${escHtml(duration)}${escHtml(method)}${escHtml(statusLabel)}
    -
    -
    -` - - // ========================================================================= - // Section 5: Detaillierte Loeschregeln - // ========================================================================= - html += ` -
    -
    5. Detaillierte Loeschregeln
    -
    -` - for (const p of activePolicies) { - const trigger = TRIGGER_LABELS[getEffectiveDeletionTrigger(p)] - const duration = formatRetentionDuration(p.retentionDuration, p.retentionUnit) - const method = DELETION_METHOD_LABELS[p.deletionMethod] - const statusLabel = STATUS_LABELS[p.status] - const driverLabel = p.retentionDriver ? RETENTION_DRIVER_META[p.retentionDriver]?.label || p.retentionDriver : '-' - const driverStatute = p.retentionDriver ? RETENTION_DRIVER_META[p.retentionDriver]?.statute || '' : '' - const locations = p.storageLocations.map(l => l.name || l.type).join(', ') || '-' - const responsible = [p.responsiblePerson, p.responsibleRole].filter(s => s.trim()).join(' / ') || '-' - const activeHolds = getActiveLegalHolds(p) - - html += ` -
    -
    - ${escHtml(p.policyId)} — ${escHtml(p.dataObjectName)} - ${escHtml(statusLabel)} -
    -
    - - - - - - - - - - - - - - - ${activeHolds.length > 0 ? `` : ''} -
    Beschreibung${escHtml(p.description || '-')}
    Betroffenengruppen${escHtml(p.affectedGroups.join(', ') || '-')}
    Datenkategorien${escHtml(p.dataCategories.join(', ') || '-')}
    Verarbeitungszweck${escHtml(p.primaryPurpose || '-')}
    Loeschtrigger${escHtml(trigger)}
    Aufbewahrungstreiber${escHtml(driverLabel)}${driverStatute ? ` (${escHtml(driverStatute)})` : ''}
    Aufbewahrungsfrist${escHtml(duration)}
    Startereignis${escHtml(p.startEvent || '-')}
    Loeschmethode${escHtml(method)}
    Loeschmethode (Detail)${escHtml(p.deletionMethodDetail || '-')}
    Speicherorte${escHtml(locations)}
    Verantwortlich${escHtml(responsible)}
    Pruefintervall${escHtml(REVIEW_INTERVAL_LABELS[p.reviewInterval] || p.reviewInterval)}
    Aktive Legal Holds${activeHolds.map(h => `${escHtml(h.reason)} (seit ${formatDateDE(h.startDate)})`).join('
    ')}
    -
    -
    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 6: VVT-Verknuepfung - // ========================================================================= - html += ` -
    -
    6. VVT-Verknuepfung
    -
    -

    Die folgende Tabelle zeigt die Verknuepfung zwischen Loeschregeln und Verarbeitungstaetigkeiten - im VVT (Art. 30 DSGVO):

    -` - if (vvtRefs.length > 0) { - html += ` - -` - for (const ref of vvtRefs) { - html += ` - - - - - -` - } - html += `
    LoeschregelLF-Nr.VVT-Nr.Verarbeitungstaetigkeit
    ${escHtml(ref.policyName)}${escHtml(ref.policyId)}${escHtml(ref.vvtId)}${escHtml(ref.vvtName)}
    -` - } else { - html += `

    Noch keine VVT-Verknuepfungen dokumentiert. Verknuepfen Sie Ihre Loeschregeln - mit den entsprechenden Verarbeitungstaetigkeiten im Editor-Tab.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 7: Auftragsverarbeiter mit Loeschpflichten - // ========================================================================= - html += ` -
    -
    7. Auftragsverarbeiter mit Loeschpflichten
    -
    -

    Die folgende Tabelle zeigt Loeschregeln, die mit Auftragsverarbeitern verknuepft sind. - Diese Verknuepfungen stellen sicher, dass auch bei extern verarbeiteten Daten die Loeschpflichten - eingehalten werden (Art. 28 DSGVO).

    -` - if (vendorRefs.length > 0) { - html += ` - -` - for (const ref of vendorRefs) { - html += ` - - - - - -` - } - html += `
    LoeschregelLF-Nr.Auftragsverarbeiter (ID)Aufbewahrungsfrist
    ${escHtml(ref.policyName)}${escHtml(ref.policyId)}${escHtml(ref.vendorId)}${escHtml(ref.duration)}
    -` - } else { - html += `

    Noch keine Auftragsverarbeiter mit Loeschregeln verknuepft. Verknuepfen Sie Ihre - Loeschregeln mit den entsprechenden Auftragsverarbeitern im Editor-Tab.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 8: Legal Hold Verfahren - // ========================================================================= - html += ` -
    -
    8. Legal Hold Verfahren
    -
    -

    Ein Legal Hold (Aufbewahrungspflicht aufgrund rechtlicher Verfahren) setzt die regulaere - Loeschung aus. Betroffene Daten duerfen trotz abgelaufener Loeschfrist nicht geloescht werden, - bis der Legal Hold aufgehoben wird.

    -

    Verfahrensschritte:

    -
      -
    1. Rechtsabteilung/DSB identifiziert betroffene Datenkategorien
    2. -
    3. Legal Hold wird im System aktiviert (Status: Aktiv)
    4. -
    5. Automatische Loeschung wird fuer betroffene Policies ausgesetzt
    6. -
    7. Regelmaessige Pruefung, ob der Legal Hold noch erforderlich ist
    8. -
    9. Nach Aufhebung: Regulaere Loeschfristen greifen wieder
    10. -
    -` - if (allActiveLegalHolds.length > 0) { - html += `

    Aktuell aktive Legal Holds (${allActiveLegalHolds.length}):

    - - -` - for (const { policy, hold } of allActiveLegalHolds) { - html += ` - - - - - - -` - } - html += `
    DatenobjektGrundRechtsgrundlageSeitVoraussichtlich bis
    ${escHtml(policy)}${escHtml(hold.reason)}${escHtml(hold.legalBasis)}${formatDateDE(hold.startDate)}${hold.expectedEndDate ? formatDateDE(hold.expectedEndDate) : 'Unbefristet'}
    -` - } else { - html += `

    Derzeit sind keine aktiven Legal Holds vorhanden.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 9: Verantwortlichkeiten - // ========================================================================= - html += ` -
    -
    9. Verantwortlichkeiten
    -
    -

    Die folgende Rollenmatrix zeigt, welche Organisationseinheiten fuer welche Datenobjekte - die Loeschverantwortung tragen:

    - - -` - for (const [role, objects] of roleMap.entries()) { - html += ` - - - - -` - } - - html += `
    Rolle / VerantwortlichDatenobjekteAnzahl
    ${escHtml(role)}${objects.map(o => escHtml(o)).join(', ')}${objects.length}
    -
    -
    -` - - // ========================================================================= - // Section 10: Pruef- und Revisionszyklus - // ========================================================================= - html += ` -
    -
    10. Pruef- und Revisionszyklus
    -
    - - - - - - -
    EigenschaftWert
    Aktuelles Pruefintervall${escHtml(orgHeader.reviewInterval)}
    Letzte Pruefung${formatDateDE(orgHeader.lastReviewDate)}
    Naechste Pruefung${formatDateDE(orgHeader.nextReviewDate)}
    Aktuelle Version${escHtml(orgHeader.loeschkonzeptVersion)}
    -

    Bei jeder Pruefung wird das Loeschkonzept auf folgende Punkte ueberprueft:

    -
      -
    • Vollstaendigkeit aller Loeschregeln (neue Verarbeitungen erfasst?)
    • -
    • Aktualitaet der gesetzlichen Aufbewahrungsfristen
    • -
    • Wirksamkeit der technischen Loeschmechanismen
    • -
    • Einhaltung der definierten Loeschfristen
    • -
    • Angemessenheit der Verantwortlichkeiten
    • -
    -
    -
    -` - - // ========================================================================= - // Section 11: Compliance-Status - // ========================================================================= - html += ` -
    -
    11. Compliance-Status
    -
    -` - if (complianceResult) { - const scoreClass = complianceResult.score >= 90 ? 'score-excellent' - : complianceResult.score >= 75 ? 'score-good' - : complianceResult.score >= 50 ? 'score-needs-work' - : 'score-poor' - const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' - : complianceResult.score >= 75 ? 'Gut' - : complianceResult.score >= 50 ? 'Verbesserungswuerdig' - : 'Mangelhaft' - - html += `

    ${complianceResult.score}/100 ${escHtml(scoreLabel)}

    - - - - - -
    KennzahlWert
    Gepruefte Policies${complianceResult.stats.total}
    Bestanden${complianceResult.stats.passed}
    Beanstandungen${complianceResult.stats.failed}
    -` - if (complianceResult.issues.length > 0) { - html += `

    Befunde nach Schweregrad:

    - - -` - const severityOrder: ComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] - for (const sev of severityOrder) { - const count = complianceResult.stats.bySeverity[sev] - if (count === 0) continue - const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) - html += ` - - - - -` - } - html += `
    SchweregradAnzahlBefunde
    ${SEVERITY_LABELS_DE[sev]}${count}${issuesForSev.map(i => escHtml(i.title)).join('; ')}
    -` - } else { - html += `

    Keine Beanstandungen. Alle Policies sind konform.

    -` - } - } else { - html += `

    Compliance-Check wurde noch nicht ausgefuehrt. Fuehren Sie den Check im - Export-Tab durch, um den Status in das Dokument aufzunehmen.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 12: Aenderungshistorie - // ========================================================================= - html += ` -
    -
    12. Aenderungshistorie
    -
    - - -` - if (revisions.length > 0) { - for (const rev of revisions) { - html += ` - - - - - -` - } - } else { - html += ` - - - - - -` - } - - html += `
    VersionDatumAutorAenderungen
    ${escHtml(rev.version)}${formatDateDE(rev.date)}${escHtml(rev.author)}${escHtml(rev.changes)}
    ${escHtml(orgHeader.loeschkonzeptVersion)}${today}${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '-')}Erstversion des Loeschkonzepts
    -
    -
    -` - - // ========================================================================= - // Footer - // ========================================================================= - html += ` - - - -` - - return html -} - -// ============================================================================= -// INTERNAL HELPERS -// ============================================================================= - -function escHtml(str: string): string { - return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') -} - -function formatDateDE(dateStr: string | null | undefined): string { - if (!dateStr) return '-' - try { - const date = new Date(dateStr) - if (isNaN(date.getTime())) return '-' - return date.toLocaleDateString('de-DE', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }) - } catch { - return '-' - } -} +export type { LoeschkonzeptOrgHeader, LoeschkonzeptRevision } from './loeschfristen-document/types-defaults' +export { createDefaultLoeschkonzeptOrgHeader } from './loeschfristen-document/types-defaults' +export { buildLoeschkonzeptHtml } from './loeschfristen-document/html-builder' diff --git a/admin-compliance/lib/sdk/loeschfristen-document/helpers.ts b/admin-compliance/lib/sdk/loeschfristen-document/helpers.ts new file mode 100644 index 0000000..c95a41b --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-document/helpers.ts @@ -0,0 +1,26 @@ +// ============================================================================= +// Loeschfristen Document — Internal Helpers +// ============================================================================= + +export function escHtml(str: string): string { + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') +} + +export function formatDateDE(dateStr: string | null | undefined): string { + if (!dateStr) return '-' + try { + const date = new Date(dateStr) + if (isNaN(date.getTime())) return '-' + return date.toLocaleDateString('de-DE', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }) + } catch { + return '-' + } +} diff --git a/admin-compliance/lib/sdk/loeschfristen-document/html-builder.ts b/admin-compliance/lib/sdk/loeschfristen-document/html-builder.ts new file mode 100644 index 0000000..848f73a --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-document/html-builder.ts @@ -0,0 +1,603 @@ +// ============================================================================= +// Loeschfristen Document — HTML Document Builder +// ============================================================================= + +import type { + LoeschfristPolicy, +} from '../loeschfristen-types' +import { + RETENTION_DRIVER_META, + DELETION_METHOD_LABELS, + STATUS_LABELS, + TRIGGER_LABELS, + REVIEW_INTERVAL_LABELS, + formatRetentionDuration, + getEffectiveDeletionTrigger, + getActiveLegalHolds, +} from '../loeschfristen-types' +import type { ComplianceCheckResult, ComplianceIssueSeverity } from '../loeschfristen-compliance' +import type { LoeschkonzeptOrgHeader, LoeschkonzeptRevision } from './types-defaults' +import { SEVERITY_LABELS_DE, SEVERITY_COLORS } from './types-defaults' +import { escHtml, formatDateDE } from './helpers' + +type VVTActivity = { id: string; vvt_id?: string; vvtId?: string; name?: string; activity_name?: string } + +export function buildLoeschkonzeptHtml( + policies: LoeschfristPolicy[], + orgHeader: LoeschkonzeptOrgHeader, + vvtActivities: VVTActivity[], + complianceResult: ComplianceCheckResult | null, + revisions: LoeschkonzeptRevision[] +): string { + const today = new Date().toLocaleDateString('de-DE', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }) + + const activePolicies = policies.filter(p => p.status !== 'ARCHIVED') + const orgName = orgHeader.organizationName || 'Organisation' + + // Collect unique storage locations + const allStorageLocations = new Set() + for (const p of activePolicies) { + for (const loc of p.storageLocations) { + allStorageLocations.add(loc.name || loc.type) + } + } + + // Collect unique responsible roles + const roleMap = new Map() + for (const p of activePolicies) { + const role = p.responsibleRole || p.responsiblePerson || 'Nicht zugewiesen' + if (!roleMap.has(role)) roleMap.set(role, []) + roleMap.get(role)!.push(p.dataObjectName || p.policyId) + } + + // Collect active legal holds + const allActiveLegalHolds: Array<{ policy: string; hold: LoeschfristPolicy['legalHolds'][0] }> = [] + for (const p of activePolicies) { + for (const h of getActiveLegalHolds(p)) { + allActiveLegalHolds.push({ policy: p.dataObjectName || p.policyId, hold: h }) + } + } + + // Build VVT cross-reference data + const vvtRefs: Array<{ policyName: string; policyId: string; vvtId: string; vvtName: string }> = [] + for (const p of activePolicies) { + for (const linkedId of p.linkedVVTActivityIds) { + const activity = vvtActivities.find(a => a.id === linkedId) + if (activity) { + vvtRefs.push({ + policyName: p.dataObjectName || p.policyId, + policyId: p.policyId, + vvtId: activity.vvt_id || activity.vvtId || linkedId.substring(0, 8), + vvtName: activity.activity_name || activity.name || 'Unbenannte Verarbeitungstaetigkeit', + }) + } + } + } + + // Build vendor cross-reference data + const vendorRefs: Array<{ policyName: string; policyId: string; vendorId: string; duration: string }> = [] + for (const p of activePolicies) { + if (p.linkedVendorIds && p.linkedVendorIds.length > 0) { + for (const vendorId of p.linkedVendorIds) { + vendorRefs.push({ + policyName: p.dataObjectName || p.policyId, + policyId: p.policyId, + vendorId, + duration: formatRetentionDuration(p.retentionDuration, p.retentionUnit), + }) + } + } + } + + let html = buildDocumentHeader(orgName) + html += buildCoverAndTOC(orgHeader, orgName, today) + html += buildSections1to5(orgName, orgHeader, activePolicies, allStorageLocations) + html += buildSections6to9(activePolicies, vvtRefs, vendorRefs, allActiveLegalHolds, roleMap) + html += buildSections10to12(orgHeader, complianceResult, revisions, today) + html += ` + + + +` + + return html +} + +function buildDocumentHeader(orgName: string): string { + return ` + + + +Loeschkonzept — ${escHtml(orgName)} + + + +` +} + +function buildCoverAndTOC( + orgHeader: LoeschkonzeptOrgHeader, + orgName: string, + today: string +): string { + const sections = [ + 'Ziel und Zweck', 'Geltungsbereich', 'Grundprinzipien der Datenspeicherung', + 'Loeschregeln-Uebersicht', 'Detaillierte Loeschregeln', 'VVT-Verknuepfung', + 'Auftragsverarbeiter mit Loeschpflichten', 'Legal Hold Verfahren', + 'Verantwortlichkeiten', 'Pruef- und Revisionszyklus', 'Compliance-Status', 'Aenderungshistorie', + ] + + return ` +
    +

    Loeschkonzept

    +
    gemaess Art. 5 Abs. 1 lit. e, Art. 17, Art. 30 DSGVO
    +
    +
    Organisation: ${escHtml(orgName)}
    + ${orgHeader.industry ? `
    Branche: ${escHtml(orgHeader.industry)}
    ` : ''} + ${orgHeader.dpoName ? `
    Datenschutzbeauftragter: ${escHtml(orgHeader.dpoName)}
    ` : ''} + ${orgHeader.dpoContact ? `
    DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
    ` : ''} + ${orgHeader.responsiblePerson ? `
    Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
    ` : ''} + ${orgHeader.employeeCount ? `
    Mitarbeiter: ${escHtml(orgHeader.employeeCount)}
    ` : ''} + ${orgHeader.locations.length > 0 ? `
    Standorte: ${escHtml(orgHeader.locations.join(', '))}
    ` : ''} +
    + +
    +
    +

    Inhaltsverzeichnis

    + ${sections.map((s, i) => `
    ${i + 1}. ${escHtml(s)}
    `).join('\n ')} +
    +` +} + +function buildSections1to5( + orgName: string, + orgHeader: LoeschkonzeptOrgHeader, + activePolicies: LoeschfristPolicy[], + allStorageLocations: Set +): string { + const storageListHtml = allStorageLocations.size > 0 + ? Array.from(allStorageLocations).map(s => `
  • ${escHtml(s)}
  • `).join('') + : '
  • Keine Speicherorte dokumentiert
  • ' + + return ` +
    +
    1. Ziel und Zweck
    +
    +

    Dieses Loeschkonzept definiert die systematischen Regeln und Verfahren fuer die Loeschung + personenbezogener Daten bei ${escHtml(orgName)}. Es dient der Umsetzung + folgender DSGVO-Anforderungen:

    + + + + + +
    RechtsgrundlageInhalt
    Art. 5 Abs. 1 lit. e DSGVOGrundsatz der Speicherbegrenzung — personenbezogene Daten duerfen nur so lange gespeichert werden, wie es fuer die Zwecke der Verarbeitung erforderlich ist.
    Art. 17 DSGVORecht auf Loeschung („Recht auf Vergessenwerden“) — Betroffene haben das Recht, die Loeschung ihrer Daten zu verlangen.
    Art. 30 DSGVOVerzeichnis von Verarbeitungstaetigkeiten — vorgesehene Fristen fuer die Loeschung der verschiedenen Datenkategorien muessen dokumentiert werden.
    +

    Das Loeschkonzept ist fester Bestandteil des Datenschutz-Managementsystems und wird + regelmaessig ueberprueft und aktualisiert.

    +
    +
    + +
    +
    2. Geltungsbereich
    +
    +

    Dieses Loeschkonzept gilt fuer alle personenbezogenen Daten, die von ${escHtml(orgName)} + verarbeitet werden. Es umfasst ${activePolicies.length} Loeschregeln fuer folgende Systeme und Speicherorte:

    +
      ${storageListHtml}
    +

    Saemtliche Verarbeitungstaetigkeiten, die im Verzeichnis von Verarbeitungstaetigkeiten (VVT) + erfasst sind, werden durch dieses Loeschkonzept abgedeckt.

    +
    +
    + +
    +
    3. Grundprinzipien der Datenspeicherung
    +
    +
    Speicherbegrenzung: Personenbezogene Daten werden nur so lange gespeichert, wie es fuer den jeweiligen Verarbeitungszweck erforderlich ist (Art. 5 Abs. 1 lit. e DSGVO).
    +
    3-Level-Loeschlogik: Die Loeschung folgt einer dreistufigen Priorisierung: (1) Zweckende, (2) gesetzliche Aufbewahrungspflichten, (3) Legal Hold — jeweils mit der laengsten Frist als massgeblich.
    +
    Dokumentationspflicht: Jede Loeschregel ist dokumentiert mit Rechtsgrundlage, Frist, Loeschmethode und Verantwortlichkeit.
    +
    Regelmaessige Ueberpruefung: Alle Loeschregeln werden im definierten Intervall ueberprueft und bei Bedarf angepasst.
    +
    Datenschutz durch Technikgestaltung: Loeschmechanismen werden moeglichst automatisiert, um menschliche Fehler zu minimieren (Art. 25 DSGVO).
    +
    +
    + +${buildSection4Overview(activePolicies)} +${buildSection5Detail(activePolicies)} +` +} + +function buildSection4Overview(activePolicies: LoeschfristPolicy[]): string { + let html = ` +
    +
    4. Loeschregeln-Uebersicht
    +
    +

    Die folgende Tabelle zeigt eine Uebersicht aller ${activePolicies.length} aktiven Loeschregeln:

    + + + + + + + + + +` + for (const p of activePolicies) { + const trigger = TRIGGER_LABELS[getEffectiveDeletionTrigger(p)] + const duration = formatRetentionDuration(p.retentionDuration, p.retentionUnit) + const method = DELETION_METHOD_LABELS[p.deletionMethod] + const statusLabel = STATUS_LABELS[p.status] + const statusClass = p.status === 'ACTIVE' ? 'badge-active' : p.status === 'REVIEW_NEEDED' ? 'badge-review' : 'badge-draft' + + html += ` + + + + + + + +` + } + + html += `
    LF-Nr.DatenobjektLoeschtriggerAufbewahrungsfristLoeschmethodeStatus
    ${escHtml(p.policyId)}${escHtml(p.dataObjectName)}${escHtml(trigger)}${escHtml(duration)}${escHtml(method)}${escHtml(statusLabel)}
    +
    +
    +` + return html +} + +function buildSection5Detail(activePolicies: LoeschfristPolicy[]): string { + let html = ` +
    +
    5. Detaillierte Loeschregeln
    +
    +` + for (const p of activePolicies) { + const trigger = TRIGGER_LABELS[getEffectiveDeletionTrigger(p)] + const duration = formatRetentionDuration(p.retentionDuration, p.retentionUnit) + const method = DELETION_METHOD_LABELS[p.deletionMethod] + const statusLabel = STATUS_LABELS[p.status] + const driverLabel = p.retentionDriver ? RETENTION_DRIVER_META[p.retentionDriver]?.label || p.retentionDriver : '-' + const driverStatute = p.retentionDriver ? RETENTION_DRIVER_META[p.retentionDriver]?.statute || '' : '' + const locations = p.storageLocations.map(l => l.name || l.type).join(', ') || '-' + const responsible = [p.responsiblePerson, p.responsibleRole].filter(s => s.trim()).join(' / ') || '-' + const activeHolds = getActiveLegalHolds(p) + + html += ` +
    +
    + ${escHtml(p.policyId)} — ${escHtml(p.dataObjectName)} + ${escHtml(statusLabel)} +
    +
    + + + + + + + + + + + + + + + ${activeHolds.length > 0 ? `` : ''} +
    Beschreibung${escHtml(p.description || '-')}
    Betroffenengruppen${escHtml(p.affectedGroups.join(', ') || '-')}
    Datenkategorien${escHtml(p.dataCategories.join(', ') || '-')}
    Verarbeitungszweck${escHtml(p.primaryPurpose || '-')}
    Loeschtrigger${escHtml(trigger)}
    Aufbewahrungstreiber${escHtml(driverLabel)}${driverStatute ? ` (${escHtml(driverStatute)})` : ''}
    Aufbewahrungsfrist${escHtml(duration)}
    Startereignis${escHtml(p.startEvent || '-')}
    Loeschmethode${escHtml(method)}
    Loeschmethode (Detail)${escHtml(p.deletionMethodDetail || '-')}
    Speicherorte${escHtml(locations)}
    Verantwortlich${escHtml(responsible)}
    Pruefintervall${escHtml(REVIEW_INTERVAL_LABELS[p.reviewInterval] || p.reviewInterval)}
    Aktive Legal Holds${activeHolds.map(h => `${escHtml(h.reason)} (seit ${formatDateDE(h.startDate)})`).join('
    ')}
    +
    +
    +` + } + + html += `
    +
    +` + return html +} + +function buildSections6to9( + activePolicies: LoeschfristPolicy[], + vvtRefs: Array<{ policyName: string; policyId: string; vvtId: string; vvtName: string }>, + vendorRefs: Array<{ policyName: string; policyId: string; vendorId: string; duration: string }>, + allActiveLegalHolds: Array<{ policy: string; hold: LoeschfristPolicy['legalHolds'][0] }>, + roleMap: Map +): string { + let html = ` +
    +
    6. VVT-Verknuepfung
    +
    +

    Die folgende Tabelle zeigt die Verknuepfung zwischen Loeschregeln und Verarbeitungstaetigkeiten im VVT (Art. 30 DSGVO):

    +` + if (vvtRefs.length > 0) { + html += ` + +` + for (const ref of vvtRefs) { + html += ` + + + + + +` + } + html += `
    LoeschregelLF-Nr.VVT-Nr.Verarbeitungstaetigkeit
    ${escHtml(ref.policyName)}${escHtml(ref.policyId)}${escHtml(ref.vvtId)}${escHtml(ref.vvtName)}
    +` + } else { + html += `

    Noch keine VVT-Verknuepfungen dokumentiert.

    +` + } + html += `
    +
    + +
    +
    7. Auftragsverarbeiter mit Loeschpflichten
    +
    +

    Die folgende Tabelle zeigt Loeschregeln, die mit Auftragsverarbeitern verknuepft sind (Art. 28 DSGVO).

    +` + if (vendorRefs.length > 0) { + html += ` + +` + for (const ref of vendorRefs) { + html += ` + + + + + +` + } + html += `
    LoeschregelLF-Nr.Auftragsverarbeiter (ID)Aufbewahrungsfrist
    ${escHtml(ref.policyName)}${escHtml(ref.policyId)}${escHtml(ref.vendorId)}${escHtml(ref.duration)}
    +` + } else { + html += `

    Noch keine Auftragsverarbeiter mit Loeschregeln verknuepft.

    +` + } + html += `
    +
    + +
    +
    8. Legal Hold Verfahren
    +
    +

    Ein Legal Hold setzt die regulaere Loeschung aus. Betroffene Daten duerfen trotz abgelaufener Loeschfrist nicht geloescht werden, bis der Legal Hold aufgehoben wird.

    +

    Verfahrensschritte:

    +
      +
    1. Rechtsabteilung/DSB identifiziert betroffene Datenkategorien
    2. +
    3. Legal Hold wird im System aktiviert (Status: Aktiv)
    4. +
    5. Automatische Loeschung wird fuer betroffene Policies ausgesetzt
    6. +
    7. Regelmaessige Pruefung, ob der Legal Hold noch erforderlich ist
    8. +
    9. Nach Aufhebung: Regulaere Loeschfristen greifen wieder
    10. +
    +` + if (allActiveLegalHolds.length > 0) { + html += `

    Aktuell aktive Legal Holds (${allActiveLegalHolds.length}):

    + + +` + for (const { policy, hold } of allActiveLegalHolds) { + html += ` + + + + + + +` + } + html += `
    DatenobjektGrundRechtsgrundlageSeitVoraussichtlich bis
    ${escHtml(policy)}${escHtml(hold.reason)}${escHtml(hold.legalBasis)}${formatDateDE(hold.startDate)}${hold.expectedEndDate ? formatDateDE(hold.expectedEndDate) : 'Unbefristet'}
    +` + } else { + html += `

    Derzeit sind keine aktiven Legal Holds vorhanden.

    +` + } + html += `
    +
    + +
    +
    9. Verantwortlichkeiten
    +
    +

    Die folgende Rollenmatrix zeigt, welche Organisationseinheiten fuer welche Datenobjekte die Loeschverantwortung tragen:

    + + +` + for (const [role, objects] of roleMap.entries()) { + html += ` + + + + +` + } + html += `
    Rolle / VerantwortlichDatenobjekteAnzahl
    ${escHtml(role)}${objects.map(o => escHtml(o)).join(', ')}${objects.length}
    +
    +
    +` + return html +} + +function buildSections10to12( + orgHeader: LoeschkonzeptOrgHeader, + complianceResult: ComplianceCheckResult | null, + revisions: LoeschkonzeptRevision[], + today: string +): string { + let html = ` +
    +
    10. Pruef- und Revisionszyklus
    +
    + + + + + + +
    EigenschaftWert
    Aktuelles Pruefintervall${escHtml(orgHeader.reviewInterval)}
    Letzte Pruefung${formatDateDE(orgHeader.lastReviewDate)}
    Naechste Pruefung${formatDateDE(orgHeader.nextReviewDate)}
    Aktuelle Version${escHtml(orgHeader.loeschkonzeptVersion)}
    +

    Bei jeder Pruefung wird das Loeschkonzept auf folgende Punkte ueberprueft:

    +
      +
    • Vollstaendigkeit aller Loeschregeln (neue Verarbeitungen erfasst?)
    • +
    • Aktualitaet der gesetzlichen Aufbewahrungsfristen
    • +
    • Wirksamkeit der technischen Loeschmechanismen
    • +
    • Einhaltung der definierten Loeschfristen
    • +
    • Angemessenheit der Verantwortlichkeiten
    • +
    +
    +
    +` + + html += buildSection11Compliance(complianceResult) + html += buildSection12History(revisions, orgHeader, today) + return html +} + +function buildSection11Compliance(complianceResult: ComplianceCheckResult | null): string { + let html = ` +
    +
    11. Compliance-Status
    +
    +` + if (complianceResult) { + const scoreClass = complianceResult.score >= 90 ? 'score-excellent' + : complianceResult.score >= 75 ? 'score-good' + : complianceResult.score >= 50 ? 'score-needs-work' + : 'score-poor' + const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' + : complianceResult.score >= 75 ? 'Gut' + : complianceResult.score >= 50 ? 'Verbesserungswuerdig' + : 'Mangelhaft' + + html += `

    ${complianceResult.score}/100 ${escHtml(scoreLabel)}

    + + + + + +
    KennzahlWert
    Gepruefte Policies${complianceResult.stats.total}
    Bestanden${complianceResult.stats.passed}
    Beanstandungen${complianceResult.stats.failed}
    +` + if (complianceResult.issues.length > 0) { + html += `

    Befunde nach Schweregrad:

    + + +` + const severityOrder: ComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] + for (const sev of severityOrder) { + const count = complianceResult.stats.bySeverity[sev] + if (count === 0) continue + const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) + html += ` + + + + +` + } + html += `
    SchweregradAnzahlBefunde
    ${SEVERITY_LABELS_DE[sev]}${count}${issuesForSev.map(i => escHtml(i.title)).join('; ')}
    +` + } else { + html += `

    Keine Beanstandungen. Alle Policies sind konform.

    +` + } + } else { + html += `

    Compliance-Check wurde noch nicht ausgefuehrt.

    +` + } + html += `
    +
    +` + return html +} + +function buildSection12History( + revisions: LoeschkonzeptRevision[], + orgHeader: LoeschkonzeptOrgHeader, + today: string +): string { + let html = ` +
    +
    12. Aenderungshistorie
    +
    + + +` + if (revisions.length > 0) { + for (const rev of revisions) { + html += ` + + + + + +` + } + } else { + html += ` + + + + + +` + } + html += `
    VersionDatumAutorAenderungen
    ${escHtml(rev.version)}${formatDateDE(rev.date)}${escHtml(rev.author)}${escHtml(rev.changes)}
    ${escHtml(orgHeader.loeschkonzeptVersion)}${today}${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '-')}Erstversion des Loeschkonzepts
    +
    +
    +` + return html +} diff --git a/admin-compliance/lib/sdk/loeschfristen-document/types-defaults.ts b/admin-compliance/lib/sdk/loeschfristen-document/types-defaults.ts new file mode 100644 index 0000000..3b0ab6a --- /dev/null +++ b/admin-compliance/lib/sdk/loeschfristen-document/types-defaults.ts @@ -0,0 +1,60 @@ +// ============================================================================= +// Loeschfristen Document — Types, Defaults & Severity Labels +// ============================================================================= + +import type { ComplianceIssueSeverity } from '../loeschfristen-compliance' + +export interface LoeschkonzeptOrgHeader { + organizationName: string + industry: string + dpoName: string + dpoContact: string + responsiblePerson: string + locations: string[] + employeeCount: string + loeschkonzeptVersion: string + lastReviewDate: string + nextReviewDate: string + reviewInterval: string +} + +export interface LoeschkonzeptRevision { + version: string + date: string + author: string + changes: string +} + +export function createDefaultLoeschkonzeptOrgHeader(): LoeschkonzeptOrgHeader { + const now = new Date() + const nextYear = new Date() + nextYear.setFullYear(nextYear.getFullYear() + 1) + + return { + organizationName: '', + industry: '', + dpoName: '', + dpoContact: '', + responsiblePerson: '', + locations: [], + employeeCount: '', + loeschkonzeptVersion: '1.0', + lastReviewDate: now.toISOString().split('T')[0], + nextReviewDate: nextYear.toISOString().split('T')[0], + reviewInterval: 'Jaehrlich', + } +} + +export const SEVERITY_LABELS_DE: Record = { + CRITICAL: 'Kritisch', + HIGH: 'Hoch', + MEDIUM: 'Mittel', + LOW: 'Niedrig', +} + +export const SEVERITY_COLORS: Record = { + CRITICAL: '#dc2626', + HIGH: '#ea580c', + MEDIUM: '#d97706', + LOW: '#6b7280', +} diff --git a/admin-compliance/lib/sdk/obligations-document.ts b/admin-compliance/lib/sdk/obligations-document.ts index e663c57..70fde83 100644 --- a/admin-compliance/lib/sdk/obligations-document.ts +++ b/admin-compliance/lib/sdk/obligations-document.ts @@ -1,915 +1,8 @@ // ============================================================================= // Obligations Module - Pflichtenregister Document Generator -// Generates a printable, audit-ready HTML document for the obligation register +// Barrel re-export — implementation split into obligations-document/ // ============================================================================= -import type { Obligation, ObligationComplianceCheckResult, ObligationComplianceIssueSeverity } from './obligations-compliance' -import { OBLIGATION_SEVERITY_LABELS_DE, OBLIGATION_SEVERITY_COLORS } from './obligations-compliance' - -// ============================================================================= -// TYPES -// ============================================================================= - -export interface ObligationDocumentOrgHeader { - organizationName: string - industry: string - dpoName: string - dpoContact: string - responsiblePerson: string - legalDepartment: string - documentVersion: string - lastReviewDate: string - nextReviewDate: string - reviewInterval: string -} - -export interface ObligationDocumentRevision { - version: string - date: string - author: string - changes: string -} - -// ============================================================================= -// DEFAULTS -// ============================================================================= - -export function createDefaultObligationDocumentOrgHeader(): ObligationDocumentOrgHeader { - const now = new Date() - const nextYear = new Date() - nextYear.setFullYear(nextYear.getFullYear() + 1) - - return { - organizationName: '', - industry: '', - dpoName: '', - dpoContact: '', - responsiblePerson: '', - legalDepartment: '', - documentVersion: '1.0', - lastReviewDate: now.toISOString().split('T')[0], - nextReviewDate: nextYear.toISOString().split('T')[0], - reviewInterval: 'Jaehrlich', - } -} - -// ============================================================================= -// STATUS & PRIORITY LABELS -// ============================================================================= - -const STATUS_LABELS_DE: Record = { - 'pending': 'Ausstehend', - 'in-progress': 'In Bearbeitung', - 'completed': 'Abgeschlossen', - 'overdue': 'Ueberfaellig', -} - -const STATUS_BADGE_CLASSES: Record = { - 'pending': 'badge-draft', - 'in-progress': 'badge-review', - 'completed': 'badge-active', - 'overdue': 'badge-critical', -} - -const PRIORITY_LABELS_DE: Record = { - critical: 'Kritisch', - high: 'Hoch', - medium: 'Mittel', - low: 'Niedrig', -} - -const PRIORITY_BADGE_CLASSES: Record = { - critical: 'badge-critical', - high: 'badge-high', - medium: 'badge-medium', - low: 'badge-low', -} - -// ============================================================================= -// HTML DOCUMENT BUILDER -// ============================================================================= - -export function buildObligationDocumentHtml( - obligations: Obligation[], - orgHeader: ObligationDocumentOrgHeader, - complianceResult: ObligationComplianceCheckResult | null, - revisions: ObligationDocumentRevision[] -): string { - const today = new Date().toLocaleDateString('de-DE', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }) - - const orgName = orgHeader.organizationName || 'Organisation' - - // Group obligations by source (regulation) - const bySource = new Map() - for (const o of obligations) { - const src = o.source || 'Sonstig' - if (!bySource.has(src)) bySource.set(src, []) - bySource.get(src)!.push(o) - } - - // Build role map - const roleMap = new Map() - for (const o of obligations) { - const role = o.responsible || 'Nicht zugewiesen' - if (!roleMap.has(role)) roleMap.set(role, []) - roleMap.get(role)!.push(o) - } - - // Distinct sources - const distinctSources = Array.from(bySource.keys()).sort() - - // ========================================================================= - // HTML Template - // ========================================================================= - - let html = ` - - - -Pflichtenregister — ${escHtml(orgName)} - - - -` - - // ========================================================================= - // Section 0: Cover Page - // ========================================================================= - html += ` -
    -

    Pflichtenregister

    -
    Regulatorische Pflichten — DSGVO, AI Act, NIS2 und weitere
    -
    -
    Organisation: ${escHtml(orgName)}
    - ${orgHeader.industry ? `
    Branche: ${escHtml(orgHeader.industry)}
    ` : ''} - ${orgHeader.dpoName ? `
    DSB: ${escHtml(orgHeader.dpoName)}
    ` : ''} - ${orgHeader.dpoContact ? `
    DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
    ` : ''} - ${orgHeader.responsiblePerson ? `
    Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
    ` : ''} - ${orgHeader.legalDepartment ? `
    Rechtsabteilung: ${escHtml(orgHeader.legalDepartment)}
    ` : ''} -
    - -
    -` - - // ========================================================================= - // Table of Contents - // ========================================================================= - const sections = [ - 'Ziel und Zweck', - 'Geltungsbereich', - 'Methodik', - 'Regulatorische Grundlagen', - 'Pflichtenuebersicht', - 'Detaillierte Pflichten', - 'Verantwortlichkeiten', - 'Fristen und Termine', - 'Nachweisverzeichnis', - 'Compliance-Status', - 'Aenderungshistorie', - ] - - html += ` -
    -

    Inhaltsverzeichnis

    - ${sections.map((s, i) => `
    ${i + 1}. ${escHtml(s)}
    `).join('\n ')} -
    -` - - // ========================================================================= - // Section 1: Ziel und Zweck - // ========================================================================= - html += ` -
    -
    1. Ziel und Zweck
    -
    -

    Dieses Pflichtenregister dokumentiert alle regulatorischen Pflichten, denen - ${escHtml(orgName)} unterliegt. Es dient der systematischen Erfassung, - Ueberwachung und Nachverfolgung aller Compliance-Anforderungen aus den anwendbaren - Regulierungen.

    -

    Das Register erfuellt folgende Zwecke:

    -
      -
    • Vollstaendige Erfassung aller anwendbaren regulatorischen Pflichten
    • -
    • Zuordnung von Verantwortlichkeiten und Fristen
    • -
    • Nachverfolgung des Umsetzungsstatus
    • -
    • Dokumentation von Nachweisen fuer Audits
    • -
    • Identifikation von Compliance-Luecken und Handlungsbedarf
    • -
    - - - - - - -
    RechtsrahmenRelevanz
    DSGVO (EU) 2016/679Datenschutz-Grundverordnung — Kernregulierung fuer personenbezogene Daten
    AI Act (EU) 2024/1689KI-Verordnung — Anforderungen an KI-Systeme nach Risikoklasse
    NIS2 (EU) 2022/2555Netzwerk- und Informationssicherheit — Cybersicherheitspflichten
    BDSGBundesdatenschutzgesetz — Nationale Ergaenzung zur DSGVO
    -
    -
    -` - - // ========================================================================= - // Section 2: Geltungsbereich - // ========================================================================= - html += ` -
    -
    2. Geltungsbereich
    -
    -

    Dieses Pflichtenregister gilt fuer alle Geschaeftsprozesse und IT-Systeme von - ${escHtml(orgName)}${orgHeader.industry ? ` (Branche: ${escHtml(orgHeader.industry)})` : ''}.

    -

    Anwendbare Regulierungen:

    - - -` - for (const [source, obls] of bySource.entries()) { - const completed = obls.filter(o => o.status === 'completed').length - const pct = obls.length > 0 ? Math.round((completed / obls.length) * 100) : 0 - html += ` - - - - -` - } - html += `
    RegulierungAnzahl PflichtenStatus
    ${escHtml(source)}${obls.length}${completed}/${obls.length} abgeschlossen (${pct}%)
    -

    Insgesamt umfasst dieses Register ${obligations.length} Pflichten aus - ${distinctSources.length} Regulierungen.

    -
    -
    -` - - // ========================================================================= - // Section 3: Methodik - // ========================================================================= - html += ` -
    -
    3. Methodik
    -
    -

    Die Identifikation und Bewertung der Pflichten erfolgt in drei Schritten:

    -
    Pflicht-Identifikation: Systematische Analyse aller anwendbaren Regulierungen und Extraktion der einzelnen Pflichten mit Artikel-Referenz, Beschreibung und Zielgruppe.
    -
    Bewertung und Priorisierung: Jede Pflicht wird nach Prioritaet (kritisch, hoch, mittel, niedrig) und Dringlichkeit (Frist) bewertet. Die Bewertung basiert auf dem Risikopotenzial bei Nichterfuellung.
    -
    Ueberwachung und Nachverfolgung: Regelmaessige Pruefung des Umsetzungsstatus, Aktualisierung der Fristen und Dokumentation von Nachweisen.
    -

    Die Pflichten werden ueber einen automatisierten Compliance-Check geprueft, der - 11 Kriterien umfasst (siehe Abschnitt 10: Compliance-Status).

    -
    -
    -` - - // ========================================================================= - // Section 4: Regulatorische Grundlagen - // ========================================================================= - html += ` -
    -
    4. Regulatorische Grundlagen
    -
    -

    Die folgende Tabelle zeigt die regulatorischen Grundlagen mit Artikelzahl und Umsetzungsstatus:

    - - - - - - - - - - -` - for (const [source, obls] of bySource.entries()) { - const critical = obls.filter(o => o.priority === 'critical').length - const high = obls.filter(o => o.priority === 'high').length - const medium = obls.filter(o => o.priority === 'medium').length - const low = obls.filter(o => o.priority === 'low').length - const completed = obls.filter(o => o.status === 'completed').length - - html += ` - - - - - - - - -` - } - - // Totals row - const totalCritical = obligations.filter(o => o.priority === 'critical').length - const totalHigh = obligations.filter(o => o.priority === 'high').length - const totalMedium = obligations.filter(o => o.priority === 'medium').length - const totalLow = obligations.filter(o => o.priority === 'low').length - const totalCompleted = obligations.filter(o => o.status === 'completed').length - - html += ` - - - - - - - - -` - - html += `
    RegulierungPflichtenKritischHochMittelNiedrigAbgeschlossen
    ${escHtml(source)}${obls.length}${critical}${high}${medium}${low}${completed}
    Gesamt${obligations.length}${totalCritical}${totalHigh}${totalMedium}${totalLow}${totalCompleted}
    -
    -
    -` - - // ========================================================================= - // Section 5: Pflichtenuebersicht - // ========================================================================= - html += ` -
    -
    5. Pflichtenuebersicht
    -
    -

    Uebersicht aller ${obligations.length} Pflichten nach Regulierung und Status:

    - - - - - - - - - -` - for (const [source, obls] of bySource.entries()) { - const pending = obls.filter(o => o.status === 'pending').length - const inProgress = obls.filter(o => o.status === 'in-progress').length - const completed = obls.filter(o => o.status === 'completed').length - const overdue = obls.filter(o => o.status === 'overdue').length - - html += ` - - - - - - - -` - } - - html += `
    RegulierungGesamtAusstehendIn BearbeitungAbgeschlossenUeberfaellig
    ${escHtml(source)}${obls.length}${pending}${inProgress}${completed}${overdue > 0 ? `${overdue}` : '0'}
    -
    -
    -` - - // ========================================================================= - // Section 6: Detaillierte Pflichten - // ========================================================================= - html += ` -
    -
    6. Detaillierte Pflichten
    -
    -` - - for (const [source, obls] of bySource.entries()) { - // Sort by priority (critical first) then by title - const priorityOrder: Record = { critical: 0, high: 1, medium: 2, low: 3 } - const sorted = [...obls].sort((a, b) => { - const pa = priorityOrder[a.priority] ?? 2 - const pb = priorityOrder[b.priority] ?? 2 - if (pa !== pb) return pa - pb - return a.title.localeCompare(b.title) - }) - - html += `

    ${escHtml(source)} (${sorted.length} Pflichten)

    -` - - for (const o of sorted) { - const statusLabel = STATUS_LABELS_DE[o.status] || o.status - const statusBadge = STATUS_BADGE_CLASSES[o.status] || 'badge-draft' - const priorityLabel = PRIORITY_LABELS_DE[o.priority] || o.priority - const priorityBadge = PRIORITY_BADGE_CLASSES[o.priority] || 'badge-draft' - const deadlineStr = o.deadline ? formatDateDE(o.deadline) : '—' - const evidenceStr = o.evidence && o.evidence.length > 0 - ? o.evidence.map(e => escHtml(e)).join(', ') - : 'Kein Nachweis' - const systemsStr = o.linked_systems && o.linked_systems.length > 0 - ? o.linked_systems.map(s => escHtml(s)).join(', ') - : '—' - - html += ` -
    -
    - ${escHtml(o.title)} - ${escHtml(statusLabel)} -
    -
    - - - - - - - - - - ${o.linked_vendor_ids && o.linked_vendor_ids.length > 0 ? `` : ''} - ${o.notes ? `` : ''} -
    Rechtsquelle${escHtml(o.source)} ${escHtml(o.source_article || '')}
    Beschreibung${escHtml(o.description || '—')}
    Prioritaet${escHtml(priorityLabel)}
    Status${escHtml(statusLabel)}
    Verantwortlich${escHtml(o.responsible || '—')}
    Frist${deadlineStr}
    Nachweise${evidenceStr}
    Betroffene Systeme${systemsStr}
    Auftragsverarbeiter${o.linked_vendor_ids.map(id => escHtml(id)).join(', ')}
    Notizen${escHtml(o.notes)}
    -
    -
    -` - } - } - - html += `
    -
    -` - - // ========================================================================= - // Section 7: Verantwortlichkeiten - // ========================================================================= - html += ` -
    -
    7. Verantwortlichkeiten
    -
    -

    Die folgende Rollenmatrix zeigt, welche Personen oder Abteilungen fuer welche Pflichten - die Umsetzungsverantwortung tragen:

    - - -` - for (const [role, obls] of roleMap.entries()) { - const openCount = obls.filter(o => o.status !== 'completed').length - const titles = obls.slice(0, 5).map(o => escHtml(o.title)) - const suffix = obls.length > 5 ? `, ... (+${obls.length - 5})` : '' - html += ` - - - - - -` - } - - html += `
    VerantwortlichPflichtenAnzahlDavon offen
    ${escHtml(role)}${titles.join('; ')}${suffix}${obls.length}${openCount}
    -
    -
    -` - - // ========================================================================= - // Section 8: Fristen und Termine - // ========================================================================= - const now = new Date() - const withDeadline = obligations - .filter(o => o.deadline && o.status !== 'completed') - .sort((a, b) => new Date(a.deadline!).getTime() - new Date(b.deadline!).getTime()) - - const overdue = withDeadline.filter(o => new Date(o.deadline!) < now) - const upcoming = withDeadline.filter(o => new Date(o.deadline!) >= now) - - html += ` -
    -
    8. Fristen und Termine
    -
    -` - if (overdue.length > 0) { - html += `

    Ueberfaellige Pflichten (${overdue.length})

    - - -` - for (const o of overdue) { - const days = daysBetween(new Date(o.deadline!), now) - html += ` - - - - - - -` - } - html += `
    PflichtRegulierungFristTage ueberfaelligPrioritaet
    ${escHtml(o.title)}${escHtml(o.source)}${formatDateDE(o.deadline)}${days} Tage${escHtml(PRIORITY_LABELS_DE[o.priority] || o.priority)}
    -` - } - - if (upcoming.length > 0) { - html += `

    Anstehende Fristen (${upcoming.length})

    - - -` - for (const o of upcoming.slice(0, 20)) { - const days = daysBetween(now, new Date(o.deadline!)) - html += ` - - - - - - -` - } - if (upcoming.length > 20) { - html += ` -` - } - html += `
    PflichtRegulierungFristVerbleibendVerantwortlich
    ${escHtml(o.title)}${escHtml(o.source)}${formatDateDE(o.deadline)}${days} Tage${escHtml(o.responsible || '—')}
    ... und ${upcoming.length - 20} weitere
    -` - } - - if (withDeadline.length === 0) { - html += `

    Keine offenen Pflichten mit Fristen vorhanden.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 9: Nachweisverzeichnis - // ========================================================================= - const withEvidence = obligations.filter(o => o.evidence && o.evidence.length > 0) - const withoutEvidence = obligations.filter(o => !o.evidence || o.evidence.length === 0) - - html += ` -
    -
    9. Nachweisverzeichnis
    -
    -

    ${withEvidence.length} von ${obligations.length} Pflichten haben Nachweise hinterlegt.

    -` - if (withEvidence.length > 0) { - html += ` - -` - for (const o of withEvidence) { - html += ` - - - - - -` - } - html += `
    PflichtRegulierungNachweiseStatus
    ${escHtml(o.title)}${escHtml(o.source)}${o.evidence!.map(e => escHtml(e)).join(', ')}${escHtml(STATUS_LABELS_DE[o.status] || o.status)}
    -` - } - - if (withoutEvidence.length > 0) { - html += `

    Pflichten ohne Nachweise (${withoutEvidence.length}):

    -
      -` - for (const o of withoutEvidence.slice(0, 15)) { - html += `
    • ${escHtml(o.title)} (${escHtml(o.source)})
    • -` - } - if (withoutEvidence.length > 15) { - html += `
    • ... und ${withoutEvidence.length - 15} weitere
    • -` - } - html += `
    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 10: Compliance-Status - // ========================================================================= - html += ` -
    -
    10. Compliance-Status
    -
    -` - if (complianceResult) { - const scoreClass = complianceResult.score >= 90 ? 'score-excellent' - : complianceResult.score >= 75 ? 'score-good' - : complianceResult.score >= 50 ? 'score-needs-work' - : 'score-poor' - const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' - : complianceResult.score >= 75 ? 'Gut' - : complianceResult.score >= 50 ? 'Verbesserungswuerdig' - : 'Mangelhaft' - - html += `

    ${complianceResult.score}/100 ${escHtml(scoreLabel)}

    - - - - - - - - -
    KennzahlWert
    Geprueft am${formatDateDE(complianceResult.checkedAt)}
    Befunde gesamt${complianceResult.summary.total}
    Kritisch${complianceResult.summary.critical}
    Hoch${complianceResult.summary.high}
    Mittel${complianceResult.summary.medium}
    Niedrig${complianceResult.summary.low}
    -` - if (complianceResult.issues.length > 0) { - html += `

    Befunde nach Schweregrad:

    - - -` - const severityOrder: ObligationComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] - for (const sev of severityOrder) { - const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) - for (const issue of issuesForSev) { - html += ` - - - - - -` - } - } - html += `
    SchweregradBefundBetroffene PflichtenEmpfehlung
    ${OBLIGATION_SEVERITY_LABELS_DE[sev]}${escHtml(issue.message)}${issue.affectedObligations.length > 0 ? issue.affectedObligations.length + ' Pflicht(en)' : '—'}${escHtml(issue.recommendation)}
    -` - } else { - html += `

    Keine Beanstandungen. Alle Pflichten sind konform.

    -` - } - } else { - html += `

    Compliance-Check wurde noch nicht ausgefuehrt. Fuehren Sie den Check im - Pflichtenregister-Tab durch, um den Status in das Dokument aufzunehmen.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 11: Aenderungshistorie - // ========================================================================= - html += ` -
    -
    11. Aenderungshistorie
    -
    - - -` - if (revisions.length > 0) { - for (const rev of revisions) { - html += ` - - - - - -` - } - } else { - html += ` - - - - - -` - } - - html += `
    VersionDatumAutorAenderungen
    ${escHtml(rev.version)}${formatDateDE(rev.date)}${escHtml(rev.author)}${escHtml(rev.changes)}
    ${escHtml(orgHeader.documentVersion)}${today}${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '—')}Erstversion des Pflichtenregisters
    -
    -
    -` - - // ========================================================================= - // Footer - // ========================================================================= - html += ` - - - -` - - return html -} - -// ============================================================================= -// INTERNAL HELPERS -// ============================================================================= - -function escHtml(str: string): string { - return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') -} - -function formatDateDE(dateStr: string | null | undefined): string { - if (!dateStr) return '—' - try { - const date = new Date(dateStr) - if (isNaN(date.getTime())) return '—' - return date.toLocaleDateString('de-DE', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }) - } catch { - return '—' - } -} - -function daysBetween(earlier: Date, later: Date): number { - const diffMs = later.getTime() - earlier.getTime() - return Math.floor(diffMs / (1000 * 60 * 60 * 24)) -} +export type { ObligationDocumentOrgHeader, ObligationDocumentRevision } from './obligations-document/types-defaults' +export { createDefaultObligationDocumentOrgHeader } from './obligations-document/types-defaults' +export { buildObligationDocumentHtml } from './obligations-document/html-builder' diff --git a/admin-compliance/lib/sdk/obligations-document/helpers.ts b/admin-compliance/lib/sdk/obligations-document/helpers.ts new file mode 100644 index 0000000..e407328 --- /dev/null +++ b/admin-compliance/lib/sdk/obligations-document/helpers.ts @@ -0,0 +1,31 @@ +// ============================================================================= +// Obligations Document — Internal Helpers +// ============================================================================= + +export function escHtml(str: string): string { + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') +} + +export function formatDateDE(dateStr: string | null | undefined): string { + if (!dateStr) return '—' + try { + const date = new Date(dateStr) + if (isNaN(date.getTime())) return '—' + return date.toLocaleDateString('de-DE', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }) + } catch { + return '—' + } +} + +export function daysBetween(earlier: Date, later: Date): number { + const diffMs = later.getTime() - earlier.getTime() + return Math.floor(diffMs / (1000 * 60 * 60 * 24)) +} diff --git a/admin-compliance/lib/sdk/obligations-document/html-builder.ts b/admin-compliance/lib/sdk/obligations-document/html-builder.ts new file mode 100644 index 0000000..eac02f7 --- /dev/null +++ b/admin-compliance/lib/sdk/obligations-document/html-builder.ts @@ -0,0 +1,620 @@ +// ============================================================================= +// Obligations Document — HTML Document Builder +// ============================================================================= + +import type { Obligation, ObligationComplianceCheckResult, ObligationComplianceIssueSeverity } from '../obligations-compliance' +import { OBLIGATION_SEVERITY_LABELS_DE, OBLIGATION_SEVERITY_COLORS } from '../obligations-compliance' +import type { ObligationDocumentOrgHeader, ObligationDocumentRevision } from './types-defaults' +import { + STATUS_LABELS_DE, + STATUS_BADGE_CLASSES, + PRIORITY_LABELS_DE, + PRIORITY_BADGE_CLASSES, +} from './types-defaults' +import { escHtml, formatDateDE, daysBetween } from './helpers' +import { getDocumentStyles } from './html-styles' + +export function buildObligationDocumentHtml( + obligations: Obligation[], + orgHeader: ObligationDocumentOrgHeader, + complianceResult: ObligationComplianceCheckResult | null, + revisions: ObligationDocumentRevision[] +): string { + const today = new Date().toLocaleDateString('de-DE', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }) + + const orgName = orgHeader.organizationName || 'Organisation' + + // Group obligations by source (regulation) + const bySource = new Map() + for (const o of obligations) { + const src = o.source || 'Sonstig' + if (!bySource.has(src)) bySource.set(src, []) + bySource.get(src)!.push(o) + } + + // Build role map + const roleMap = new Map() + for (const o of obligations) { + const role = o.responsible || 'Nicht zugewiesen' + if (!roleMap.has(role)) roleMap.set(role, []) + roleMap.get(role)!.push(o) + } + + const distinctSources = Array.from(bySource.keys()).sort() + + let html = getDocumentStyles(`Pflichtenregister — ${escHtml(orgName)}`) + + html += buildCoverPage(orgHeader, orgName, today) + html += buildTOC() + html += buildSection1(orgName) + html += buildSection2(orgName, orgHeader, bySource, obligations, distinctSources) + html += buildSection3() + html += buildSection4(bySource, obligations) + html += buildSection5(bySource) + html += buildSection6(bySource) + html += buildSection7(roleMap) + html += buildSection8(obligations, today) + html += buildSection9(obligations) + html += buildSection10(complianceResult) + html += buildSection11(revisions, orgHeader, today) + html += buildFooter(orgName, today, orgHeader.documentVersion) + + return html +} + +function buildCoverPage( + orgHeader: ObligationDocumentOrgHeader, + orgName: string, + today: string +): string { + return ` +
    +

    Pflichtenregister

    +
    Regulatorische Pflichten — DSGVO, AI Act, NIS2 und weitere
    +
    +
    Organisation: ${escHtml(orgName)}
    + ${orgHeader.industry ? `
    Branche: ${escHtml(orgHeader.industry)}
    ` : ''} + ${orgHeader.dpoName ? `
    DSB: ${escHtml(orgHeader.dpoName)}
    ` : ''} + ${orgHeader.dpoContact ? `
    DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
    ` : ''} + ${orgHeader.responsiblePerson ? `
    Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
    ` : ''} + ${orgHeader.legalDepartment ? `
    Rechtsabteilung: ${escHtml(orgHeader.legalDepartment)}
    ` : ''} +
    + +
    +` +} + +function buildTOC(): string { + const sections = [ + 'Ziel und Zweck', + 'Geltungsbereich', + 'Methodik', + 'Regulatorische Grundlagen', + 'Pflichtenuebersicht', + 'Detaillierte Pflichten', + 'Verantwortlichkeiten', + 'Fristen und Termine', + 'Nachweisverzeichnis', + 'Compliance-Status', + 'Aenderungshistorie', + ] + + return ` +
    +

    Inhaltsverzeichnis

    + ${sections.map((s, i) => `
    ${i + 1}. ${escHtml(s)}
    `).join('\n ')} +
    +` +} + +function buildSection1(orgName: string): string { + return ` +
    +
    1. Ziel und Zweck
    +
    +

    Dieses Pflichtenregister dokumentiert alle regulatorischen Pflichten, denen + ${escHtml(orgName)} unterliegt. Es dient der systematischen Erfassung, + Ueberwachung und Nachverfolgung aller Compliance-Anforderungen aus den anwendbaren + Regulierungen.

    +

    Das Register erfuellt folgende Zwecke:

    +
      +
    • Vollstaendige Erfassung aller anwendbaren regulatorischen Pflichten
    • +
    • Zuordnung von Verantwortlichkeiten und Fristen
    • +
    • Nachverfolgung des Umsetzungsstatus
    • +
    • Dokumentation von Nachweisen fuer Audits
    • +
    • Identifikation von Compliance-Luecken und Handlungsbedarf
    • +
    + + + + + + +
    RechtsrahmenRelevanz
    DSGVO (EU) 2016/679Datenschutz-Grundverordnung — Kernregulierung fuer personenbezogene Daten
    AI Act (EU) 2024/1689KI-Verordnung — Anforderungen an KI-Systeme nach Risikoklasse
    NIS2 (EU) 2022/2555Netzwerk- und Informationssicherheit — Cybersicherheitspflichten
    BDSGBundesdatenschutzgesetz — Nationale Ergaenzung zur DSGVO
    +
    +
    +` +} + +function buildSection2( + orgName: string, + orgHeader: ObligationDocumentOrgHeader, + bySource: Map, + obligations: Obligation[], + distinctSources: string[] +): string { + let html = ` +
    +
    2. Geltungsbereich
    +
    +

    Dieses Pflichtenregister gilt fuer alle Geschaeftsprozesse und IT-Systeme von + ${escHtml(orgName)}${orgHeader.industry ? ` (Branche: ${escHtml(orgHeader.industry)})` : ''}.

    +

    Anwendbare Regulierungen:

    + + +` + for (const [source, obls] of bySource.entries()) { + const completed = obls.filter(o => o.status === 'completed').length + const pct = obls.length > 0 ? Math.round((completed / obls.length) * 100) : 0 + html += ` + + + + +` + } + html += `
    RegulierungAnzahl PflichtenStatus
    ${escHtml(source)}${obls.length}${completed}/${obls.length} abgeschlossen (${pct}%)
    +

    Insgesamt umfasst dieses Register ${obligations.length} Pflichten aus + ${distinctSources.length} Regulierungen.

    +
    +
    +` + return html +} + +function buildSection3(): string { + return ` +
    +
    3. Methodik
    +
    +

    Die Identifikation und Bewertung der Pflichten erfolgt in drei Schritten:

    +
    Pflicht-Identifikation: Systematische Analyse aller anwendbaren Regulierungen und Extraktion der einzelnen Pflichten mit Artikel-Referenz, Beschreibung und Zielgruppe.
    +
    Bewertung und Priorisierung: Jede Pflicht wird nach Prioritaet (kritisch, hoch, mittel, niedrig) und Dringlichkeit (Frist) bewertet. Die Bewertung basiert auf dem Risikopotenzial bei Nichterfuellung.
    +
    Ueberwachung und Nachverfolgung: Regelmaessige Pruefung des Umsetzungsstatus, Aktualisierung der Fristen und Dokumentation von Nachweisen.
    +

    Die Pflichten werden ueber einen automatisierten Compliance-Check geprueft, der + 11 Kriterien umfasst (siehe Abschnitt 10: Compliance-Status).

    +
    +
    +` +} + +function buildSection4(bySource: Map, obligations: Obligation[]): string { + const totalCritical = obligations.filter(o => o.priority === 'critical').length + const totalHigh = obligations.filter(o => o.priority === 'high').length + const totalMedium = obligations.filter(o => o.priority === 'medium').length + const totalLow = obligations.filter(o => o.priority === 'low').length + const totalCompleted = obligations.filter(o => o.status === 'completed').length + + let html = ` +
    +
    4. Regulatorische Grundlagen
    +
    +

    Die folgende Tabelle zeigt die regulatorischen Grundlagen mit Artikelzahl und Umsetzungsstatus:

    + + + + + + + + + + +` + for (const [source, obls] of bySource.entries()) { + const critical = obls.filter(o => o.priority === 'critical').length + const high = obls.filter(o => o.priority === 'high').length + const medium = obls.filter(o => o.priority === 'medium').length + const low = obls.filter(o => o.priority === 'low').length + const completed = obls.filter(o => o.status === 'completed').length + + html += ` + + + + + + + + +` + } + + html += ` + + + + + + + + +
    RegulierungPflichtenKritischHochMittelNiedrigAbgeschlossen
    ${escHtml(source)}${obls.length}${critical}${high}${medium}${low}${completed}
    Gesamt${obligations.length}${totalCritical}${totalHigh}${totalMedium}${totalLow}${totalCompleted}
    +
    +
    +` + return html +} + +function buildSection5(bySource: Map): string { + let html = ` +
    +
    5. Pflichtenuebersicht
    +
    +

    Uebersicht aller Pflichten nach Regulierung und Status:

    + + + + + + + + + +` + for (const [source, obls] of bySource.entries()) { + const pending = obls.filter(o => o.status === 'pending').length + const inProgress = obls.filter(o => o.status === 'in-progress').length + const completed = obls.filter(o => o.status === 'completed').length + const overdue = obls.filter(o => o.status === 'overdue').length + + html += ` + + + + + + + +` + } + + html += `
    RegulierungGesamtAusstehendIn BearbeitungAbgeschlossenUeberfaellig
    ${escHtml(source)}${obls.length}${pending}${inProgress}${completed}${overdue > 0 ? `${overdue}` : '0'}
    +
    +
    +` + return html +} + +function buildSection6(bySource: Map): string { + const priorityOrder: Record = { critical: 0, high: 1, medium: 2, low: 3 } + + let html = ` +
    +
    6. Detaillierte Pflichten
    +
    +` + + for (const [source, obls] of bySource.entries()) { + const sorted = [...obls].sort((a, b) => { + const pa = priorityOrder[a.priority] ?? 2 + const pb = priorityOrder[b.priority] ?? 2 + if (pa !== pb) return pa - pb + return a.title.localeCompare(b.title) + }) + + html += `

    ${escHtml(source)} (${sorted.length} Pflichten)

    +` + + for (const o of sorted) { + const statusLabel = STATUS_LABELS_DE[o.status] || o.status + const statusBadge = STATUS_BADGE_CLASSES[o.status] || 'badge-draft' + const priorityLabel = PRIORITY_LABELS_DE[o.priority] || o.priority + const priorityBadge = PRIORITY_BADGE_CLASSES[o.priority] || 'badge-draft' + const deadlineStr = o.deadline ? formatDateDE(o.deadline) : '—' + const evidenceStr = o.evidence && o.evidence.length > 0 + ? o.evidence.map(e => escHtml(e)).join(', ') + : 'Kein Nachweis' + const systemsStr = o.linked_systems && o.linked_systems.length > 0 + ? o.linked_systems.map(s => escHtml(s)).join(', ') + : '—' + + html += ` +
    +
    + ${escHtml(o.title)} + ${escHtml(statusLabel)} +
    +
    + + + + + + + + + + ${o.linked_vendor_ids && o.linked_vendor_ids.length > 0 ? `` : ''} + ${o.notes ? `` : ''} +
    Rechtsquelle${escHtml(o.source)} ${escHtml(o.source_article || '')}
    Beschreibung${escHtml(o.description || '—')}
    Prioritaet${escHtml(priorityLabel)}
    Status${escHtml(statusLabel)}
    Verantwortlich${escHtml(o.responsible || '—')}
    Frist${deadlineStr}
    Nachweise${evidenceStr}
    Betroffene Systeme${systemsStr}
    Auftragsverarbeiter${o.linked_vendor_ids.map(id => escHtml(id)).join(', ')}
    Notizen${escHtml(o.notes)}
    +
    +
    +` + } + } + + html += `
    +
    +` + return html +} + +function buildSection7(roleMap: Map): string { + let html = ` +
    +
    7. Verantwortlichkeiten
    +
    +

    Die folgende Rollenmatrix zeigt, welche Personen oder Abteilungen fuer welche Pflichten + die Umsetzungsverantwortung tragen:

    + + +` + for (const [role, obls] of roleMap.entries()) { + const openCount = obls.filter(o => o.status !== 'completed').length + const titles = obls.slice(0, 5).map(o => escHtml(o.title)) + const suffix = obls.length > 5 ? `, ... (+${obls.length - 5})` : '' + html += ` + + + + + +` + } + + html += `
    VerantwortlichPflichtenAnzahlDavon offen
    ${escHtml(role)}${titles.join('; ')}${suffix}${obls.length}${openCount}
    +
    +
    +` + return html +} + +function buildSection8(obligations: Obligation[], _today: string): string { + const now = new Date() + const withDeadline = obligations + .filter(o => o.deadline && o.status !== 'completed') + .sort((a, b) => new Date(a.deadline!).getTime() - new Date(b.deadline!).getTime()) + + const overdue = withDeadline.filter(o => new Date(o.deadline!) < now) + const upcoming = withDeadline.filter(o => new Date(o.deadline!) >= now) + + let html = ` +
    +
    8. Fristen und Termine
    +
    +` + if (overdue.length > 0) { + html += `

    Ueberfaellige Pflichten (${overdue.length})

    + + +` + for (const o of overdue) { + const days = daysBetween(new Date(o.deadline!), now) + html += ` + + + + + + +` + } + html += `
    PflichtRegulierungFristTage ueberfaelligPrioritaet
    ${escHtml(o.title)}${escHtml(o.source)}${formatDateDE(o.deadline)}${days} Tage${escHtml(PRIORITY_LABELS_DE[o.priority] || o.priority)}
    +` + } + + if (upcoming.length > 0) { + html += `

    Anstehende Fristen (${upcoming.length})

    + + +` + for (const o of upcoming.slice(0, 20)) { + const days = daysBetween(now, new Date(o.deadline!)) + html += ` + + + + + + +` + } + if (upcoming.length > 20) { + html += ` +` + } + html += `
    PflichtRegulierungFristVerbleibendVerantwortlich
    ${escHtml(o.title)}${escHtml(o.source)}${formatDateDE(o.deadline)}${days} Tage${escHtml(o.responsible || '—')}
    ... und ${upcoming.length - 20} weitere
    +` + } + + if (withDeadline.length === 0) { + html += `

    Keine offenen Pflichten mit Fristen vorhanden.

    +` + } + + html += `
    +
    +` + return html +} + +function buildSection9(obligations: Obligation[]): string { + const withEvidence = obligations.filter(o => o.evidence && o.evidence.length > 0) + const withoutEvidence = obligations.filter(o => !o.evidence || o.evidence.length === 0) + + let html = ` +
    +
    9. Nachweisverzeichnis
    +
    +

    ${withEvidence.length} von ${obligations.length} Pflichten haben Nachweise hinterlegt.

    +` + if (withEvidence.length > 0) { + html += ` + +` + for (const o of withEvidence) { + html += ` + + + + + +` + } + html += `
    PflichtRegulierungNachweiseStatus
    ${escHtml(o.title)}${escHtml(o.source)}${o.evidence!.map(e => escHtml(e)).join(', ')}${escHtml(STATUS_LABELS_DE[o.status] || o.status)}
    +` + } + + if (withoutEvidence.length > 0) { + html += `

    Pflichten ohne Nachweise (${withoutEvidence.length}):

    +
      +` + for (const o of withoutEvidence.slice(0, 15)) { + html += `
    • ${escHtml(o.title)} (${escHtml(o.source)})
    • +` + } + if (withoutEvidence.length > 15) { + html += `
    • ... und ${withoutEvidence.length - 15} weitere
    • +` + } + html += `
    +` + } + + html += `
    +
    +` + return html +} + +function buildSection10(complianceResult: ObligationComplianceCheckResult | null): string { + let html = ` +
    +
    10. Compliance-Status
    +
    +` + if (complianceResult) { + const scoreClass = complianceResult.score >= 90 ? 'score-excellent' + : complianceResult.score >= 75 ? 'score-good' + : complianceResult.score >= 50 ? 'score-needs-work' + : 'score-poor' + const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' + : complianceResult.score >= 75 ? 'Gut' + : complianceResult.score >= 50 ? 'Verbesserungswuerdig' + : 'Mangelhaft' + + html += `

    ${complianceResult.score}/100 ${escHtml(scoreLabel)}

    + + + + + + + + +
    KennzahlWert
    Geprueft am${formatDateDE(complianceResult.checkedAt)}
    Befunde gesamt${complianceResult.summary.total}
    Kritisch${complianceResult.summary.critical}
    Hoch${complianceResult.summary.high}
    Mittel${complianceResult.summary.medium}
    Niedrig${complianceResult.summary.low}
    +` + if (complianceResult.issues.length > 0) { + html += `

    Befunde nach Schweregrad:

    + + +` + const severityOrder: ObligationComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] + for (const sev of severityOrder) { + const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) + for (const issue of issuesForSev) { + html += ` + + + + + +` + } + } + html += `
    SchweregradBefundBetroffene PflichtenEmpfehlung
    ${OBLIGATION_SEVERITY_LABELS_DE[sev]}${escHtml(issue.message)}${issue.affectedObligations.length > 0 ? issue.affectedObligations.length + ' Pflicht(en)' : '—'}${escHtml(issue.recommendation)}
    +` + } else { + html += `

    Keine Beanstandungen. Alle Pflichten sind konform.

    +` + } + } else { + html += `

    Compliance-Check wurde noch nicht ausgefuehrt. Fuehren Sie den Check im + Pflichtenregister-Tab durch, um den Status in das Dokument aufzunehmen.

    +` + } + + html += `
    +
    +` + return html +} + +function buildSection11( + revisions: ObligationDocumentRevision[], + orgHeader: ObligationDocumentOrgHeader, + today: string +): string { + let html = ` +
    +
    11. Aenderungshistorie
    +
    + + +` + if (revisions.length > 0) { + for (const rev of revisions) { + html += ` + + + + + +` + } + } else { + html += ` + + + + + +` + } + + html += `
    VersionDatumAutorAenderungen
    ${escHtml(rev.version)}${formatDateDE(rev.date)}${escHtml(rev.author)}${escHtml(rev.changes)}
    ${escHtml(orgHeader.documentVersion)}${today}${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '—')}Erstversion des Pflichtenregisters
    +
    +
    +` + return html +} + +function buildFooter(orgName: string, today: string, version: string): string { + return ` + + + +` +} diff --git a/admin-compliance/lib/sdk/obligations-document/html-sections-1-5.ts b/admin-compliance/lib/sdk/obligations-document/html-sections-1-5.ts new file mode 100644 index 0000000..ea81de3 --- /dev/null +++ b/admin-compliance/lib/sdk/obligations-document/html-sections-1-5.ts @@ -0,0 +1,207 @@ +// ============================================================================= +// Obligations Document — HTML Sections 1–5 (cover, TOC, purpose, scope, method, sources, overview) +// ============================================================================= + +import type { Obligation } from '../obligations-compliance' +import type { ObligationDocumentOrgHeader } from './types-defaults' +import { escHtml, formatDateDE } from './helpers' + +export function buildCoverPage( + orgHeader: ObligationDocumentOrgHeader, + orgName: string, + today: string +): string { + return ` +
    +

    Pflichtenregister

    +
    Regulatorische Pflichten — DSGVO, AI Act, NIS2 und weitere
    +
    +
    Organisation: ${escHtml(orgName)}
    + ${orgHeader.industry ? `
    Branche: ${escHtml(orgHeader.industry)}
    ` : ''} + ${orgHeader.dpoName ? `
    DSB: ${escHtml(orgHeader.dpoName)}
    ` : ''} + ${orgHeader.dpoContact ? `
    DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
    ` : ''} + ${orgHeader.responsiblePerson ? `
    Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
    ` : ''} + ${orgHeader.legalDepartment ? `
    Rechtsabteilung: ${escHtml(orgHeader.legalDepartment)}
    ` : ''} +
    + +
    +` +} + +export function buildTOC(): string { + const sections = [ + 'Ziel und Zweck', 'Geltungsbereich', 'Methodik', 'Regulatorische Grundlagen', + 'Pflichtenuebersicht', 'Detaillierte Pflichten', 'Verantwortlichkeiten', + 'Fristen und Termine', 'Nachweisverzeichnis', 'Compliance-Status', 'Aenderungshistorie', + ] + + return ` +
    +

    Inhaltsverzeichnis

    + ${sections.map((s, i) => `
    ${i + 1}. ${escHtml(s)}
    `).join('\n ')} +
    +` +} + +export function buildSection1(orgName: string): string { + return ` +
    +
    1. Ziel und Zweck
    +
    +

    Dieses Pflichtenregister dokumentiert alle regulatorischen Pflichten, denen + ${escHtml(orgName)} unterliegt. Es dient der systematischen Erfassung, + Ueberwachung und Nachverfolgung aller Compliance-Anforderungen aus den anwendbaren + Regulierungen.

    +

    Das Register erfuellt folgende Zwecke:

    +
      +
    • Vollstaendige Erfassung aller anwendbaren regulatorischen Pflichten
    • +
    • Zuordnung von Verantwortlichkeiten und Fristen
    • +
    • Nachverfolgung des Umsetzungsstatus
    • +
    • Dokumentation von Nachweisen fuer Audits
    • +
    • Identifikation von Compliance-Luecken und Handlungsbedarf
    • +
    + + + + + + +
    RechtsrahmenRelevanz
    DSGVO (EU) 2016/679Datenschutz-Grundverordnung — Kernregulierung fuer personenbezogene Daten
    AI Act (EU) 2024/1689KI-Verordnung — Anforderungen an KI-Systeme nach Risikoklasse
    NIS2 (EU) 2022/2555Netzwerk- und Informationssicherheit — Cybersicherheitspflichten
    BDSGBundesdatenschutzgesetz — Nationale Ergaenzung zur DSGVO
    +
    +
    +` +} + +export function buildSection2( + orgName: string, + orgHeader: ObligationDocumentOrgHeader, + bySource: Map, + obligations: Obligation[], + distinctSources: string[] +): string { + let html = ` +
    +
    2. Geltungsbereich
    +
    +

    Dieses Pflichtenregister gilt fuer alle Geschaeftsprozesse und IT-Systeme von + ${escHtml(orgName)}${orgHeader.industry ? ` (Branche: ${escHtml(orgHeader.industry)})` : ''}.

    +

    Anwendbare Regulierungen:

    + + +` + for (const [source, obls] of bySource.entries()) { + const completed = obls.filter(o => o.status === 'completed').length + const pct = obls.length > 0 ? Math.round((completed / obls.length) * 100) : 0 + html += ` + + + + +` + } + html += `
    RegulierungAnzahl PflichtenStatus
    ${escHtml(source)}${obls.length}${completed}/${obls.length} abgeschlossen (${pct}%)
    +

    Insgesamt umfasst dieses Register ${obligations.length} Pflichten aus + ${distinctSources.length} Regulierungen.

    +
    +
    +` + return html +} + +export function buildSection3(): string { + return ` +
    +
    3. Methodik
    +
    +

    Die Identifikation und Bewertung der Pflichten erfolgt in drei Schritten:

    +
    Pflicht-Identifikation: Systematische Analyse aller anwendbaren Regulierungen und Extraktion der einzelnen Pflichten mit Artikel-Referenz, Beschreibung und Zielgruppe.
    +
    Bewertung und Priorisierung: Jede Pflicht wird nach Prioritaet (kritisch, hoch, mittel, niedrig) und Dringlichkeit (Frist) bewertet. Die Bewertung basiert auf dem Risikopotenzial bei Nichterfuellung.
    +
    Ueberwachung und Nachverfolgung: Regelmaessige Pruefung des Umsetzungsstatus, Aktualisierung der Fristen und Dokumentation von Nachweisen.
    +

    Die Pflichten werden ueber einen automatisierten Compliance-Check geprueft, der + 11 Kriterien umfasst (siehe Abschnitt 10: Compliance-Status).

    +
    +
    +` +} + +export function buildSection4(bySource: Map, obligations: Obligation[]): string { + const totalCritical = obligations.filter(o => o.priority === 'critical').length + const totalHigh = obligations.filter(o => o.priority === 'high').length + const totalMedium = obligations.filter(o => o.priority === 'medium').length + const totalLow = obligations.filter(o => o.priority === 'low').length + const totalCompleted = obligations.filter(o => o.status === 'completed').length + + let html = ` +
    +
    4. Regulatorische Grundlagen
    +
    +

    Die folgende Tabelle zeigt die regulatorischen Grundlagen mit Artikelzahl und Umsetzungsstatus:

    + + + + + +` + for (const [source, obls] of bySource.entries()) { + const critical = obls.filter(o => o.priority === 'critical').length + const high = obls.filter(o => o.priority === 'high').length + const medium = obls.filter(o => o.priority === 'medium').length + const low = obls.filter(o => o.priority === 'low').length + const completed = obls.filter(o => o.status === 'completed').length + + html += ` + + + + +` + } + + html += ` + + + + +
    RegulierungPflichtenKritischHochMittelNiedrigAbgeschlossen
    ${escHtml(source)}${obls.length}${critical}${high}${medium}${low}${completed}
    Gesamt${obligations.length}${totalCritical}${totalHigh}${totalMedium}${totalLow}${totalCompleted}
    +
    +
    +` + return html +} + +export function buildSection5(bySource: Map): string { + let html = ` +
    +
    5. Pflichtenuebersicht
    +
    +

    Uebersicht aller Pflichten nach Regulierung und Status:

    + + + + + +` + for (const [source, obls] of bySource.entries()) { + const pending = obls.filter(o => o.status === 'pending').length + const inProgress = obls.filter(o => o.status === 'in-progress').length + const completed = obls.filter(o => o.status === 'completed').length + const overdue = obls.filter(o => o.status === 'overdue').length + + html += ` + + + + +` + } + + html += `
    RegulierungGesamtAusstehendIn BearbeitungAbgeschlossenUeberfaellig
    ${escHtml(source)}${obls.length}${pending}${inProgress}${completed}${overdue > 0 ? `${overdue}` : '0'}
    +
    +
    +` + return html +} diff --git a/admin-compliance/lib/sdk/obligations-document/html-styles.ts b/admin-compliance/lib/sdk/obligations-document/html-styles.ts new file mode 100644 index 0000000..69742e5 --- /dev/null +++ b/admin-compliance/lib/sdk/obligations-document/html-styles.ts @@ -0,0 +1,211 @@ +// ============================================================================= +// Obligations Document — Shared HTML/CSS Styles +// ============================================================================= + +export function getDocumentStyles(title: string): string { + return ` + + + +${title} + + + +` +} diff --git a/admin-compliance/lib/sdk/obligations-document/types-defaults.ts b/admin-compliance/lib/sdk/obligations-document/types-defaults.ts new file mode 100644 index 0000000..dea008f --- /dev/null +++ b/admin-compliance/lib/sdk/obligations-document/types-defaults.ts @@ -0,0 +1,70 @@ +// ============================================================================= +// Obligations Document — Types, Defaults & Status/Priority Labels +// ============================================================================= + +export interface ObligationDocumentOrgHeader { + organizationName: string + industry: string + dpoName: string + dpoContact: string + responsiblePerson: string + legalDepartment: string + documentVersion: string + lastReviewDate: string + nextReviewDate: string + reviewInterval: string +} + +export interface ObligationDocumentRevision { + version: string + date: string + author: string + changes: string +} + +export function createDefaultObligationDocumentOrgHeader(): ObligationDocumentOrgHeader { + const now = new Date() + const nextYear = new Date() + nextYear.setFullYear(nextYear.getFullYear() + 1) + + return { + organizationName: '', + industry: '', + dpoName: '', + dpoContact: '', + responsiblePerson: '', + legalDepartment: '', + documentVersion: '1.0', + lastReviewDate: now.toISOString().split('T')[0], + nextReviewDate: nextYear.toISOString().split('T')[0], + reviewInterval: 'Jaehrlich', + } +} + +export const STATUS_LABELS_DE: Record = { + 'pending': 'Ausstehend', + 'in-progress': 'In Bearbeitung', + 'completed': 'Abgeschlossen', + 'overdue': 'Ueberfaellig', +} + +export const STATUS_BADGE_CLASSES: Record = { + 'pending': 'badge-draft', + 'in-progress': 'badge-review', + 'completed': 'badge-active', + 'overdue': 'badge-critical', +} + +export const PRIORITY_LABELS_DE: Record = { + critical: 'Kritisch', + high: 'Hoch', + medium: 'Mittel', + low: 'Niedrig', +} + +export const PRIORITY_BADGE_CLASSES: Record = { + critical: 'badge-critical', + high: 'badge-high', + medium: 'badge-medium', + low: 'badge-low', +} diff --git a/admin-compliance/lib/sdk/tom-compliance-checks.ts b/admin-compliance/lib/sdk/tom-compliance-checks.ts new file mode 100644 index 0000000..437f5ca --- /dev/null +++ b/admin-compliance/lib/sdk/tom-compliance-checks.ts @@ -0,0 +1,328 @@ +// ============================================================================= +// TOM Compliance Checks — Per-TOM and Aggregate checks +// +// Barrel-split from tom-compliance.ts. Do NOT import directly; use tom-compliance.ts. +// ============================================================================= + +import type { + TOMGeneratorState, + DerivedTOM, + RiskProfile, + DataProfile, + ControlCategory, +} from './tom-generator/types' + +import { getControlById } from './tom-generator/controls/loader' +import { SDM_CATEGORY_MAPPING } from './tom-generator/types' +import type { TOMComplianceIssue, TOMComplianceIssueType, TOMComplianceIssueSeverity } from './tom-compliance' + +// ============================================================================= +// HELPERS +// ============================================================================= + +let issueCounter = 0 + +export function resetIssueCounter(): void { + issueCounter = 0 +} + +export function createIssue( + controlId: string, + controlName: string, + type: TOMComplianceIssueType, + severity: TOMComplianceIssueSeverity, + title: string, + description: string, + recommendation: string +): TOMComplianceIssue { + issueCounter++ + const id = `TCI-${Date.now()}-${String(issueCounter).padStart(4, '0')}` + return { id, controlId, controlName, type, severity, title, description, recommendation } +} + +function daysBetween(date: Date, now: Date): number { + const diffMs = now.getTime() - date.getTime() + return Math.floor(diffMs / (1000 * 60 * 60 * 24)) +} + +// ============================================================================= +// PER-TOM CHECKS (1-3, 11) +// ============================================================================= + +/** + * Check 1: MISSING_RESPONSIBLE (MEDIUM) + */ +export function checkMissingResponsible(tom: DerivedTOM): TOMComplianceIssue | null { + if (tom.applicability !== 'REQUIRED') return null + + if (!tom.responsiblePerson && !tom.responsibleDepartment) { + return createIssue( + tom.controlId, tom.name, 'MISSING_RESPONSIBLE', 'MEDIUM', + 'Keine verantwortliche Person/Abteilung', + `Die TOM "${tom.name}" ist als REQUIRED eingestuft, hat aber weder eine verantwortliche Person noch eine verantwortliche Abteilung zugewiesen. Ohne klare Verantwortlichkeit kann die Massnahme nicht zuverlaessig umgesetzt und gepflegt werden.`, + 'Weisen Sie eine verantwortliche Person oder Abteilung zu, die fuer die Umsetzung und regelmaessige Pruefung dieser Massnahme zustaendig ist.' + ) + } + + return null +} + +/** + * Check 2: OVERDUE_REVIEW (MEDIUM) + */ +export function checkOverdueReview(tom: DerivedTOM): TOMComplianceIssue | null { + if (!tom.reviewDate) return null + + const reviewDate = new Date(tom.reviewDate) + const now = new Date() + + if (reviewDate < now) { + const overdueDays = daysBetween(reviewDate, now) + return createIssue( + tom.controlId, tom.name, 'OVERDUE_REVIEW', 'MEDIUM', + 'Ueberfaellige Pruefung', + `Die TOM "${tom.name}" haette am ${reviewDate.toLocaleDateString('de-DE')} geprueft werden muessen. Die Pruefung ist ${overdueDays} Tag(e) ueberfaellig. Gemaess Art. 32 Abs. 1 lit. d DSGVO ist eine regelmaessige Ueberpruefung der Wirksamkeit von TOMs erforderlich.`, + 'Fuehren Sie umgehend eine Wirksamkeitspruefung dieser Massnahme durch und aktualisieren Sie das naechste Pruefungsdatum.' + ) + } + + return null +} + +/** + * Check 3: MISSING_EVIDENCE (HIGH) + */ +export function checkMissingEvidence(tom: DerivedTOM): TOMComplianceIssue | null { + if (tom.implementationStatus !== 'IMPLEMENTED') return null + if (tom.linkedEvidence.length > 0) return null + + const control = getControlById(tom.controlId) + if (!control || control.evidenceRequirements.length === 0) return null + + return createIssue( + tom.controlId, tom.name, 'MISSING_EVIDENCE', 'HIGH', + 'Kein Nachweis hinterlegt', + `Die TOM "${tom.name}" ist als IMPLEMENTED markiert, hat aber keine verknuepften Nachweisdokumente. Der Control erfordert ${control.evidenceRequirements.length} Nachweis(e): ${control.evidenceRequirements.join(', ')}. Ohne Nachweise ist die Umsetzung nicht auditfaehig.`, + 'Laden Sie die erforderlichen Nachweisdokumente hoch und verknuepfen Sie sie mit dieser Massnahme.' + ) +} + +/** + * Check 11: STALE_NOT_IMPLEMENTED (LOW) + */ +export function checkStaleNotImplemented(tom: DerivedTOM, state: TOMGeneratorState): TOMComplianceIssue | null { + if (tom.applicability !== 'REQUIRED') return null + if (tom.implementationStatus !== 'NOT_IMPLEMENTED') return null + if (tom.implementationDate !== null) return null + + const referenceDate = state.createdAt ? new Date(state.createdAt) : (state.updatedAt ? new Date(state.updatedAt) : null) + if (!referenceDate) return null + + const ageInDays = daysBetween(referenceDate, new Date()) + if (ageInDays <= 90) return null + + return createIssue( + tom.controlId, tom.name, 'STALE_NOT_IMPLEMENTED', 'LOW', + 'Langfristig nicht umgesetzte Pflichtmassnahme', + `Die TOM "${tom.name}" ist als REQUIRED eingestuft, aber seit ${ageInDays} Tagen nicht umgesetzt. Pflichtmassnahmen, die laenger als 90 Tage nicht implementiert werden, deuten auf organisatorische Blockaden oder unzureichende Priorisierung hin.`, + 'Pruefen Sie, ob die Massnahme weiterhin erforderlich ist, und erstellen Sie einen konkreten Umsetzungsplan mit Verantwortlichkeiten und Fristen.' + ) +} + +// ============================================================================= +// AGGREGATE CHECKS (4-10) +// ============================================================================= + +/** + * Check 4: INCOMPLETE_CATEGORY (HIGH) + */ +export function checkIncompleteCategory(toms: DerivedTOM[]): TOMComplianceIssue[] { + const issues: TOMComplianceIssue[] = [] + const categoryMap = new Map() + + for (const tom of toms) { + const control = getControlById(tom.controlId) + if (!control) continue + const category = control.category + if (!categoryMap.has(category)) categoryMap.set(category, []) + categoryMap.get(category)!.push(tom) + } + + for (const [category, categoryToms] of Array.from(categoryMap.entries())) { + const requiredToms = categoryToms.filter((t: DerivedTOM) => t.applicability === 'REQUIRED') + if (requiredToms.length === 0) continue + + const allNotImplemented = requiredToms.every((t: DerivedTOM) => t.implementationStatus === 'NOT_IMPLEMENTED') + if (allNotImplemented) { + issues.push(createIssue( + category, category, 'INCOMPLETE_CATEGORY', 'HIGH', + `Kategorie "${category}" vollstaendig ohne Umsetzung`, + `Alle ${requiredToms.length} Pflichtmassnahme(n) in der Kategorie "${category}" sind nicht umgesetzt. Eine vollstaendig unabgedeckte Kategorie stellt eine erhebliche Luecke im TOM-Konzept dar.`, + `Setzen Sie mindestens die wichtigsten Massnahmen in der Kategorie "${category}" um, um eine Grundabdeckung sicherzustellen.` + )) + } + } + + return issues +} + +/** + * Check 5: NO_ENCRYPTION_MEASURES (CRITICAL) + */ +export function checkNoEncryption(toms: DerivedTOM[]): TOMComplianceIssue | null { + const hasImplementedEncryption = toms.some((tom) => { + const control = getControlById(tom.controlId) + return control?.category === 'ENCRYPTION' && tom.implementationStatus === 'IMPLEMENTED' + }) + + if (!hasImplementedEncryption) { + return createIssue( + 'ENCRYPTION', 'Verschluesselung', 'NO_ENCRYPTION_MEASURES', 'CRITICAL', + 'Keine Verschluesselungsmassnahmen umgesetzt', + 'Es ist keine einzige Verschluesselungsmassnahme als IMPLEMENTED markiert. Art. 32 Abs. 1 lit. a DSGVO nennt Verschluesselung explizit als geeignete technische Massnahme. Ohne Verschluesselung sind personenbezogene Daten bei Zugriff oder Verlust ungeschuetzt.', + 'Implementieren Sie umgehend Verschluesselungsmassnahmen fuer Daten im Ruhezustand (Encryption at Rest) und waehrend der Uebertragung (Encryption in Transit).' + ) + } + + return null +} + +/** + * Check 6: NO_PSEUDONYMIZATION (MEDIUM) + */ +export function checkNoPseudonymization(toms: DerivedTOM[], dataProfile: DataProfile | null): TOMComplianceIssue | null { + if (!dataProfile || !dataProfile.hasSpecialCategories) return null + + const hasImplementedPseudonymization = toms.some((tom) => { + const control = getControlById(tom.controlId) + return control?.category === 'PSEUDONYMIZATION' && tom.implementationStatus === 'IMPLEMENTED' + }) + + if (!hasImplementedPseudonymization) { + return createIssue( + 'PSEUDONYMIZATION', 'Pseudonymisierung', 'NO_PSEUDONYMIZATION', 'MEDIUM', + 'Keine Pseudonymisierung bei besonderen Datenkategorien', + 'Das Datenprofil enthaelt besondere Kategorien personenbezogener Daten (Art. 9 DSGVO), aber keine Pseudonymisierungsmassnahme ist umgesetzt. Art. 32 Abs. 1 lit. a DSGVO empfiehlt Pseudonymisierung ausdruecklich als Schutzmassnahme.', + 'Implementieren Sie Pseudonymisierungsmassnahmen fuer die Verarbeitung besonderer Datenkategorien, um das Risiko fuer betroffene Personen zu minimieren.' + ) + } + + return null +} + +/** + * Check 7: MISSING_AVAILABILITY (HIGH) + */ +export function checkMissingAvailability(toms: DerivedTOM[], state: TOMGeneratorState): TOMComplianceIssue | null { + const hasAvailabilityOrRecovery = toms.some((tom) => { + const control = getControlById(tom.controlId) + return ( + (control?.category === 'AVAILABILITY' || control?.category === 'RECOVERY') && + tom.implementationStatus === 'IMPLEMENTED' + ) + }) + + const hasDRPlan = state.securityProfile?.hasDRPlan ?? false + + if (!hasAvailabilityOrRecovery && !hasDRPlan) { + return createIssue( + 'AVAILABILITY', 'Verfuegbarkeit / Wiederherstellbarkeit', 'MISSING_AVAILABILITY', 'HIGH', + 'Keine Verfuegbarkeits- oder Wiederherstellungsmassnahmen', + 'Weder Verfuegbarkeits- noch Wiederherstellungsmassnahmen sind umgesetzt, und es existiert kein Disaster-Recovery-Plan im Security-Profil. Art. 32 Abs. 1 lit. b und c DSGVO verlangen die Faehigkeit zur raschen Wiederherstellung der Verfuegbarkeit personenbezogener Daten.', + 'Implementieren Sie Backup-Konzepte, Redundanzloesungen und einen Disaster-Recovery-Plan, um die Verfuegbarkeit und Wiederherstellbarkeit sicherzustellen.' + ) + } + + return null +} + +/** + * Check 8: NO_REVIEW_PROCESS (MEDIUM) + */ +export function checkNoReviewProcess(toms: DerivedTOM[]): TOMComplianceIssue | null { + const hasImplementedReview = toms.some((tom) => { + const control = getControlById(tom.controlId) + return control?.category === 'REVIEW' && tom.implementationStatus === 'IMPLEMENTED' + }) + + if (!hasImplementedReview) { + return createIssue( + 'REVIEW', 'Ueberpruefung & Bewertung', 'NO_REVIEW_PROCESS', 'MEDIUM', + 'Kein Verfahren zur regelmaessigen Ueberpruefung', + 'Es ist keine Ueberpruefungsmassnahme als IMPLEMENTED markiert. Art. 32 Abs. 1 lit. d DSGVO verlangt ein Verfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit der technischen und organisatorischen Massnahmen.', + 'Implementieren Sie einen regelmaessigen Review-Prozess (z.B. quartalsweise TOM-Audits, jaehrliche Wirksamkeitspruefung) und dokumentieren Sie die Ergebnisse.' + ) + } + + return null +} + +/** + * Check 9: UNCOVERED_SDM_GOAL (HIGH) + */ +export function checkUncoveredSDMGoal(toms: DerivedTOM[]): TOMComplianceIssue[] { + const issues: TOMComplianceIssue[] = [] + + const sdmGoals = [ + 'Verfuegbarkeit', 'Integritaet', 'Vertraulichkeit', + 'Nichtverkettung', 'Intervenierbarkeit', 'Transparenz', 'Datenminimierung', + ] as const + + const goalToCategoriesMap = new Map() + for (const goal of sdmGoals) goalToCategoriesMap.set(goal, []) + + for (const [category, goals] of Object.entries(SDM_CATEGORY_MAPPING)) { + for (const goal of goals) { + const existing = goalToCategoriesMap.get(goal) + if (existing) existing.push(category as ControlCategory) + } + } + + const implementedCategories = new Set() + for (const tom of toms) { + if (tom.implementationStatus !== 'IMPLEMENTED') continue + const control = getControlById(tom.controlId) + if (control) implementedCategories.add(control.category) + } + + for (const goal of sdmGoals) { + const coveringCategories = goalToCategoriesMap.get(goal) ?? [] + const hasCoverage = coveringCategories.some((cat) => implementedCategories.has(cat)) + + if (!hasCoverage) { + issues.push(createIssue( + `SDM-${goal}`, goal, 'UNCOVERED_SDM_GOAL', 'HIGH', + `SDM-Gewaehrleistungsziel "${goal}" nicht abgedeckt`, + `Das Gewaehrleistungsziel "${goal}" des Standard-Datenschutzmodells (SDM) ist durch keine umgesetzte Massnahme abgedeckt. Zugehoerige Kategorien (${coveringCategories.join(', ')}) haben keine IMPLEMENTED Controls. Das SDM ist die anerkannte Methodik zur Umsetzung der DSGVO-Anforderungen.`, + `Setzen Sie mindestens eine Massnahme aus den Kategorien ${coveringCategories.join(', ')} um, um das SDM-Ziel "${goal}" abzudecken.` + )) + } + } + + return issues +} + +/** + * Check 10: HIGH_RISK_WITHOUT_MEASURES (CRITICAL) + */ +export function checkHighRiskWithoutMeasures(toms: DerivedTOM[], riskProfile: RiskProfile | null): TOMComplianceIssue | null { + if (!riskProfile || riskProfile.protectionLevel !== 'VERY_HIGH') return null + + const requiredToms = toms.filter((t) => t.applicability === 'REQUIRED') + if (requiredToms.length === 0) return null + + const implementedCount = requiredToms.filter((t) => t.implementationStatus === 'IMPLEMENTED').length + const implementationRate = implementedCount / requiredToms.length + + if (implementationRate < 0.5) { + const percentage = Math.round(implementationRate * 100) + return createIssue( + 'RISK-PROFILE', 'Risikoprofil VERY_HIGH', 'HIGH_RISK_WITHOUT_MEASURES', 'CRITICAL', + 'Sehr hoher Schutzbedarf bei niedriger Umsetzungsrate', + `Der Schutzbedarf ist als VERY_HIGH eingestuft, aber nur ${implementedCount} von ${requiredToms.length} Pflichtmassnahmen (${percentage}%) sind umgesetzt. Bei sehr hohem Schutzbedarf muessen mindestens 50% der Pflichtmassnahmen implementiert sein, um ein angemessenes Schutzniveau gemaess Art. 32 DSGVO zu gewaehrleisten.`, + 'Priorisieren Sie die Umsetzung der verbleibenden Pflichtmassnahmen. Beginnen Sie mit CRITICAL- und HIGH-Priority Controls. Erwaeegen Sie einen Umsetzungsplan mit klaren Meilensteinen.' + ) + } + + return null +} diff --git a/admin-compliance/lib/sdk/tom-compliance.ts b/admin-compliance/lib/sdk/tom-compliance.ts index 32534c0..f8a77b0 100644 --- a/admin-compliance/lib/sdk/tom-compliance.ts +++ b/admin-compliance/lib/sdk/tom-compliance.ts @@ -2,19 +2,26 @@ // TOM Module - Compliance Check Engine // Prueft Technische und Organisatorische Massnahmen auf Vollstaendigkeit, // Konsistenz und DSGVO-Konformitaet (Art. 32 DSGVO) +// +// Check functions live in tom-compliance-checks.ts (barrel split). // ============================================================================= -import type { - TOMGeneratorState, - DerivedTOM, - RiskProfile, - DataProfile, - ControlCategory, - ImplementationStatus, -} from './tom-generator/types' +import type { TOMGeneratorState } from './tom-generator/types' -import { getControlById, getControlsByCategory, getAllCategories } from './tom-generator/controls/loader' -import { SDM_CATEGORY_MAPPING } from './tom-generator/types' +import { + resetIssueCounter, + checkMissingResponsible, + checkOverdueReview, + checkMissingEvidence, + checkStaleNotImplemented, + checkIncompleteCategory, + checkNoEncryption, + checkNoPseudonymization, + checkMissingAvailability, + checkNoReviewProcess, + checkUncoveredSDMGoal, + checkHighRiskWithoutMeasures, +} from './tom-compliance-checks' // ============================================================================= // TYPES @@ -75,386 +82,6 @@ export const TOM_SEVERITY_COLORS: Record = { LOW: '#6b7280', } -// ============================================================================= -// HELPERS -// ============================================================================= - -let issueCounter = 0 - -function createIssueId(): string { - issueCounter++ - return `TCI-${Date.now()}-${String(issueCounter).padStart(4, '0')}` -} - -function createIssue( - controlId: string, - controlName: string, - type: TOMComplianceIssueType, - severity: TOMComplianceIssueSeverity, - title: string, - description: string, - recommendation: string -): TOMComplianceIssue { - return { id: createIssueId(), controlId, controlName, type, severity, title, description, recommendation } -} - -function daysBetween(date: Date, now: Date): number { - const diffMs = now.getTime() - date.getTime() - return Math.floor(diffMs / (1000 * 60 * 60 * 24)) -} - -// ============================================================================= -// PER-TOM CHECKS (1-3, 11) -// ============================================================================= - -/** - * Check 1: MISSING_RESPONSIBLE (MEDIUM) - * REQUIRED TOM without responsiblePerson AND responsibleDepartment. - */ -function checkMissingResponsible(tom: DerivedTOM): TOMComplianceIssue | null { - if (tom.applicability !== 'REQUIRED') return null - - if (!tom.responsiblePerson && !tom.responsibleDepartment) { - return createIssue( - tom.controlId, - tom.name, - 'MISSING_RESPONSIBLE', - 'MEDIUM', - 'Keine verantwortliche Person/Abteilung', - `Die TOM "${tom.name}" ist als REQUIRED eingestuft, hat aber weder eine verantwortliche Person noch eine verantwortliche Abteilung zugewiesen. Ohne klare Verantwortlichkeit kann die Massnahme nicht zuverlaessig umgesetzt und gepflegt werden.`, - 'Weisen Sie eine verantwortliche Person oder Abteilung zu, die fuer die Umsetzung und regelmaessige Pruefung dieser Massnahme zustaendig ist.' - ) - } - - return null -} - -/** - * Check 2: OVERDUE_REVIEW (MEDIUM) - * TOM with reviewDate in the past. - */ -function checkOverdueReview(tom: DerivedTOM): TOMComplianceIssue | null { - if (!tom.reviewDate) return null - - const reviewDate = new Date(tom.reviewDate) - const now = new Date() - - if (reviewDate < now) { - const overdueDays = daysBetween(reviewDate, now) - return createIssue( - tom.controlId, - tom.name, - 'OVERDUE_REVIEW', - 'MEDIUM', - 'Ueberfaellige Pruefung', - `Die TOM "${tom.name}" haette am ${reviewDate.toLocaleDateString('de-DE')} geprueft werden muessen. Die Pruefung ist ${overdueDays} Tag(e) ueberfaellig. Gemaess Art. 32 Abs. 1 lit. d DSGVO ist eine regelmaessige Ueberpruefung der Wirksamkeit von TOMs erforderlich.`, - 'Fuehren Sie umgehend eine Wirksamkeitspruefung dieser Massnahme durch und aktualisieren Sie das naechste Pruefungsdatum.' - ) - } - - return null -} - -/** - * Check 3: MISSING_EVIDENCE (HIGH) - * IMPLEMENTED TOM where linkedEvidence is empty but the control has evidenceRequirements. - */ -function checkMissingEvidence(tom: DerivedTOM): TOMComplianceIssue | null { - if (tom.implementationStatus !== 'IMPLEMENTED') return null - if (tom.linkedEvidence.length > 0) return null - - const control = getControlById(tom.controlId) - if (!control || control.evidenceRequirements.length === 0) return null - - return createIssue( - tom.controlId, - tom.name, - 'MISSING_EVIDENCE', - 'HIGH', - 'Kein Nachweis hinterlegt', - `Die TOM "${tom.name}" ist als IMPLEMENTED markiert, hat aber keine verknuepften Nachweisdokumente. Der Control erfordert ${control.evidenceRequirements.length} Nachweis(e): ${control.evidenceRequirements.join(', ')}. Ohne Nachweise ist die Umsetzung nicht auditfaehig.`, - 'Laden Sie die erforderlichen Nachweisdokumente hoch und verknuepfen Sie sie mit dieser Massnahme.' - ) -} - -/** - * Check 11: STALE_NOT_IMPLEMENTED (LOW) - * REQUIRED TOM that has been NOT_IMPLEMENTED for >90 days. - * Uses implementationDate === null and state.createdAt / state.updatedAt as reference. - */ -function checkStaleNotImplemented(tom: DerivedTOM, state: TOMGeneratorState): TOMComplianceIssue | null { - if (tom.applicability !== 'REQUIRED') return null - if (tom.implementationStatus !== 'NOT_IMPLEMENTED') return null - if (tom.implementationDate !== null) return null - - const referenceDate = state.createdAt ? new Date(state.createdAt) : (state.updatedAt ? new Date(state.updatedAt) : null) - if (!referenceDate) return null - - const ageInDays = daysBetween(referenceDate, new Date()) - if (ageInDays <= 90) return null - - return createIssue( - tom.controlId, - tom.name, - 'STALE_NOT_IMPLEMENTED', - 'LOW', - 'Langfristig nicht umgesetzte Pflichtmassnahme', - `Die TOM "${tom.name}" ist als REQUIRED eingestuft, aber seit ${ageInDays} Tagen nicht umgesetzt. Pflichtmassnahmen, die laenger als 90 Tage nicht implementiert werden, deuten auf organisatorische Blockaden oder unzureichende Priorisierung hin.`, - 'Pruefen Sie, ob die Massnahme weiterhin erforderlich ist, und erstellen Sie einen konkreten Umsetzungsplan mit Verantwortlichkeiten und Fristen.' - ) -} - -// ============================================================================= -// AGGREGATE CHECKS (4-10) -// ============================================================================= - -/** - * Check 4: INCOMPLETE_CATEGORY (HIGH) - * Category where ALL applicable (REQUIRED) controls are NOT_IMPLEMENTED. - */ -function checkIncompleteCategory(toms: DerivedTOM[]): TOMComplianceIssue[] { - const issues: TOMComplianceIssue[] = [] - - // Group applicable TOMs by category - const categoryMap = new Map() - - for (const tom of toms) { - const control = getControlById(tom.controlId) - if (!control) continue - - const category = control.category - if (!categoryMap.has(category)) { - categoryMap.set(category, []) - } - categoryMap.get(category)!.push(tom) - } - - for (const [category, categoryToms] of Array.from(categoryMap.entries())) { - // Only check categories that have at least one REQUIRED control - const requiredToms = categoryToms.filter((t: DerivedTOM) => t.applicability === 'REQUIRED') - if (requiredToms.length === 0) continue - - const allNotImplemented = requiredToms.every((t: DerivedTOM) => t.implementationStatus === 'NOT_IMPLEMENTED') - if (allNotImplemented) { - issues.push( - createIssue( - category, - category, - 'INCOMPLETE_CATEGORY', - 'HIGH', - `Kategorie "${category}" vollstaendig ohne Umsetzung`, - `Alle ${requiredToms.length} Pflichtmassnahme(n) in der Kategorie "${category}" sind nicht umgesetzt. Eine vollstaendig unabgedeckte Kategorie stellt eine erhebliche Luecke im TOM-Konzept dar.`, - `Setzen Sie mindestens die wichtigsten Massnahmen in der Kategorie "${category}" um, um eine Grundabdeckung sicherzustellen.` - ) - ) - } - } - - return issues -} - -/** - * Check 5: NO_ENCRYPTION_MEASURES (CRITICAL) - * No ENCRYPTION control with status IMPLEMENTED. - */ -function checkNoEncryption(toms: DerivedTOM[]): TOMComplianceIssue | null { - const hasImplementedEncryption = toms.some((tom) => { - const control = getControlById(tom.controlId) - return control?.category === 'ENCRYPTION' && tom.implementationStatus === 'IMPLEMENTED' - }) - - if (!hasImplementedEncryption) { - return createIssue( - 'ENCRYPTION', - 'Verschluesselung', - 'NO_ENCRYPTION_MEASURES', - 'CRITICAL', - 'Keine Verschluesselungsmassnahmen umgesetzt', - 'Es ist keine einzige Verschluesselungsmassnahme als IMPLEMENTED markiert. Art. 32 Abs. 1 lit. a DSGVO nennt Verschluesselung explizit als geeignete technische Massnahme. Ohne Verschluesselung sind personenbezogene Daten bei Zugriff oder Verlust ungeschuetzt.', - 'Implementieren Sie umgehend Verschluesselungsmassnahmen fuer Daten im Ruhezustand (Encryption at Rest) und waehrend der Uebertragung (Encryption in Transit).' - ) - } - - return null -} - -/** - * Check 6: NO_PSEUDONYMIZATION (MEDIUM) - * DataProfile has special categories (Art. 9) but no PSEUDONYMIZATION control implemented. - */ -function checkNoPseudonymization(toms: DerivedTOM[], dataProfile: DataProfile | null): TOMComplianceIssue | null { - if (!dataProfile || !dataProfile.hasSpecialCategories) return null - - const hasImplementedPseudonymization = toms.some((tom) => { - const control = getControlById(tom.controlId) - return control?.category === 'PSEUDONYMIZATION' && tom.implementationStatus === 'IMPLEMENTED' - }) - - if (!hasImplementedPseudonymization) { - return createIssue( - 'PSEUDONYMIZATION', - 'Pseudonymisierung', - 'NO_PSEUDONYMIZATION', - 'MEDIUM', - 'Keine Pseudonymisierung bei besonderen Datenkategorien', - 'Das Datenprofil enthaelt besondere Kategorien personenbezogener Daten (Art. 9 DSGVO), aber keine Pseudonymisierungsmassnahme ist umgesetzt. Art. 32 Abs. 1 lit. a DSGVO empfiehlt Pseudonymisierung ausdruecklich als Schutzmassnahme.', - 'Implementieren Sie Pseudonymisierungsmassnahmen fuer die Verarbeitung besonderer Datenkategorien, um das Risiko fuer betroffene Personen zu minimieren.' - ) - } - - return null -} - -/** - * Check 7: MISSING_AVAILABILITY (HIGH) - * No AVAILABILITY or RECOVERY control implemented AND no DR plan in securityProfile. - */ -function checkMissingAvailability(toms: DerivedTOM[], state: TOMGeneratorState): TOMComplianceIssue | null { - const hasAvailabilityOrRecovery = toms.some((tom) => { - const control = getControlById(tom.controlId) - return ( - (control?.category === 'AVAILABILITY' || control?.category === 'RECOVERY') && - tom.implementationStatus === 'IMPLEMENTED' - ) - }) - - const hasDRPlan = state.securityProfile?.hasDRPlan ?? false - - if (!hasAvailabilityOrRecovery && !hasDRPlan) { - return createIssue( - 'AVAILABILITY', - 'Verfuegbarkeit / Wiederherstellbarkeit', - 'MISSING_AVAILABILITY', - 'HIGH', - 'Keine Verfuegbarkeits- oder Wiederherstellungsmassnahmen', - 'Weder Verfuegbarkeits- noch Wiederherstellungsmassnahmen sind umgesetzt, und es existiert kein Disaster-Recovery-Plan im Security-Profil. Art. 32 Abs. 1 lit. b und c DSGVO verlangen die Faehigkeit zur raschen Wiederherstellung der Verfuegbarkeit personenbezogener Daten.', - 'Implementieren Sie Backup-Konzepte, Redundanzloesungen und einen Disaster-Recovery-Plan, um die Verfuegbarkeit und Wiederherstellbarkeit sicherzustellen.' - ) - } - - return null -} - -/** - * Check 8: NO_REVIEW_PROCESS (MEDIUM) - * No REVIEW control implemented (Art. 32 Abs. 1 lit. d requires periodic review). - */ -function checkNoReviewProcess(toms: DerivedTOM[]): TOMComplianceIssue | null { - const hasImplementedReview = toms.some((tom) => { - const control = getControlById(tom.controlId) - return control?.category === 'REVIEW' && tom.implementationStatus === 'IMPLEMENTED' - }) - - if (!hasImplementedReview) { - return createIssue( - 'REVIEW', - 'Ueberpruefung & Bewertung', - 'NO_REVIEW_PROCESS', - 'MEDIUM', - 'Kein Verfahren zur regelmaessigen Ueberpruefung', - 'Es ist keine Ueberpruefungsmassnahme als IMPLEMENTED markiert. Art. 32 Abs. 1 lit. d DSGVO verlangt ein Verfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit der technischen und organisatorischen Massnahmen.', - 'Implementieren Sie einen regelmaessigen Review-Prozess (z.B. quartalsweise TOM-Audits, jaehrliche Wirksamkeitspruefung) und dokumentieren Sie die Ergebnisse.' - ) - } - - return null -} - -/** - * Check 9: UNCOVERED_SDM_GOAL (HIGH) - * SDM goal with 0% coverage — no implemented control maps to it via SDM_CATEGORY_MAPPING. - */ -function checkUncoveredSDMGoal(toms: DerivedTOM[]): TOMComplianceIssue[] { - const issues: TOMComplianceIssue[] = [] - - // Build reverse mapping: SDM goal -> ControlCategories that cover it - const sdmGoals = [ - 'Verfuegbarkeit', - 'Integritaet', - 'Vertraulichkeit', - 'Nichtverkettung', - 'Intervenierbarkeit', - 'Transparenz', - 'Datenminimierung', - ] as const - - const goalToCategoriesMap = new Map() - for (const goal of sdmGoals) { - goalToCategoriesMap.set(goal, []) - } - - // Build reverse lookup from SDM_CATEGORY_MAPPING - for (const [category, goals] of Object.entries(SDM_CATEGORY_MAPPING)) { - for (const goal of goals) { - const existing = goalToCategoriesMap.get(goal) - if (existing) { - existing.push(category as ControlCategory) - } - } - } - - // Collect implemented categories - const implementedCategories = new Set() - for (const tom of toms) { - if (tom.implementationStatus !== 'IMPLEMENTED') continue - const control = getControlById(tom.controlId) - if (control) { - implementedCategories.add(control.category) - } - } - - // Check each SDM goal - for (const goal of sdmGoals) { - const coveringCategories = goalToCategoriesMap.get(goal) ?? [] - const hasCoverage = coveringCategories.some((cat) => implementedCategories.has(cat)) - - if (!hasCoverage) { - issues.push( - createIssue( - `SDM-${goal}`, - goal, - 'UNCOVERED_SDM_GOAL', - 'HIGH', - `SDM-Gewaehrleistungsziel "${goal}" nicht abgedeckt`, - `Das Gewaehrleistungsziel "${goal}" des Standard-Datenschutzmodells (SDM) ist durch keine umgesetzte Massnahme abgedeckt. Zugehoerige Kategorien (${coveringCategories.join(', ')}) haben keine IMPLEMENTED Controls. Das SDM ist die anerkannte Methodik zur Umsetzung der DSGVO-Anforderungen.`, - `Setzen Sie mindestens eine Massnahme aus den Kategorien ${coveringCategories.join(', ')} um, um das SDM-Ziel "${goal}" abzudecken.` - ) - ) - } - } - - return issues -} - -/** - * Check 10: HIGH_RISK_WITHOUT_MEASURES (CRITICAL) - * Protection level VERY_HIGH but < 50% of REQUIRED controls implemented. - */ -function checkHighRiskWithoutMeasures(toms: DerivedTOM[], riskProfile: RiskProfile | null): TOMComplianceIssue | null { - if (!riskProfile || riskProfile.protectionLevel !== 'VERY_HIGH') return null - - const requiredToms = toms.filter((t) => t.applicability === 'REQUIRED') - if (requiredToms.length === 0) return null - - const implementedCount = requiredToms.filter((t) => t.implementationStatus === 'IMPLEMENTED').length - const implementationRate = implementedCount / requiredToms.length - - if (implementationRate < 0.5) { - const percentage = Math.round(implementationRate * 100) - return createIssue( - 'RISK-PROFILE', - 'Risikoprofil VERY_HIGH', - 'HIGH_RISK_WITHOUT_MEASURES', - 'CRITICAL', - 'Sehr hoher Schutzbedarf bei niedriger Umsetzungsrate', - `Der Schutzbedarf ist als VERY_HIGH eingestuft, aber nur ${implementedCount} von ${requiredToms.length} Pflichtmassnahmen (${percentage}%) sind umgesetzt. Bei sehr hohem Schutzbedarf muessen mindestens 50% der Pflichtmassnahmen implementiert sein, um ein angemessenes Schutzniveau gemaess Art. 32 DSGVO zu gewaehrleisten.`, - 'Priorisieren Sie die Umsetzung der verbleibenden Pflichtmassnahmen. Beginnen Sie mit CRITICAL- und HIGH-Priority Controls. Erwaeegen Sie einen Umsetzungsplan mit klaren Meilensteinen.' - ) - } - - return null -} - // ============================================================================= // MAIN COMPLIANCE CHECK // ============================================================================= @@ -467,7 +94,7 @@ function checkHighRiskWithoutMeasures(toms: DerivedTOM[], riskProfile: RiskProfi */ export function runTOMComplianceCheck(state: TOMGeneratorState): TOMComplianceCheckResult { // Reset counter for deterministic IDs within a single check run - issueCounter = 0 + resetIssueCounter() const issues: TOMComplianceIssue[] = [] @@ -513,10 +140,7 @@ export function runTOMComplianceCheck(state: TOMGeneratorState): TOMComplianceCh // Calculate score const bySeverity: Record = { - LOW: 0, - MEDIUM: 0, - HIGH: 0, - CRITICAL: 0, + LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0, } for (const issue of issues) { diff --git a/admin-compliance/lib/sdk/tom-document.ts b/admin-compliance/lib/sdk/tom-document.ts index 834d86a..ffb7724 100644 --- a/admin-compliance/lib/sdk/tom-document.ts +++ b/admin-compliance/lib/sdk/tom-document.ts @@ -1,906 +1,8 @@ // ============================================================================= // TOM Module - TOM-Dokumentation Document Generator -// Generates a printable, audit-ready HTML document according to DSGVO Art. 32 +// Barrel re-export — implementation split into tom-document/ // ============================================================================= -import type { - TOMGeneratorState, - DerivedTOM, - CompanyProfile, - RiskProfile, - ControlCategory, -} from './tom-generator/types' - -import { SDM_CATEGORY_MAPPING } from './tom-generator/types' - -import { - getControlById, - getControlsByCategory, - getAllCategories, - getCategoryMetadata, -} from './tom-generator/controls/loader' - -import type { TOMComplianceCheckResult, TOMComplianceIssueSeverity } from './tom-compliance' - -// ============================================================================= -// TYPES -// ============================================================================= - -export interface TOMDocumentOrgHeader { - organizationName: string - industry: string - dpoName: string - dpoContact: string - responsiblePerson: string - itSecurityContact: string - locations: string[] - employeeCount: string - documentVersion: string - lastReviewDate: string - nextReviewDate: string - reviewInterval: string -} - -export interface TOMDocumentRevision { - version: string - date: string - author: string - changes: string -} - -// ============================================================================= -// DEFAULTS -// ============================================================================= - -export function createDefaultTOMDocumentOrgHeader(): TOMDocumentOrgHeader { - const now = new Date() - const nextYear = new Date() - nextYear.setFullYear(nextYear.getFullYear() + 1) - - return { - organizationName: '', - industry: '', - dpoName: '', - dpoContact: '', - responsiblePerson: '', - itSecurityContact: '', - locations: [], - employeeCount: '', - documentVersion: '1.0', - lastReviewDate: now.toISOString().split('T')[0], - nextReviewDate: nextYear.toISOString().split('T')[0], - reviewInterval: 'Jaehrlich', - } -} - -// ============================================================================= -// SEVERITY LABELS (for Compliance Status section) -// ============================================================================= - -const SEVERITY_LABELS_DE: Record = { - CRITICAL: 'Kritisch', - HIGH: 'Hoch', - MEDIUM: 'Mittel', - LOW: 'Niedrig', -} - -const SEVERITY_COLORS: Record = { - CRITICAL: '#dc2626', - HIGH: '#ea580c', - MEDIUM: '#d97706', - LOW: '#6b7280', -} - -// ============================================================================= -// CATEGORY LABELS (German) -// ============================================================================= - -const CATEGORY_LABELS_DE: Record = { - ACCESS_CONTROL: 'Zutrittskontrolle', - ADMISSION_CONTROL: 'Zugangskontrolle', - ACCESS_AUTHORIZATION: 'Zugriffskontrolle', - TRANSFER_CONTROL: 'Weitergabekontrolle', - INPUT_CONTROL: 'Eingabekontrolle', - ORDER_CONTROL: 'Auftragskontrolle', - AVAILABILITY: 'Verfuegbarkeit', - SEPARATION: 'Trennbarkeit', - ENCRYPTION: 'Verschluesselung', - PSEUDONYMIZATION: 'Pseudonymisierung', - RESILIENCE: 'Belastbarkeit', - RECOVERY: 'Wiederherstellbarkeit', - REVIEW: 'Ueberpruefung & Bewertung', -} - -// ============================================================================= -// STATUS & APPLICABILITY LABELS -// ============================================================================= - -const STATUS_LABELS_DE: Record = { - IMPLEMENTED: 'Umgesetzt', - PARTIAL: 'Teilweise umgesetzt', - NOT_IMPLEMENTED: 'Nicht umgesetzt', -} - -const STATUS_BADGE_CLASSES: Record = { - IMPLEMENTED: 'badge-active', - PARTIAL: 'badge-review', - NOT_IMPLEMENTED: 'badge-critical', -} - -const APPLICABILITY_LABELS_DE: Record = { - REQUIRED: 'Erforderlich', - RECOMMENDED: 'Empfohlen', - OPTIONAL: 'Optional', - NOT_APPLICABLE: 'Nicht anwendbar', -} - -// ============================================================================= -// HTML DOCUMENT BUILDER -// ============================================================================= - -export function buildTOMDocumentHtml( - derivedTOMs: DerivedTOM[], - orgHeader: TOMDocumentOrgHeader, - companyProfile: CompanyProfile | null, - riskProfile: RiskProfile | null, - complianceResult: TOMComplianceCheckResult | null, - revisions: TOMDocumentRevision[] -): string { - const today = new Date().toLocaleDateString('de-DE', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }) - - const orgName = orgHeader.organizationName || 'Organisation' - - // Filter out NOT_APPLICABLE TOMs for display - const applicableTOMs = derivedTOMs.filter(t => t.applicability !== 'NOT_APPLICABLE') - - // Group TOMs by category via control library lookup - const tomsByCategory = new Map() - for (const tom of applicableTOMs) { - const control = getControlById(tom.controlId) - const cat = control?.category || 'REVIEW' - if (!tomsByCategory.has(cat)) tomsByCategory.set(cat, []) - tomsByCategory.get(cat)!.push(tom) - } - - // Build role map: role/department → list of control codes - const roleMap = new Map() - for (const tom of applicableTOMs) { - const role = tom.responsiblePerson || tom.responsibleDepartment || 'Nicht zugewiesen' - if (!roleMap.has(role)) roleMap.set(role, []) - const control = getControlById(tom.controlId) - roleMap.get(role)!.push(control?.code || tom.controlId) - } - - // ========================================================================= - // HTML Template - // ========================================================================= - - let html = ` - - - -TOM-Dokumentation — ${escHtml(orgName)} - - - -` - - // ========================================================================= - // Section 0: Cover Page - // ========================================================================= - html += ` -
    -

    TOM-Dokumentation

    -
    Technische und Organisatorische Massnahmen gemaess Art. 32 DSGVO
    -
    -
    Organisation: ${escHtml(orgName)}
    - ${orgHeader.industry ? `
    Branche: ${escHtml(orgHeader.industry)}
    ` : ''} - ${orgHeader.dpoName ? `
    DSB: ${escHtml(orgHeader.dpoName)}
    ` : ''} - ${orgHeader.dpoContact ? `
    DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
    ` : ''} - ${orgHeader.responsiblePerson ? `
    Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
    ` : ''} - ${orgHeader.itSecurityContact ? `
    IT-Sicherheit: ${escHtml(orgHeader.itSecurityContact)}
    ` : ''} - ${orgHeader.employeeCount ? `
    Mitarbeiter: ${escHtml(orgHeader.employeeCount)}
    ` : ''} - ${orgHeader.locations.length > 0 ? `
    Standorte: ${escHtml(orgHeader.locations.join(', '))}
    ` : ''} -
    - -
    -` - - // ========================================================================= - // Table of Contents - // ========================================================================= - const sections = [ - 'Ziel und Zweck', - 'Geltungsbereich', - 'Grundprinzipien Art. 32', - 'Schutzbedarf und Risikoanalyse', - 'Massnahmen-Uebersicht', - 'Detaillierte Massnahmen', - 'SDM Gewaehrleistungsziele', - 'Verantwortlichkeiten', - 'Pruef- und Revisionszyklus', - 'Compliance-Status', - 'Aenderungshistorie', - ] - - html += ` -
    -

    Inhaltsverzeichnis

    - ${sections.map((s, i) => `
    ${i + 1}. ${escHtml(s)}
    `).join('\n ')} -
    -` - - // ========================================================================= - // Section 1: Ziel und Zweck - // ========================================================================= - html += ` -
    -
    1. Ziel und Zweck
    -
    -

    Diese TOM-Dokumentation beschreibt die technischen und organisatorischen Massnahmen - zum Schutz personenbezogener Daten bei ${escHtml(orgName)}. Sie dient - der Umsetzung folgender DSGVO-Anforderungen:

    - - - - - - -
    RechtsgrundlageInhalt
    Art. 32 Abs. 1 lit. a DSGVOPseudonymisierung und Verschluesselung personenbezogener Daten
    Art. 32 Abs. 1 lit. b DSGVOFaehigkeit, die Vertraulichkeit, Integritaet, Verfuegbarkeit und Belastbarkeit der Systeme und Dienste im Zusammenhang mit der Verarbeitung auf Dauer sicherzustellen
    Art. 32 Abs. 1 lit. c DSGVOFaehigkeit, die Verfuegbarkeit der personenbezogenen Daten und den Zugang zu ihnen bei einem physischen oder technischen Zwischenfall rasch wiederherzustellen
    Art. 32 Abs. 1 lit. d DSGVOVerfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit der technischen und organisatorischen Massnahmen
    -

    Die TOM-Dokumentation ist fester Bestandteil des Datenschutz-Managementsystems und wird - regelmaessig ueberprueft und aktualisiert.

    -
    -
    -` - - // ========================================================================= - // Section 2: Geltungsbereich - // ========================================================================= - const industryInfo = companyProfile?.industry || orgHeader.industry || '' - const hostingInfo = companyProfile ? `Unternehmen: ${escHtml(companyProfile.name || orgName)}, Groesse: ${escHtml(companyProfile.size || '-')}` : '' - - html += ` -
    -
    2. Geltungsbereich
    -
    -

    Diese TOM-Dokumentation gilt fuer alle IT-Systeme, Anwendungen und Verarbeitungsprozesse - von ${escHtml(orgName)}${industryInfo ? ` (Branche: ${escHtml(industryInfo)})` : ''}.

    - ${hostingInfo ? `

    ${hostingInfo}

    ` : ''} - ${orgHeader.locations.length > 0 ? `

    Standorte: ${escHtml(orgHeader.locations.join(', '))}

    ` : ''} -

    Die dokumentierten Massnahmen stammen aus zwei Quellen:

    -
      -
    • Embedded Library (TOM-xxx): Integrierte Kontrollbibliothek mit spezifischen Massnahmen fuer Art. 32 DSGVO
    • -
    • Canonical Control Library (CP-CLIB): Uebergreifende Kontrollbibliothek mit framework-uebergreifenden Massnahmen
    • -
    -

    Insgesamt umfasst dieses Dokument ${applicableTOMs.length} anwendbare Massnahmen - in ${tomsByCategory.size} Kategorien.

    -
    -
    -` - - // ========================================================================= - // Section 3: Grundprinzipien Art. 32 - // ========================================================================= - html += ` -
    -
    3. Grundprinzipien Art. 32
    -
    -
    Vertraulichkeit: Schutz personenbezogener Daten vor unbefugter Kenntnisnahme durch Zutrittskontrolle, Zugangskontrolle, Zugriffskontrolle und Verschluesselung (Art. 32 Abs. 1 lit. b DSGVO).
    -
    Integritaet: Sicherstellung, dass personenbezogene Daten nicht unbefugt oder unbeabsichtigt veraendert werden koennen, durch Eingabekontrolle, Weitergabekontrolle und Protokollierung (Art. 32 Abs. 1 lit. b DSGVO).
    -
    Verfuegbarkeit und Belastbarkeit: Gewaehrleistung, dass Systeme und Dienste bei Lastspitzen und Stoerungen zuverlaessig funktionieren, durch Backup, Redundanz und Disaster Recovery (Art. 32 Abs. 1 lit. b DSGVO).
    -
    Rasche Wiederherstellbarkeit: Faehigkeit, nach einem physischen oder technischen Zwischenfall Daten und Systeme schnell wiederherzustellen, durch getestete Recovery-Prozesse (Art. 32 Abs. 1 lit. c DSGVO).
    -
    Regelmaessige Wirksamkeitspruefung: Verfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit aller technischen und organisatorischen Massnahmen (Art. 32 Abs. 1 lit. d DSGVO).
    -
    -
    -` - - // ========================================================================= - // Section 4: Schutzbedarf und Risikoanalyse - // ========================================================================= - html += ` -
    -
    4. Schutzbedarf und Risikoanalyse
    -
    -` - if (riskProfile) { - html += `

    Die folgende Schutzbedarfsanalyse bildet die Grundlage fuer die Auswahl und Priorisierung - der technischen und organisatorischen Massnahmen:

    - - - - - - - - ${riskProfile.specialRisks.length > 0 ? `` : ''} - ${riskProfile.regulatoryRequirements.length > 0 ? `` : ''} -
    KriteriumBewertung
    Vertraulichkeit${riskProfile.ciaAssessment.confidentiality}/5
    Integritaet${riskProfile.ciaAssessment.integrity}/5
    Verfuegbarkeit${riskProfile.ciaAssessment.availability}/5
    Schutzniveau${escHtml(riskProfile.protectionLevel)}
    DSFA-Pflicht${riskProfile.dsfaRequired ? 'Ja' : 'Nein'}
    Spezialrisiken${escHtml(riskProfile.specialRisks.join(', '))}
    Regulatorische Anforderungen${escHtml(riskProfile.regulatoryRequirements.join(', '))}
    -` - } else { - html += `

    Die Schutzbedarfsanalyse wurde noch nicht durchgefuehrt. Fuehren Sie den - Risiko-Wizard im TOM-Generator durch, um den Schutzbedarf zu ermitteln.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 5: Massnahmen-Uebersicht - // ========================================================================= - html += ` -
    -
    5. Massnahmen-Uebersicht
    -
    -

    Die folgende Tabelle zeigt eine Uebersicht aller ${applicableTOMs.length} anwendbaren Massnahmen - nach Kategorie:

    - - - - - - - - -` - const allCategories = getAllCategories() - for (const cat of allCategories) { - const tomsInCat = tomsByCategory.get(cat) - if (!tomsInCat || tomsInCat.length === 0) continue - - const implemented = tomsInCat.filter(t => t.implementationStatus === 'IMPLEMENTED').length - const partial = tomsInCat.filter(t => t.implementationStatus === 'PARTIAL').length - const notImpl = tomsInCat.filter(t => t.implementationStatus === 'NOT_IMPLEMENTED').length - const catLabel = CATEGORY_LABELS_DE[cat] || cat - - html += ` - - - - - - -` - } - - html += `
    KategorieGesamtUmgesetztTeilweiseOffen
    ${escHtml(catLabel)}${tomsInCat.length}${implemented}${partial}${notImpl}
    -
    -
    -` - - // ========================================================================= - // Section 6: Detaillierte Massnahmen - // ========================================================================= - html += ` -
    -
    6. Detaillierte Massnahmen
    -
    -` - - for (const cat of allCategories) { - const tomsInCat = tomsByCategory.get(cat) - if (!tomsInCat || tomsInCat.length === 0) continue - - const catLabel = CATEGORY_LABELS_DE[cat] || cat - const catMeta = getCategoryMetadata(cat) - const gdprRef = catMeta?.gdprReference || '' - - html += `

    ${escHtml(catLabel)}${gdprRef ? ` (${escHtml(gdprRef)})` : ''}

    -` - - // Sort TOMs by control code - const sortedTOMs = [...tomsInCat].sort((a, b) => { - const codeA = getControlById(a.controlId)?.code || a.controlId - const codeB = getControlById(b.controlId)?.code || b.controlId - return codeA.localeCompare(codeB) - }) - - for (const tom of sortedTOMs) { - const control = getControlById(tom.controlId) - const code = control?.code || tom.controlId - const nameDE = control?.name?.de || tom.name - const descDE = control?.description?.de || tom.description - const typeLabel = control?.type === 'TECHNICAL' ? 'Technisch' : control?.type === 'ORGANIZATIONAL' ? 'Organisatorisch' : '-' - const statusLabel = STATUS_LABELS_DE[tom.implementationStatus] || tom.implementationStatus - const statusBadge = STATUS_BADGE_CLASSES[tom.implementationStatus] || 'badge-draft' - const applicabilityLabel = APPLICABILITY_LABELS_DE[tom.applicability] || tom.applicability - const responsible = [tom.responsiblePerson, tom.responsibleDepartment].filter(s => s && s.trim()).join(' / ') || '-' - const implDate = tom.implementationDate ? formatDateDE(typeof tom.implementationDate === 'string' ? tom.implementationDate : tom.implementationDate.toISOString()) : '-' - const reviewDate = tom.reviewDate ? formatDateDE(typeof tom.reviewDate === 'string' ? tom.reviewDate : tom.reviewDate.toISOString()) : '-' - - // Evidence - const evidenceInfo = tom.linkedEvidence.length > 0 - ? tom.linkedEvidence.join(', ') - : tom.evidenceGaps.length > 0 - ? `Fehlend: ${escHtml(tom.evidenceGaps.join(', '))}` - : '-' - - // Framework mappings - let mappingsHtml = '-' - if (control?.mappings && control.mappings.length > 0) { - mappingsHtml = control.mappings.map(m => `${escHtml(m.framework)}: ${escHtml(m.reference)}`).join('
    ') - } - - html += ` -
    -
    - ${escHtml(code)} — ${escHtml(nameDE)} - ${escHtml(statusLabel)} -
    -
    - - - - - - - - - - -
    Beschreibung${escHtml(descDE)}
    Massnahmentyp${escHtml(typeLabel)}
    Anwendbarkeit${escHtml(applicabilityLabel)}${tom.applicabilityReason ? ` — ${escHtml(tom.applicabilityReason)}` : ''}
    Umsetzungsstatus${escHtml(statusLabel)}
    Verantwortlich${escHtml(responsible)}
    Umsetzungsdatum${implDate}
    Naechste Pruefung${reviewDate}
    Evidence${evidenceInfo}
    Framework-Mappings${mappingsHtml}
    -
    -
    -` - } - } - - html += `
    -
    -` - - // ========================================================================= - // Section 7: SDM Gewaehrleistungsziele - // ========================================================================= - const sdmGoals: Array<{ goal: string; categories: ControlCategory[] }> = [] - const allSDMGoals = [ - 'Verfuegbarkeit', - 'Integritaet', - 'Vertraulichkeit', - 'Nichtverkettung', - 'Intervenierbarkeit', - 'Transparenz', - 'Datenminimierung', - ] as const - - for (const goal of allSDMGoals) { - const cats: ControlCategory[] = [] - for (const [cat, goals] of Object.entries(SDM_CATEGORY_MAPPING)) { - if (goals.includes(goal)) { - cats.push(cat as ControlCategory) - } - } - sdmGoals.push({ goal, categories: cats }) - } - - html += ` -
    -
    7. SDM Gewaehrleistungsziele
    -
    -

    Die folgende Tabelle zeigt die Abdeckung der sieben Gewaehrleistungsziele des - Standard-Datenschutzmodells (SDM) durch die implementierten Massnahmen:

    - - - - - - - -` - for (const { goal, categories } of sdmGoals) { - let totalInGoal = 0 - let implementedInGoal = 0 - for (const cat of categories) { - const tomsInCat = tomsByCategory.get(cat) || [] - totalInGoal += tomsInCat.length - implementedInGoal += tomsInCat.filter(t => t.implementationStatus === 'IMPLEMENTED').length - } - const percentage = totalInGoal > 0 ? Math.round((implementedInGoal / totalInGoal) * 100) : 0 - - html += ` - - - - - -` - } - - html += `
    GewaehrleistungszielAbgedecktGesamtAbdeckung (%)
    ${escHtml(goal)}${implementedInGoal}${totalInGoal}${percentage}%
    -
    -
    -` - - // ========================================================================= - // Section 8: Verantwortlichkeiten - // ========================================================================= - html += ` -
    -
    8. Verantwortlichkeiten
    -
    -

    Die folgende Rollenmatrix zeigt, welche Personen oder Abteilungen fuer welche Massnahmen - die Umsetzungsverantwortung tragen:

    - - -` - for (const [role, controls] of roleMap.entries()) { - html += ` - - - - -` - } - - html += `
    Rolle / VerantwortlichMassnahmenAnzahl
    ${escHtml(role)}${controls.map(c => escHtml(c)).join(', ')}${controls.length}
    -
    -
    -` - - // ========================================================================= - // Section 9: Pruef- und Revisionszyklus - // ========================================================================= - html += ` -
    -
    9. Pruef- und Revisionszyklus
    -
    - - - - - - -
    EigenschaftWert
    Aktuelles Pruefintervall${escHtml(orgHeader.reviewInterval)}
    Letzte Pruefung${formatDateDE(orgHeader.lastReviewDate)}
    Naechste Pruefung${formatDateDE(orgHeader.nextReviewDate)}
    Aktuelle Version${escHtml(orgHeader.documentVersion)}
    -

    Bei jeder Pruefung wird die TOM-Dokumentation auf folgende Punkte ueberprueft:

    -
      -
    • Vollstaendigkeit aller Massnahmen (neue Systeme oder Verarbeitungen erfasst?)
    • -
    • Aktualitaet des Umsetzungsstatus (Aenderungen seit letzter Pruefung?)
    • -
    • Wirksamkeit der technischen Massnahmen (Penetration-Tests, Audit-Ergebnisse)
    • -
    • Angemessenheit der organisatorischen Massnahmen (Schulungen, Richtlinien aktuell?)
    • -
    • Abdeckung aller SDM-Gewaehrleistungsziele
    • -
    • Zuordnung von Verantwortlichkeiten zu allen Massnahmen
    • -
    -
    -
    -` - - // ========================================================================= - // Section 10: Compliance-Status - // ========================================================================= - html += ` -
    -
    10. Compliance-Status
    -
    -` - if (complianceResult) { - const scoreClass = complianceResult.score >= 90 ? 'score-excellent' - : complianceResult.score >= 75 ? 'score-good' - : complianceResult.score >= 50 ? 'score-needs-work' - : 'score-poor' - const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' - : complianceResult.score >= 75 ? 'Gut' - : complianceResult.score >= 50 ? 'Verbesserungswuerdig' - : 'Mangelhaft' - - html += `

    ${complianceResult.score}/100 ${escHtml(scoreLabel)}

    - - - - - -
    KennzahlWert
    Gepruefte Massnahmen${complianceResult.stats.total}
    Bestanden${complianceResult.stats.passed}
    Beanstandungen${complianceResult.stats.failed}
    -` - if (complianceResult.issues.length > 0) { - html += `

    Befunde nach Schweregrad:

    - - -` - const severityOrder: TOMComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] - for (const sev of severityOrder) { - const count = complianceResult.stats.bySeverity[sev] - if (count === 0) continue - const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) - html += ` - - - - -` - } - html += `
    SchweregradAnzahlBefunde
    ${SEVERITY_LABELS_DE[sev]}${count}${issuesForSev.map(i => escHtml(i.title)).join('; ')}
    -` - } else { - html += `

    Keine Beanstandungen. Alle Massnahmen sind konform.

    -` - } - } else { - html += `

    Compliance-Check wurde noch nicht ausgefuehrt. Fuehren Sie den Check im - Export-Tab durch, um den Status in das Dokument aufzunehmen.

    -` - } - - html += `
    -
    -` - - // ========================================================================= - // Section 11: Aenderungshistorie - // ========================================================================= - html += ` -
    -
    11. Aenderungshistorie
    -
    - - -` - if (revisions.length > 0) { - for (const rev of revisions) { - html += ` - - - - - -` - } - } else { - html += ` - - - - - -` - } - - html += `
    VersionDatumAutorAenderungen
    ${escHtml(rev.version)}${formatDateDE(rev.date)}${escHtml(rev.author)}${escHtml(rev.changes)}
    ${escHtml(orgHeader.documentVersion)}${today}${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '-')}Erstversion der TOM-Dokumentation
    -
    -
    -` - - // ========================================================================= - // Footer - // ========================================================================= - html += ` - - - -` - - return html -} - -// ============================================================================= -// INTERNAL HELPERS -// ============================================================================= - -function escHtml(str: string): string { - return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') -} - -function formatDateDE(dateStr: string | null | undefined): string { - if (!dateStr) return '-' - try { - const date = new Date(dateStr) - if (isNaN(date.getTime())) return '-' - return date.toLocaleDateString('de-DE', { - day: '2-digit', - month: '2-digit', - year: 'numeric', - }) - } catch { - return '-' - } -} +export type { TOMDocumentOrgHeader, TOMDocumentRevision } from './tom-document/types-defaults' +export { createDefaultTOMDocumentOrgHeader } from './tom-document/types-defaults' +export { buildTOMDocumentHtml } from './tom-document/html-builder' diff --git a/admin-compliance/lib/sdk/tom-document/helpers.ts b/admin-compliance/lib/sdk/tom-document/helpers.ts new file mode 100644 index 0000000..3ec0578 --- /dev/null +++ b/admin-compliance/lib/sdk/tom-document/helpers.ts @@ -0,0 +1,26 @@ +// ============================================================================= +// TOM Document — Internal Helpers +// ============================================================================= + +export function escHtml(str: string): string { + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') +} + +export function formatDateDE(dateStr: string | null | undefined): string { + if (!dateStr) return '-' + try { + const date = new Date(dateStr) + if (isNaN(date.getTime())) return '-' + return date.toLocaleDateString('de-DE', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }) + } catch { + return '-' + } +} diff --git a/admin-compliance/lib/sdk/tom-document/html-builder.ts b/admin-compliance/lib/sdk/tom-document/html-builder.ts new file mode 100644 index 0000000..3bbac1c --- /dev/null +++ b/admin-compliance/lib/sdk/tom-document/html-builder.ts @@ -0,0 +1,82 @@ +// ============================================================================= +// TOM Document — HTML Document Builder (main entry point) +// ============================================================================= + +import type { + TOMGeneratorState, + DerivedTOM, + CompanyProfile, + RiskProfile, + ControlCategory, +} from '../tom-generator/types' +import { SDM_CATEGORY_MAPPING } from '../tom-generator/types' +import { + getControlById, + getAllCategories, +} from '../tom-generator/controls/loader' +import type { TOMComplianceCheckResult } from '../tom-compliance' +import type { TOMDocumentOrgHeader, TOMDocumentRevision } from './types-defaults' +import { CATEGORY_LABELS_DE } from './types-defaults' +import { escHtml, formatDateDE } from './helpers' +import { buildDocumentStyles } from './html-styles' +import { buildSections1to6 } from './html-sections-1-6' +import { buildSections7to11 } from './html-sections-7-11' + +export function buildTOMDocumentHtml( + derivedTOMs: DerivedTOM[], + orgHeader: TOMDocumentOrgHeader, + companyProfile: CompanyProfile | null, + riskProfile: RiskProfile | null, + complianceResult: TOMComplianceCheckResult | null, + revisions: TOMDocumentRevision[] +): string { + const today = new Date().toLocaleDateString('de-DE', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + }) + + const orgName = orgHeader.organizationName || 'Organisation' + const applicableTOMs = derivedTOMs.filter(t => t.applicability !== 'NOT_APPLICABLE') + + // Group TOMs by category + const tomsByCategory = new Map() + for (const tom of applicableTOMs) { + const control = getControlById(tom.controlId) + const cat = control?.category || 'REVIEW' + if (!tomsByCategory.has(cat)) tomsByCategory.set(cat, []) + tomsByCategory.get(cat)!.push(tom) + } + + // Build role map + const roleMap = new Map() + for (const tom of applicableTOMs) { + const role = tom.responsiblePerson || tom.responsibleDepartment || 'Nicht zugewiesen' + if (!roleMap.has(role)) roleMap.set(role, []) + const control = getControlById(tom.controlId) + roleMap.get(role)!.push(control?.code || tom.controlId) + } + + let html = buildDocumentStyles(escHtml(orgName)) + + html += buildSections1to6( + orgName, orgHeader, companyProfile, riskProfile, + applicableTOMs, tomsByCategory, today + ) + + html += buildSections7to11( + orgName, orgHeader, tomsByCategory, roleMap, + complianceResult, revisions, today + ) + + html += ` + + + +` + + return html +} diff --git a/admin-compliance/lib/sdk/tom-document/html-sections-1-6.ts b/admin-compliance/lib/sdk/tom-document/html-sections-1-6.ts new file mode 100644 index 0000000..df37862 --- /dev/null +++ b/admin-compliance/lib/sdk/tom-document/html-sections-1-6.ts @@ -0,0 +1,306 @@ +// ============================================================================= +// TOM Document — HTML Sections 1–6 +// ============================================================================= + +import type { DerivedTOM, CompanyProfile, RiskProfile, ControlCategory } from '../tom-generator/types' +import { getControlById, getAllCategories, getCategoryMetadata } from '../tom-generator/controls/loader' +import type { TOMDocumentOrgHeader } from './types-defaults' +import { + CATEGORY_LABELS_DE, + STATUS_LABELS_DE, + STATUS_BADGE_CLASSES, + APPLICABILITY_LABELS_DE, +} from './types-defaults' +import { escHtml, formatDateDE } from './helpers' + +export function buildSections1to6( + orgName: string, + orgHeader: TOMDocumentOrgHeader, + companyProfile: CompanyProfile | null, + riskProfile: RiskProfile | null, + applicableTOMs: DerivedTOM[], + tomsByCategory: Map, + today: string +): string { + let html = '' + html += buildCoverAndTOC(orgName, orgHeader, applicableTOMs, tomsByCategory, today) + html += buildSection1(orgName) + html += buildSection2(orgName, orgHeader, companyProfile, applicableTOMs, tomsByCategory) + html += buildSection3() + html += buildSection4(riskProfile) + html += buildSection5(tomsByCategory) + html += buildSection6(tomsByCategory) + return html +} + +function buildCoverAndTOC( + orgName: string, + orgHeader: TOMDocumentOrgHeader, + applicableTOMs: DerivedTOM[], + tomsByCategory: Map, + today: string +): string { + const sections = [ + 'Ziel und Zweck', + 'Geltungsbereich', + 'Grundprinzipien Art. 32', + 'Schutzbedarf und Risikoanalyse', + 'Massnahmen-Uebersicht', + 'Detaillierte Massnahmen', + 'SDM Gewaehrleistungsziele', + 'Verantwortlichkeiten', + 'Pruef- und Revisionszyklus', + 'Compliance-Status', + 'Aenderungshistorie', + ] + + return ` +
    +

    TOM-Dokumentation

    +
    Technische und Organisatorische Massnahmen gemaess Art. 32 DSGVO
    +
    +
    Organisation: ${escHtml(orgName)}
    + ${orgHeader.industry ? `
    Branche: ${escHtml(orgHeader.industry)}
    ` : ''} + ${orgHeader.dpoName ? `
    DSB: ${escHtml(orgHeader.dpoName)}
    ` : ''} + ${orgHeader.dpoContact ? `
    DSB-Kontakt: ${escHtml(orgHeader.dpoContact)}
    ` : ''} + ${orgHeader.responsiblePerson ? `
    Verantwortlicher: ${escHtml(orgHeader.responsiblePerson)}
    ` : ''} + ${orgHeader.itSecurityContact ? `
    IT-Sicherheit: ${escHtml(orgHeader.itSecurityContact)}
    ` : ''} + ${orgHeader.employeeCount ? `
    Mitarbeiter: ${escHtml(orgHeader.employeeCount)}
    ` : ''} + ${orgHeader.locations.length > 0 ? `
    Standorte: ${escHtml(orgHeader.locations.join(', '))}
    ` : ''} +
    + +
    + +
    +

    Inhaltsverzeichnis

    + ${sections.map((s, i) => `
    ${i + 1}. ${escHtml(s)}
    `).join('\n ')} +
    +` +} + +function buildSection1(orgName: string): string { + return ` +
    +
    1. Ziel und Zweck
    +
    +

    Diese TOM-Dokumentation beschreibt die technischen und organisatorischen Massnahmen + zum Schutz personenbezogener Daten bei ${escHtml(orgName)}. Sie dient + der Umsetzung folgender DSGVO-Anforderungen:

    + + + + + + +
    RechtsgrundlageInhalt
    Art. 32 Abs. 1 lit. a DSGVOPseudonymisierung und Verschluesselung personenbezogener Daten
    Art. 32 Abs. 1 lit. b DSGVOFaehigkeit, die Vertraulichkeit, Integritaet, Verfuegbarkeit und Belastbarkeit der Systeme und Dienste im Zusammenhang mit der Verarbeitung auf Dauer sicherzustellen
    Art. 32 Abs. 1 lit. c DSGVOFaehigkeit, die Verfuegbarkeit der personenbezogenen Daten und den Zugang zu ihnen bei einem physischen oder technischen Zwischenfall rasch wiederherzustellen
    Art. 32 Abs. 1 lit. d DSGVOVerfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit der technischen und organisatorischen Massnahmen
    +

    Die TOM-Dokumentation ist fester Bestandteil des Datenschutz-Managementsystems und wird + regelmaessig ueberprueft und aktualisiert.

    +
    +
    +` +} + +function buildSection2( + orgName: string, + orgHeader: TOMDocumentOrgHeader, + companyProfile: CompanyProfile | null, + applicableTOMs: DerivedTOM[], + tomsByCategory: Map +): string { + const industryInfo = companyProfile?.industry || orgHeader.industry || '' + const hostingInfo = companyProfile + ? `Unternehmen: ${escHtml(companyProfile.name || orgName)}, Groesse: ${escHtml(companyProfile.size || '-')}` + : '' + + return ` +
    +
    2. Geltungsbereich
    +
    +

    Diese TOM-Dokumentation gilt fuer alle IT-Systeme, Anwendungen und Verarbeitungsprozesse + von ${escHtml(orgName)}${industryInfo ? ` (Branche: ${escHtml(industryInfo)})` : ''}.

    + ${hostingInfo ? `

    ${hostingInfo}

    ` : ''} + ${orgHeader.locations.length > 0 ? `

    Standorte: ${escHtml(orgHeader.locations.join(', '))}

    ` : ''} +

    Die dokumentierten Massnahmen stammen aus zwei Quellen:

    +
      +
    • Embedded Library (TOM-xxx): Integrierte Kontrollbibliothek mit spezifischen Massnahmen fuer Art. 32 DSGVO
    • +
    • Canonical Control Library (CP-CLIB): Uebergreifende Kontrollbibliothek mit framework-uebergreifenden Massnahmen
    • +
    +

    Insgesamt umfasst dieses Dokument ${applicableTOMs.length} anwendbare Massnahmen + in ${tomsByCategory.size} Kategorien.

    +
    +
    +` +} + +function buildSection3(): string { + return ` +
    +
    3. Grundprinzipien Art. 32
    +
    +
    Vertraulichkeit: Schutz personenbezogener Daten vor unbefugter Kenntnisnahme durch Zutrittskontrolle, Zugangskontrolle, Zugriffskontrolle und Verschluesselung (Art. 32 Abs. 1 lit. b DSGVO).
    +
    Integritaet: Sicherstellung, dass personenbezogene Daten nicht unbefugt oder unbeabsichtigt veraendert werden koennen, durch Eingabekontrolle, Weitergabekontrolle und Protokollierung (Art. 32 Abs. 1 lit. b DSGVO).
    +
    Verfuegbarkeit und Belastbarkeit: Gewaehrleistung, dass Systeme und Dienste bei Lastspitzen und Stoerungen zuverlaessig funktionieren, durch Backup, Redundanz und Disaster Recovery (Art. 32 Abs. 1 lit. b DSGVO).
    +
    Rasche Wiederherstellbarkeit: Faehigkeit, nach einem physischen oder technischen Zwischenfall Daten und Systeme schnell wiederherzustellen, durch getestete Recovery-Prozesse (Art. 32 Abs. 1 lit. c DSGVO).
    +
    Regelmaessige Wirksamkeitspruefung: Verfahren zur regelmaessigen Ueberpruefung, Bewertung und Evaluierung der Wirksamkeit aller technischen und organisatorischen Massnahmen (Art. 32 Abs. 1 lit. d DSGVO).
    +
    +
    +` +} + +function buildSection4(riskProfile: RiskProfile | null): string { + let html = ` +
    +
    4. Schutzbedarf und Risikoanalyse
    +
    +` + if (riskProfile) { + html += `

    Die folgende Schutzbedarfsanalyse bildet die Grundlage fuer die Auswahl und Priorisierung + der technischen und organisatorischen Massnahmen:

    + + + + + + + + ${riskProfile.specialRisks.length > 0 ? `` : ''} + ${riskProfile.regulatoryRequirements.length > 0 ? `` : ''} +
    KriteriumBewertung
    Vertraulichkeit${riskProfile.ciaAssessment.confidentiality}/5
    Integritaet${riskProfile.ciaAssessment.integrity}/5
    Verfuegbarkeit${riskProfile.ciaAssessment.availability}/5
    Schutzniveau${escHtml(riskProfile.protectionLevel)}
    DSFA-Pflicht${riskProfile.dsfaRequired ? 'Ja' : 'Nein'}
    Spezialrisiken${escHtml(riskProfile.specialRisks.join(', '))}
    Regulatorische Anforderungen${escHtml(riskProfile.regulatoryRequirements.join(', '))}
    +` + } else { + html += `

    Die Schutzbedarfsanalyse wurde noch nicht durchgefuehrt. Fuehren Sie den + Risiko-Wizard im TOM-Generator durch, um den Schutzbedarf zu ermitteln.

    +` + } + html += `
    +
    +` + return html +} + +function buildSection5(tomsByCategory: Map): string { + const allCategories = getAllCategories() + + let html = ` +
    +
    5. Massnahmen-Uebersicht
    +
    +

    Die folgende Tabelle zeigt eine Uebersicht aller anwendbaren Massnahmen nach Kategorie:

    + + + + + + + + +` + for (const cat of allCategories) { + const tomsInCat = tomsByCategory.get(cat) + if (!tomsInCat || tomsInCat.length === 0) continue + + const implemented = tomsInCat.filter(t => t.implementationStatus === 'IMPLEMENTED').length + const partial = tomsInCat.filter(t => t.implementationStatus === 'PARTIAL').length + const notImpl = tomsInCat.filter(t => t.implementationStatus === 'NOT_IMPLEMENTED').length + const catLabel = CATEGORY_LABELS_DE[cat] || cat + + html += ` + + + + + + +` + } + + html += `
    KategorieGesamtUmgesetztTeilweiseOffen
    ${escHtml(catLabel)}${tomsInCat.length}${implemented}${partial}${notImpl}
    +
    +
    +` + return html +} + +function buildSection6(tomsByCategory: Map): string { + const allCategories = getAllCategories() + + let html = ` +
    +
    6. Detaillierte Massnahmen
    +
    +` + + for (const cat of allCategories) { + const tomsInCat = tomsByCategory.get(cat) + if (!tomsInCat || tomsInCat.length === 0) continue + + const catLabel = CATEGORY_LABELS_DE[cat] || cat + const catMeta = getCategoryMetadata(cat) + const gdprRef = catMeta?.gdprReference || '' + + html += `

    ${escHtml(catLabel)}${gdprRef ? ` (${escHtml(gdprRef)})` : ''}

    +` + + const sortedTOMs = [...tomsInCat].sort((a, b) => { + const codeA = getControlById(a.controlId)?.code || a.controlId + const codeB = getControlById(b.controlId)?.code || b.controlId + return codeA.localeCompare(codeB) + }) + + for (const tom of sortedTOMs) { + const control = getControlById(tom.controlId) + const code = control?.code || tom.controlId + const nameDE = control?.name?.de || tom.name + const descDE = control?.description?.de || tom.description + const typeLabel = control?.type === 'TECHNICAL' ? 'Technisch' : control?.type === 'ORGANIZATIONAL' ? 'Organisatorisch' : '-' + const statusLabel = STATUS_LABELS_DE[tom.implementationStatus] || tom.implementationStatus + const statusBadge = STATUS_BADGE_CLASSES[tom.implementationStatus] || 'badge-draft' + const applicabilityLabel = APPLICABILITY_LABELS_DE[tom.applicability] || tom.applicability + const responsible = [tom.responsiblePerson, tom.responsibleDepartment].filter(s => s && s.trim()).join(' / ') || '-' + const implDate = tom.implementationDate ? formatDateDE(typeof tom.implementationDate === 'string' ? tom.implementationDate : tom.implementationDate.toISOString()) : '-' + const reviewDate = tom.reviewDate ? formatDateDE(typeof tom.reviewDate === 'string' ? tom.reviewDate : tom.reviewDate.toISOString()) : '-' + + const evidenceInfo = tom.linkedEvidence.length > 0 + ? tom.linkedEvidence.join(', ') + : tom.evidenceGaps.length > 0 + ? `Fehlend: ${escHtml(tom.evidenceGaps.join(', '))}` + : '-' + + let mappingsHtml = '-' + if (control?.mappings && control.mappings.length > 0) { + mappingsHtml = control.mappings.map(m => `${escHtml(m.framework)}: ${escHtml(m.reference)}`).join('
    ') + } + + html += ` +
    +
    + ${escHtml(code)} — ${escHtml(nameDE)} + ${escHtml(statusLabel)} +
    +
    + + + + + + + + + + +
    Beschreibung${escHtml(descDE)}
    Massnahmentyp${escHtml(typeLabel)}
    Anwendbarkeit${escHtml(applicabilityLabel)}${tom.applicabilityReason ? ` — ${escHtml(tom.applicabilityReason)}` : ''}
    Umsetzungsstatus${escHtml(statusLabel)}
    Verantwortlich${escHtml(responsible)}
    Umsetzungsdatum${implDate}
    Naechste Pruefung${reviewDate}
    Evidence${evidenceInfo}
    Framework-Mappings${mappingsHtml}
    +
    +
    +` + } + } + + html += `
    +
    +` + return html +} diff --git a/admin-compliance/lib/sdk/tom-document/html-sections-7-11.ts b/admin-compliance/lib/sdk/tom-document/html-sections-7-11.ts new file mode 100644 index 0000000..d7fdbc9 --- /dev/null +++ b/admin-compliance/lib/sdk/tom-document/html-sections-7-11.ts @@ -0,0 +1,241 @@ +// ============================================================================= +// TOM Document — HTML Sections 7–11 +// ============================================================================= + +import type { DerivedTOM, ControlCategory } from '../tom-generator/types' +import { SDM_CATEGORY_MAPPING } from '../tom-generator/types' +import type { TOMComplianceCheckResult, TOMComplianceIssueSeverity } from '../tom-compliance' +import type { TOMDocumentOrgHeader, TOMDocumentRevision } from './types-defaults' +import { SEVERITY_LABELS_DE, SEVERITY_COLORS } from './types-defaults' +import { escHtml, formatDateDE } from './helpers' + +export function buildSections7to11( + orgName: string, + orgHeader: TOMDocumentOrgHeader, + tomsByCategory: Map, + roleMap: Map, + complianceResult: TOMComplianceCheckResult | null, + revisions: TOMDocumentRevision[], + today: string +): string { + let html = '' + html += buildSection7(tomsByCategory) + html += buildSection8(roleMap) + html += buildSection9(orgHeader) + html += buildSection10(complianceResult) + html += buildSection11(revisions, orgHeader, today) + return html +} + +function buildSection7(tomsByCategory: Map): string { + const allSDMGoals = [ + 'Verfuegbarkeit', + 'Integritaet', + 'Vertraulichkeit', + 'Nichtverkettung', + 'Intervenierbarkeit', + 'Transparenz', + 'Datenminimierung', + ] as const + + const sdmGoals: Array<{ goal: string; categories: ControlCategory[] }> = [] + for (const goal of allSDMGoals) { + const cats: ControlCategory[] = [] + for (const [cat, goals] of Object.entries(SDM_CATEGORY_MAPPING)) { + if (goals.includes(goal)) { + cats.push(cat as ControlCategory) + } + } + sdmGoals.push({ goal, categories: cats }) + } + + let html = ` +
    +
    7. SDM Gewaehrleistungsziele
    +
    +

    Die folgende Tabelle zeigt die Abdeckung der sieben Gewaehrleistungsziele des + Standard-Datenschutzmodells (SDM) durch die implementierten Massnahmen:

    + + + + + + + +` + + for (const { goal, categories } of sdmGoals) { + let totalInGoal = 0 + let implementedInGoal = 0 + for (const cat of categories) { + const tomsInCat = tomsByCategory.get(cat) || [] + totalInGoal += tomsInCat.length + implementedInGoal += tomsInCat.filter(t => t.implementationStatus === 'IMPLEMENTED').length + } + const percentage = totalInGoal > 0 ? Math.round((implementedInGoal / totalInGoal) * 100) : 0 + + html += ` + + + + + +` + } + + html += `
    GewaehrleistungszielAbgedecktGesamtAbdeckung (%)
    ${escHtml(goal)}${implementedInGoal}${totalInGoal}${percentage}%
    +
    +
    +` + return html +} + +function buildSection8(roleMap: Map): string { + let html = ` +
    +
    8. Verantwortlichkeiten
    +
    +

    Die folgende Rollenmatrix zeigt, welche Personen oder Abteilungen fuer welche Massnahmen + die Umsetzungsverantwortung tragen:

    + + +` + for (const [role, controls] of roleMap.entries()) { + html += ` + + + + +` + } + + html += `
    Rolle / VerantwortlichMassnahmenAnzahl
    ${escHtml(role)}${controls.map(c => escHtml(c)).join(', ')}${controls.length}
    +
    +
    +` + return html +} + +function buildSection9(orgHeader: TOMDocumentOrgHeader): string { + return ` +
    +
    9. Pruef- und Revisionszyklus
    +
    + + + + + + +
    EigenschaftWert
    Aktuelles Pruefintervall${escHtml(orgHeader.reviewInterval)}
    Letzte Pruefung${formatDateDE(orgHeader.lastReviewDate)}
    Naechste Pruefung${formatDateDE(orgHeader.nextReviewDate)}
    Aktuelle Version${escHtml(orgHeader.documentVersion)}
    +

    Bei jeder Pruefung wird die TOM-Dokumentation auf folgende Punkte ueberprueft:

    +
      +
    • Vollstaendigkeit aller Massnahmen (neue Systeme oder Verarbeitungen erfasst?)
    • +
    • Aktualitaet des Umsetzungsstatus (Aenderungen seit letzter Pruefung?)
    • +
    • Wirksamkeit der technischen Massnahmen (Penetration-Tests, Audit-Ergebnisse)
    • +
    • Angemessenheit der organisatorischen Massnahmen (Schulungen, Richtlinien aktuell?)
    • +
    • Abdeckung aller SDM-Gewaehrleistungsziele
    • +
    • Zuordnung von Verantwortlichkeiten zu allen Massnahmen
    • +
    +
    +
    +` +} + +function buildSection10(complianceResult: TOMComplianceCheckResult | null): string { + let html = ` +
    +
    10. Compliance-Status
    +
    +` + if (complianceResult) { + const scoreClass = complianceResult.score >= 90 ? 'score-excellent' + : complianceResult.score >= 75 ? 'score-good' + : complianceResult.score >= 50 ? 'score-needs-work' + : 'score-poor' + const scoreLabel = complianceResult.score >= 90 ? 'Ausgezeichnet' + : complianceResult.score >= 75 ? 'Gut' + : complianceResult.score >= 50 ? 'Verbesserungswuerdig' + : 'Mangelhaft' + + html += `

    ${complianceResult.score}/100 ${escHtml(scoreLabel)}

    + + + + + +
    KennzahlWert
    Gepruefte Massnahmen${complianceResult.stats.total}
    Bestanden${complianceResult.stats.passed}
    Beanstandungen${complianceResult.stats.failed}
    +` + if (complianceResult.issues.length > 0) { + html += `

    Befunde nach Schweregrad:

    + + +` + const severityOrder: TOMComplianceIssueSeverity[] = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] + for (const sev of severityOrder) { + const count = complianceResult.stats.bySeverity[sev] + if (count === 0) continue + const issuesForSev = complianceResult.issues.filter(i => i.severity === sev) + html += ` + + + + +` + } + html += `
    SchweregradAnzahlBefunde
    ${SEVERITY_LABELS_DE[sev]}${count}${issuesForSev.map(i => escHtml(i.title)).join('; ')}
    +` + } else { + html += `

    Keine Beanstandungen. Alle Massnahmen sind konform.

    +` + } + } else { + html += `

    Compliance-Check wurde noch nicht ausgefuehrt. Fuehren Sie den Check im + Export-Tab durch, um den Status in das Dokument aufzunehmen.

    +` + } + + html += `
    +
    +` + return html +} + +function buildSection11( + revisions: TOMDocumentRevision[], + orgHeader: TOMDocumentOrgHeader, + today: string +): string { + let html = ` +
    +
    11. Aenderungshistorie
    +
    + + +` + if (revisions.length > 0) { + for (const rev of revisions) { + html += ` + + + + + +` + } + } else { + html += ` + + + + + +` + } + + html += `
    VersionDatumAutorAenderungen
    ${escHtml(rev.version)}${formatDateDE(rev.date)}${escHtml(rev.author)}${escHtml(rev.changes)}
    ${escHtml(orgHeader.documentVersion)}${today}${escHtml(orgHeader.dpoName || orgHeader.responsiblePerson || '-')}Erstversion der TOM-Dokumentation
    +
    +
    +` + return html +} diff --git a/admin-compliance/lib/sdk/tom-document/html-styles.ts b/admin-compliance/lib/sdk/tom-document/html-styles.ts new file mode 100644 index 0000000..a7c9b9a --- /dev/null +++ b/admin-compliance/lib/sdk/tom-document/html-styles.ts @@ -0,0 +1,85 @@ +// ============================================================================= +// TOM Document — HTML/CSS Styles +// ============================================================================= + +export function buildDocumentStyles(orgNameEscaped: string): string { + return ` + + + +TOM-Dokumentation — ${orgNameEscaped} + + + +` +} diff --git a/admin-compliance/lib/sdk/tom-document/types-defaults.ts b/admin-compliance/lib/sdk/tom-document/types-defaults.ts new file mode 100644 index 0000000..dcdf0ab --- /dev/null +++ b/admin-compliance/lib/sdk/tom-document/types-defaults.ts @@ -0,0 +1,98 @@ +// ============================================================================= +// TOM Document — Types, Defaults & Label Constants +// ============================================================================= + +import type { ControlCategory } from '../tom-generator/types' +import type { TOMComplianceIssueSeverity } from '../tom-compliance' + +export interface TOMDocumentOrgHeader { + organizationName: string + industry: string + dpoName: string + dpoContact: string + responsiblePerson: string + itSecurityContact: string + locations: string[] + employeeCount: string + documentVersion: string + lastReviewDate: string + nextReviewDate: string + reviewInterval: string +} + +export interface TOMDocumentRevision { + version: string + date: string + author: string + changes: string +} + +export function createDefaultTOMDocumentOrgHeader(): TOMDocumentOrgHeader { + const now = new Date() + const nextYear = new Date() + nextYear.setFullYear(nextYear.getFullYear() + 1) + + return { + organizationName: '', + industry: '', + dpoName: '', + dpoContact: '', + responsiblePerson: '', + itSecurityContact: '', + locations: [], + employeeCount: '', + documentVersion: '1.0', + lastReviewDate: now.toISOString().split('T')[0], + nextReviewDate: nextYear.toISOString().split('T')[0], + reviewInterval: 'Jaehrlich', + } +} + +export const SEVERITY_LABELS_DE: Record = { + CRITICAL: 'Kritisch', + HIGH: 'Hoch', + MEDIUM: 'Mittel', + LOW: 'Niedrig', +} + +export const SEVERITY_COLORS: Record = { + CRITICAL: '#dc2626', + HIGH: '#ea580c', + MEDIUM: '#d97706', + LOW: '#6b7280', +} + +export const CATEGORY_LABELS_DE: Record = { + ACCESS_CONTROL: 'Zutrittskontrolle', + ADMISSION_CONTROL: 'Zugangskontrolle', + ACCESS_AUTHORIZATION: 'Zugriffskontrolle', + TRANSFER_CONTROL: 'Weitergabekontrolle', + INPUT_CONTROL: 'Eingabekontrolle', + ORDER_CONTROL: 'Auftragskontrolle', + AVAILABILITY: 'Verfuegbarkeit', + SEPARATION: 'Trennbarkeit', + ENCRYPTION: 'Verschluesselung', + PSEUDONYMIZATION: 'Pseudonymisierung', + RESILIENCE: 'Belastbarkeit', + RECOVERY: 'Wiederherstellbarkeit', + REVIEW: 'Ueberpruefung & Bewertung', +} + +export const STATUS_LABELS_DE: Record = { + IMPLEMENTED: 'Umgesetzt', + PARTIAL: 'Teilweise umgesetzt', + NOT_IMPLEMENTED: 'Nicht umgesetzt', +} + +export const STATUS_BADGE_CLASSES: Record = { + IMPLEMENTED: 'badge-active', + PARTIAL: 'badge-review', + NOT_IMPLEMENTED: 'badge-critical', +} + +export const APPLICABILITY_LABELS_DE: Record = { + REQUIRED: 'Erforderlich', + RECOMMENDED: 'Empfohlen', + OPTIONAL: 'Optional', + NOT_APPLICABLE: 'Nicht anwendbar', +} diff --git a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities.ts b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities.ts index 401942b..55901f4 100644 --- a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities.ts +++ b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities.ts @@ -1,813 +1,12 @@ /** - * Standard Processing Activities Catalog + * Standard Processing Activities Catalog — Barrel * * 28 predefined processing activities templates following Art. 30 DSGVO + * Split into domain modules; re-exported here for backward compatibility. */ -import { - ProcessingActivityFormData, - DataSubjectCategory, - PersonalDataCategory, - LegalBasisType, - ProtectionLevel, - LocalizedText, -} from '../types' - -export interface ProcessingActivityTemplate { - id: string - category: ProcessingActivityCategory - name: LocalizedText - description: LocalizedText - purposes: LocalizedText[] - dataSubjectCategories: DataSubjectCategory[] - personalDataCategories: PersonalDataCategory[] - suggestedLegalBasis: LegalBasisType[] - suggestedRetentionYears: number - suggestedProtectionLevel: ProtectionLevel - dpiaLikely: boolean - commonSystems: string[] - commonVendorCategories: string[] -} - -export type ProcessingActivityCategory = - | 'HR' // Human Resources - | 'SALES' // Vertrieb - | 'MARKETING' // Marketing - | 'FINANCE' // Finanzen - | 'IT' // IT & Sicherheit - | 'CUSTOMER_SERVICE' // Kundenservice - | 'WEBSITE' // Website & Apps - | 'GENERAL' // Allgemein - -export const PROCESSING_ACTIVITY_CATEGORY_META: Record = { - HR: { de: 'Personal', en: 'Human Resources' }, - SALES: { de: 'Vertrieb', en: 'Sales' }, - MARKETING: { de: 'Marketing', en: 'Marketing' }, - FINANCE: { de: 'Finanzen', en: 'Finance' }, - IT: { de: 'IT & Sicherheit', en: 'IT & Security' }, - CUSTOMER_SERVICE: { de: 'Kundenservice', en: 'Customer Service' }, - WEBSITE: { de: 'Website & Apps', en: 'Website & Apps' }, - GENERAL: { de: 'Allgemein', en: 'General' }, -} - -export const PROCESSING_ACTIVITY_TEMPLATES: ProcessingActivityTemplate[] = [ - // ========================================== - // HR - Human Resources - // ========================================== - { - id: 'tpl-hr-recruitment', - category: 'HR', - name: { - de: 'Bewerbermanagement', - en: 'Recruitment Management', - }, - description: { - de: 'Verarbeitung von Bewerberdaten im Rahmen des Recruiting-Prozesses', - en: 'Processing of applicant data as part of the recruitment process', - }, - purposes: [ - { de: 'Durchführung des Bewerbungsverfahrens', en: 'Conducting the application process' }, - { de: 'Prüfung der Eignung', en: 'Assessing suitability' }, - { de: 'Aufbau eines Talentpools (bei Einwilligung)', en: 'Building a talent pool (with consent)' }, - ], - dataSubjectCategories: ['APPLICANTS'], - personalDataCategories: [ - 'NAME', 'CONTACT', 'ADDRESS', 'DOB', 'EDUCATION_DATA', - 'EMPLOYMENT_DATA', 'PHOTO_VIDEO', - ], - suggestedLegalBasis: ['CONTRACT', 'CONSENT'], - suggestedRetentionYears: 0.5, // 6 Monate nach Absage - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['E-Recruiting', 'Personio', 'Workday'], - commonVendorCategories: ['HR_SOFTWARE', 'CLOUD_INFRASTRUCTURE'], - }, - { - id: 'tpl-hr-personnel', - category: 'HR', - name: { - de: 'Personalverwaltung', - en: 'Personnel Administration', - }, - description: { - de: 'Führung der Personalakte und Verwaltung des Beschäftigungsverhältnisses', - en: 'Maintaining personnel files and managing employment relationships', - }, - purposes: [ - { de: 'Führung der Personalakte', en: 'Maintaining personnel files' }, - { de: 'Durchführung des Arbeitsverhältnisses', en: 'Executing the employment relationship' }, - { de: 'Erfüllung gesetzlicher Pflichten', en: 'Fulfilling legal obligations' }, - ], - dataSubjectCategories: ['EMPLOYEES'], - personalDataCategories: [ - 'NAME', 'CONTACT', 'ADDRESS', 'DOB', 'ID_NUMBER', - 'SOCIAL_SECURITY', 'TAX_ID', 'BANK_ACCOUNT', 'EMPLOYMENT_DATA', - 'SALARY_DATA', 'EDUCATION_DATA', 'PHOTO_VIDEO', - ], - suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], - suggestedRetentionYears: 10, // Nach Beendigung - suggestedProtectionLevel: 'HIGH', - dpiaLikely: false, - commonSystems: ['SAP HCM', 'Personio', 'DATEV'], - commonVendorCategories: ['HR_SOFTWARE', 'ERP'], - }, - { - id: 'tpl-hr-payroll', - category: 'HR', - name: { - de: 'Lohn- und Gehaltsabrechnung', - en: 'Payroll Processing', - }, - description: { - de: 'Berechnung und Auszahlung von Gehältern, Abführung von Steuern und Sozialabgaben', - en: 'Calculation and payment of salaries, tax and social security contributions', - }, - purposes: [ - { de: 'Gehaltsberechnung und -auszahlung', en: 'Salary calculation and payment' }, - { de: 'Abführung von Lohnsteuer und Sozialabgaben', en: 'Payment of payroll taxes and social contributions' }, - { de: 'Erstellung von Lohnabrechnungen', en: 'Creating payslips' }, - ], - dataSubjectCategories: ['EMPLOYEES'], - personalDataCategories: [ - 'NAME', 'ADDRESS', 'DOB', 'SOCIAL_SECURITY', 'TAX_ID', - 'BANK_ACCOUNT', 'SALARY_DATA', 'EMPLOYMENT_DATA', - ], - suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], - suggestedRetentionYears: 10, // Handels- und Steuerrecht - suggestedProtectionLevel: 'HIGH', - dpiaLikely: false, - commonSystems: ['DATEV', 'SAP', 'Lexware'], - commonVendorCategories: ['ACCOUNTING', 'HR_SOFTWARE'], - }, - { - id: 'tpl-hr-time-tracking', - category: 'HR', - name: { - de: 'Arbeitszeiterfassung', - en: 'Time Tracking', - }, - description: { - de: 'Erfassung der Arbeitszeiten zur Einhaltung des Arbeitszeitgesetzes', - en: 'Recording working hours for compliance with working time regulations', - }, - purposes: [ - { de: 'Erfassung der Arbeitszeiten', en: 'Recording working hours' }, - { de: 'Einhaltung des Arbeitszeitgesetzes', en: 'Compliance with working time regulations' }, - { de: 'Grundlage für Gehaltsabrechnung', en: 'Basis for payroll' }, - ], - dataSubjectCategories: ['EMPLOYEES'], - personalDataCategories: ['NAME', 'EMPLOYMENT_DATA', 'USAGE_DATA'], - suggestedLegalBasis: ['LEGAL_OBLIGATION', 'CONTRACT'], - suggestedRetentionYears: 2, - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['ATOSS', 'Clockodo', 'Toggl'], - commonVendorCategories: ['HR_SOFTWARE'], - }, - { - id: 'tpl-hr-health-management', - category: 'HR', - name: { - de: 'Betriebliches Gesundheitsmanagement', - en: 'Occupational Health Management', - }, - description: { - de: 'Verwaltung von Arbeitsunfähigkeitsbescheinigungen und betriebsärztlichen Untersuchungen', - en: 'Management of sick notes and occupational health examinations', - }, - purposes: [ - { de: 'Verwaltung von Krankmeldungen', en: 'Managing sick leave' }, - { de: 'Organisation betriebsärztlicher Untersuchungen', en: 'Organizing occupational health examinations' }, - { de: 'Betriebliches Eingliederungsmanagement', en: 'Occupational reintegration management' }, - ], - dataSubjectCategories: ['EMPLOYEES'], - personalDataCategories: ['NAME', 'EMPLOYMENT_DATA', 'HEALTH_DATA'], - suggestedLegalBasis: ['ART9_EMPLOYMENT', 'LEGAL_OBLIGATION'], - suggestedRetentionYears: 3, - suggestedProtectionLevel: 'HIGH', - dpiaLikely: true, - commonSystems: ['HR-Software', 'BEM-System'], - commonVendorCategories: ['HR_SOFTWARE', 'CONSULTING'], - }, - - // ========================================== - // SALES - Vertrieb - // ========================================== - { - id: 'tpl-sales-crm', - category: 'SALES', - name: { - de: 'Kundenbeziehungsmanagement (CRM)', - en: 'Customer Relationship Management (CRM)', - }, - description: { - de: 'Verwaltung von Kundenbeziehungen, Kontakthistorie und Verkaufschancen', - en: 'Managing customer relationships, contact history, and sales opportunities', - }, - purposes: [ - { de: 'Pflege von Kundenbeziehungen', en: 'Maintaining customer relationships' }, - { de: 'Dokumentation von Kundenkontakten', en: 'Documenting customer contacts' }, - { de: 'Vertriebssteuerung', en: 'Sales management' }, - ], - dataSubjectCategories: ['CUSTOMERS', 'PROSPECTIVE_CUSTOMERS', 'BUSINESS_PARTNERS'], - personalDataCategories: [ - 'NAME', 'CONTACT', 'ADDRESS', 'CONTRACT_DATA', 'COMMUNICATION_DATA', - ], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 3, // Nach letztem Kontakt - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['Salesforce', 'HubSpot', 'Pipedrive', 'Microsoft Dynamics'], - commonVendorCategories: ['CRM'], - }, - { - id: 'tpl-sales-contract-management', - category: 'SALES', - name: { - de: 'Vertragsmanagement', - en: 'Contract Management', - }, - description: { - de: 'Verwaltung von Kundenverträgen, Angeboten und Aufträgen', - en: 'Managing customer contracts, quotes, and orders', - }, - purposes: [ - { de: 'Erstellung und Verwaltung von Verträgen', en: 'Creating and managing contracts' }, - { de: 'Angebotsverfolgung', en: 'Quote tracking' }, - { de: 'Auftragsabwicklung', en: 'Order processing' }, - ], - dataSubjectCategories: ['CUSTOMERS', 'BUSINESS_PARTNERS'], - personalDataCategories: [ - 'NAME', 'CONTACT', 'ADDRESS', 'CONTRACT_DATA', 'PAYMENT_DATA', - ], - suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], - suggestedRetentionYears: 10, // Handelsrechtlich - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['ERP', 'CRM', 'Vertragsverwaltung'], - commonVendorCategories: ['ERP', 'CRM'], - }, - - // ========================================== - // MARKETING - // ========================================== - { - id: 'tpl-marketing-newsletter', - category: 'MARKETING', - name: { - de: 'Newsletter-Versand', - en: 'Newsletter Distribution', - }, - description: { - de: 'Versand von E-Mail-Newslettern und Marketing-Kommunikation', - en: 'Sending email newsletters and marketing communications', - }, - purposes: [ - { de: 'Versand von Newsletter und Marketing-E-Mails', en: 'Sending newsletters and marketing emails' }, - { de: 'Messung von Öffnungs- und Klickraten', en: 'Measuring open and click rates' }, - ], - dataSubjectCategories: ['NEWSLETTER_SUBSCRIBERS', 'CUSTOMERS'], - personalDataCategories: ['NAME', 'CONTACT', 'USAGE_DATA'], - suggestedLegalBasis: ['CONSENT'], - suggestedRetentionYears: 0, // Bis Widerruf - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['Mailchimp', 'CleverReach', 'Sendinblue'], - commonVendorCategories: ['EMAIL', 'MARKETING'], - }, - { - id: 'tpl-marketing-advertising', - category: 'MARKETING', - name: { - de: 'Online-Werbung', - en: 'Online Advertising', - }, - description: { - de: 'Schaltung und Auswertung von Online-Werbeanzeigen', - en: 'Running and analyzing online advertisements', - }, - purposes: [ - { de: 'Schaltung von Online-Werbung', en: 'Running online advertisements' }, - { de: 'Conversion-Tracking', en: 'Conversion tracking' }, - { de: 'Retargeting', en: 'Retargeting' }, - ], - dataSubjectCategories: ['WEBSITE_USERS'], - personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA'], - suggestedLegalBasis: ['CONSENT'], - suggestedRetentionYears: 1, - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: true, - commonSystems: ['Google Ads', 'Meta Ads', 'LinkedIn Ads'], - commonVendorCategories: ['MARKETING', 'ANALYTICS'], - }, - { - id: 'tpl-marketing-events', - category: 'MARKETING', - name: { - de: 'Veranstaltungsmanagement', - en: 'Event Management', - }, - description: { - de: 'Organisation und Durchführung von Veranstaltungen, Messen und Webinaren', - en: 'Organizing and conducting events, trade shows, and webinars', - }, - purposes: [ - { de: 'Teilnehmerregistrierung', en: 'Participant registration' }, - { de: 'Veranstaltungsdurchführung', en: 'Event execution' }, - { de: 'Nachbereitung und Follow-up', en: 'Follow-up activities' }, - ], - dataSubjectCategories: ['CUSTOMERS', 'PROSPECTIVE_CUSTOMERS', 'BUSINESS_PARTNERS'], - personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'PHOTO_VIDEO'], - suggestedLegalBasis: ['CONTRACT', 'CONSENT'], - suggestedRetentionYears: 2, - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['Eventbrite', 'GoToWebinar', 'Zoom'], - commonVendorCategories: ['MARKETING', 'COMMUNICATION'], - }, - - // ========================================== - // FINANCE - // ========================================== - { - id: 'tpl-finance-accounting', - category: 'FINANCE', - name: { - de: 'Finanzbuchhaltung', - en: 'Financial Accounting', - }, - description: { - de: 'Führung der Finanzbuchhaltung, Rechnungsstellung und Zahlungsabwicklung', - en: 'Financial accounting, invoicing, and payment processing', - }, - purposes: [ - { de: 'Buchführung und Rechnungswesen', en: 'Bookkeeping and accounting' }, - { de: 'Rechnungsstellung', en: 'Invoicing' }, - { de: 'Zahlungsabwicklung', en: 'Payment processing' }, - ], - dataSubjectCategories: ['CUSTOMERS', 'SUPPLIERS', 'BUSINESS_PARTNERS'], - personalDataCategories: [ - 'NAME', 'ADDRESS', 'BANK_ACCOUNT', 'PAYMENT_DATA', 'CONTRACT_DATA', 'TAX_ID', - ], - suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], - suggestedRetentionYears: 10, // HGB/AO - suggestedProtectionLevel: 'HIGH', - dpiaLikely: false, - commonSystems: ['DATEV', 'SAP', 'Lexware', 'Xero'], - commonVendorCategories: ['ACCOUNTING', 'ERP'], - }, - { - id: 'tpl-finance-debt-collection', - category: 'FINANCE', - name: { - de: 'Forderungsmanagement', - en: 'Debt Collection', - }, - description: { - de: 'Verwaltung offener Forderungen und Mahnwesen', - en: 'Managing outstanding receivables and dunning', - }, - purposes: [ - { de: 'Überwachung offener Forderungen', en: 'Monitoring outstanding receivables' }, - { de: 'Mahnwesen', en: 'Dunning process' }, - { de: 'Inkasso bei Bedarf', en: 'Debt collection if necessary' }, - ], - dataSubjectCategories: ['CUSTOMERS'], - personalDataCategories: ['NAME', 'ADDRESS', 'CONTACT', 'PAYMENT_DATA', 'CONTRACT_DATA'], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 10, - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['ERP', 'Inkasso-Software'], - commonVendorCategories: ['ACCOUNTING', 'LEGAL'], - }, - - // ========================================== - // IT & SICHERHEIT - // ========================================== - { - id: 'tpl-it-user-management', - category: 'IT', - name: { - de: 'IT-Benutzerverwaltung', - en: 'IT User Management', - }, - description: { - de: 'Verwaltung von Benutzerkonten, Zugriffsrechten und Authentifizierung', - en: 'Managing user accounts, access rights, and authentication', - }, - purposes: [ - { de: 'Verwaltung von Benutzerkonten', en: 'Managing user accounts' }, - { de: 'Zugriffssteuerung', en: 'Access control' }, - { de: 'Single Sign-On', en: 'Single Sign-On' }, - ], - dataSubjectCategories: ['EMPLOYEES'], - personalDataCategories: ['NAME', 'CONTACT', 'LOGIN_DATA', 'USAGE_DATA'], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 1, // Nach Kontoschließung - suggestedProtectionLevel: 'HIGH', - dpiaLikely: false, - commonSystems: ['Active Directory', 'Okta', 'Azure AD'], - commonVendorCategories: ['SECURITY', 'CLOUD_INFRASTRUCTURE'], - }, - { - id: 'tpl-it-logging', - category: 'IT', - name: { - de: 'IT-Protokollierung', - en: 'IT Logging', - }, - description: { - de: 'Protokollierung von IT-Aktivitäten zur Sicherheit und Fehleranalyse', - en: 'Logging IT activities for security and error analysis', - }, - purposes: [ - { de: 'Sicherheitsüberwachung', en: 'Security monitoring' }, - { de: 'Fehleranalyse', en: 'Error analysis' }, - { de: 'Nachvollziehbarkeit', en: 'Traceability' }, - ], - dataSubjectCategories: ['EMPLOYEES', 'CUSTOMERS', 'WEBSITE_USERS'], - personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA', 'LOGIN_DATA'], - suggestedLegalBasis: ['LEGITIMATE_INTEREST'], - suggestedRetentionYears: 1, - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['Splunk', 'ELK Stack', 'Datadog'], - commonVendorCategories: ['SECURITY', 'ANALYTICS'], - }, - { - id: 'tpl-it-video-surveillance', - category: 'IT', - name: { - de: 'Videoüberwachung', - en: 'Video Surveillance', - }, - description: { - de: 'Videoüberwachung von Geschäftsräumen zum Schutz vor Diebstahl und Vandalismus', - en: 'Video surveillance of business premises for theft and vandalism prevention', - }, - purposes: [ - { de: 'Schutz vor Diebstahl und Vandalismus', en: 'Protection against theft and vandalism' }, - { de: 'Zugangskontrolle', en: 'Access control' }, - { de: 'Beweissicherung', en: 'Evidence preservation' }, - ], - dataSubjectCategories: ['EMPLOYEES', 'VISITORS', 'CUSTOMERS'], - personalDataCategories: ['PHOTO_VIDEO', 'BIOMETRIC_DATA'], - suggestedLegalBasis: ['LEGITIMATE_INTEREST'], - suggestedRetentionYears: 0.1, // 72 Stunden - suggestedProtectionLevel: 'HIGH', - dpiaLikely: true, - commonSystems: ['CCTV-System'], - commonVendorCategories: ['SECURITY'], - }, - { - id: 'tpl-it-backup', - category: 'IT', - name: { - de: 'Datensicherung (Backup)', - en: 'Data Backup', - }, - description: { - de: 'Regelmäßige Sicherung von Unternehmensdaten', - en: 'Regular backup of company data', - }, - purposes: [ - { de: 'Datensicherung', en: 'Data backup' }, - { de: 'Disaster Recovery', en: 'Disaster Recovery' }, - { de: 'Geschäftskontinuität', en: 'Business continuity' }, - ], - dataSubjectCategories: ['EMPLOYEES', 'CUSTOMERS', 'SUPPLIERS'], - personalDataCategories: ['NAME', 'CONTACT', 'CONTRACT_DATA', 'COMMUNICATION_DATA'], - suggestedLegalBasis: ['LEGITIMATE_INTEREST', 'LEGAL_OBLIGATION'], - suggestedRetentionYears: 1, // Je nach Backup-Konzept - suggestedProtectionLevel: 'HIGH', - dpiaLikely: false, - commonSystems: ['Veeam', 'AWS Backup', 'Azure Backup'], - commonVendorCategories: ['BACKUP', 'CLOUD_INFRASTRUCTURE'], - }, - - // ========================================== - // CUSTOMER SERVICE - // ========================================== - { - id: 'tpl-cs-support', - category: 'CUSTOMER_SERVICE', - name: { - de: 'Kundenbetreuung und Support', - en: 'Customer Support', - }, - description: { - de: 'Bearbeitung von Kundenanfragen, Beschwerden und Support-Tickets', - en: 'Handling customer inquiries, complaints, and support tickets', - }, - purposes: [ - { de: 'Bearbeitung von Kundenanfragen', en: 'Handling customer inquiries' }, - { de: 'Beschwerdemanagement', en: 'Complaint management' }, - { de: 'Technischer Support', en: 'Technical support' }, - ], - dataSubjectCategories: ['CUSTOMERS'], - personalDataCategories: ['NAME', 'CONTACT', 'CONTRACT_DATA', 'COMMUNICATION_DATA'], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 3, - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['Zendesk', 'Freshdesk', 'Intercom'], - commonVendorCategories: ['SUPPORT', 'CRM'], - }, - { - id: 'tpl-cs-satisfaction', - category: 'CUSTOMER_SERVICE', - name: { - de: 'Kundenzufriedenheitsbefragungen', - en: 'Customer Satisfaction Surveys', - }, - description: { - de: 'Durchführung von Umfragen zur Messung der Kundenzufriedenheit', - en: 'Conducting surveys to measure customer satisfaction', - }, - purposes: [ - { de: 'Messung der Kundenzufriedenheit', en: 'Measuring customer satisfaction' }, - { de: 'Qualitätsverbesserung', en: 'Quality improvement' }, - ], - dataSubjectCategories: ['CUSTOMERS'], - personalDataCategories: ['NAME', 'CONTACT', 'USAGE_DATA'], - suggestedLegalBasis: ['CONSENT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 2, - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['SurveyMonkey', 'Typeform', 'NPS-Tools'], - commonVendorCategories: ['ANALYTICS', 'MARKETING'], - }, - - // ========================================== - // WEBSITE & APPS - // ========================================== - { - id: 'tpl-web-analytics', - category: 'WEBSITE', - name: { - de: 'Web-Analyse', - en: 'Web Analytics', - }, - description: { - de: 'Analyse des Nutzerverhaltens auf der Website zur Optimierung', - en: 'Analyzing user behavior on the website for optimization', - }, - purposes: [ - { de: 'Analyse des Nutzerverhaltens', en: 'Analyzing user behavior' }, - { de: 'Website-Optimierung', en: 'Website optimization' }, - { de: 'Conversion-Tracking', en: 'Conversion tracking' }, - ], - dataSubjectCategories: ['WEBSITE_USERS'], - personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA', 'LOCATION_DATA'], - suggestedLegalBasis: ['CONSENT'], - suggestedRetentionYears: 2, - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['Google Analytics', 'Matomo', 'Plausible'], - commonVendorCategories: ['ANALYTICS'], - }, - { - id: 'tpl-web-contact-form', - category: 'WEBSITE', - name: { - de: 'Kontaktformular', - en: 'Contact Form', - }, - description: { - de: 'Verarbeitung von Anfragen über das Website-Kontaktformular', - en: 'Processing inquiries submitted via the website contact form', - }, - purposes: [ - { de: 'Bearbeitung von Kontaktanfragen', en: 'Processing contact inquiries' }, - { de: 'Kommunikation mit Interessenten', en: 'Communication with prospects' }, - ], - dataSubjectCategories: ['PROSPECTIVE_CUSTOMERS', 'WEBSITE_USERS'], - personalDataCategories: ['NAME', 'CONTACT', 'COMMUNICATION_DATA'], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 1, - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['CRM', 'E-Mail-System'], - commonVendorCategories: ['CRM', 'EMAIL'], - }, - { - id: 'tpl-web-user-accounts', - category: 'WEBSITE', - name: { - de: 'Benutzerkonten / Kundenportal', - en: 'User Accounts / Customer Portal', - }, - description: { - de: 'Verwaltung von Benutzerkonten im Kundenportal oder Online-Shop', - en: 'Managing user accounts in customer portal or online shop', - }, - purposes: [ - { de: 'Bereitstellung des Kundenportals', en: 'Providing customer portal' }, - { de: 'Benutzerverwaltung', en: 'User management' }, - { de: 'Personalisierung', en: 'Personalization' }, - ], - dataSubjectCategories: ['CUSTOMERS', 'APP_USERS'], - personalDataCategories: ['NAME', 'CONTACT', 'LOGIN_DATA', 'USAGE_DATA', 'CONTRACT_DATA'], - suggestedLegalBasis: ['CONTRACT'], - suggestedRetentionYears: 1, // Nach Kontoschließung - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['E-Commerce', 'CRM', 'Auth0'], - commonVendorCategories: ['HOSTING', 'CRM', 'SECURITY'], - }, - { - id: 'tpl-web-cookies', - category: 'WEBSITE', - name: { - de: 'Cookie-Verwaltung', - en: 'Cookie Management', - }, - description: { - de: 'Verwaltung von Cookies und Einholung von Cookie-Einwilligungen', - en: 'Managing cookies and obtaining cookie consents', - }, - purposes: [ - { de: 'Speicherung von Cookie-Präferenzen', en: 'Storing cookie preferences' }, - { de: 'Einwilligungsmanagement', en: 'Consent management' }, - ], - dataSubjectCategories: ['WEBSITE_USERS'], - personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA'], - suggestedLegalBasis: ['CONSENT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 1, - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['Cookiebot', 'Usercentrics', 'OneTrust'], - commonVendorCategories: ['ANALYTICS', 'SECURITY'], - }, - - // ========================================== - // GENERAL - // ========================================== - { - id: 'tpl-gen-communication', - category: 'GENERAL', - name: { - de: 'Geschäftliche Kommunikation', - en: 'Business Communication', - }, - description: { - de: 'E-Mail-Kommunikation, Telefonie und Messaging im Geschäftsverkehr', - en: 'Email communication, telephony, and messaging in business operations', - }, - purposes: [ - { de: 'Geschäftliche Kommunikation', en: 'Business communication' }, - { de: 'Dokumentation von Korrespondenz', en: 'Documentation of correspondence' }, - ], - dataSubjectCategories: ['CUSTOMERS', 'SUPPLIERS', 'BUSINESS_PARTNERS', 'EMPLOYEES'], - personalDataCategories: ['NAME', 'CONTACT', 'COMMUNICATION_DATA'], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 6, // Handelsrechtlich relevant - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['Microsoft 365', 'Google Workspace', 'Slack'], - commonVendorCategories: ['EMAIL', 'COMMUNICATION', 'CLOUD_INFRASTRUCTURE'], - }, - { - id: 'tpl-gen-visitor', - category: 'GENERAL', - name: { - de: 'Besucherverwaltung', - en: 'Visitor Management', - }, - description: { - de: 'Erfassung und Verwaltung von Besuchern in Geschäftsräumen', - en: 'Recording and managing visitors in business premises', - }, - purposes: [ - { de: 'Zutrittskontrolle', en: 'Access control' }, - { de: 'Sicherheit', en: 'Security' }, - { de: 'Nachvollziehbarkeit', en: 'Traceability' }, - ], - dataSubjectCategories: ['VISITORS'], - personalDataCategories: ['NAME', 'CONTACT', 'PHOTO_VIDEO'], - suggestedLegalBasis: ['LEGITIMATE_INTEREST'], - suggestedRetentionYears: 0.1, // 1 Monat - suggestedProtectionLevel: 'LOW', - dpiaLikely: false, - commonSystems: ['Besuchermanagement-System'], - commonVendorCategories: ['SECURITY'], - }, - { - id: 'tpl-gen-supplier', - category: 'GENERAL', - name: { - de: 'Lieferantenverwaltung', - en: 'Supplier Management', - }, - description: { - de: 'Verwaltung von Lieferantenbeziehungen und Beschaffung', - en: 'Managing supplier relationships and procurement', - }, - purposes: [ - { de: 'Lieferantenverwaltung', en: 'Supplier management' }, - { de: 'Beschaffung', en: 'Procurement' }, - { de: 'Qualitätsmanagement', en: 'Quality management' }, - ], - dataSubjectCategories: ['SUPPLIERS', 'BUSINESS_PARTNERS'], - personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'CONTRACT_DATA', 'BANK_ACCOUNT'], - suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], - suggestedRetentionYears: 10, - suggestedProtectionLevel: 'MEDIUM', - dpiaLikely: false, - commonSystems: ['ERP', 'Lieferantenportal'], - commonVendorCategories: ['ERP'], - }, - { - id: 'tpl-gen-whistleblower', - category: 'GENERAL', - name: { - de: 'Hinweisgebersystem', - en: 'Whistleblower System', - }, - description: { - de: 'Entgegennahme und Bearbeitung von Hinweisen gemäß Hinweisgeberschutzgesetz', - en: 'Receiving and processing reports according to whistleblower protection law', - }, - purposes: [ - { de: 'Entgegennahme von Hinweisen', en: 'Receiving reports' }, - { de: 'Untersuchung von Verstößen', en: 'Investigating violations' }, - { de: 'Schutz von Hinweisgebern', en: 'Protecting whistleblowers' }, - ], - dataSubjectCategories: ['EMPLOYEES', 'BUSINESS_PARTNERS'], - personalDataCategories: ['NAME', 'CONTACT', 'COMMUNICATION_DATA'], - suggestedLegalBasis: ['LEGAL_OBLIGATION'], - suggestedRetentionYears: 3, - suggestedProtectionLevel: 'HIGH', - dpiaLikely: true, - commonSystems: ['Hinweisgeberportal'], - commonVendorCategories: ['SECURITY', 'LEGAL'], - }, -] - -/** - * Get templates by category - */ -export function getTemplatesByCategory( - category: ProcessingActivityCategory -): ProcessingActivityTemplate[] { - return PROCESSING_ACTIVITY_TEMPLATES.filter((t) => t.category === category) -} - -/** - * Get template by ID - */ -export function getTemplateById(id: string): ProcessingActivityTemplate | undefined { - return PROCESSING_ACTIVITY_TEMPLATES.find((t) => t.id === id) -} - -/** - * Get all categories with their templates - */ -export function getGroupedTemplates(): Map { - const grouped = new Map() - - for (const template of PROCESSING_ACTIVITY_TEMPLATES) { - const existing = grouped.get(template.category) || [] - grouped.set(template.category, [...existing, template]) - } - - return grouped -} - -/** - * Create form data from template - */ -export function createFormDataFromTemplate( - template: ProcessingActivityTemplate, - organizationDefaults?: { - responsible?: ProcessingActivityFormData['responsible'] - dpoContact?: ProcessingActivityFormData['dpoContact'] - } -): Partial { - return { - vvtId: '', // Will be generated - name: template.name, - purposes: template.purposes, - dataSubjectCategories: template.dataSubjectCategories, - personalDataCategories: template.personalDataCategories, - legalBasis: template.suggestedLegalBasis.map((type) => ({ type })), - protectionLevel: template.suggestedProtectionLevel, - dpiaRequired: template.dpiaLikely, - retentionPeriod: { - duration: template.suggestedRetentionYears, - durationUnit: 'YEARS', - description: { de: '', en: '' }, - }, - recipientCategories: [], - thirdCountryTransfers: [], - technicalMeasures: [], - dataSources: [], - systems: [], - dataFlows: [], - subProcessors: [], - owner: '', - responsible: organizationDefaults?.responsible, - dpoContact: organizationDefaults?.dpoContact, - } -} +export * from './processing-activities/types' +export * from './processing-activities/hr-sales' +export * from './processing-activities/marketing-finance' +export * from './processing-activities/it-customer-web-general' +export * from './processing-activities/helpers' diff --git a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/helpers.ts b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/helpers.ts new file mode 100644 index 0000000..46b8f31 --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/helpers.ts @@ -0,0 +1,87 @@ +/** + * Processing Activities — Helper Functions + */ + +import type { ProcessingActivityFormData } from '../../types' +import type { ProcessingActivityTemplate, ProcessingActivityCategory } from './types' +import { HR_TEMPLATES, SALES_TEMPLATES } from './hr-sales' +import { MARKETING_TEMPLATES, FINANCE_TEMPLATES } from './marketing-finance' +import { IT_TEMPLATES, CUSTOMER_SERVICE_TEMPLATES, WEBSITE_TEMPLATES, GENERAL_TEMPLATES } from './it-customer-web-general' + +export const PROCESSING_ACTIVITY_TEMPLATES: ProcessingActivityTemplate[] = [ + ...HR_TEMPLATES, + ...SALES_TEMPLATES, + ...MARKETING_TEMPLATES, + ...FINANCE_TEMPLATES, + ...IT_TEMPLATES, + ...CUSTOMER_SERVICE_TEMPLATES, + ...WEBSITE_TEMPLATES, + ...GENERAL_TEMPLATES, +] + +/** + * Get templates by category + */ +export function getTemplatesByCategory( + category: ProcessingActivityCategory +): ProcessingActivityTemplate[] { + return PROCESSING_ACTIVITY_TEMPLATES.filter((t) => t.category === category) +} + +/** + * Get template by ID + */ +export function getTemplateById(id: string): ProcessingActivityTemplate | undefined { + return PROCESSING_ACTIVITY_TEMPLATES.find((t) => t.id === id) +} + +/** + * Get all categories with their templates + */ +export function getGroupedTemplates(): Map { + const grouped = new Map() + + for (const template of PROCESSING_ACTIVITY_TEMPLATES) { + const existing = grouped.get(template.category) || [] + grouped.set(template.category, [...existing, template]) + } + + return grouped +} + +/** + * Create form data from template + */ +export function createFormDataFromTemplate( + template: ProcessingActivityTemplate, + organizationDefaults?: { + responsible?: ProcessingActivityFormData['responsible'] + dpoContact?: ProcessingActivityFormData['dpoContact'] + } +): Partial { + return { + vvtId: '', + name: template.name, + purposes: template.purposes, + dataSubjectCategories: template.dataSubjectCategories, + personalDataCategories: template.personalDataCategories, + legalBasis: template.suggestedLegalBasis.map((type) => ({ type })), + protectionLevel: template.suggestedProtectionLevel, + dpiaRequired: template.dpiaLikely, + retentionPeriod: { + duration: template.suggestedRetentionYears, + durationUnit: 'YEARS', + description: { de: '', en: '' }, + }, + recipientCategories: [], + thirdCountryTransfers: [], + technicalMeasures: [], + dataSources: [], + systems: [], + dataFlows: [], + subProcessors: [], + owner: '', + responsible: organizationDefaults?.responsible, + dpoContact: organizationDefaults?.dpoContact, + } +} diff --git a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/hr-sales.ts b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/hr-sales.ts new file mode 100644 index 0000000..ed2dd32 --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/hr-sales.ts @@ -0,0 +1,200 @@ +/** + * Processing Activities — HR & Sales Templates + */ + +import { ProcessingActivityTemplate } from './types' + +export const HR_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-hr-recruitment', + category: 'HR', + name: { + de: 'Bewerbermanagement', + en: 'Recruitment Management', + }, + description: { + de: 'Verarbeitung von Bewerberdaten im Rahmen des Recruiting-Prozesses', + en: 'Processing of applicant data as part of the recruitment process', + }, + purposes: [ + { de: 'Durchführung des Bewerbungsverfahrens', en: 'Conducting the application process' }, + { de: 'Prüfung der Eignung', en: 'Assessing suitability' }, + { de: 'Aufbau eines Talentpools (bei Einwilligung)', en: 'Building a talent pool (with consent)' }, + ], + dataSubjectCategories: ['APPLICANTS'], + personalDataCategories: [ + 'NAME', 'CONTACT', 'ADDRESS', 'DOB', 'EDUCATION_DATA', + 'EMPLOYMENT_DATA', 'PHOTO_VIDEO', + ], + suggestedLegalBasis: ['CONTRACT', 'CONSENT'], + suggestedRetentionYears: 0.5, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['E-Recruiting', 'Personio', 'Workday'], + commonVendorCategories: ['HR_SOFTWARE', 'CLOUD_INFRASTRUCTURE'], + }, + { + id: 'tpl-hr-personnel', + category: 'HR', + name: { + de: 'Personalverwaltung', + en: 'Personnel Administration', + }, + description: { + de: 'Führung der Personalakte und Verwaltung des Beschäftigungsverhältnisses', + en: 'Maintaining personnel files and managing employment relationships', + }, + purposes: [ + { de: 'Führung der Personalakte', en: 'Maintaining personnel files' }, + { de: 'Durchführung des Arbeitsverhältnisses', en: 'Executing the employment relationship' }, + { de: 'Erfüllung gesetzlicher Pflichten', en: 'Fulfilling legal obligations' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: [ + 'NAME', 'CONTACT', 'ADDRESS', 'DOB', 'ID_NUMBER', + 'SOCIAL_SECURITY', 'TAX_ID', 'BANK_ACCOUNT', 'EMPLOYMENT_DATA', + 'SALARY_DATA', 'EDUCATION_DATA', 'PHOTO_VIDEO', + ], + suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], + suggestedRetentionYears: 10, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: false, + commonSystems: ['SAP HCM', 'Personio', 'DATEV'], + commonVendorCategories: ['HR_SOFTWARE', 'ERP'], + }, + { + id: 'tpl-hr-payroll', + category: 'HR', + name: { + de: 'Lohn- und Gehaltsabrechnung', + en: 'Payroll Processing', + }, + description: { + de: 'Berechnung und Auszahlung von Gehältern, Abführung von Steuern und Sozialabgaben', + en: 'Calculation and payment of salaries, tax and social security contributions', + }, + purposes: [ + { de: 'Gehaltsberechnung und -auszahlung', en: 'Salary calculation and payment' }, + { de: 'Abführung von Lohnsteuer und Sozialabgaben', en: 'Payment of payroll taxes and social contributions' }, + { de: 'Erstellung von Lohnabrechnungen', en: 'Creating payslips' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: [ + 'NAME', 'ADDRESS', 'DOB', 'SOCIAL_SECURITY', 'TAX_ID', + 'BANK_ACCOUNT', 'SALARY_DATA', 'EMPLOYMENT_DATA', + ], + suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], + suggestedRetentionYears: 10, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: false, + commonSystems: ['DATEV', 'SAP', 'Lexware'], + commonVendorCategories: ['ACCOUNTING', 'HR_SOFTWARE'], + }, + { + id: 'tpl-hr-time-tracking', + category: 'HR', + name: { + de: 'Arbeitszeiterfassung', + en: 'Time Tracking', + }, + description: { + de: 'Erfassung der Arbeitszeiten zur Einhaltung des Arbeitszeitgesetzes', + en: 'Recording working hours for compliance with working time regulations', + }, + purposes: [ + { de: 'Erfassung der Arbeitszeiten', en: 'Recording working hours' }, + { de: 'Einhaltung des Arbeitszeitgesetzes', en: 'Compliance with working time regulations' }, + { de: 'Grundlage für Gehaltsabrechnung', en: 'Basis for payroll' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: ['NAME', 'EMPLOYMENT_DATA', 'USAGE_DATA'], + suggestedLegalBasis: ['LEGAL_OBLIGATION', 'CONTRACT'], + suggestedRetentionYears: 2, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['ATOSS', 'Clockodo', 'Toggl'], + commonVendorCategories: ['HR_SOFTWARE'], + }, + { + id: 'tpl-hr-health-management', + category: 'HR', + name: { + de: 'Betriebliches Gesundheitsmanagement', + en: 'Occupational Health Management', + }, + description: { + de: 'Verwaltung von Arbeitsunfähigkeitsbescheinigungen und betriebsärztlichen Untersuchungen', + en: 'Management of sick notes and occupational health examinations', + }, + purposes: [ + { de: 'Verwaltung von Krankmeldungen', en: 'Managing sick leave' }, + { de: 'Organisation betriebsärztlicher Untersuchungen', en: 'Organizing occupational health examinations' }, + { de: 'Betriebliches Eingliederungsmanagement', en: 'Occupational reintegration management' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: ['NAME', 'EMPLOYMENT_DATA', 'HEALTH_DATA'], + suggestedLegalBasis: ['ART9_EMPLOYMENT', 'LEGAL_OBLIGATION'], + suggestedRetentionYears: 3, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: true, + commonSystems: ['HR-Software', 'BEM-System'], + commonVendorCategories: ['HR_SOFTWARE', 'CONSULTING'], + }, +] + +export const SALES_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-sales-crm', + category: 'SALES', + name: { + de: 'Kundenbeziehungsmanagement (CRM)', + en: 'Customer Relationship Management (CRM)', + }, + description: { + de: 'Verwaltung von Kundenbeziehungen, Kontakthistorie und Verkaufschancen', + en: 'Managing customer relationships, contact history, and sales opportunities', + }, + purposes: [ + { de: 'Pflege von Kundenbeziehungen', en: 'Maintaining customer relationships' }, + { de: 'Dokumentation von Kundenkontakten', en: 'Documenting customer contacts' }, + { de: 'Vertriebssteuerung', en: 'Sales management' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'PROSPECTIVE_CUSTOMERS', 'BUSINESS_PARTNERS'], + personalDataCategories: [ + 'NAME', 'CONTACT', 'ADDRESS', 'CONTRACT_DATA', 'COMMUNICATION_DATA', + ], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 3, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['Salesforce', 'HubSpot', 'Pipedrive', 'Microsoft Dynamics'], + commonVendorCategories: ['CRM'], + }, + { + id: 'tpl-sales-contract-management', + category: 'SALES', + name: { + de: 'Vertragsmanagement', + en: 'Contract Management', + }, + description: { + de: 'Verwaltung von Kundenverträgen, Angeboten und Aufträgen', + en: 'Managing customer contracts, quotes, and orders', + }, + purposes: [ + { de: 'Erstellung und Verwaltung von Verträgen', en: 'Creating and managing contracts' }, + { de: 'Angebotsverfolgung', en: 'Quote tracking' }, + { de: 'Auftragsabwicklung', en: 'Order processing' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'BUSINESS_PARTNERS'], + personalDataCategories: [ + 'NAME', 'CONTACT', 'ADDRESS', 'CONTRACT_DATA', 'PAYMENT_DATA', + ], + suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], + suggestedRetentionYears: 10, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['ERP', 'CRM', 'Vertragsverwaltung'], + commonVendorCategories: ['ERP', 'CRM'], + }, +] diff --git a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/it-customer-web-general.ts b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/it-customer-web-general.ts new file mode 100644 index 0000000..fbfd685 --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/it-customer-web-general.ts @@ -0,0 +1,363 @@ +/** + * Processing Activities — IT, Customer Service, Website & General Templates + */ + +import { ProcessingActivityTemplate } from './types' + +export const IT_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-it-user-management', + category: 'IT', + name: { + de: 'IT-Benutzerverwaltung', + en: 'IT User Management', + }, + description: { + de: 'Verwaltung von Benutzerkonten, Zugriffsrechten und Authentifizierung', + en: 'Managing user accounts, access rights, and authentication', + }, + purposes: [ + { de: 'Verwaltung von Benutzerkonten', en: 'Managing user accounts' }, + { de: 'Zugriffssteuerung', en: 'Access control' }, + { de: 'Single Sign-On', en: 'Single Sign-On' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: ['NAME', 'CONTACT', 'LOGIN_DATA', 'USAGE_DATA'], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: false, + commonSystems: ['Active Directory', 'Okta', 'Azure AD'], + commonVendorCategories: ['SECURITY', 'CLOUD_INFRASTRUCTURE'], + }, + { + id: 'tpl-it-logging', + category: 'IT', + name: { + de: 'IT-Protokollierung', + en: 'IT Logging', + }, + description: { + de: 'Protokollierung von IT-Aktivitäten zur Sicherheit und Fehleranalyse', + en: 'Logging IT activities for security and error analysis', + }, + purposes: [ + { de: 'Sicherheitsüberwachung', en: 'Security monitoring' }, + { de: 'Fehleranalyse', en: 'Error analysis' }, + { de: 'Nachvollziehbarkeit', en: 'Traceability' }, + ], + dataSubjectCategories: ['EMPLOYEES', 'CUSTOMERS', 'WEBSITE_USERS'], + personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA', 'LOGIN_DATA'], + suggestedLegalBasis: ['LEGITIMATE_INTEREST'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['Splunk', 'ELK Stack', 'Datadog'], + commonVendorCategories: ['SECURITY', 'ANALYTICS'], + }, + { + id: 'tpl-it-video-surveillance', + category: 'IT', + name: { + de: 'Videoüberwachung', + en: 'Video Surveillance', + }, + description: { + de: 'Videoüberwachung von Geschäftsräumen zum Schutz vor Diebstahl und Vandalismus', + en: 'Video surveillance of business premises for theft and vandalism prevention', + }, + purposes: [ + { de: 'Schutz vor Diebstahl und Vandalismus', en: 'Protection against theft and vandalism' }, + { de: 'Zugangskontrolle', en: 'Access control' }, + { de: 'Beweissicherung', en: 'Evidence preservation' }, + ], + dataSubjectCategories: ['EMPLOYEES', 'VISITORS', 'CUSTOMERS'], + personalDataCategories: ['PHOTO_VIDEO', 'BIOMETRIC_DATA'], + suggestedLegalBasis: ['LEGITIMATE_INTEREST'], + suggestedRetentionYears: 0.1, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: true, + commonSystems: ['CCTV-System'], + commonVendorCategories: ['SECURITY'], + }, + { + id: 'tpl-it-backup', + category: 'IT', + name: { + de: 'Datensicherung (Backup)', + en: 'Data Backup', + }, + description: { + de: 'Regelmäßige Sicherung von Unternehmensdaten', + en: 'Regular backup of company data', + }, + purposes: [ + { de: 'Datensicherung', en: 'Data backup' }, + { de: 'Disaster Recovery', en: 'Disaster Recovery' }, + { de: 'Geschäftskontinuität', en: 'Business continuity' }, + ], + dataSubjectCategories: ['EMPLOYEES', 'CUSTOMERS', 'SUPPLIERS'], + personalDataCategories: ['NAME', 'CONTACT', 'CONTRACT_DATA', 'COMMUNICATION_DATA'], + suggestedLegalBasis: ['LEGITIMATE_INTEREST', 'LEGAL_OBLIGATION'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: false, + commonSystems: ['Veeam', 'AWS Backup', 'Azure Backup'], + commonVendorCategories: ['BACKUP', 'CLOUD_INFRASTRUCTURE'], + }, +] + +export const CUSTOMER_SERVICE_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-cs-support', + category: 'CUSTOMER_SERVICE', + name: { + de: 'Kundenbetreuung und Support', + en: 'Customer Support', + }, + description: { + de: 'Bearbeitung von Kundenanfragen, Beschwerden und Support-Tickets', + en: 'Handling customer inquiries, complaints, and support tickets', + }, + purposes: [ + { de: 'Bearbeitung von Kundenanfragen', en: 'Handling customer inquiries' }, + { de: 'Beschwerdemanagement', en: 'Complaint management' }, + { de: 'Technischer Support', en: 'Technical support' }, + ], + dataSubjectCategories: ['CUSTOMERS'], + personalDataCategories: ['NAME', 'CONTACT', 'CONTRACT_DATA', 'COMMUNICATION_DATA'], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 3, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['Zendesk', 'Freshdesk', 'Intercom'], + commonVendorCategories: ['SUPPORT', 'CRM'], + }, + { + id: 'tpl-cs-satisfaction', + category: 'CUSTOMER_SERVICE', + name: { + de: 'Kundenzufriedenheitsbefragungen', + en: 'Customer Satisfaction Surveys', + }, + description: { + de: 'Durchführung von Umfragen zur Messung der Kundenzufriedenheit', + en: 'Conducting surveys to measure customer satisfaction', + }, + purposes: [ + { de: 'Messung der Kundenzufriedenheit', en: 'Measuring customer satisfaction' }, + { de: 'Qualitätsverbesserung', en: 'Quality improvement' }, + ], + dataSubjectCategories: ['CUSTOMERS'], + personalDataCategories: ['NAME', 'CONTACT', 'USAGE_DATA'], + suggestedLegalBasis: ['CONSENT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 2, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['SurveyMonkey', 'Typeform', 'NPS-Tools'], + commonVendorCategories: ['ANALYTICS', 'MARKETING'], + }, +] + +export const WEBSITE_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-web-analytics', + category: 'WEBSITE', + name: { + de: 'Web-Analyse', + en: 'Web Analytics', + }, + description: { + de: 'Analyse des Nutzerverhaltens auf der Website zur Optimierung', + en: 'Analyzing user behavior on the website for optimization', + }, + purposes: [ + { de: 'Analyse des Nutzerverhaltens', en: 'Analyzing user behavior' }, + { de: 'Website-Optimierung', en: 'Website optimization' }, + { de: 'Conversion-Tracking', en: 'Conversion tracking' }, + ], + dataSubjectCategories: ['WEBSITE_USERS'], + personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA', 'LOCATION_DATA'], + suggestedLegalBasis: ['CONSENT'], + suggestedRetentionYears: 2, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['Google Analytics', 'Matomo', 'Plausible'], + commonVendorCategories: ['ANALYTICS'], + }, + { + id: 'tpl-web-contact-form', + category: 'WEBSITE', + name: { + de: 'Kontaktformular', + en: 'Contact Form', + }, + description: { + de: 'Verarbeitung von Anfragen über das Website-Kontaktformular', + en: 'Processing inquiries submitted via the website contact form', + }, + purposes: [ + { de: 'Bearbeitung von Kontaktanfragen', en: 'Processing contact inquiries' }, + { de: 'Kommunikation mit Interessenten', en: 'Communication with prospects' }, + ], + dataSubjectCategories: ['PROSPECTIVE_CUSTOMERS', 'WEBSITE_USERS'], + personalDataCategories: ['NAME', 'CONTACT', 'COMMUNICATION_DATA'], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['CRM', 'E-Mail-System'], + commonVendorCategories: ['CRM', 'EMAIL'], + }, + { + id: 'tpl-web-user-accounts', + category: 'WEBSITE', + name: { + de: 'Benutzerkonten / Kundenportal', + en: 'User Accounts / Customer Portal', + }, + description: { + de: 'Verwaltung von Benutzerkonten im Kundenportal oder Online-Shop', + en: 'Managing user accounts in customer portal or online shop', + }, + purposes: [ + { de: 'Bereitstellung des Kundenportals', en: 'Providing customer portal' }, + { de: 'Benutzerverwaltung', en: 'User management' }, + { de: 'Personalisierung', en: 'Personalization' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'APP_USERS'], + personalDataCategories: ['NAME', 'CONTACT', 'LOGIN_DATA', 'USAGE_DATA', 'CONTRACT_DATA'], + suggestedLegalBasis: ['CONTRACT'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['E-Commerce', 'CRM', 'Auth0'], + commonVendorCategories: ['HOSTING', 'CRM', 'SECURITY'], + }, + { + id: 'tpl-web-cookies', + category: 'WEBSITE', + name: { + de: 'Cookie-Verwaltung', + en: 'Cookie Management', + }, + description: { + de: 'Verwaltung von Cookies und Einholung von Cookie-Einwilligungen', + en: 'Managing cookies and obtaining cookie consents', + }, + purposes: [ + { de: 'Speicherung von Cookie-Präferenzen', en: 'Storing cookie preferences' }, + { de: 'Einwilligungsmanagement', en: 'Consent management' }, + ], + dataSubjectCategories: ['WEBSITE_USERS'], + personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA'], + suggestedLegalBasis: ['CONSENT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['Cookiebot', 'Usercentrics', 'OneTrust'], + commonVendorCategories: ['ANALYTICS', 'SECURITY'], + }, +] + +export const GENERAL_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-gen-communication', + category: 'GENERAL', + name: { + de: 'Geschäftliche Kommunikation', + en: 'Business Communication', + }, + description: { + de: 'E-Mail-Kommunikation, Telefonie und Messaging im Geschäftsverkehr', + en: 'Email communication, telephony, and messaging in business operations', + }, + purposes: [ + { de: 'Geschäftliche Kommunikation', en: 'Business communication' }, + { de: 'Dokumentation von Korrespondenz', en: 'Documentation of correspondence' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'SUPPLIERS', 'BUSINESS_PARTNERS', 'EMPLOYEES'], + personalDataCategories: ['NAME', 'CONTACT', 'COMMUNICATION_DATA'], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 6, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['Microsoft 365', 'Google Workspace', 'Slack'], + commonVendorCategories: ['EMAIL', 'COMMUNICATION', 'CLOUD_INFRASTRUCTURE'], + }, + { + id: 'tpl-gen-visitor', + category: 'GENERAL', + name: { + de: 'Besucherverwaltung', + en: 'Visitor Management', + }, + description: { + de: 'Erfassung und Verwaltung von Besuchern in Geschäftsräumen', + en: 'Recording and managing visitors in business premises', + }, + purposes: [ + { de: 'Zutrittskontrolle', en: 'Access control' }, + { de: 'Sicherheit', en: 'Security' }, + { de: 'Nachvollziehbarkeit', en: 'Traceability' }, + ], + dataSubjectCategories: ['VISITORS'], + personalDataCategories: ['NAME', 'CONTACT', 'PHOTO_VIDEO'], + suggestedLegalBasis: ['LEGITIMATE_INTEREST'], + suggestedRetentionYears: 0.1, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['Besuchermanagement-System'], + commonVendorCategories: ['SECURITY'], + }, + { + id: 'tpl-gen-supplier', + category: 'GENERAL', + name: { + de: 'Lieferantenverwaltung', + en: 'Supplier Management', + }, + description: { + de: 'Verwaltung von Lieferantenbeziehungen und Beschaffung', + en: 'Managing supplier relationships and procurement', + }, + purposes: [ + { de: 'Lieferantenverwaltung', en: 'Supplier management' }, + { de: 'Beschaffung', en: 'Procurement' }, + { de: 'Qualitätsmanagement', en: 'Quality management' }, + ], + dataSubjectCategories: ['SUPPLIERS', 'BUSINESS_PARTNERS'], + personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'CONTRACT_DATA', 'BANK_ACCOUNT'], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 10, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['ERP', 'Lieferantenportal'], + commonVendorCategories: ['ERP'], + }, + { + id: 'tpl-gen-whistleblower', + category: 'GENERAL', + name: { + de: 'Hinweisgebersystem', + en: 'Whistleblower System', + }, + description: { + de: 'Entgegennahme und Bearbeitung von Hinweisen gemäß Hinweisgeberschutzgesetz', + en: 'Receiving and processing reports according to whistleblower protection law', + }, + purposes: [ + { de: 'Entgegennahme von Hinweisen', en: 'Receiving reports' }, + { de: 'Untersuchung von Verstößen', en: 'Investigating violations' }, + { de: 'Schutz von Hinweisgebern', en: 'Protecting whistleblowers' }, + ], + dataSubjectCategories: ['EMPLOYEES', 'BUSINESS_PARTNERS'], + personalDataCategories: ['NAME', 'CONTACT', 'COMMUNICATION_DATA'], + suggestedLegalBasis: ['LEGAL_OBLIGATION'], + suggestedRetentionYears: 3, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: true, + commonSystems: ['Hinweisgeberportal'], + commonVendorCategories: ['SECURITY', 'LEGAL'], + }, +] diff --git a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/marketing-finance.ts b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/marketing-finance.ts new file mode 100644 index 0000000..ba45982 --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/marketing-finance.ts @@ -0,0 +1,137 @@ +/** + * Processing Activities — Marketing & Finance Templates + */ + +import { ProcessingActivityTemplate } from './types' + +export const MARKETING_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-marketing-newsletter', + category: 'MARKETING', + name: { + de: 'Newsletter-Versand', + en: 'Newsletter Distribution', + }, + description: { + de: 'Versand von E-Mail-Newslettern und Marketing-Kommunikation', + en: 'Sending email newsletters and marketing communications', + }, + purposes: [ + { de: 'Versand von Newsletter und Marketing-E-Mails', en: 'Sending newsletters and marketing emails' }, + { de: 'Messung von Öffnungs- und Klickraten', en: 'Measuring open and click rates' }, + ], + dataSubjectCategories: ['NEWSLETTER_SUBSCRIBERS', 'CUSTOMERS'], + personalDataCategories: ['NAME', 'CONTACT', 'USAGE_DATA'], + suggestedLegalBasis: ['CONSENT'], + suggestedRetentionYears: 0, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['Mailchimp', 'CleverReach', 'Sendinblue'], + commonVendorCategories: ['EMAIL', 'MARKETING'], + }, + { + id: 'tpl-marketing-advertising', + category: 'MARKETING', + name: { + de: 'Online-Werbung', + en: 'Online Advertising', + }, + description: { + de: 'Schaltung und Auswertung von Online-Werbeanzeigen', + en: 'Running and analyzing online advertisements', + }, + purposes: [ + { de: 'Schaltung von Online-Werbung', en: 'Running online advertisements' }, + { de: 'Conversion-Tracking', en: 'Conversion tracking' }, + { de: 'Retargeting', en: 'Retargeting' }, + ], + dataSubjectCategories: ['WEBSITE_USERS'], + personalDataCategories: ['IP_ADDRESS', 'DEVICE_ID', 'USAGE_DATA'], + suggestedLegalBasis: ['CONSENT'], + suggestedRetentionYears: 1, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: true, + commonSystems: ['Google Ads', 'Meta Ads', 'LinkedIn Ads'], + commonVendorCategories: ['MARKETING', 'ANALYTICS'], + }, + { + id: 'tpl-marketing-events', + category: 'MARKETING', + name: { + de: 'Veranstaltungsmanagement', + en: 'Event Management', + }, + description: { + de: 'Organisation und Durchführung von Veranstaltungen, Messen und Webinaren', + en: 'Organizing and conducting events, trade shows, and webinars', + }, + purposes: [ + { de: 'Teilnehmerregistrierung', en: 'Participant registration' }, + { de: 'Veranstaltungsdurchführung', en: 'Event execution' }, + { de: 'Nachbereitung und Follow-up', en: 'Follow-up activities' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'PROSPECTIVE_CUSTOMERS', 'BUSINESS_PARTNERS'], + personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'PHOTO_VIDEO'], + suggestedLegalBasis: ['CONTRACT', 'CONSENT'], + suggestedRetentionYears: 2, + suggestedProtectionLevel: 'LOW', + dpiaLikely: false, + commonSystems: ['Eventbrite', 'GoToWebinar', 'Zoom'], + commonVendorCategories: ['MARKETING', 'COMMUNICATION'], + }, +] + +export const FINANCE_TEMPLATES: ProcessingActivityTemplate[] = [ + { + id: 'tpl-finance-accounting', + category: 'FINANCE', + name: { + de: 'Finanzbuchhaltung', + en: 'Financial Accounting', + }, + description: { + de: 'Führung der Finanzbuchhaltung, Rechnungsstellung und Zahlungsabwicklung', + en: 'Financial accounting, invoicing, and payment processing', + }, + purposes: [ + { de: 'Buchführung und Rechnungswesen', en: 'Bookkeeping and accounting' }, + { de: 'Rechnungsstellung', en: 'Invoicing' }, + { de: 'Zahlungsabwicklung', en: 'Payment processing' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'SUPPLIERS', 'BUSINESS_PARTNERS'], + personalDataCategories: [ + 'NAME', 'ADDRESS', 'BANK_ACCOUNT', 'PAYMENT_DATA', 'CONTRACT_DATA', 'TAX_ID', + ], + suggestedLegalBasis: ['CONTRACT', 'LEGAL_OBLIGATION'], + suggestedRetentionYears: 10, + suggestedProtectionLevel: 'HIGH', + dpiaLikely: false, + commonSystems: ['DATEV', 'SAP', 'Lexware', 'Xero'], + commonVendorCategories: ['ACCOUNTING', 'ERP'], + }, + { + id: 'tpl-finance-debt-collection', + category: 'FINANCE', + name: { + de: 'Forderungsmanagement', + en: 'Debt Collection', + }, + description: { + de: 'Verwaltung offener Forderungen und Mahnwesen', + en: 'Managing outstanding receivables and dunning', + }, + purposes: [ + { de: 'Überwachung offener Forderungen', en: 'Monitoring outstanding receivables' }, + { de: 'Mahnwesen', en: 'Dunning process' }, + { de: 'Inkasso bei Bedarf', en: 'Debt collection if necessary' }, + ], + dataSubjectCategories: ['CUSTOMERS'], + personalDataCategories: ['NAME', 'ADDRESS', 'CONTACT', 'PAYMENT_DATA', 'CONTRACT_DATA'], + suggestedLegalBasis: ['CONTRACT', 'LEGITIMATE_INTEREST'], + suggestedRetentionYears: 10, + suggestedProtectionLevel: 'MEDIUM', + dpiaLikely: false, + commonSystems: ['ERP', 'Inkasso-Software'], + commonVendorCategories: ['ACCOUNTING', 'LEGAL'], + }, +] diff --git a/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/types.ts b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/types.ts new file mode 100644 index 0000000..a203620 --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/catalog/processing-activities/types.ts @@ -0,0 +1,48 @@ +/** + * Processing Activities Catalog — Shared Types & Metadata + */ + +import { + DataSubjectCategory, + PersonalDataCategory, + LegalBasisType, + ProtectionLevel, + LocalizedText, +} from '../../types' + +export interface ProcessingActivityTemplate { + id: string + category: ProcessingActivityCategory + name: LocalizedText + description: LocalizedText + purposes: LocalizedText[] + dataSubjectCategories: DataSubjectCategory[] + personalDataCategories: PersonalDataCategory[] + suggestedLegalBasis: LegalBasisType[] + suggestedRetentionYears: number + suggestedProtectionLevel: ProtectionLevel + dpiaLikely: boolean + commonSystems: string[] + commonVendorCategories: string[] +} + +export type ProcessingActivityCategory = + | 'HR' // Human Resources + | 'SALES' // Vertrieb + | 'MARKETING' // Marketing + | 'FINANCE' // Finanzen + | 'IT' // IT & Sicherheit + | 'CUSTOMER_SERVICE' // Kundenservice + | 'WEBSITE' // Website & Apps + | 'GENERAL' // Allgemein + +export const PROCESSING_ACTIVITY_CATEGORY_META: Record = { + HR: { de: 'Personal', en: 'Human Resources' }, + SALES: { de: 'Vertrieb', en: 'Sales' }, + MARKETING: { de: 'Marketing', en: 'Marketing' }, + FINANCE: { de: 'Finanzen', en: 'Finance' }, + IT: { de: 'IT & Sicherheit', en: 'IT & Security' }, + CUSTOMER_SERVICE: { de: 'Kundenservice', en: 'Customer Service' }, + WEBSITE: { de: 'Website & Apps', en: 'Website & Apps' }, + GENERAL: { de: 'Allgemein', en: 'General' }, +} diff --git a/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists-data.ts b/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists-data.ts new file mode 100644 index 0000000..3d3558b --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists-data.ts @@ -0,0 +1,322 @@ +/** + * Contract Review Checklist Data + * + * Pure data arrays for AVV, Incident, Transfer, and SLA/Liability checklists. + * Barrel-split from checklists.ts. Do NOT import directly; use checklists.ts. + */ + +import { LocalizedText, FindingCategory } from '../types' + +export interface ChecklistItem { + id: string + category: FindingCategory + requirement: LocalizedText + article: string + description: LocalizedText + checkPoints: LocalizedText[] + isRequired: boolean + severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' +} + +// ========================================== +// ART. 28 DSGVO CHECKLIST +// ========================================== + +export const AVV_CHECKLIST: ChecklistItem[] = [ + { + id: 'art28_3_a', + category: 'INSTRUCTION', + requirement: { de: 'Weisungsgebundenheit', en: 'Instruction binding' }, + article: 'Art. 28 Abs. 3 lit. a DSGVO', + description: { + de: 'Der Auftragsverarbeiter verarbeitet personenbezogene Daten nur auf dokumentierte Weisung des Verantwortlichen.', + en: 'The processor processes personal data only on documented instructions from the controller.', + }, + checkPoints: [ + { de: 'Weisungsgebundenheit explizit vereinbart', en: 'Instruction binding explicitly agreed' }, + { de: 'Dokumentierte Weisungen vorgesehen', en: 'Documented instructions provided for' }, + { de: 'Hinweispflicht bei rechtswidrigen Weisungen', en: 'Obligation to notify of unlawful instructions' }, + { de: 'Keine eigenständige Verarbeitung erlaubt', en: 'No independent processing allowed' }, + ], + isRequired: true, + severity: 'CRITICAL', + }, + { + id: 'art28_3_b', + category: 'CONFIDENTIALITY', + requirement: { de: 'Vertraulichkeitsverpflichtung', en: 'Confidentiality obligation' }, + article: 'Art. 28 Abs. 3 lit. b DSGVO', + description: { + de: 'Der Auftragsverarbeiter gewährleistet, dass sich die zur Verarbeitung befugten Personen zur Vertraulichkeit verpflichtet haben.', + en: 'The processor ensures that persons authorised to process personal data have committed themselves to confidentiality.', + }, + checkPoints: [ + { de: 'Vertraulichkeitsverpflichtung der Mitarbeiter', en: 'Confidentiality obligation of employees' }, + { de: 'Gesetzliche Verschwiegenheitspflicht oder', en: 'Statutory confidentiality obligation or' }, + { de: 'Vertragliche Verpflichtung', en: 'Contractual obligation' }, + ], + isRequired: true, + severity: 'HIGH', + }, + { + id: 'art28_3_c', + category: 'TOM', + requirement: { de: 'Technische und organisatorische Maßnahmen', en: 'Technical and organisational measures' }, + article: 'Art. 28 Abs. 3 lit. c DSGVO', + description: { + de: 'Der Auftragsverarbeiter trifft alle gemäß Art. 32 erforderlichen Maßnahmen.', + en: 'The processor takes all measures required pursuant to Art. 32.', + }, + checkPoints: [ + { de: 'TOM-Anlage vorhanden', en: 'TOM annex present' }, + { de: 'TOM konkret und aktuell', en: 'TOM specific and current' }, + { de: 'Bezug zu Art. 32 DSGVO', en: 'Reference to Art. 32 GDPR' }, + { de: 'Aktualisierungspflicht vereinbart', en: 'Update obligation agreed' }, + ], + isRequired: true, + severity: 'CRITICAL', + }, + { + id: 'art28_3_d', + category: 'SUBPROCESSOR', + requirement: { de: 'Unterauftragsverarbeitung', en: 'Sub-processing' }, + article: 'Art. 28 Abs. 3 lit. d DSGVO', + description: { + de: 'Der Auftragsverarbeiter nimmt keinen weiteren Auftragsverarbeiter ohne vorherige Genehmigung in Anspruch.', + en: 'The processor does not engage another processor without prior authorisation.', + }, + checkPoints: [ + { de: 'Genehmigungserfordernis (allgemein oder spezifisch)', en: 'Authorisation requirement (general or specific)' }, + { de: 'Bei allgemeiner Genehmigung: Informationspflicht', en: 'With general authorisation: notification obligation' }, + { de: 'Einspruchsrecht des Verantwortlichen', en: 'Right of objection for controller' }, + { de: 'Liste aktueller Unterauftragnehmer', en: 'List of current sub-processors' }, + { de: 'Weitergabe der Pflichten an Unterauftragnehmer', en: 'Transfer of obligations to sub-processors' }, + ], + isRequired: true, + severity: 'CRITICAL', + }, + { + id: 'art28_3_e', + category: 'DATA_SUBJECT_RIGHTS', + requirement: { de: 'Unterstützung bei Betroffenenrechten', en: 'Assistance with data subject rights' }, + article: 'Art. 28 Abs. 3 lit. e DSGVO', + description: { + de: 'Der Auftragsverarbeiter unterstützt den Verantwortlichen bei der Erfüllung der Betroffenenrechte.', + en: 'The processor assists the controller in fulfilling data subject rights obligations.', + }, + checkPoints: [ + { de: 'Unterstützungspflicht vereinbart', en: 'Assistance obligation agreed' }, + { de: 'Verfahren zur Weiterleitung von Anfragen', en: 'Procedure for forwarding requests' }, + { de: 'Fristen für Unterstützung', en: 'Deadlines for assistance' }, + { de: 'Kostenregelung', en: 'Cost arrangement' }, + ], + isRequired: true, + severity: 'HIGH', + }, + { + id: 'art28_3_f', + category: 'GENERAL', + requirement: { de: 'Unterstützung bei DSFA und Konsultation', en: 'Assistance with DPIA and consultation' }, + article: 'Art. 28 Abs. 3 lit. f DSGVO', + description: { + de: 'Der Auftragsverarbeiter unterstützt den Verantwortlichen bei der Einhaltung der Pflichten gemäß Art. 32-36.', + en: 'The processor assists the controller in ensuring compliance with obligations pursuant to Art. 32-36.', + }, + checkPoints: [ + { de: 'Unterstützung bei DSFA', en: 'Assistance with DPIA' }, + { de: 'Unterstützung bei vorheriger Konsultation', en: 'Assistance with prior consultation' }, + { de: 'Bereitstellung notwendiger Informationen', en: 'Provision of necessary information' }, + ], + isRequired: true, + severity: 'MEDIUM', + }, + { + id: 'art28_3_g', + category: 'DELETION', + requirement: { de: 'Löschung/Rückgabe nach Vertragsende', en: 'Deletion/return after contract end' }, + article: 'Art. 28 Abs. 3 lit. g DSGVO', + description: { + de: 'Nach Abschluss der Verarbeitung werden alle personenbezogenen Daten gelöscht oder zurückgegeben.', + en: 'After the end of processing, all personal data is deleted or returned.', + }, + checkPoints: [ + { de: 'Löschung oder Rückgabe nach Wahl des Verantwortlichen', en: 'Deletion or return at controller choice' }, + { de: 'Frist für Löschung/Rückgabe (max. 30 Tage empfohlen)', en: 'Deadline for deletion/return (max. 30 days recommended)' }, + { de: 'Löschung auch bei Unterauftragnehmern', en: 'Deletion also at sub-processors' }, + { de: 'Löschbestätigung/Nachweis', en: 'Deletion confirmation/proof' }, + { de: 'Ausnahme nur bei gesetzlicher Aufbewahrungspflicht', en: 'Exception only for legal retention obligation' }, + ], + isRequired: true, + severity: 'CRITICAL', + }, + { + id: 'art28_3_h', + category: 'AUDIT_RIGHTS', + requirement: { de: 'Audit- und Inspektionsrechte', en: 'Audit and inspection rights' }, + article: 'Art. 28 Abs. 3 lit. h DSGVO', + description: { + de: 'Der Auftragsverarbeiter ermöglicht und unterstützt Überprüfungen durch den Verantwortlichen.', + en: 'The processor enables and contributes to audits and inspections by the controller.', + }, + checkPoints: [ + { de: 'Auditrecht ausdrücklich vereinbart', en: 'Audit right explicitly agreed' }, + { de: 'Vor-Ort-Inspektionen möglich', en: 'On-site inspections possible' }, + { de: 'Angemessene Vorlaufzeit (max. 30 Tage)', en: 'Reasonable notice period (max. 30 days)' }, + { de: 'Keine unangemessenen Einschränkungen', en: 'No unreasonable restrictions' }, + { de: 'Bereitstellung aller relevanten Informationen', en: 'Provision of all relevant information' }, + { de: 'Akzeptanz unabhängiger Prüfer', en: 'Acceptance of independent auditors' }, + ], + isRequired: true, + severity: 'HIGH', + }, +] + +// ========================================== +// INCIDENT RESPONSE CHECKLIST +// ========================================== + +export const INCIDENT_CHECKLIST: ChecklistItem[] = [ + { + id: 'incident_notification', + category: 'INCIDENT', + requirement: { de: 'Meldung von Datenschutzverletzungen', en: 'Notification of data breaches' }, + article: 'Art. 33 Abs. 2 DSGVO', + description: { + de: 'Der Auftragsverarbeiter meldet dem Verantwortlichen unverzüglich jede Datenschutzverletzung.', + en: 'The processor notifies the controller without undue delay of any personal data breach.', + }, + checkPoints: [ + { de: 'Meldepflicht vereinbart', en: 'Notification obligation agreed' }, + { de: 'Frist: Unverzüglich (max. 24-48h empfohlen)', en: 'Deadline: Without undue delay (max. 24-48h recommended)' }, + { de: 'Mindestinhalt der Meldung definiert', en: 'Minimum content of notification defined' }, + { de: 'Kontaktstelle für Meldungen', en: 'Contact point for notifications' }, + { de: 'Unterstützung bei Dokumentation', en: 'Assistance with documentation' }, + ], + isRequired: true, + severity: 'CRITICAL', + }, + { + id: 'incident_content', + category: 'INCIDENT', + requirement: { de: 'Inhalt der Incident-Meldung', en: 'Content of incident notification' }, + article: 'Art. 33 Abs. 3 DSGVO', + description: { + de: 'Die Meldung muss bestimmte Mindestinformationen enthalten.', + en: 'The notification must contain certain minimum information.', + }, + checkPoints: [ + { de: 'Art der Verletzung', en: 'Nature of the breach' }, + { de: 'Betroffene Datenkategorien', en: 'Affected data categories' }, + { de: 'Ungefähre Anzahl betroffener Personen', en: 'Approximate number of affected persons' }, + { de: 'Wahrscheinliche Folgen', en: 'Likely consequences' }, + { de: 'Ergriffene Maßnahmen', en: 'Measures taken' }, + ], + isRequired: true, + severity: 'HIGH', + }, +] + +// ========================================== +// THIRD COUNTRY TRANSFER CHECKLIST +// ========================================== + +export const TRANSFER_CHECKLIST: ChecklistItem[] = [ + { + id: 'transfer_basis', + category: 'TRANSFER', + requirement: { de: 'Rechtsgrundlage für Drittlandtransfer', en: 'Legal basis for third country transfer' }, + article: 'Art. 44-49 DSGVO', + description: { + de: 'Drittlandtransfers nur auf Basis geeigneter Garantien.', + en: 'Third country transfers only on the basis of appropriate safeguards.', + }, + checkPoints: [ + { de: 'Angemessenheitsbeschluss oder', en: 'Adequacy decision or' }, + { de: 'Standardvertragsklauseln (SCC) oder', en: 'Standard contractual clauses (SCC) or' }, + { de: 'Binding Corporate Rules (BCR) oder', en: 'Binding Corporate Rules (BCR) or' }, + { de: 'Sonstige Ausnahme Art. 49', en: 'Other derogation Art. 49' }, + ], + isRequired: true, + severity: 'CRITICAL', + }, + { + id: 'transfer_scc', + category: 'TRANSFER', + requirement: { de: 'Standardvertragsklauseln', en: 'Standard Contractual Clauses' }, + article: 'Art. 46 Abs. 2 lit. c DSGVO', + description: { + de: 'Bei SCC: Verwendung der aktuellen EU-Kommission-Klauseln.', + en: 'With SCC: Use of current EU Commission clauses.', + }, + checkPoints: [ + { de: 'SCC 2021 verwendet', en: 'SCC 2021 used' }, + { de: 'Korrektes Modul gewählt', en: 'Correct module selected' }, + { de: 'Anhänge vollständig ausgefüllt', en: 'Annexes completely filled out' }, + { de: 'TIA durchgeführt (bei Risiko)', en: 'TIA conducted (if risk)' }, + { de: 'Zusätzliche Maßnahmen dokumentiert', en: 'Additional measures documented' }, + ], + isRequired: false, + severity: 'HIGH', + }, + { + id: 'transfer_tia', + category: 'TRANSFER', + requirement: { de: 'Transfer Impact Assessment', en: 'Transfer Impact Assessment' }, + article: 'Schrems II, EDSA 01/2020', + description: { + de: 'Bewertung der Risiken im Drittland.', + en: 'Assessment of risks in the third country.', + }, + checkPoints: [ + { de: 'Rechtslage im Drittland analysiert', en: 'Legal situation in third country analyzed' }, + { de: 'Zugriff durch Behörden bewertet', en: 'Access by authorities assessed' }, + { de: 'Zusätzliche technische Maßnahmen', en: 'Additional technical measures' }, + { de: 'Dokumentation der Bewertung', en: 'Documentation of assessment' }, + ], + isRequired: true, + severity: 'HIGH', + }, +] + +// ========================================== +// SLA & LIABILITY CHECKLIST +// ========================================== + +export const SLA_LIABILITY_CHECKLIST: ChecklistItem[] = [ + { + id: 'sla_availability', + category: 'SLA', + requirement: { de: 'Verfügbarkeit', en: 'Availability' }, + article: 'Vertragliche Vereinbarung', + description: { + de: 'Service Level Agreement für Verfügbarkeit des Dienstes.', + en: 'Service Level Agreement for service availability.', + }, + checkPoints: [ + { de: 'Verfügbarkeit definiert (z.B. 99,9%)', en: 'Availability defined (e.g., 99.9%)' }, + { de: 'Messzeitraum festgelegt', en: 'Measurement period defined' }, + { de: 'Ausnahmen klar definiert', en: 'Exceptions clearly defined' }, + { de: 'Konsequenzen bei Nichteinhaltung', en: 'Consequences of non-compliance' }, + ], + isRequired: false, + severity: 'MEDIUM', + }, + { + id: 'liability_cap', + category: 'LIABILITY', + requirement: { de: 'Haftungsbegrenzung', en: 'Liability cap' }, + article: 'Vertragliche Vereinbarung', + description: { + de: 'Prüfung von Haftungsbegrenzungen und deren Auswirkungen.', + en: 'Review of liability caps and their implications.', + }, + checkPoints: [ + { de: 'Haftungshöchstgrenze prüfen', en: 'Check liability cap' }, + { de: 'Ausschluss von Vorsatz/grober Fahrlässigkeit', en: 'Exclusion of intent/gross negligence' }, + { de: 'Freistellungsklauseln (Indemnity)', en: 'Indemnification clauses' }, + { de: 'Versicherungsnachweis', en: 'Insurance proof' }, + ], + isRequired: false, + severity: 'MEDIUM', + }, +] diff --git a/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists.ts b/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists.ts index 7795ee7..5b798b8 100644 --- a/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists.ts +++ b/admin-compliance/lib/sdk/vendor-compliance/contract-review/checklists.ts @@ -1,21 +1,32 @@ /** * Contract Review Checklists * - * DSGVO Art. 28 compliance checklists for contract reviews + * DSGVO Art. 28 compliance checklists for contract reviews. + * Checklist data arrays live in checklists-data.ts. */ import { LocalizedText, FindingCategory } from '../types' -export interface ChecklistItem { - id: string - category: FindingCategory - requirement: LocalizedText - article: string - description: LocalizedText - checkPoints: LocalizedText[] - isRequired: boolean - severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' -} +// Re-export data arrays and item type +export type { ChecklistItem } from './checklists-data' +export { + AVV_CHECKLIST, + INCIDENT_CHECKLIST, + TRANSFER_CHECKLIST, + SLA_LIABILITY_CHECKLIST, +} from './checklists-data' + +import type { ChecklistItem } from './checklists-data' +import { + AVV_CHECKLIST, + INCIDENT_CHECKLIST, + TRANSFER_CHECKLIST, + SLA_LIABILITY_CHECKLIST, +} from './checklists-data' + +// ========================================== +// CHECKLIST GROUP TYPE +// ========================================== export interface ChecklistGroup { id: string @@ -24,369 +35,6 @@ export interface ChecklistGroup { items: ChecklistItem[] } -// ========================================== -// ART. 28 DSGVO CHECKLIST -// ========================================== - -export const AVV_CHECKLIST: ChecklistItem[] = [ - // Art. 28 Abs. 3 lit. a - Weisungsgebundenheit - { - id: 'art28_3_a', - category: 'INSTRUCTION', - requirement: { - de: 'Weisungsgebundenheit', - en: 'Instruction binding', - }, - article: 'Art. 28 Abs. 3 lit. a DSGVO', - description: { - de: 'Der Auftragsverarbeiter verarbeitet personenbezogene Daten nur auf dokumentierte Weisung des Verantwortlichen.', - en: 'The processor processes personal data only on documented instructions from the controller.', - }, - checkPoints: [ - { de: 'Weisungsgebundenheit explizit vereinbart', en: 'Instruction binding explicitly agreed' }, - { de: 'Dokumentierte Weisungen vorgesehen', en: 'Documented instructions provided for' }, - { de: 'Hinweispflicht bei rechtswidrigen Weisungen', en: 'Obligation to notify of unlawful instructions' }, - { de: 'Keine eigenständige Verarbeitung erlaubt', en: 'No independent processing allowed' }, - ], - isRequired: true, - severity: 'CRITICAL', - }, - - // Art. 28 Abs. 3 lit. b - Vertraulichkeit - { - id: 'art28_3_b', - category: 'CONFIDENTIALITY', - requirement: { - de: 'Vertraulichkeitsverpflichtung', - en: 'Confidentiality obligation', - }, - article: 'Art. 28 Abs. 3 lit. b DSGVO', - description: { - de: 'Der Auftragsverarbeiter gewährleistet, dass sich die zur Verarbeitung befugten Personen zur Vertraulichkeit verpflichtet haben.', - en: 'The processor ensures that persons authorised to process personal data have committed themselves to confidentiality.', - }, - checkPoints: [ - { de: 'Vertraulichkeitsverpflichtung der Mitarbeiter', en: 'Confidentiality obligation of employees' }, - { de: 'Gesetzliche Verschwiegenheitspflicht oder', en: 'Statutory confidentiality obligation or' }, - { de: 'Vertragliche Verpflichtung', en: 'Contractual obligation' }, - ], - isRequired: true, - severity: 'HIGH', - }, - - // Art. 28 Abs. 3 lit. c - Technische und organisatorische Maßnahmen - { - id: 'art28_3_c', - category: 'TOM', - requirement: { - de: 'Technische und organisatorische Maßnahmen', - en: 'Technical and organisational measures', - }, - article: 'Art. 28 Abs. 3 lit. c DSGVO', - description: { - de: 'Der Auftragsverarbeiter trifft alle gemäß Art. 32 erforderlichen Maßnahmen.', - en: 'The processor takes all measures required pursuant to Art. 32.', - }, - checkPoints: [ - { de: 'TOM-Anlage vorhanden', en: 'TOM annex present' }, - { de: 'TOM konkret und aktuell', en: 'TOM specific and current' }, - { de: 'Bezug zu Art. 32 DSGVO', en: 'Reference to Art. 32 GDPR' }, - { de: 'Aktualisierungspflicht vereinbart', en: 'Update obligation agreed' }, - ], - isRequired: true, - severity: 'CRITICAL', - }, - - // Art. 28 Abs. 3 lit. d - Unterauftragsverarbeitung - { - id: 'art28_3_d', - category: 'SUBPROCESSOR', - requirement: { - de: 'Unterauftragsverarbeitung', - en: 'Sub-processing', - }, - article: 'Art. 28 Abs. 3 lit. d DSGVO', - description: { - de: 'Der Auftragsverarbeiter nimmt keinen weiteren Auftragsverarbeiter ohne vorherige Genehmigung in Anspruch.', - en: 'The processor does not engage another processor without prior authorisation.', - }, - checkPoints: [ - { de: 'Genehmigungserfordernis (allgemein oder spezifisch)', en: 'Authorisation requirement (general or specific)' }, - { de: 'Bei allgemeiner Genehmigung: Informationspflicht', en: 'With general authorisation: notification obligation' }, - { de: 'Einspruchsrecht des Verantwortlichen', en: 'Right of objection for controller' }, - { de: 'Liste aktueller Unterauftragnehmer', en: 'List of current sub-processors' }, - { de: 'Weitergabe der Pflichten an Unterauftragnehmer', en: 'Transfer of obligations to sub-processors' }, - ], - isRequired: true, - severity: 'CRITICAL', - }, - - // Art. 28 Abs. 3 lit. e - Unterstützung bei Betroffenenrechten - { - id: 'art28_3_e', - category: 'DATA_SUBJECT_RIGHTS', - requirement: { - de: 'Unterstützung bei Betroffenenrechten', - en: 'Assistance with data subject rights', - }, - article: 'Art. 28 Abs. 3 lit. e DSGVO', - description: { - de: 'Der Auftragsverarbeiter unterstützt den Verantwortlichen bei der Erfüllung der Betroffenenrechte.', - en: 'The processor assists the controller in fulfilling data subject rights obligations.', - }, - checkPoints: [ - { de: 'Unterstützungspflicht vereinbart', en: 'Assistance obligation agreed' }, - { de: 'Verfahren zur Weiterleitung von Anfragen', en: 'Procedure for forwarding requests' }, - { de: 'Fristen für Unterstützung', en: 'Deadlines for assistance' }, - { de: 'Kostenregelung', en: 'Cost arrangement' }, - ], - isRequired: true, - severity: 'HIGH', - }, - - // Art. 28 Abs. 3 lit. f - Unterstützung bei DSFA - { - id: 'art28_3_f', - category: 'GENERAL', - requirement: { - de: 'Unterstützung bei DSFA und Konsultation', - en: 'Assistance with DPIA and consultation', - }, - article: 'Art. 28 Abs. 3 lit. f DSGVO', - description: { - de: 'Der Auftragsverarbeiter unterstützt den Verantwortlichen bei der Einhaltung der Pflichten gemäß Art. 32-36.', - en: 'The processor assists the controller in ensuring compliance with obligations pursuant to Art. 32-36.', - }, - checkPoints: [ - { de: 'Unterstützung bei DSFA', en: 'Assistance with DPIA' }, - { de: 'Unterstützung bei vorheriger Konsultation', en: 'Assistance with prior consultation' }, - { de: 'Bereitstellung notwendiger Informationen', en: 'Provision of necessary information' }, - ], - isRequired: true, - severity: 'MEDIUM', - }, - - // Art. 28 Abs. 3 lit. g - Löschung/Rückgabe - { - id: 'art28_3_g', - category: 'DELETION', - requirement: { - de: 'Löschung/Rückgabe nach Vertragsende', - en: 'Deletion/return after contract end', - }, - article: 'Art. 28 Abs. 3 lit. g DSGVO', - description: { - de: 'Nach Abschluss der Verarbeitung werden alle personenbezogenen Daten gelöscht oder zurückgegeben.', - en: 'After the end of processing, all personal data is deleted or returned.', - }, - checkPoints: [ - { de: 'Löschung oder Rückgabe nach Wahl des Verantwortlichen', en: 'Deletion or return at controller choice' }, - { de: 'Frist für Löschung/Rückgabe (max. 30 Tage empfohlen)', en: 'Deadline for deletion/return (max. 30 days recommended)' }, - { de: 'Löschung auch bei Unterauftragnehmern', en: 'Deletion also at sub-processors' }, - { de: 'Löschbestätigung/Nachweis', en: 'Deletion confirmation/proof' }, - { de: 'Ausnahme nur bei gesetzlicher Aufbewahrungspflicht', en: 'Exception only for legal retention obligation' }, - ], - isRequired: true, - severity: 'CRITICAL', - }, - - // Art. 28 Abs. 3 lit. h - Audit/Inspektion - { - id: 'art28_3_h', - category: 'AUDIT_RIGHTS', - requirement: { - de: 'Audit- und Inspektionsrechte', - en: 'Audit and inspection rights', - }, - article: 'Art. 28 Abs. 3 lit. h DSGVO', - description: { - de: 'Der Auftragsverarbeiter ermöglicht und unterstützt Überprüfungen durch den Verantwortlichen.', - en: 'The processor enables and contributes to audits and inspections by the controller.', - }, - checkPoints: [ - { de: 'Auditrecht ausdrücklich vereinbart', en: 'Audit right explicitly agreed' }, - { de: 'Vor-Ort-Inspektionen möglich', en: 'On-site inspections possible' }, - { de: 'Angemessene Vorlaufzeit (max. 30 Tage)', en: 'Reasonable notice period (max. 30 days)' }, - { de: 'Keine unangemessenen Einschränkungen', en: 'No unreasonable restrictions' }, - { de: 'Bereitstellung aller relevanten Informationen', en: 'Provision of all relevant information' }, - { de: 'Akzeptanz unabhängiger Prüfer', en: 'Acceptance of independent auditors' }, - ], - isRequired: true, - severity: 'HIGH', - }, -] - -// ========================================== -// INCIDENT RESPONSE CHECKLIST -// ========================================== - -export const INCIDENT_CHECKLIST: ChecklistItem[] = [ - { - id: 'incident_notification', - category: 'INCIDENT', - requirement: { - de: 'Meldung von Datenschutzverletzungen', - en: 'Notification of data breaches', - }, - article: 'Art. 33 Abs. 2 DSGVO', - description: { - de: 'Der Auftragsverarbeiter meldet dem Verantwortlichen unverzüglich jede Datenschutzverletzung.', - en: 'The processor notifies the controller without undue delay of any personal data breach.', - }, - checkPoints: [ - { de: 'Meldepflicht vereinbart', en: 'Notification obligation agreed' }, - { de: 'Frist: Unverzüglich (max. 24-48h empfohlen)', en: 'Deadline: Without undue delay (max. 24-48h recommended)' }, - { de: 'Mindestinhalt der Meldung definiert', en: 'Minimum content of notification defined' }, - { de: 'Kontaktstelle für Meldungen', en: 'Contact point for notifications' }, - { de: 'Unterstützung bei Dokumentation', en: 'Assistance with documentation' }, - ], - isRequired: true, - severity: 'CRITICAL', - }, - { - id: 'incident_content', - category: 'INCIDENT', - requirement: { - de: 'Inhalt der Incident-Meldung', - en: 'Content of incident notification', - }, - article: 'Art. 33 Abs. 3 DSGVO', - description: { - de: 'Die Meldung muss bestimmte Mindestinformationen enthalten.', - en: 'The notification must contain certain minimum information.', - }, - checkPoints: [ - { de: 'Art der Verletzung', en: 'Nature of the breach' }, - { de: 'Betroffene Datenkategorien', en: 'Affected data categories' }, - { de: 'Ungefähre Anzahl betroffener Personen', en: 'Approximate number of affected persons' }, - { de: 'Wahrscheinliche Folgen', en: 'Likely consequences' }, - { de: 'Ergriffene Maßnahmen', en: 'Measures taken' }, - ], - isRequired: true, - severity: 'HIGH', - }, -] - -// ========================================== -// THIRD COUNTRY TRANSFER CHECKLIST -// ========================================== - -export const TRANSFER_CHECKLIST: ChecklistItem[] = [ - { - id: 'transfer_basis', - category: 'TRANSFER', - requirement: { - de: 'Rechtsgrundlage für Drittlandtransfer', - en: 'Legal basis for third country transfer', - }, - article: 'Art. 44-49 DSGVO', - description: { - de: 'Drittlandtransfers nur auf Basis geeigneter Garantien.', - en: 'Third country transfers only on the basis of appropriate safeguards.', - }, - checkPoints: [ - { de: 'Angemessenheitsbeschluss oder', en: 'Adequacy decision or' }, - { de: 'Standardvertragsklauseln (SCC) oder', en: 'Standard contractual clauses (SCC) or' }, - { de: 'Binding Corporate Rules (BCR) oder', en: 'Binding Corporate Rules (BCR) or' }, - { de: 'Sonstige Ausnahme Art. 49', en: 'Other derogation Art. 49' }, - ], - isRequired: true, - severity: 'CRITICAL', - }, - { - id: 'transfer_scc', - category: 'TRANSFER', - requirement: { - de: 'Standardvertragsklauseln', - en: 'Standard Contractual Clauses', - }, - article: 'Art. 46 Abs. 2 lit. c DSGVO', - description: { - de: 'Bei SCC: Verwendung der aktuellen EU-Kommission-Klauseln.', - en: 'With SCC: Use of current EU Commission clauses.', - }, - checkPoints: [ - { de: 'SCC 2021 verwendet', en: 'SCC 2021 used' }, - { de: 'Korrektes Modul gewählt', en: 'Correct module selected' }, - { de: 'Anhänge vollständig ausgefüllt', en: 'Annexes completely filled out' }, - { de: 'TIA durchgeführt (bei Risiko)', en: 'TIA conducted (if risk)' }, - { de: 'Zusätzliche Maßnahmen dokumentiert', en: 'Additional measures documented' }, - ], - isRequired: false, - severity: 'HIGH', - }, - { - id: 'transfer_tia', - category: 'TRANSFER', - requirement: { - de: 'Transfer Impact Assessment', - en: 'Transfer Impact Assessment', - }, - article: 'Schrems II, EDSA 01/2020', - description: { - de: 'Bewertung der Risiken im Drittland.', - en: 'Assessment of risks in the third country.', - }, - checkPoints: [ - { de: 'Rechtslage im Drittland analysiert', en: 'Legal situation in third country analyzed' }, - { de: 'Zugriff durch Behörden bewertet', en: 'Access by authorities assessed' }, - { de: 'Zusätzliche technische Maßnahmen', en: 'Additional technical measures' }, - { de: 'Dokumentation der Bewertung', en: 'Documentation of assessment' }, - ], - isRequired: true, - severity: 'HIGH', - }, -] - -// ========================================== -// SLA & LIABILITY CHECKLIST -// ========================================== - -export const SLA_LIABILITY_CHECKLIST: ChecklistItem[] = [ - { - id: 'sla_availability', - category: 'SLA', - requirement: { - de: 'Verfügbarkeit', - en: 'Availability', - }, - article: 'Vertragliche Vereinbarung', - description: { - de: 'Service Level Agreement für Verfügbarkeit des Dienstes.', - en: 'Service Level Agreement for service availability.', - }, - checkPoints: [ - { de: 'Verfügbarkeit definiert (z.B. 99,9%)', en: 'Availability defined (e.g., 99.9%)' }, - { de: 'Messzeitraum festgelegt', en: 'Measurement period defined' }, - { de: 'Ausnahmen klar definiert', en: 'Exceptions clearly defined' }, - { de: 'Konsequenzen bei Nichteinhaltung', en: 'Consequences of non-compliance' }, - ], - isRequired: false, - severity: 'MEDIUM', - }, - { - id: 'liability_cap', - category: 'LIABILITY', - requirement: { - de: 'Haftungsbegrenzung', - en: 'Liability cap', - }, - article: 'Vertragliche Vereinbarung', - description: { - de: 'Prüfung von Haftungsbegrenzungen und deren Auswirkungen.', - en: 'Review of liability caps and their implications.', - }, - checkPoints: [ - { de: 'Haftungshöchstgrenze prüfen', en: 'Check liability cap' }, - { de: 'Ausschluss von Vorsatz/grober Fahrlässigkeit', en: 'Exclusion of intent/gross negligence' }, - { de: 'Freistellungsklauseln (Indemnity)', en: 'Indemnification clauses' }, - { de: 'Versicherungsnachweis', en: 'Insurance proof' }, - ], - isRequired: false, - severity: 'MEDIUM', - }, -] - // ========================================== // GROUPED CHECKLISTS // ========================================== diff --git a/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings-templates.ts b/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings-templates.ts new file mode 100644 index 0000000..0fe9e24 --- /dev/null +++ b/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings-templates.ts @@ -0,0 +1,331 @@ +/** + * Finding Templates — pre-defined templates for contract reviews + * + * Barrel-split from findings.ts to stay under 500 LOC. + * Do NOT import this file directly; use findings.ts instead. + */ + +import { FindingType, FindingCategory, FindingSeverity, LocalizedText } from '../types' + +export interface FindingTemplate { + id: string + type: FindingType + category: FindingCategory + severity: FindingSeverity + title: LocalizedText + description: LocalizedText + recommendation: LocalizedText + affectedRequirement: string + triggerControls: string[] +} + +export const FINDING_TEMPLATES: FindingTemplate[] = [ + // AVV_CONTENT - Weisungsgebundenheit + { + id: 'tpl-avv-instruction-missing', + type: 'GAP', + category: 'AVV_CONTENT', + severity: 'CRITICAL', + title: { de: 'Weisungsgebundenheit fehlt', en: 'Instruction binding missing' }, + description: { + de: 'Der Vertrag enthält keine Regelung zur Weisungsgebundenheit des Auftragsverarbeiters.', + en: 'The contract does not contain a provision on the processor\'s instruction binding.', + }, + recommendation: { + de: 'Ergänzen Sie eine Klausel, die den Auftragsverarbeiter verpflichtet, personenbezogene Daten nur auf dokumentierte Weisung des Verantwortlichen zu verarbeiten.', + en: 'Add a clause obligating the processor to process personal data only on documented instructions from the controller.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. a DSGVO', + triggerControls: ['VND-CON-01'], + }, + { + id: 'tpl-avv-instruction-weak', + type: 'RISK', + category: 'AVV_CONTENT', + severity: 'MEDIUM', + title: { de: 'Weisungsgebundenheit unvollständig', en: 'Instruction binding incomplete' }, + description: { + de: 'Die Regelung zur Weisungsgebundenheit ist vorhanden, aber es fehlt die Hinweispflicht bei rechtswidrigen Weisungen.', + en: 'The instruction binding provision exists, but the obligation to notify of unlawful instructions is missing.', + }, + recommendation: { + de: 'Ergänzen Sie eine Pflicht des Auftragsverarbeiters, den Verantwortlichen unverzüglich zu informieren, wenn eine Weisung nach seiner Auffassung gegen Datenschutzrecht verstößt.', + en: 'Add an obligation for the processor to immediately inform the controller if an instruction, in their opinion, violates data protection law.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. a DSGVO', + triggerControls: ['VND-CON-01'], + }, + + // AVV_CONTENT - TOM + { + id: 'tpl-avv-tom-missing', + type: 'GAP', + category: 'TOM', + severity: 'CRITICAL', + title: { de: 'TOM-Anlage fehlt', en: 'TOM annex missing' }, + description: { + de: 'Der Vertrag enthält keine technischen und organisatorischen Maßnahmen (TOM) als Anlage.', + en: 'The contract does not contain technical and organizational measures (TOM) as an annex.', + }, + recommendation: { + de: 'Fordern Sie eine detaillierte TOM-Anlage an, die die Maßnahmen gemäß Art. 32 DSGVO beschreibt.', + en: 'Request a detailed TOM annex describing the measures according to Art. 32 GDPR.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. c DSGVO', + triggerControls: ['VND-TOM-01'], + }, + { + id: 'tpl-avv-tom-generic', + type: 'RISK', + category: 'TOM', + severity: 'MEDIUM', + title: { de: 'TOM zu unspezifisch', en: 'TOM too generic' }, + description: { + de: 'Die TOM-Anlage enthält nur allgemeine Aussagen ohne konkrete Maßnahmen.', + en: 'The TOM annex contains only general statements without specific measures.', + }, + recommendation: { + de: 'Fordern Sie eine konkretere Beschreibung der Maßnahmen mit Bezug zum spezifischen Verarbeitungskontext an.', + en: 'Request a more specific description of measures with reference to the specific processing context.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. c DSGVO', + triggerControls: ['VND-TOM-01'], + }, + + // SUBPROCESSOR + { + id: 'tpl-subprocessor-no-approval', + type: 'GAP', + category: 'SUBPROCESSOR', + severity: 'CRITICAL', + title: { de: 'Keine Genehmigungspflicht für Unterauftragnehmer', en: 'No approval requirement for sub-processors' }, + description: { + de: 'Der Vertrag regelt nicht, ob und wie der Einsatz von Unterauftragnehmern zu genehmigen ist.', + en: 'The contract does not regulate whether and how the use of sub-processors must be approved.', + }, + recommendation: { + de: 'Ergänzen Sie eine Klausel, die entweder eine spezifische oder allgemeine Genehmigung für Unterauftragnehmer vorsieht, einschließlich Informations- und Einspruchsrechten.', + en: 'Add a clause providing either specific or general authorization for sub-processors, including information and objection rights.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. d DSGVO', + triggerControls: ['VND-SUB-01'], + }, + { + id: 'tpl-subprocessor-no-list', + type: 'RISK', + category: 'SUBPROCESSOR', + severity: 'HIGH', + title: { de: 'Keine Liste der Unterauftragnehmer', en: 'No list of sub-processors' }, + description: { + de: 'Es liegt keine aktuelle Liste der eingesetzten Unterauftragnehmer vor.', + en: 'There is no current list of sub-processors used.', + }, + recommendation: { + de: 'Fordern Sie eine vollständige Liste aller Unterauftragnehmer mit Name, Sitz und Verarbeitungszweck an.', + en: 'Request a complete list of all sub-processors with name, location, and processing purpose.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. d DSGVO', + triggerControls: ['VND-SUB-02'], + }, + + // INCIDENT + { + id: 'tpl-incident-no-notification', + type: 'GAP', + category: 'INCIDENT', + severity: 'CRITICAL', + title: { de: 'Keine Meldepflicht bei Datenpannen', en: 'No notification obligation for data breaches' }, + description: { + de: 'Der Vertrag enthält keine Regelung zur Meldung von Datenschutzverletzungen.', + en: 'The contract does not contain a provision for reporting data breaches.', + }, + recommendation: { + de: 'Ergänzen Sie eine Klausel, die den Auftragsverarbeiter verpflichtet, Datenschutzverletzungen unverzüglich (innerhalb von 24-48h) zu melden.', + en: 'Add a clause obligating the processor to report data breaches without undue delay (within 24-48h).', + }, + affectedRequirement: 'Art. 33 Abs. 2 DSGVO', + triggerControls: ['VND-INC-01'], + }, + { + id: 'tpl-incident-long-deadline', + type: 'RISK', + category: 'INCIDENT', + severity: 'HIGH', + title: { de: 'Zu lange Meldefrist', en: 'Notification deadline too long' }, + description: { + de: 'Die vereinbarte Meldefrist für Datenschutzverletzungen ist zu lang (>72h), um die eigene Meldepflicht einhalten zu können.', + en: 'The agreed notification deadline for data breaches is too long (>72h) to meet own notification obligations.', + }, + recommendation: { + de: 'Verkürzen Sie die Meldefrist auf maximal 24-48 Stunden, um ausreichend Zeit für die eigene Meldung an die Aufsichtsbehörde zu haben.', + en: 'Reduce the notification deadline to a maximum of 24-48 hours to have sufficient time for own notification to the supervisory authority.', + }, + affectedRequirement: 'Art. 33 DSGVO', + triggerControls: ['VND-INC-01'], + }, + + // AUDIT_RIGHTS + { + id: 'tpl-audit-no-right', + type: 'GAP', + category: 'AUDIT_RIGHTS', + severity: 'HIGH', + title: { de: 'Kein Auditrecht vereinbart', en: 'No audit right agreed' }, + description: { + de: 'Der Vertrag enthält kein Recht des Verantwortlichen auf Prüfungen und Inspektionen.', + en: 'The contract does not contain a right of the controller to audits and inspections.', + }, + recommendation: { + de: 'Ergänzen Sie ein ausdrückliches Recht auf Vor-Ort-Inspektionen und die Einsicht in relevante Unterlagen.', + en: 'Add an explicit right to on-site inspections and access to relevant documents.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. h DSGVO', + triggerControls: ['VND-AUD-01'], + }, + { + id: 'tpl-audit-restricted', + type: 'RISK', + category: 'AUDIT_RIGHTS', + severity: 'MEDIUM', + title: { de: 'Auditrecht eingeschränkt', en: 'Audit right restricted' }, + description: { + de: 'Das Auditrecht ist durch unangemessene Einschränkungen (z.B. sehr lange Vorlaufzeit, Ausschluss von Vor-Ort-Inspektionen) begrenzt.', + en: 'The audit right is limited by unreasonable restrictions (e.g., very long notice period, exclusion of on-site inspections).', + }, + recommendation: { + de: 'Verhandeln Sie angemessene Bedingungen für Audits (max. 30 Tage Vorlaufzeit, Möglichkeit zur Vor-Ort-Inspektion).', + en: 'Negotiate reasonable audit conditions (max. 30 days notice, possibility for on-site inspection).', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. h DSGVO', + triggerControls: ['VND-AUD-01'], + }, + + // DELETION + { + id: 'tpl-deletion-no-clause', + type: 'GAP', + category: 'DELETION', + severity: 'CRITICAL', + title: { de: 'Keine Lösch-/Rückgaberegelung', en: 'No deletion/return clause' }, + description: { + de: 'Der Vertrag regelt nicht, was mit den Daten nach Vertragsende geschieht.', + en: 'The contract does not regulate what happens to the data after contract termination.', + }, + recommendation: { + de: 'Ergänzen Sie eine Klausel zur Löschung oder Rückgabe aller personenbezogenen Daten nach Vertragsende (max. 30 Tage).', + en: 'Add a clause for deletion or return of all personal data after contract end (max. 30 days).', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. g DSGVO', + triggerControls: ['VND-DEL-01'], + }, + { + id: 'tpl-deletion-no-confirmation', + type: 'RISK', + category: 'DELETION', + severity: 'MEDIUM', + title: { de: 'Keine Löschbestätigung vorgesehen', en: 'No deletion confirmation provided' }, + description: { + de: 'Der Vertrag sieht keine Bestätigung der Löschung durch den Auftragsverarbeiter vor.', + en: 'The contract does not provide for confirmation of deletion by the processor.', + }, + recommendation: { + de: 'Ergänzen Sie eine Pflicht zur schriftlichen Bestätigung der vollständigen Löschung.', + en: 'Add an obligation for written confirmation of complete deletion.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. g DSGVO', + triggerControls: ['VND-DEL-01'], + }, + + // TRANSFER + { + id: 'tpl-transfer-no-basis', + type: 'GAP', + category: 'TRANSFER', + severity: 'CRITICAL', + title: { de: 'Drittlandtransfer ohne Rechtsgrundlage', en: 'Third country transfer without legal basis' }, + description: { + de: 'Der Vertrag erlaubt oder impliziert Transfers in Drittländer ohne geeignete Garantien.', + en: 'The contract allows or implies transfers to third countries without appropriate safeguards.', + }, + recommendation: { + de: 'Vereinbaren Sie geeignete Garantien (SCC, BCR) oder beschränken Sie die Verarbeitung auf EU/EWR.', + en: 'Agree on appropriate safeguards (SCC, BCR) or restrict processing to EU/EEA.', + }, + affectedRequirement: 'Art. 44-49 DSGVO', + triggerControls: ['VND-TRF-01'], + }, + { + id: 'tpl-transfer-old-scc', + type: 'RISK', + category: 'TRANSFER', + severity: 'HIGH', + title: { de: 'Veraltete Standardvertragsklauseln', en: 'Outdated Standard Contractual Clauses' }, + description: { + de: 'Der Vertrag verwendet die alten SCC (vor 2021), die nicht mehr gültig sind.', + en: 'The contract uses old SCC (pre-2021) that are no longer valid.', + }, + recommendation: { + de: 'Aktualisieren Sie auf die SCC 2021 (Durchführungsbeschluss (EU) 2021/914).', + en: 'Update to SCC 2021 (Implementing Decision (EU) 2021/914).', + }, + affectedRequirement: 'Art. 46 Abs. 2 lit. c DSGVO', + triggerControls: ['VND-TRF-02'], + }, + + // LIABILITY + { + id: 'tpl-liability-excessive-cap', + type: 'RISK', + category: 'LIABILITY', + severity: 'MEDIUM', + title: { de: 'Unangemessene Haftungsbegrenzung', en: 'Inappropriate liability cap' }, + description: { + de: 'Die Haftungsbegrenzung ist sehr niedrig und könnte bei Datenschutzverletzungen problematisch sein.', + en: 'The liability cap is very low and could be problematic in case of data protection violations.', + }, + recommendation: { + de: 'Prüfen Sie, ob die Haftungsbegrenzung angemessen ist. Erwägen Sie eine Ausnahme für Datenschutzverletzungen oder eine höhere Obergrenze.', + en: 'Check if the liability cap is appropriate. Consider an exception for data protection violations or a higher limit.', + }, + affectedRequirement: 'Vertragliche Vereinbarung', + triggerControls: [], + }, + + // DATA_SUBJECT_RIGHTS + { + id: 'tpl-dsr-no-support', + type: 'GAP', + category: 'DATA_SUBJECT_RIGHTS', + severity: 'HIGH', + title: { de: 'Keine Unterstützung bei Betroffenenrechten', en: 'No support for data subject rights' }, + description: { + de: 'Der Vertrag enthält keine Regelung zur Unterstützung bei der Erfüllung von Betroffenenrechten.', + en: 'The contract does not contain a provision for support in fulfilling data subject rights.', + }, + recommendation: { + de: 'Ergänzen Sie eine Klausel zur Unterstützung bei Auskunft, Berichtigung, Löschung und anderen Betroffenenrechten.', + en: 'Add a clause for support with access, rectification, deletion, and other data subject rights.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. e DSGVO', + triggerControls: ['VND-DSR-01'], + }, + + // CONFIDENTIALITY + { + id: 'tpl-confidentiality-missing', + type: 'GAP', + category: 'CONFIDENTIALITY', + severity: 'HIGH', + title: { de: 'Keine Vertraulichkeitsverpflichtung', en: 'No confidentiality obligation' }, + description: { + de: 'Der Vertrag enthält keine Verpflichtung zur Vertraulichkeit der Mitarbeiter.', + en: 'The contract does not contain an obligation for employee confidentiality.', + }, + recommendation: { + de: 'Ergänzen Sie eine Klausel, die die Verpflichtung der Mitarbeiter zur Vertraulichkeit sicherstellt.', + en: 'Add a clause ensuring the obligation of employees to confidentiality.', + }, + affectedRequirement: 'Art. 28 Abs. 3 lit. b DSGVO', + triggerControls: ['VND-CON-02'], + }, +] diff --git a/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings.ts b/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings.ts index e39081f..c1c10a6 100644 --- a/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings.ts +++ b/admin-compliance/lib/sdk/vendor-compliance/contract-review/findings.ts @@ -1,7 +1,8 @@ /** * Finding Types and Templates * - * Pre-defined finding templates for contract reviews + * Pre-defined finding templates for contract reviews. + * Barrel re-export — FINDING_TEMPLATES lives in findings-templates.ts. */ import { @@ -11,18 +12,6 @@ import { LocalizedText, } from '../types' -export interface FindingTemplate { - id: string - type: FindingType - category: FindingCategory - severity: FindingSeverity - title: LocalizedText - description: LocalizedText - recommendation: LocalizedText - affectedRequirement: string - triggerControls: string[] -} - // ========================================== // FINDING SEVERITY DEFINITIONS // ========================================== @@ -126,371 +115,11 @@ export const FINDING_TYPE_DEFINITIONS: Record72h), um die eigene Meldepflicht einhalten zu können.', - en: 'The agreed notification deadline for data breaches is too long (>72h) to meet own notification obligations.', - }, - recommendation: { - de: 'Verkürzen Sie die Meldefrist auf maximal 24-48 Stunden, um ausreichend Zeit für die eigene Meldung an die Aufsichtsbehörde zu haben.', - en: 'Reduce the notification deadline to a maximum of 24-48 hours to have sufficient time for own notification to the supervisory authority.', - }, - affectedRequirement: 'Art. 33 DSGVO', - triggerControls: ['VND-INC-01'], - }, - - // AUDIT_RIGHTS - { - id: 'tpl-audit-no-right', - type: 'GAP', - category: 'AUDIT_RIGHTS', - severity: 'HIGH', - title: { - de: 'Kein Auditrecht vereinbart', - en: 'No audit right agreed', - }, - description: { - de: 'Der Vertrag enthält kein Recht des Verantwortlichen auf Prüfungen und Inspektionen.', - en: 'The contract does not contain a right of the controller to audits and inspections.', - }, - recommendation: { - de: 'Ergänzen Sie ein ausdrückliches Recht auf Vor-Ort-Inspektionen und die Einsicht in relevante Unterlagen.', - en: 'Add an explicit right to on-site inspections and access to relevant documents.', - }, - affectedRequirement: 'Art. 28 Abs. 3 lit. h DSGVO', - triggerControls: ['VND-AUD-01'], - }, - { - id: 'tpl-audit-restricted', - type: 'RISK', - category: 'AUDIT_RIGHTS', - severity: 'MEDIUM', - title: { - de: 'Auditrecht eingeschränkt', - en: 'Audit right restricted', - }, - description: { - de: 'Das Auditrecht ist durch unangemessene Einschränkungen (z.B. sehr lange Vorlaufzeit, Ausschluss von Vor-Ort-Inspektionen) begrenzt.', - en: 'The audit right is limited by unreasonable restrictions (e.g., very long notice period, exclusion of on-site inspections).', - }, - recommendation: { - de: 'Verhandeln Sie angemessene Bedingungen für Audits (max. 30 Tage Vorlaufzeit, Möglichkeit zur Vor-Ort-Inspektion).', - en: 'Negotiate reasonable audit conditions (max. 30 days notice, possibility for on-site inspection).', - }, - affectedRequirement: 'Art. 28 Abs. 3 lit. h DSGVO', - triggerControls: ['VND-AUD-01'], - }, - - // DELETION - { - id: 'tpl-deletion-no-clause', - type: 'GAP', - category: 'DELETION', - severity: 'CRITICAL', - title: { - de: 'Keine Lösch-/Rückgaberegelung', - en: 'No deletion/return clause', - }, - description: { - de: 'Der Vertrag regelt nicht, was mit den Daten nach Vertragsende geschieht.', - en: 'The contract does not regulate what happens to the data after contract termination.', - }, - recommendation: { - de: 'Ergänzen Sie eine Klausel zur Löschung oder Rückgabe aller personenbezogenen Daten nach Vertragsende (max. 30 Tage).', - en: 'Add a clause for deletion or return of all personal data after contract end (max. 30 days).', - }, - affectedRequirement: 'Art. 28 Abs. 3 lit. g DSGVO', - triggerControls: ['VND-DEL-01'], - }, - { - id: 'tpl-deletion-no-confirmation', - type: 'RISK', - category: 'DELETION', - severity: 'MEDIUM', - title: { - de: 'Keine Löschbestätigung vorgesehen', - en: 'No deletion confirmation provided', - }, - description: { - de: 'Der Vertrag sieht keine Bestätigung der Löschung durch den Auftragsverarbeiter vor.', - en: 'The contract does not provide for confirmation of deletion by the processor.', - }, - recommendation: { - de: 'Ergänzen Sie eine Pflicht zur schriftlichen Bestätigung der vollständigen Löschung.', - en: 'Add an obligation for written confirmation of complete deletion.', - }, - affectedRequirement: 'Art. 28 Abs. 3 lit. g DSGVO', - triggerControls: ['VND-DEL-01'], - }, - - // TRANSFER - { - id: 'tpl-transfer-no-basis', - type: 'GAP', - category: 'TRANSFER', - severity: 'CRITICAL', - title: { - de: 'Drittlandtransfer ohne Rechtsgrundlage', - en: 'Third country transfer without legal basis', - }, - description: { - de: 'Der Vertrag erlaubt oder impliziert Transfers in Drittländer ohne geeignete Garantien.', - en: 'The contract allows or implies transfers to third countries without appropriate safeguards.', - }, - recommendation: { - de: 'Vereinbaren Sie geeignete Garantien (SCC, BCR) oder beschränken Sie die Verarbeitung auf EU/EWR.', - en: 'Agree on appropriate safeguards (SCC, BCR) or restrict processing to EU/EEA.', - }, - affectedRequirement: 'Art. 44-49 DSGVO', - triggerControls: ['VND-TRF-01'], - }, - { - id: 'tpl-transfer-old-scc', - type: 'RISK', - category: 'TRANSFER', - severity: 'HIGH', - title: { - de: 'Veraltete Standardvertragsklauseln', - en: 'Outdated Standard Contractual Clauses', - }, - description: { - de: 'Der Vertrag verwendet die alten SCC (vor 2021), die nicht mehr gültig sind.', - en: 'The contract uses old SCC (pre-2021) that are no longer valid.', - }, - recommendation: { - de: 'Aktualisieren Sie auf die SCC 2021 (Durchführungsbeschluss (EU) 2021/914).', - en: 'Update to SCC 2021 (Implementing Decision (EU) 2021/914).', - }, - affectedRequirement: 'Art. 46 Abs. 2 lit. c DSGVO', - triggerControls: ['VND-TRF-02'], - }, - - // LIABILITY - { - id: 'tpl-liability-excessive-cap', - type: 'RISK', - category: 'LIABILITY', - severity: 'MEDIUM', - title: { - de: 'Unangemessene Haftungsbegrenzung', - en: 'Inappropriate liability cap', - }, - description: { - de: 'Die Haftungsbegrenzung ist sehr niedrig und könnte bei Datenschutzverletzungen problematisch sein.', - en: 'The liability cap is very low and could be problematic in case of data protection violations.', - }, - recommendation: { - de: 'Prüfen Sie, ob die Haftungsbegrenzung angemessen ist. Erwägen Sie eine Ausnahme für Datenschutzverletzungen oder eine höhere Obergrenze.', - en: 'Check if the liability cap is appropriate. Consider an exception for data protection violations or a higher limit.', - }, - affectedRequirement: 'Vertragliche Vereinbarung', - triggerControls: [], - }, - - // DATA_SUBJECT_RIGHTS - { - id: 'tpl-dsr-no-support', - type: 'GAP', - category: 'DATA_SUBJECT_RIGHTS', - severity: 'HIGH', - title: { - de: 'Keine Unterstützung bei Betroffenenrechten', - en: 'No support for data subject rights', - }, - description: { - de: 'Der Vertrag enthält keine Regelung zur Unterstützung bei der Erfüllung von Betroffenenrechten.', - en: 'The contract does not contain a provision for support in fulfilling data subject rights.', - }, - recommendation: { - de: 'Ergänzen Sie eine Klausel zur Unterstützung bei Auskunft, Berichtigung, Löschung und anderen Betroffenenrechten.', - en: 'Add a clause for support with access, rectification, deletion, and other data subject rights.', - }, - affectedRequirement: 'Art. 28 Abs. 3 lit. e DSGVO', - triggerControls: ['VND-DSR-01'], - }, - - // CONFIDENTIALITY - { - id: 'tpl-confidentiality-missing', - type: 'GAP', - category: 'CONFIDENTIALITY', - severity: 'HIGH', - title: { - de: 'Keine Vertraulichkeitsverpflichtung', - en: 'No confidentiality obligation', - }, - description: { - de: 'Der Vertrag enthält keine Verpflichtung zur Vertraulichkeit der Mitarbeiter.', - en: 'The contract does not contain an obligation for employee confidentiality.', - }, - recommendation: { - de: 'Ergänzen Sie eine Klausel, die die Verpflichtung der Mitarbeiter zur Vertraulichkeit sicherstellt.', - en: 'Add a clause ensuring the obligation of employees to confidentiality.', - }, - affectedRequirement: 'Art. 28 Abs. 3 lit. b DSGVO', - triggerControls: ['VND-CON-02'], - }, -] +export type { FindingTemplate } +export { FINDING_TEMPLATES } // ========================================== // HELPER FUNCTIONS diff --git a/admin-compliance/lib/sdk/vvt-baseline-catalog/hr-finance.ts b/admin-compliance/lib/sdk/vvt-baseline-catalog/hr-finance.ts new file mode 100644 index 0000000..4ebaf33 --- /dev/null +++ b/admin-compliance/lib/sdk/vvt-baseline-catalog/hr-finance.ts @@ -0,0 +1,191 @@ +/** + * VVT Baseline-Katalog — HR & Finanzen + */ + +import type { BaselineTemplate } from './types' + +export const HR_VVT_TEMPLATES: BaselineTemplate[] = [ + { + templateId: 'hr-mitarbeiterverwaltung', + businessFunction: 'hr', + name: 'Mitarbeiterverwaltung', + description: 'Verwaltung von Stammdaten, Vertraegen und Personalakten der Beschaeftigten', + purposes: ['Durchfuehrung des Beschaeftigungsverhaeltnisses', 'Personalverwaltung und -planung'], + legalBases: [ + { type: 'CONTRACT', description: 'Arbeitsvertrag', reference: 'Art. 6 Abs. 1 lit. b DSGVO' }, + { type: 'LEGAL_OBLIGATION', description: 'Arbeitsrechtliche Pflichten', reference: '§ 26 BDSG' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'DOB', 'SOCIAL_SECURITY', 'TAX_ID', 'BANK_ACCOUNT', 'EMPLOYMENT_DATA'], + recipientCategories: [ + { type: 'INTERNAL', name: 'Personalabteilung' }, + { type: 'AUTHORITY', name: 'Finanzamt' }, + { type: 'AUTHORITY', name: 'Sozialversicherungstraeger' }, + ], + retentionPeriod: { duration: 10, durationUnit: 'YEARS', description: '10 Jahre nach Ende des Beschaeftigungsverhaeltnisses', legalBasis: 'HGB § 257, AO § 147', deletionProcedure: 'Sichere Loeschung nach Ablauf' }, + tomDescription: 'Zugriffskontrolle auf Personalakten, Verschluesselung, Protokollierung', + structuredToms: { + accessControl: ['RBAC', 'Need-to-know-Prinzip', 'Personalakten nur fuer HR'], + confidentiality: ['Verschluesselung personenbezogener Daten', 'Vertraulichkeitsvereinbarungen'], + integrity: ['Aenderungsprotokollierung', 'Vier-Augen-Prinzip bei Gehaltsaenderungen'], + availability: ['Regelmaessige Backups', 'Redundante Speicherung'], + separation: ['Trennung Personal-/Gehaltsdaten'], + }, + typicalSystems: ['HR-Software', 'Gehaltsabrechnung', 'Dokumentenmanagement'], + protectionLevel: 'HIGH', + dpiaRequired: false, + tags: ['hr', 'mitarbeiter', 'personal'], + }, + { + templateId: 'hr-gehaltsabrechnung', + businessFunction: 'hr', + name: 'Gehaltsabrechnung', + description: 'Berechnung und Auszahlung von Gehaeltern, Sozialabgaben und Steuern', + purposes: ['Lohn- und Gehaltsabrechnung', 'Erfuellung steuer- und sozialversicherungsrechtlicher Pflichten'], + legalBases: [ + { type: 'CONTRACT', description: 'Arbeitsvertrag', reference: 'Art. 6 Abs. 1 lit. b DSGVO' }, + { type: 'LEGAL_OBLIGATION', description: 'Steuer-/Sozialversicherungsrecht', reference: 'Art. 6 Abs. 1 lit. c DSGVO' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: ['NAME', 'ADDRESS', 'SOCIAL_SECURITY', 'TAX_ID', 'BANK_ACCOUNT', 'SALARY_DATA'], + recipientCategories: [ + { type: 'PROCESSOR', name: 'Lohnbuero / Steuerberater' }, + { type: 'AUTHORITY', name: 'Finanzamt' }, + { type: 'AUTHORITY', name: 'Krankenkassen' }, + ], + retentionPeriod: { duration: 10, durationUnit: 'YEARS', description: '10 Jahre (steuerrechtlich)', legalBasis: 'AO § 147 Abs. 1 Nr. 1', deletionProcedure: 'Automatische Loeschung nach Fristablauf' }, + tomDescription: 'Strenge Zugriffskontrolle, Verschluesselung, Trennung von Stamm- und Gehaltsdaten', + structuredToms: { + accessControl: ['Nur Lohnbuchhaltung/Steuerberater', 'MFA'], + confidentiality: ['Verschluesselung at-rest und in-transit', 'Vertraulichkeitsklausel'], + integrity: ['Revisionssichere Ablage', 'Pruefprotokoll'], + availability: ['Monatliche Backups', 'Jahresabschluss-Archiv'], + separation: ['Gehaltsdaten getrennt von allgemeinen Personaldaten'], + }, + typicalSystems: ['DATEV', 'Lohnabrechnungssoftware'], + protectionLevel: 'HIGH', + dpiaRequired: false, + tags: ['hr', 'gehalt', 'lohn', 'steuer'], + }, + { + templateId: 'hr-bewerbermanagement', + businessFunction: 'hr', + name: 'Bewerbermanagement', + description: 'Entgegennahme, Verwaltung und Bewertung von Bewerbungen', + purposes: ['Bearbeitung eingehender Bewerbungen', 'Bewerberauswahl'], + legalBases: [ + { type: 'CONTRACT', description: 'Vorvertragliche Massnahmen', reference: 'Art. 6 Abs. 1 lit. b DSGVO' }, + { type: 'LEGITIMATE_INTEREST', description: 'Bewerberauswahl', reference: '§ 26 Abs. 1 BDSG' }, + ], + dataSubjectCategories: ['APPLICANTS'], + personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'EDUCATION_DATA', 'EMPLOYMENT_DATA', 'PHOTO_VIDEO'], + recipientCategories: [ + { type: 'INTERNAL', name: 'Personalabteilung' }, + { type: 'INTERNAL', name: 'Fachabteilung' }, + ], + retentionPeriod: { duration: 6, durationUnit: 'MONTHS', description: '6 Monate nach Absage (AGG-Frist)', legalBasis: 'AGG § 15 Abs. 4', deletionProcedure: 'Automatische Loeschung 6 Monate nach Absage' }, + tomDescription: 'Zugriffsbeschraenkung auf beteiligte Entscheidungstraeger, verschluesselte Uebertragung', + structuredToms: { + accessControl: ['Nur HR + Fachabteilung', 'Zeitlich begrenzter Zugriff'], + confidentiality: ['TLS fuer Bewerbungsportale', 'Verschluesselter E-Mail-Empfang'], + integrity: ['Unveraenderbare Bewerbungseingaenge'], + availability: ['Regelmaessige Backups'], + separation: ['Getrennte Bewerberdatenbank'], + }, + typicalSystems: ['Bewerbermanagementsystem', 'E-Mail'], + protectionLevel: 'MEDIUM', + dpiaRequired: false, + tags: ['hr', 'bewerbung', 'recruiting'], + }, + { + templateId: 'hr-zeiterfassung', + businessFunction: 'hr', + name: 'Zeiterfassung', + description: 'Erfassung von Arbeitszeiten, Urlaub und Fehlzeiten', + purposes: ['Arbeitszeiterfassung gemaess ArbZG', 'Urlaubsverwaltung'], + legalBases: [ + { type: 'LEGAL_OBLIGATION', description: 'Arbeitszeitgesetz', reference: 'Art. 6 Abs. 1 lit. c DSGVO, ArbZG § 16 Abs. 2' }, + ], + dataSubjectCategories: ['EMPLOYEES'], + personalDataCategories: ['NAME', 'EMPLOYMENT_DATA'], + recipientCategories: [ + { type: 'INTERNAL', name: 'Personalabteilung' }, + { type: 'INTERNAL', name: 'Vorgesetzte' }, + ], + retentionPeriod: { duration: 2, durationUnit: 'YEARS', description: '2 Jahre (ArbZG)', legalBasis: 'ArbZG § 16 Abs. 2', deletionProcedure: 'Automatische Loeschung' }, + tomDescription: 'Zugriffskontrolle nach Abteilung, Protokollierung von Aenderungen', + structuredToms: { + accessControl: ['Vorgesetzte sehen nur eigene Abteilung', 'HR sieht alle'], + confidentiality: ['Krankmeldungen nur HR'], + integrity: ['Aenderungshistorie'], + availability: ['Taegliches Backup'], + separation: ['Trennung Zeitdaten / Gehaltsdaten'], + }, + typicalSystems: ['Zeiterfassungssystem', 'HR-Software'], + protectionLevel: 'MEDIUM', + dpiaRequired: false, + tags: ['hr', 'zeiterfassung', 'arbeitszeit'], + }, +] + +export const FINANCE_VVT_TEMPLATES: BaselineTemplate[] = [ + { + templateId: 'finance-buchhaltung', + businessFunction: 'finance', + name: 'Buchhaltung & Rechnungswesen', + description: 'Finanzbuchhaltung, Rechnungsstellung und Zahlungsverkehr', + purposes: ['Finanzbuchhaltung', 'Rechnungsstellung', 'Erfuellung handels-/steuerrechtlicher Aufbewahrungspflichten'], + legalBases: [ + { type: 'LEGAL_OBLIGATION', description: 'HGB, AO', reference: 'Art. 6 Abs. 1 lit. c DSGVO' }, + { type: 'CONTRACT', description: 'Vertragserfuellung', reference: 'Art. 6 Abs. 1 lit. b DSGVO' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'SUPPLIERS', 'BUSINESS_PARTNERS'], + personalDataCategories: ['NAME', 'CONTACT', 'ADDRESS', 'BANK_ACCOUNT', 'PAYMENT_DATA', 'CONTRACT_DATA', 'TAX_ID'], + recipientCategories: [ + { type: 'PROCESSOR', name: 'Steuerberater / Wirtschaftspruefer' }, + { type: 'AUTHORITY', name: 'Finanzamt' }, + ], + retentionPeriod: { duration: 10, durationUnit: 'YEARS', description: '10 Jahre (HGB) / 6 Jahre (Geschaeftsbriefe)', legalBasis: 'HGB § 257, AO § 147', deletionProcedure: 'Loeschung nach Ablauf der jeweiligen Frist' }, + tomDescription: 'Zugriffskontrolle nach Vier-Augen-Prinzip, revisionssichere Archivierung', + structuredToms: { + accessControl: ['Vier-Augen-Prinzip', 'RBAC nach Buchhaltungsrollen'], + confidentiality: ['Verschluesselung Finanzdaten'], + integrity: ['Revisionssichere Archivierung (GoBD)', 'Aenderungsprotokoll'], + availability: ['Redundante Speicherung', 'Jaehrliche Backups'], + separation: ['Trennung Debitoren/Kreditoren'], + }, + typicalSystems: ['DATEV', 'ERP-System', 'Buchhaltungssoftware'], + protectionLevel: 'MEDIUM', + dpiaRequired: false, + tags: ['finance', 'buchhaltung', 'rechnungswesen'], + }, + { + templateId: 'finance-zahlungsverkehr', + businessFunction: 'finance', + name: 'Zahlungsverkehr', + description: 'Abwicklung von Zahlungen, SEPA-Lastschriften und Ueberweisungen', + purposes: ['Zahlungsabwicklung', 'Mahnwesen'], + legalBases: [ + { type: 'CONTRACT', description: 'Vertragserfuellung', reference: 'Art. 6 Abs. 1 lit. b DSGVO' }, + ], + dataSubjectCategories: ['CUSTOMERS', 'SUPPLIERS'], + personalDataCategories: ['NAME', 'BANK_ACCOUNT', 'PAYMENT_DATA'], + recipientCategories: [ + { type: 'PROCESSOR', name: 'Zahlungsdienstleister' }, + { type: 'PROCESSOR', name: 'Kreditinstitut' }, + ], + retentionPeriod: { duration: 10, durationUnit: 'YEARS', description: '10 Jahre', legalBasis: 'HGB § 257', deletionProcedure: 'Automatische Loeschung' }, + tomDescription: 'PCI-DSS-konforme Verarbeitung, Verschluesselung, Zugriffsbeschraenkung', + structuredToms: { + accessControl: ['Streng limitierter Zugriff', 'MFA'], + confidentiality: ['TLS 1.3', 'Tokenisierung von Zahlungsdaten'], + integrity: ['Transaktionsprotokoll'], + availability: ['Hochverfuegbarer Zahlungsservice'], + separation: ['Zahlungsdaten getrennt von CRM'], + }, + typicalSystems: ['Banking-Software', 'Payment Gateway'], + protectionLevel: 'HIGH', + dpiaRequired: false, + tags: ['finance', 'zahlung', 'payment'], + }, +] diff --git a/admin-compliance/lib/sdk/vvt-baseline-catalog/types.ts b/admin-compliance/lib/sdk/vvt-baseline-catalog/types.ts new file mode 100644 index 0000000..f55fbe7 --- /dev/null +++ b/admin-compliance/lib/sdk/vvt-baseline-catalog/types.ts @@ -0,0 +1,30 @@ +/** + * VVT Baseline-Katalog — Types + */ + +import type { BusinessFunction } from '../vvt-types' + +export interface BaselineTemplate { + templateId: string + businessFunction: BusinessFunction + name: string + description: string + purposes: string[] + legalBases: { type: string; description?: string; reference?: string }[] + dataSubjectCategories: string[] + personalDataCategories: string[] + recipientCategories: { type: string; name: string; description?: string }[] + retentionPeriod: { duration?: number; durationUnit?: string; description: string; legalBasis?: string; deletionProcedure?: string } + tomDescription: string + structuredToms: { + accessControl: string[] + confidentiality: string[] + integrity: string[] + availability: string[] + separation: string[] + } + typicalSystems: string[] + protectionLevel: 'LOW' | 'MEDIUM' | 'HIGH' + dpiaRequired: boolean + tags: string[] +}