Files
Benjamin Boenisch 4435e7ea0a Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:28 +01:00

216 lines
11 KiB
SQL

-- DSGVO Schema Migration
-- AI Compliance SDK - Phase 4: DSGVO Integration
-- ============================================================================
-- VVT - Verarbeitungsverzeichnis (Art. 30 DSGVO)
-- ============================================================================
CREATE TABLE IF NOT EXISTS dsgvo_processing_activities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
namespace_id UUID REFERENCES compliance_namespaces(id) ON DELETE SET NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
purpose TEXT NOT NULL,
legal_basis VARCHAR(50) NOT NULL, -- consent, contract, legal_obligation, vital_interests, public_interest, legitimate_interests
legal_basis_details TEXT,
data_categories JSONB DEFAULT '[]',
data_subject_categories JSONB DEFAULT '[]',
recipients JSONB DEFAULT '[]',
third_country_transfer BOOLEAN DEFAULT FALSE,
transfer_safeguards TEXT,
retention_period VARCHAR(255),
retention_policy_id UUID,
tom_reference JSONB DEFAULT '[]',
dsfa_required BOOLEAN DEFAULT FALSE,
dsfa_id UUID,
responsible_person VARCHAR(255),
responsible_department VARCHAR(255),
systems JSONB DEFAULT '[]',
status VARCHAR(50) DEFAULT 'draft', -- draft, active, under_review, archived
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID NOT NULL,
last_reviewed_at TIMESTAMPTZ,
next_review_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_dsgvo_pa_tenant ON dsgvo_processing_activities(tenant_id);
CREATE INDEX IF NOT EXISTS idx_dsgvo_pa_status ON dsgvo_processing_activities(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_dsgvo_pa_namespace ON dsgvo_processing_activities(namespace_id) WHERE namespace_id IS NOT NULL;
-- ============================================================================
-- DSFA - Datenschutz-Folgenabschätzung (Art. 35 DSGVO)
-- ============================================================================
CREATE TABLE IF NOT EXISTS dsgvo_dsfa (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
namespace_id UUID REFERENCES compliance_namespaces(id) ON DELETE SET NULL,
processing_activity_id UUID REFERENCES dsgvo_processing_activities(id) ON DELETE SET NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
processing_description TEXT,
necessity_assessment TEXT,
proportionality_assessment TEXT,
risks JSONB DEFAULT '[]',
mitigations JSONB DEFAULT '[]',
dpo_consulted BOOLEAN DEFAULT FALSE,
dpo_opinion TEXT,
authority_consulted BOOLEAN DEFAULT FALSE,
authority_reference VARCHAR(255),
status VARCHAR(50) DEFAULT 'draft', -- draft, in_progress, completed, approved, rejected
overall_risk_level VARCHAR(20), -- low, medium, high, very_high
conclusion TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID NOT NULL,
approved_by UUID,
approved_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsfa_tenant ON dsgvo_dsfa(tenant_id);
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsfa_status ON dsgvo_dsfa(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsfa_pa ON dsgvo_dsfa(processing_activity_id) WHERE processing_activity_id IS NOT NULL;
-- ============================================================================
-- TOM - Technische und Organisatorische Maßnahmen (Art. 32 DSGVO)
-- ============================================================================
CREATE TABLE IF NOT EXISTS dsgvo_tom (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
namespace_id UUID REFERENCES compliance_namespaces(id) ON DELETE SET NULL,
category VARCHAR(50) NOT NULL, -- access_control, encryption, pseudonymization, etc.
subcategory VARCHAR(100),
name VARCHAR(255) NOT NULL,
description TEXT,
type VARCHAR(20) NOT NULL, -- technical, organizational
implementation_status VARCHAR(50) DEFAULT 'planned', -- planned, in_progress, implemented, verified, not_applicable
implemented_at TIMESTAMPTZ,
verified_at TIMESTAMPTZ,
verified_by UUID,
effectiveness_rating VARCHAR(20), -- low, medium, high
documentation TEXT,
responsible_person VARCHAR(255),
responsible_department VARCHAR(255),
review_frequency VARCHAR(50), -- monthly, quarterly, annually
last_review_at TIMESTAMPTZ,
next_review_at TIMESTAMPTZ,
related_controls JSONB DEFAULT '[]',
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_dsgvo_tom_tenant ON dsgvo_tom(tenant_id);
CREATE INDEX IF NOT EXISTS idx_dsgvo_tom_category ON dsgvo_tom(tenant_id, category);
CREATE INDEX IF NOT EXISTS idx_dsgvo_tom_status ON dsgvo_tom(tenant_id, implementation_status);
-- ============================================================================
-- DSR - Data Subject Requests / Betroffenenrechte (Art. 15-22 DSGVO)
-- ============================================================================
CREATE TABLE IF NOT EXISTS dsgvo_dsr (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
namespace_id UUID REFERENCES compliance_namespaces(id) ON DELETE SET NULL,
request_type VARCHAR(50) NOT NULL, -- access, rectification, erasure, restriction, portability, objection
status VARCHAR(50) DEFAULT 'received', -- received, verified, in_progress, completed, rejected, extended
subject_name VARCHAR(255) NOT NULL,
subject_email VARCHAR(255) NOT NULL,
subject_identifier VARCHAR(255),
request_description TEXT,
request_channel VARCHAR(50), -- email, form, phone, letter
received_at TIMESTAMPTZ NOT NULL,
verified_at TIMESTAMPTZ,
verification_method VARCHAR(100),
deadline_at TIMESTAMPTZ NOT NULL,
extended_deadline_at TIMESTAMPTZ,
extension_reason TEXT,
completed_at TIMESTAMPTZ,
response_sent BOOLEAN DEFAULT FALSE,
response_sent_at TIMESTAMPTZ,
response_method VARCHAR(50),
rejection_reason TEXT,
notes TEXT,
affected_systems JSONB DEFAULT '[]',
assigned_to UUID,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsr_tenant ON dsgvo_dsr(tenant_id);
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsr_status ON dsgvo_dsr(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsr_deadline ON dsgvo_dsr(tenant_id, deadline_at) WHERE status NOT IN ('completed', 'rejected');
CREATE INDEX IF NOT EXISTS idx_dsgvo_dsr_type ON dsgvo_dsr(tenant_id, request_type);
-- ============================================================================
-- Retention Policies - Löschfristen (Art. 17 DSGVO)
-- ============================================================================
CREATE TABLE IF NOT EXISTS dsgvo_retention_policies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES compliance_tenants(id) ON DELETE CASCADE,
namespace_id UUID REFERENCES compliance_namespaces(id) ON DELETE SET NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
data_category VARCHAR(100) NOT NULL,
retention_period_days INT NOT NULL,
retention_period_text VARCHAR(255), -- Human readable
legal_basis VARCHAR(100),
legal_reference VARCHAR(255), -- § 147 AO, § 257 HGB, etc.
deletion_method VARCHAR(50), -- automatic, manual, anonymization
deletion_procedure TEXT,
exception_criteria TEXT,
applicable_systems JSONB DEFAULT '[]',
responsible_person VARCHAR(255),
responsible_department VARCHAR(255),
status VARCHAR(50) DEFAULT 'draft', -- draft, active, archived
last_review_at TIMESTAMPTZ,
next_review_at TIMESTAMPTZ,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_dsgvo_retention_tenant ON dsgvo_retention_policies(tenant_id);
CREATE INDEX IF NOT EXISTS idx_dsgvo_retention_status ON dsgvo_retention_policies(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_dsgvo_retention_category ON dsgvo_retention_policies(tenant_id, data_category);
-- ============================================================================
-- Insert default TOM categories as reference data
-- ============================================================================
-- This is optional - the categories are also defined in code
-- But having them in the database allows for easier UI population
CREATE TABLE IF NOT EXISTS dsgvo_tom_categories (
id VARCHAR(50) PRIMARY KEY,
name_de VARCHAR(255) NOT NULL,
name_en VARCHAR(255) NOT NULL,
description_de TEXT,
article_reference VARCHAR(50)
);
INSERT INTO dsgvo_tom_categories (id, name_de, name_en, description_de, article_reference) VALUES
('access_control', 'Zutrittskontrolle', 'Physical Access Control', 'Maßnahmen zur Verhinderung des unbefugten Zutritts zu Datenverarbeitungsanlagen', 'Art. 32 Abs. 1 lit. b'),
('admission_control', 'Zugangskontrolle', 'Logical Access Control', 'Maßnahmen zur Verhinderung der unbefugten Nutzung von DV-Systemen', 'Art. 32 Abs. 1 lit. b'),
('access_management', 'Zugriffskontrolle', 'Access Management', 'Maßnahmen zur Gewährleistung, dass nur befugte Personen Zugriff auf Daten haben', 'Art. 32 Abs. 1 lit. b'),
('transfer_control', 'Weitergabekontrolle', 'Transfer Control', 'Maßnahmen zur Verhinderung des unbefugten Lesens, Kopierens oder Entfernens bei der Übertragung', 'Art. 32 Abs. 1 lit. b'),
('input_control', 'Eingabekontrolle', 'Input Control', 'Maßnahmen zur Nachvollziehbarkeit von Eingabe, Änderung und Löschung von Daten', 'Art. 32 Abs. 1 lit. b'),
('availability_control', 'Verfügbarkeitskontrolle', 'Availability Control', 'Maßnahmen zum Schutz gegen zufällige oder mutwillige Zerstörung oder Verlust', 'Art. 32 Abs. 1 lit. b, c'),
('separation_control', 'Trennungskontrolle', 'Separation Control', 'Maßnahmen zur getrennten Verarbeitung von Daten, die zu unterschiedlichen Zwecken erhoben wurden', 'Art. 32 Abs. 1 lit. b'),
('encryption', 'Verschlüsselung', 'Encryption', 'Verschlüsselung personenbezogener Daten', 'Art. 32 Abs. 1 lit. a'),
('pseudonymization', 'Pseudonymisierung', 'Pseudonymization', 'Verarbeitung in einer Weise, dass die Daten ohne zusätzliche Informationen nicht mehr zugeordnet werden können', 'Art. 32 Abs. 1 lit. a'),
('resilience', 'Belastbarkeit', 'Resilience', 'Fähigkeit, die Verfügbarkeit und den Zugang bei einem Zwischenfall rasch wiederherzustellen', 'Art. 32 Abs. 1 lit. b, c'),
('recovery', 'Wiederherstellung', 'Recovery', 'Verfahren zur Wiederherstellung der Verfügbarkeit und des Zugangs', 'Art. 32 Abs. 1 lit. c'),
('testing', 'Regelmäßige Überprüfung', 'Regular Testing', 'Verfahren zur regelmäßigen Überprüfung, Bewertung und Evaluierung der Wirksamkeit', 'Art. 32 Abs. 1 lit. d')
ON CONFLICT (id) DO NOTHING;