feat: Whistleblower backend + Scanner banner-check (last 2 gaps)
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>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
-- 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);
|
||||
Reference in New Issue
Block a user