-- 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;