c89a68e59e
Whistleblower (HinSchG): - Migration 118: 3 tables (reports, messages, measures) with HinSchG deadlines (7d acknowledgment, 3mo feedback) - whistleblower_routes.py: 14 endpoints (CRUD, acknowledge, close, messages, measures, public submit, anonymous status check) - Frontend api-operations.ts rewired from Go SDK to compliance proxy - Access key format XXXX-XXXX-XXXX for anonymous reporters Scanner banner-check (TTDSG § 25): - CMP Dashboard: green "Kein Cookie-Banner erforderlich" when no trackers detected + no banner configured - Red warning "Cookie-Banner fehlt!" when trackers found but no banner - Mandatory note: Impressum (DDG § 5) + DSE (DSGVO Art. 13) still required [migration-approved] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 lines
2.4 KiB
SQL
59 lines
2.4 KiB
SQL
-- Migration 118: Whistleblower (HinSchG) — Report + Message tables
|
|
-- Meldestelle fuer Hinweisgeber gemaess HinSchG §§ 12-18
|
|
|
|
CREATE TABLE IF NOT EXISTS compliance_whistleblower_reports (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
reference_number VARCHAR(50) NOT NULL,
|
|
access_key VARCHAR(20) NOT NULL,
|
|
category VARCHAR(30) NOT NULL DEFAULT 'other',
|
|
status VARCHAR(30) NOT NULL DEFAULT 'new',
|
|
priority VARCHAR(20) NOT NULL DEFAULT 'normal',
|
|
title VARCHAR(500) NOT NULL,
|
|
description TEXT NOT NULL,
|
|
is_anonymous BOOLEAN NOT NULL DEFAULT TRUE,
|
|
reporter_name VARCHAR(300),
|
|
reporter_email VARCHAR(300),
|
|
reporter_phone VARCHAR(100),
|
|
assigned_to VARCHAR(300),
|
|
received_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
acknowledged_at TIMESTAMPTZ,
|
|
deadline_acknowledgment TIMESTAMPTZ,
|
|
deadline_feedback TIMESTAMPTZ,
|
|
closed_at TIMESTAMPTZ,
|
|
closure_reason TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(tenant_id, reference_number),
|
|
UNIQUE(tenant_id, access_key)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_wb_reports_tenant ON compliance_whistleblower_reports(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_wb_reports_status ON compliance_whistleblower_reports(tenant_id, status);
|
|
CREATE INDEX IF NOT EXISTS idx_wb_reports_access ON compliance_whistleblower_reports(access_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS compliance_whistleblower_messages (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
report_id UUID NOT NULL REFERENCES compliance_whistleblower_reports(id) ON DELETE CASCADE,
|
|
sender_type VARCHAR(20) NOT NULL DEFAULT 'reporter',
|
|
message TEXT NOT NULL,
|
|
is_internal BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_wb_messages_report ON compliance_whistleblower_messages(report_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS compliance_whistleblower_measures (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
report_id UUID NOT NULL REFERENCES compliance_whistleblower_reports(id) ON DELETE CASCADE,
|
|
title VARCHAR(500) NOT NULL,
|
|
description TEXT,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'planned',
|
|
responsible VARCHAR(300),
|
|
due_date TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_wb_measures_report ON compliance_whistleblower_measures(report_id);
|