feat: enhance whistleblower HinSchG content, fix control-library filter layout
All checks were successful
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 34s
CI/CD / test-python-backend-compliance (push) Successful in 35s
CI/CD / test-python-document-crawler (push) Successful in 26s
CI/CD / test-python-dsms-gateway (push) Successful in 21s
CI/CD / validate-canonical-controls (push) Successful in 12s
CI/CD / Deploy (push) Successful in 2s

- Whistleblower page: expand overview tab with comprehensive HinSchG legal info
  (Gesetzliche Grundlage, Fristen-Cards, Anwendungsbereich, Schutz des Hinweisgebers)
- StepHeader: enrich whistleblower tips with detailed HinSchG paragraphs and sanctions
- Wiki: add migration 054 with 5 new/updated HinSchG articles (Anwendungsbereich,
  Hinweisgeberschutz, Meldestellen, Verfahrensablauf, Datenschutz-Anforderungen)
- MKDocs: rewrite whistleblower docs with full legal basis, architecture, API, DB schema
- Control library: fix filter dropdown overflow by splitting into search + filter rows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-15 00:23:19 +01:00
parent 2ed1c08acf
commit f3e05c1bf7
5 changed files with 746 additions and 110 deletions

View File

@@ -363,83 +363,85 @@ export default function ControlLibraryPage() {
)}
{/* Filters */}
<div className="flex items-center gap-3">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
<input
type="text"
placeholder="Controls durchsuchen..."
value={searchQuery}
onChange={e => setSearchQuery(e.target.value)}
className="w-full pl-9 pr-4 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
<div className="space-y-3">
<div className="flex items-center gap-3">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
<input
type="text"
placeholder="Controls durchsuchen..."
value={searchQuery}
onChange={e => setSearchQuery(e.target.value)}
className="w-full pl-9 pr-4 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500"
/>
</div>
</div>
<div className="flex items-center gap-1">
<div className="flex items-center gap-2 flex-wrap">
<Filter className="w-4 h-4 text-gray-400" />
<select
value={severityFilter}
onChange={e => setSeverityFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Schweregrad</option>
<option value="critical">Kritisch</option>
<option value="high">Hoch</option>
<option value="medium">Mittel</option>
<option value="low">Niedrig</option>
</select>
<select
value={domainFilter}
onChange={e => setDomainFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Domain</option>
{domains.map(d => (
<option key={d} value={d}>{d}</option>
))}
</select>
<select
value={stateFilter}
onChange={e => setStateFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Status</option>
<option value="draft">Draft</option>
<option value="approved">Approved</option>
<option value="needs_review">Review noetig</option>
<option value="too_close">Zu aehnlich</option>
<option value="duplicate">Duplikat</option>
</select>
<select
value={verificationFilter}
onChange={e => setVerificationFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Nachweis</option>
{Object.entries(VERIFICATION_METHODS).map(([k, v]) => (
<option key={k} value={k}>{v.label}</option>
))}
</select>
<select
value={categoryFilter}
onChange={e => setCategoryFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Kategorie</option>
{CATEGORY_OPTIONS.map(c => (
<option key={c.value} value={c.value}>{c.label}</option>
))}
</select>
<select
value={audienceFilter}
onChange={e => setAudienceFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Zielgruppe</option>
{Object.entries(TARGET_AUDIENCE_OPTIONS).map(([k, v]) => (
<option key={k} value={k}>{v.label}</option>
))}
</select>
</div>
<select
value={severityFilter}
onChange={e => setSeverityFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Alle Schweregrade</option>
<option value="critical">Kritisch</option>
<option value="high">Hoch</option>
<option value="medium">Mittel</option>
<option value="low">Niedrig</option>
</select>
<select
value={domainFilter}
onChange={e => setDomainFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Alle Domains</option>
{domains.map(d => (
<option key={d} value={d}>{d}</option>
))}
</select>
<select
value={stateFilter}
onChange={e => setStateFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Alle Status</option>
<option value="draft">Draft</option>
<option value="approved">Approved</option>
<option value="needs_review">Review noetig</option>
<option value="too_close">Zu aehnlich</option>
<option value="duplicate">Duplikat</option>
</select>
<select
value={verificationFilter}
onChange={e => setVerificationFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Alle Nachweismethoden</option>
{Object.entries(VERIFICATION_METHODS).map(([k, v]) => (
<option key={k} value={k}>{v.label}</option>
))}
</select>
<select
value={categoryFilter}
onChange={e => setCategoryFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Alle Kategorien</option>
{CATEGORY_OPTIONS.map(c => (
<option key={c.value} value={c.value}>{c.label}</option>
))}
</select>
<select
value={audienceFilter}
onChange={e => setAudienceFilter(e.target.value)}
className="text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Alle Zielgruppen</option>
{Object.entries(TARGET_AUDIENCE_OPTIONS).map(([k, v]) => (
<option key={k} value={k}>{v.label}</option>
))}
</select>
</div>
{/* Processing Stats */}

View File

@@ -1128,24 +1128,88 @@ export default function WhistleblowerPage() {
</div>
)}
{/* Info Box about HinSchG Deadlines (Overview Tab) */}
{/* Info Box about HinSchG (Overview Tab) */}
{activeTab === 'overview' && (
<div className="bg-blue-50 border border-blue-200 rounded-xl p-4">
<div className="flex items-start gap-3">
<svg className="w-5 h-5 text-blue-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div>
<h4 className="font-medium text-blue-800">HinSchG-Fristen</h4>
<p className="text-sm text-blue-600 mt-1">
Nach dem Hinweisgeberschutzgesetz (HinSchG) gelten folgende Fristen:
Die Eingangsbestaetigung muss innerhalb von <strong>7 Tagen</strong> an den
Hinweisgeber versendet werden (ss 17 Abs. 1 S. 2).
Eine Rueckmeldung ueber ergriffene Massnahmen muss innerhalb von <strong>3 Monaten</strong> nach
Eingangsbestaetigung erfolgen (ss 17 Abs. 2).
Der Schutz des Hinweisgebers vor Repressalien ist zwingend sicherzustellen (ss 36).
<div className="space-y-4">
{/* Gesetzliche Grundlage */}
<div className="bg-blue-50 border border-blue-200 rounded-xl p-5">
<div className="flex items-start gap-3">
<svg className="w-5 h-5 text-blue-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div>
<h4 className="font-medium text-blue-800">Gesetzliche Grundlage: Hinweisgeberschutzgesetz (HinSchG)</h4>
<p className="text-sm text-blue-600 mt-1">
Das HinSchG setzt die <strong>EU-Whistleblowing-Richtlinie (2019/1937)</strong> in deutsches Recht um
und ist seit dem <strong>2. Juli 2023</strong> in Kraft. Seit dem <strong>17. Dezember 2023</strong> gilt
die Pflicht zur Einrichtung einer internen Meldestelle auch fuer Unternehmen ab 50 Beschaeftigten (ss 12 HinSchG).
</p>
</div>
</div>
</div>
{/* Fristen & Pflichten */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="bg-white border border-gray-200 rounded-xl p-4">
<div className="flex items-center gap-2 mb-2">
<svg className="w-4 h-4 text-orange-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<h5 className="text-sm font-semibold text-gray-900">7-Tage-Frist</h5>
</div>
<p className="text-xs text-gray-600">
Eingangsbestaetigung an den Hinweisgeber innerhalb von 7 Tagen nach Meldungseingang (ss 17 Abs. 1 S. 2 HinSchG).
</p>
</div>
<div className="bg-white border border-gray-200 rounded-xl p-4">
<div className="flex items-center gap-2 mb-2">
<svg className="w-4 h-4 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<h5 className="text-sm font-semibold text-gray-900">3-Monate-Frist</h5>
</div>
<p className="text-xs text-gray-600">
Rueckmeldung ueber ergriffene Folgemaßnahmen innerhalb von 3 Monaten nach Eingangsbestaetigung (ss 17 Abs. 2 HinSchG).
</p>
</div>
<div className="bg-white border border-gray-200 rounded-xl p-4">
<div className="flex items-center gap-2 mb-2">
<svg className="w-4 h-4 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<h5 className="text-sm font-semibold text-gray-900">3 Jahre Aufbewahrung</h5>
</div>
<p className="text-xs text-gray-600">
Dokumentation der Meldungen und Folgemaßnahmen ist 3 Jahre nach Abschluss aufzubewahren (ss 11 Abs. 5 HinSchG).
</p>
</div>
</div>
{/* Sachlicher Anwendungsbereich & Schutz */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="bg-amber-50 border border-amber-200 rounded-xl p-4">
<h5 className="text-sm font-semibold text-amber-800 mb-2">Sachlicher Anwendungsbereich (ss 2 HinSchG)</h5>
<ul className="text-xs text-amber-700 space-y-1">
<li>Verstoesse gegen Strafvorschriften (StGB, Nebenstrafrecht)</li>
<li>Verstoesse gegen Datenschutzrecht (DSGVO, BDSG)</li>
<li>Geldwaesche und Terrorismusfinanzierung (GwG)</li>
<li>Produktsicherheit und Verbraucherschutz</li>
<li>Umweltschutz und Lebensmittelsicherheit</li>
<li>Arbeitsschutz und Arbeitnehmerrechte</li>
<li>Wettbewerbs- und Kartellrecht</li>
<li>Steuer- und Abgabenrecht (bei Unternehmen)</li>
</ul>
</div>
<div className="bg-green-50 border border-green-200 rounded-xl p-4">
<h5 className="text-sm font-semibold text-green-800 mb-2">Schutz des Hinweisgebers (ss 3637 HinSchG)</h5>
<ul className="text-xs text-green-700 space-y-1">
<li><strong>Repressalienverbot:</strong> Jede Benachteiligung ist untersagt (ss 36)</li>
<li><strong>Beweislastumkehr:</strong> Arbeitgeber muss beweisen, dass Maßnahmen nicht mit Meldung zusammenhaengen</li>
<li><strong>Schadensersatz:</strong> Bei Verstoessen gegen Repressalienverbot (ss 37)</li>
<li><strong>Vertraulichkeit:</strong> Identitaet darf nur bei Zustimmung oder gesetzlicher Pflicht offengelegt werden (ss 8)</li>
<li><strong>Bussgelder:</strong> Bis zu 50.000 EUR bei Verstoessen gegen die Einrichtungspflicht (ss 40)</li>
</ul>
</div>
</div>
</div>
)}

View File

@@ -852,18 +852,28 @@ export const STEP_EXPLANATIONS = {
},
'whistleblower': {
title: 'Hinweisgebersystem',
description: 'Meldestelle gemaess Hinweisgeberschutzgesetz (HinSchG)',
explanation: 'Das Hinweisgebersystem bietet eine sichere, anonyme Meldestelle fuer Compliance-Verstoesse gemaess dem Hinweisgeberschutzgesetz (HinSchG). Unternehmen ab 50 Mitarbeitern sind zur Einrichtung verpflichtet.',
description: 'Interne Meldestelle gemaess Hinweisgeberschutzgesetz (HinSchG) — seit 17. Dezember 2023 Pflicht fuer alle Unternehmen ab 50 Beschaeftigten',
explanation: 'Das Hinweisgebersystem implementiert eine HinSchG-konforme interne Meldestelle fuer die sichere, auch anonyme Meldung von Rechtsverstoessen. Es setzt die EU-Whistleblowing-Richtlinie (2019/1937) in deutsches Recht um. Beschaeftigungsgeber mit mindestens 50 Beschaeftigten sind zur Einrichtung verpflichtet (§ 12 HinSchG). Das System unterstuetzt den gesamten Meldeprozess: Einreichung, Eingangsbestaetigung (7-Tage-Frist), Sachverhaltspruefung, Folgemaßnahmen und Rueckmeldung (3-Monate-Frist).',
tips: [
{
icon: 'warning' as const,
title: 'Pflicht ab 50 MA',
description: 'Seit Juli 2023 muessen Unternehmen ab 50 Mitarbeitern eine interne Meldestelle einrichten (HinSchG §12).',
title: 'Pflicht ab 50 Beschaeftigten',
description: 'Seit 17.12.2023 gilt die Pflicht fuer ALLE Unternehmen ab 50 Beschaeftigten (§ 12 HinSchG). Verstoesse koennen mit Bussgeldern bis zu 50.000 EUR geahndet werden (§ 40 HinSchG).',
},
{
icon: 'info' as const,
title: 'Anonymitaet',
description: 'Die Identitaet des Hinweisgebers muss geschuetzt werden. Repressalien gegen Hinweisgeber sind verboten.',
title: 'Anonymitaet & Vertraulichkeit',
description: 'Die Identitaet des Hinweisgebers ist streng vertraulich zu behandeln (§ 8 HinSchG). Anonyme Meldungen sollen bearbeitet werden. Repressalien sind verboten und loesen Schadensersatzpflicht aus (§ 36, § 37 HinSchG).',
},
{
icon: 'lightbulb' as const,
title: 'Gesetzliche Fristen',
description: 'Eingangsbestaetigung innerhalb von 7 Tagen (§ 17 Abs. 1 S. 2). Rueckmeldung ueber ergriffene Folgemaßnahmen innerhalb von 3 Monaten nach Eingangsbestaetigung (§ 17 Abs. 2). Die Dokumentation muss 3 Jahre aufbewahrt werden (§ 11 HinSchG).',
},
{
icon: 'warning' as const,
title: 'Sachlicher Anwendungsbereich',
description: 'Erfasst werden Verstoesse gegen EU-Recht und nationales Recht, u.a. Strafrecht, Datenschutz (DSGVO/BDSG), Arbeitsschutz, Umweltschutz, Geldwaesche, Produktsicherheit und Verbraucherschutz (§ 2 HinSchG).',
},
],
},

View File

@@ -0,0 +1,340 @@
-- Migration 054: Erweiterte HinSchG-Wiki-Artikel
-- Ergaenzt die bestehende HinSchG-Kategorie um detaillierte Artikel
-- Bestehenden Grundlagen-Artikel mit umfassenderem Inhalt aktualisieren
UPDATE compliance_wiki_articles
SET content = '## Ueberblick
Das **Hinweisgeberschutzgesetz (HinSchG)** setzt die EU-Whistleblowing-Richtlinie (EU) 2019/1937 in deutsches Recht um. Es schuetzt Personen, die auf Missstaende in Unternehmen und Behoerden hinweisen und ist seit dem **2. Juli 2023** in Kraft.
- Ab 02.07.2023: Pflicht fuer Unternehmen ab **250 Beschaeftigten**
- Ab 17.12.2023: Pflicht fuer Unternehmen ab **50 Beschaeftigten** (§ 12 HinSchG)
## Kernpflichten
### Interne Meldestelle einrichten (§ 12 HinSchG)
- Kann eine **interne Person** (Ombudsperson) oder ein **externer Dienstleister** sein
- Meldungen muessen **muendlich, schriftlich und persoenlich** moeglich sein
- Die Meldestelle muss **unabhaengig** und **fachkundig** sein
- **Gemeinsame Meldestellen** sind fuer Unternehmen mit 50249 Beschaeftigten zulaessig
### Gesetzliche Fristen (§ 17 HinSchG)
- Eingangsbestaetigung innerhalb von **7 Tagen** nach Meldungseingang (§ 17 Abs. 1 S. 2)
- Rueckmeldung ueber Folgemaßnahmen innerhalb von **3 Monaten** nach Eingangsbestaetigung (§ 17 Abs. 2)
- Dokumentation muss **3 Jahre** nach Abschluss aufbewahrt werden (§ 11 Abs. 5)
### Vertraulichkeitsgebot (§ 8 HinSchG)
- Die **Identitaet des Hinweisgebers** darf nur den zustaendigen Personen bekannt sein
- Offenlegung nur mit **Einwilligung** oder bei **gesetzlicher Verpflichtung**
- Verstoss ist bussgeld-bewehrt (bis 50.000 EUR)
## Welche Daten fallen an?
- Identitaet des Hinweisgebers (besonders schuetzenswert!)
- Beschuldigte Personen
- Zeugen und weitere Beteiligte
- Inhalt der Meldung (kann sensible Daten enthalten)
- Kommunikationsverlauf
## Datenschutz-Anforderungen
- **Eigene Verarbeitungstaetigkeit** im VVT anlegen
- Rechtsgrundlage: Art. 6 Abs. 1c DSGVO (rechtliche Verpflichtung)
- **Zugriffsbeschraenkung:** Nur die benannte Meldestelle darf auf die Daten zugreifen
- **Loeschfrist:** 3 Jahre nach Abschluss des Verfahrens (§ 11 Abs. 5 HinSchG)
- Bei Art.-9-Daten in Meldungen: besondere Schutzmassnahmen erforderlich
## Sanktionen (§ 40 HinSchG)
| Verstoss | Bussgeld |
|----------|----------|
| Keine Meldestelle eingerichtet | Bis 20.000 EUR |
| Behinderung einer Meldung | Bis 50.000 EUR |
| Verstoss gegen Vertraulichkeitsgebot | Bis 50.000 EUR |
| Repressalien gegen Hinweisgeber | Bis 50.000 EUR |
## Praxis-Tipp
Pruefen Sie bei externen Meldestellen-Anbietern, ob ein **AVV** erforderlich ist. In den meisten Faellen ja — der Anbieter verarbeitet personenbezogene Daten in Ihrem Auftrag.',
summary = 'Das HinSchG setzt die EU-Whistleblowing-Richtlinie um und verpflichtet seit Dezember 2023 alle Unternehmen ab 50 Beschaeftigten zur Einrichtung einer internen Meldestelle. Verstoesse koennen mit bis zu 50.000 EUR geahndet werden.',
legal_refs = ARRAY['§ 2 HinSchG', '§ 8 HinSchG', '§ 11 Abs. 5 HinSchG', '§ 12 HinSchG', '§ 17 HinSchG', '§ 36 HinSchG', '§ 40 HinSchG', 'Art. 6 Abs. 1c DSGVO', 'EU-RL 2019/1937'],
tags = ARRAY['hinweisgeberschutz', 'whistleblower', 'meldestelle', 'vertraulichkeit', 'fristen', 'bussgelder'],
version = 2,
updated_at = NOW()
WHERE id = 'hinschg-grundlagen';
-- Neuer Artikel: Sachlicher Anwendungsbereich
INSERT INTO compliance_wiki_articles (id, category_id, title, summary, content, legal_refs, tags, relevance, source_urls) VALUES
('hinschg-anwendungsbereich', 'hinschg',
'Sachlicher Anwendungsbereich — Welche Verstoesse sind meldbar?',
'Das HinSchG schuetzt Meldungen ueber Verstoesse gegen EU-Recht und nationales Recht. Der Anwendungsbereich geht weit ueber rein strafrechtliche Verstoesse hinaus.',
'## Ueberblick
Der sachliche Anwendungsbereich des HinSchG (§ 2) ist bewusst weit gefasst. Geschuetzt werden Meldungen ueber Verstoesse, die **strafbewehrt** sind oder **bussgeld-bewehrt**, sowie Verstoesse gegen bestimmte **EU-Rechtsakte** und deren nationale Umsetzungsgesetze.
## Meldbare Verstoesse (§ 2 HinSchG)
### Strafvorschriften
- Alle Straftaten nach dem **StGB** (Betrug, Untreue, Korruption, Urkundenfaelschung)
- Straftaten nach **Nebenstrafrecht** (Umweltstrafrecht, Wirtschaftsstrafrecht)
### Bussgeld-bewehrte Vorschriften
- Verstoesse gegen **Ordnungswidrigkeiten-Vorschriften**, soweit die verletzte Norm dem Schutz von Leben, Leib, Gesundheit oder Rechten von Beschaeftigten dient
### EU-Rechtsakte und nationale Umsetzung
| Rechtsgebiet | Beispiele |
|-------------|-----------|
| Datenschutz | DSGVO, BDSG — z.B. unrechtmaessige Datenweitergabe |
| Geldwaesche | GwG — z.B. fehlende Verdachtsmeldungen |
| Produktsicherheit | ProdSG — z.B. mangelhafte Produkte im Verkehr |
| Umweltschutz | BImSchG, KrWG — z.B. illegale Entsorgung |
| Lebensmittelsicherheit | LFGB — z.B. Hygienemaengel |
| Arbeitsschutz | ArbSchG, ArbZG — z.B. ueberlange Arbeitszeiten |
| Verbraucherschutz | UWG — z.B. irrefuehrende Werbung |
| Wettbewerbsrecht | GWB — z.B. Preisabsprachen, Kartelle |
| Steuerrecht | AO — z.B. Steuerhinterziehung bei Unternehmen |
| Vergaberecht | GWB Teil 4 — z.B. Manipulationen bei oeffentlichen Auftraegen |
## Nicht erfasste Bereiche
- **Rein privatrechtliche Streitigkeiten** (z.B. Vertragskonflikte)
- **Nationale Sicherheit** — Informationen, die der nationalen Sicherheit unterliegen
- **Berufsgeheimnisse** — Anwalts-, Arzt- oder Seelsorgegeheimnis (mit Ausnahmen)
## Praxis-Tipp
Im Zweifelsfall sollte eine Meldung **immer entgegengenommen** und geprueft werden. Die Meldestelle entscheidet erst bei der Sachverhaltspruefung, ob ein meldepflichtiger Verstoss vorliegt.',
ARRAY['§ 2 HinSchG', '§ 3 HinSchG', '§ 5 HinSchG'],
ARRAY['anwendungsbereich', 'verstoesse', 'strafrecht', 'bussgeld', 'eu-recht', 'meldepflicht'],
'important',
ARRAY[]::text[])
ON CONFLICT (id) DO NOTHING;
-- Neuer Artikel: Schutz des Hinweisgebers
INSERT INTO compliance_wiki_articles (id, category_id, title, summary, content, legal_refs, tags, relevance, source_urls) VALUES
('hinschg-hinweisgeberschutz', 'hinschg',
'Schutz des Hinweisgebers — Repressalienverbot und Beweislastumkehr',
'Das HinSchG verbietet jede Form der Benachteiligung von Hinweisgebern. Bei Verstoessen greift eine Beweislastumkehr zugunsten des Hinweisgebers.',
'## Ueberblick
Der Schutz hinweisgebender Personen ist das **Kernziel des HinSchG**. Das Gesetz sieht ein umfassendes Verbot von Repressalien, eine Beweislastumkehr und einen Schadensersatzanspruch vor.
## Repressalienverbot (§ 36 HinSchG)
Verboten ist jede Form der **Benachteiligung** aufgrund einer Meldung:
- **Kuendigung** oder Nichterneuerung eines befristeten Vertrags
- **Abmahnung** oder negative Leistungsbewertung
- **Versetzung**, Degradierung oder Befoerderungsverweigerung
- **Gehaltsreduktion** oder Entzug von Verguenstigungen
- **Mobbing**, Ausgrenzung, Einschuechterung
- **Aufnahme in schwarze Listen** oder Branchenregister
- **Entzug einer Lizenz** oder Genehmigung
- **Anordnung einer psychiatrischen Untersuchung**
## Beweislastumkehr (§ 36 Abs. 2 HinSchG)
Erleidet ein Hinweisgeber nach einer Meldung eine Benachteiligung, wird **vermutet**, dass diese Benachteiligung eine Repressalie ist. Der **Arbeitgeber** muss beweisen, dass die Massnahme:
- Auf hinreichend gerechtfertigten Gruenden beruht
- **Keinen Zusammenhang** mit der Meldung hat
## Schadensersatz (§ 37 HinSchG)
- Hinweisgeber hat Anspruch auf **Ersatz des erlittenen Schadens**
- Umfasst **materielle** Schaeden (Gehaltsverlust) und **immaterielle** Schaeden (Mobbing)
- Kein **Mitverschulden** des Hinweisgebers, wenn die Meldung in gutem Glauben erfolgte
## Geschuetzte Personengruppen (§ 1 HinSchG)
- Arbeitnehmerinnen und Arbeitnehmer
- Beamtinnen und Beamte
- Auszubildende und Praktikanten
- Selbststaendige und Anteilseigner
- Mitglieder von Leitungs- und Aufsichtsorganen
- Ehrenamtlich Taetige und Freiwillige
- Bewerberinnen und Bewerber (bei Informationen im Bewerbungsprozess)
## Voraussetzungen fuer den Schutz (§ 33 HinSchG)
Der Schutz greift, wenn der Hinweisgeber:
- **Hinreichenden Grund** hatte anzunehmen, dass die gemeldeten Informationen der Wahrheit entsprechen
- Die Meldung ueber einen **vorgesehenen Kanal** (intern oder extern) erfolgte
- Der Verstoß in den **sachlichen Anwendungsbereich** faellt
**Achtung:** Wissentlich **falsche Meldungen** sind nicht geschuetzt und koennen eigene Schadensersatzpflichten ausloesen (§ 38 HinSchG).',
ARRAY['§ 1 HinSchG', '§ 33 HinSchG', '§ 36 HinSchG', '§ 37 HinSchG', '§ 38 HinSchG'],
ARRAY['repressalienverbot', 'beweislastumkehr', 'schadensersatz', 'hinweisgeberschutz', 'kuendigungsschutz'],
'critical',
ARRAY[]::text[])
ON CONFLICT (id) DO NOTHING;
-- Neuer Artikel: Interne vs. Externe Meldestelle
INSERT INTO compliance_wiki_articles (id, category_id, title, summary, content, legal_refs, tags, relevance, source_urls) VALUES
('hinschg-meldestellen', 'hinschg',
'Interne vs. Externe Meldestelle — Was ist der Unterschied?',
'Das HinSchG sieht interne und externe Meldestelllen vor. Hinweisgeber koennen frei waehlen, an wen sie sich wenden. Die Einrichtung einer internen Meldestelle ist Pflicht.',
'## Ueberblick
Das HinSchG unterscheidet zwischen **internen Meldestellen** (beim Unternehmen) und **externen Meldestellen** (bei Behoerden). Hinweisgeber haben ein **Wahlrecht** — sie koennen sich direkt an die externe Meldestelle wenden, ohne den internen Weg vorher beschritten zu haben.
## Interne Meldestelle (§§ 1218 HinSchG)
### Einrichtungspflicht
- **Ab 50 Beschaeftigten**: Pflicht zur Einrichtung (seit 17.12.2023)
- Unternehmen mit **50249 Beschaeftigten** duerfen eine gemeinsame Meldestelle nutzen
- Ab **250 Beschaeftigten**: eigene Meldestelle erforderlich
### Anforderungen
- **Unabhaengigkeit** — keine Interessenkonflikte
- **Fachkunde** — geschultes Personal
- Meldekanal muss **muendliche, schriftliche und persoenliche** Meldungen ermoeglichen
- **Anonyme Meldungen** sollen ermoeglicht werden (keine Pflicht, aber empfohlen)
### Besetzung
Die Meldestelle kann besetzt werden durch:
- Interne **Ombudsperson** (Compliance Officer, Datenschutzbeauftragter in Personalunion kritisch)
- **Externer Dienstleister** (Kanzlei, spezialisierter Anbieter) — erfordert AVV
- **Gremium** aus mehreren Personen
## Externe Meldestelle (§§ 1931 HinSchG)
Die wichtigsten externen Meldestellen:
| Meldestelle | Zustaendigkeit |
|-------------|---------------|
| **BfJ (Bundesamt fuer Justiz)** | Auffangmeldestelle fuer alle Verstoesse |
| **BaFin** | Finanzaufsicht, Geldwaesche, Wertpapierrecht |
| **Bundeskartellamt** | Wettbewerbsrecht, Kartelle |
## Wahlrecht des Hinweisgebers
- Hinweisgeber duerfen **frei waehlen** zwischen intern und extern
- Die interne Meldung ist **nicht vorrangig** — anders als bei vielen Unternehmenspolicies
- Ein Unternehmen darf **nicht verbieten**, sich an die externe Stelle zu wenden
## Praxis-Tipp
Gestalten Sie die interne Meldestelle **niedrigschwellig und vertrauenswuerdig**, damit Mitarbeiter sie bevorzugt nutzen. Unternehmen erfahren frueh von Problemen und koennen schneller reagieren.',
ARRAY['§ 12 HinSchG', '§ 13 HinSchG', '§ 14 HinSchG', '§ 16 HinSchG', '§ 17 HinSchG', '§ 19 HinSchG', '§ 27 HinSchG'],
ARRAY['meldestelle', 'intern', 'extern', 'ombudsperson', 'bfj', 'bafin', 'wahlrecht'],
'critical',
ARRAY[]::text[])
ON CONFLICT (id) DO NOTHING;
-- Neuer Artikel: Verfahrensablauf bei einer Meldung
INSERT INTO compliance_wiki_articles (id, category_id, title, summary, content, legal_refs, tags, relevance, source_urls) VALUES
('hinschg-verfahrensablauf', 'hinschg',
'Verfahrensablauf — Von der Meldung bis zur Rueckmeldung',
'Der gesetzlich vorgeschriebene Ablauf einer Meldung umfasst Eingangsbestaetigung, Sachverhaltspruefung, Folgemaßnahmen und Rueckmeldung an den Hinweisgeber.',
'## Ueberblick
Das HinSchG schreibt einen strukturierten Verfahrensablauf fuer jede eingehende Meldung vor (§ 17 HinSchG). Dieser Ablauf ist nicht verhandelbar — die Fristen sind gesetzlich bindend.
## Schritt-fuer-Schritt-Verfahren
### 1. Meldungseingang
- Meldung wird ueber den internen Meldekanal eingereicht
- Das System vergibt automatisch eine **Referenznummer** und einen **Zugangscode**
- Der Zugangscode ermoeglicht dem Hinweisgeber die anonyme Statusabfrage
### 2. Eingangsbestaetigung (Frist: 7 Tage)
- Innerhalb von **7 Tagen** nach Eingang muss die Meldestelle den Eingang bestaetigen (§ 17 Abs. 1 S. 2)
- Bei anonymen Meldungen: Bestaetigung ueber den anonymen Kommunikationskanal
- **Wichtig:** Die Bestaetigung darf keine inhaltliche Bewertung enthalten
### 3. Sachverhaltspruefung
- Die Meldestelle prueft, ob ein **meldepflichtiger Verstoss** vorliegt (§ 2 HinSchG)
- Stichhaltigkeitspruefung der gemeldeten Informationen
- Gegebenenfalls Rueckfragen an den Hinweisgeber (ueber anonymen Kanal)
### 4. Folgemaßnahmen (§ 18 HinSchG)
Moegliche Maßnahmen umfassen:
- **Interne Untersuchung** (ggf. mit externen Gutachtern)
- **Abstellung des Verstosses** durch organisatorische Aenderungen
- Weiterleitung an eine **zustaendige Behoerde**
- **Disziplinarmaßnahmen** gegen Verantwortliche
- **Einstellung** des Verfahrens bei unbegruendeten Meldungen
### 5. Rueckmeldung (Frist: 3 Monate)
- Innerhalb von **3 Monaten** nach Eingangsbestaetigung muss dem Hinweisgeber eine Rueckmeldung ueber ergriffene oder geplante Folgemaßnahmen gegeben werden (§ 17 Abs. 2)
- Die Rueckmeldung soll den Hinweisgeber informieren, **ohne laufende Ermittlungen zu gefaehrden**
### 6. Abschluss und Dokumentation
- Abschließende Dokumentation des gesamten Verfahrens
- Aufbewahrung fuer **3 Jahre** nach Abschluss (§ 11 Abs. 5 HinSchG)
- Danach: Loeschung aller personenbezogenen Daten
## Fristen-Uebersicht
| Schritt | Frist | Ab wann |
|---------|-------|---------|
| Eingangsbestaetigung | 7 Tage | Ab Meldungseingang |
| Rueckmeldung | 3 Monate | Ab Eingangsbestaetigung |
| Aufbewahrung | 3 Jahre | Ab Verfahrensabschluss |
## Praxis-Tipp
Richten Sie ein **automatisches Fristen-Monitoring** ein. Das BreakPilot Hinweisgebersystem berechnet die Fristen automatisch und warnt rechtzeitig vor drohender Ueberschreitung.',
ARRAY['§ 11 Abs. 5 HinSchG', '§ 17 Abs. 1 HinSchG', '§ 17 Abs. 2 HinSchG', '§ 18 HinSchG'],
ARRAY['verfahren', 'ablauf', 'fristen', 'eingangsbestaetigung', 'rueckmeldung', 'folgemaßnahmen', 'dokumentation'],
'important',
ARRAY[]::text[])
ON CONFLICT (id) DO NOTHING;
-- Neuer Artikel: Datenschutz-Anforderungen
INSERT INTO compliance_wiki_articles (id, category_id, title, summary, content, legal_refs, tags, relevance, source_urls) VALUES
('hinschg-datenschutz', 'hinschg',
'Datenschutz im Hinweisgebersystem — DSGVO-Konformitaet sicherstellen',
'Das Hinweisgebersystem verarbeitet besonders sensible personenbezogene Daten. Die DSGVO-Anforderungen an Datenschutz, Loeschfristen und Zugriffskontrollen sind strikt einzuhalten.',
'## Ueberblick
Ein Hinweisgebersystem verarbeitet **hochsensible personenbezogene Daten**: die Identitaet des Hinweisgebers, Beschuldigter, Zeugen und den Inhalt der Meldung. Die DSGVO-Anforderungen muessen mit den HinSchG-Pflichten in Einklang gebracht werden.
## Rechtsgrundlage
Die Verarbeitung stuetzt sich auf:
- **Art. 6 Abs. 1c DSGVO** — Erfuellung einer rechtlichen Verpflichtung (HinSchG)
- **Art. 6 Abs. 1f DSGVO** — Berechtigtes Interesse (fuer nicht-verpflichtete Unternehmen)
- **Art. 9 Abs. 2b DSGVO** — Fuer besondere Datenkategorien im Beschaeftigungskontext
## VVT-Eintrag (Pflicht)
Erstellen Sie einen eigenen VVT-Eintrag fuer das Hinweisgebersystem:
| Feld | Inhalt |
|------|--------|
| Bezeichnung | Betrieb des internen Hinweisgebersystems |
| Rechtsgrundlage | Art. 6 Abs. 1c DSGVO i.V.m. §§ 12 ff. HinSchG |
| Kategorien betroffener Personen | Hinweisgeber, Beschuldigte, Zeugen |
| Datenkategorien | Identitaetsdaten, Kommunikationsdaten, Meldungsinhalt |
| Loeschfrist | 3 Jahre nach Verfahrensabschluss |
| Empfaenger | Interne Meldestelle, ggf. externe Meldestelle |
## Technisch-organisatorische Massnahmen (TOM)
- **Verschluesselung** — Alle Meldungsdaten at-rest und in-transit verschluesselt
- **Zugriffsbeschraenkung** — Nur die benannte Meldestelle darf auf Daten zugreifen
- **Protokollierung** — Revisionssicherer Audit-Trail aller Zugriffe
- **Pseudonymisierung** — Anonyme Meldungen ohne Zuordnung zu Klarnamen
- **Trennung** — Meldungsdaten getrennt von sonstigen HR-Daten speichern
## Loeschkonzept
| Daten | Loeschfrist | Rechtsgrundlage |
|-------|-------------|-----------------|
| Meldungsdaten | 3 Jahre nach Abschluss | § 11 Abs. 5 HinSchG |
| Audit-Trail | 3 Jahre nach Abschluss | § 11 Abs. 5 HinSchG |
| Kommunikationsdaten | 3 Jahre nach Abschluss | § 11 Abs. 5 HinSchG |
| Zugangscodes | Nach Verfahrensabschluss | Zweckerfuellung |
## DSFA-Pflicht?
Eine **Datenschutz-Folgenabschaetzung** (Art. 35 DSGVO) ist in vielen Faellen erforderlich, da:
- **Systematische Ueberwachung** von Beschaeftigten (potenziell)
- Verarbeitung **besonderer Datenkategorien** moeglich (Art. 9 DSGVO)
- **Verletzliche Personengruppen** betroffen (Hinweisgeber, Beschuldigte)
## Praxis-Tipp
Fuehren Sie eine DSFA durch und dokumentieren Sie die Abwaegung. Dies dient auch als Nachweis der Rechenschaftspflicht (Art. 5 Abs. 2 DSGVO).',
ARRAY['Art. 5 Abs. 2 DSGVO', 'Art. 6 Abs. 1c DSGVO', 'Art. 9 Abs. 2b DSGVO', 'Art. 28 DSGVO', 'Art. 35 DSGVO', '§ 8 HinSchG', '§ 11 Abs. 5 HinSchG', '§ 26 BDSG'],
ARRAY['datenschutz', 'dsgvo', 'vvt', 'dsfa', 'loeschfristen', 'tom', 'verschluesselung', 'audit-trail'],
'critical',
ARRAY[]::text[])
ON CONFLICT (id) DO NOTHING;

View File

@@ -1,33 +1,253 @@
# Whistleblower — Hinweisgebersystem
HinSchG-konformes Hinweisgebersystem fuer anonyme Meldungen und sichere Fallbearbeitung.
HinSchG-konformes Hinweisgebersystem fuer anonyme und namentliche Meldungen, sichere Fallbearbeitung und automatische Fristenueberwachung.
## Gesetzliche Grundlage
### Hinweisgeberschutzgesetz (HinSchG)
Das **Hinweisgeberschutzgesetz (HinSchG)** setzt die EU-Whistleblowing-Richtlinie (EU) 2019/1937 in deutsches Recht um. Es ist seit dem **2. Juli 2023** in Kraft.
| Datum | Pflicht |
|-------|---------|
| 02.07.2023 | Inkrafttreten fuer Unternehmen ab 250 Beschaeftigten |
| 17.12.2023 | Erweiterung auf Unternehmen ab 50 Beschaeftigten (ss 12 HinSchG) |
### Sachlicher Anwendungsbereich (ss 2 HinSchG)
Das Gesetz schuetzt Hinweisgeber, die Informationen ueber **Verstoesse** melden, die unter anderem folgende Bereiche betreffen:
- **Strafrecht** — Straftaten nach StGB und Nebenstrafrecht
- **Datenschutz** — Verstoesse gegen DSGVO und BDSG
- **Geldwaesche** — Verstoesse gegen das Geldwaeschegesetz (GwG)
- **Produktsicherheit** — Verstoesse gegen Produktsicherheitsvorschriften
- **Umweltschutz** — Verstoesse gegen Umweltauflagen und -gesetze
- **Arbeitsschutz** — Verstoesse gegen Arbeitnehmerrechte und Arbeitsschutzvorschriften
- **Lebensmittelsicherheit** — Verstoesse gegen lebensmittelrechtliche Vorgaben
- **Wettbewerbs- und Kartellrecht** — Unlauterer Wettbewerb, Marktmanipulation
- **Verbraucherschutz** — Verstoesse gegen Verbraucherschutzvorschriften
- **Steuerrecht** — Steuerverstoesse bei Unternehmen
### Geschuetzte Personengruppen (ss 1 HinSchG)
- Arbeitnehmerinnen und Arbeitnehmer
- Beamtinnen und Beamte
- Auszubildende und Praktikanten
- Freiwillige und ehrenamtlich Taetige
- Selbststaendige und Anteilseigner
- Mitglieder von Leitungs- und Aufsichtsorganen
- Personen, die im Rahmen einer Bewerbung Informationen erlangt haben
### Fristen und Pflichten
| Pflicht | Frist | Rechtsgrundlage |
|---------|-------|-----------------|
| Eingangsbestaetigung | **7 Tage** nach Meldungseingang | ss 17 Abs. 1 S. 2 HinSchG |
| Rueckmeldung ueber Folgemaßnahmen | **3 Monate** nach Eingangsbestaetigung | ss 17 Abs. 2 HinSchG |
| Aufbewahrung der Dokumentation | **3 Jahre** nach Abschluss des Verfahrens | ss 11 Abs. 5 HinSchG |
### Schutz des Hinweisgebers
| Schutzmechanismus | Rechtsgrundlage | Beschreibung |
|-------------------|-----------------|--------------|
| **Repressalienverbot** | ss 36 HinSchG | Jede Benachteiligung wegen einer Meldung ist verboten |
| **Beweislastumkehr** | ss 36 Abs. 2 HinSchG | Arbeitgeber muss beweisen, dass Maßnahmen nicht mit Meldung zusammenhaengen |
| **Schadensersatz** | ss 37 HinSchG | Hinweisgeber hat Anspruch auf Ersatz des erlittenen Schadens |
| **Vertraulichkeit** | ss 8 HinSchG | Identitaet darf nur mit Einwilligung oder bei gesetzlicher Pflicht offengelegt werden |
### Sanktionen (ss 40 HinSchG)
| Verstoß | Bussgeld |
|---------|----------|
| Keine interne Meldestelle eingerichtet | Bis zu **20.000 EUR** |
| Behinderung einer Meldung | Bis zu **50.000 EUR** |
| Verstoß gegen Vertraulichkeitsgebot | Bis zu **50.000 EUR** |
| Repressalien gegen Hinweisgeber | Bis zu **50.000 EUR** |
---
## Features
- **Anonyme Meldungen** — Sichere, anonyme Eingabe von Hinweisen
- **Fallbearbeitung** — Workflow fuer Sichtung, Untersuchung und Abschluss
- **Fristen-Management** — Automatische Ueberwachung der gesetzlichen Bearbeitungsfristen (7 Tage Eingangsbestaetigung, 3 Monate Rueckmeldung)
- **Kommunikationskanal** — Anonymer Austausch zwischen Hinweisgeber und Ombudsperson
- **Audit-Trail** — Lueckenlose Dokumentation aller Bearbeitungsschritte
- **Anonyme und namentliche Meldungen** — Sichere Eingabe von Hinweisen, wahlweise anonym oder mit Kontaktdaten
- **Mehrstufiger Fallbearbeitungs-Workflow** — Neu → Bestaetigt → In Pruefung Untersuchung → Massnahmen → Abgeschlossen
- **Automatisches Fristen-Management** — Ueberwachung der 7-Tage- und 3-Monate-Fristen gemaess ss 17 HinSchG mit Warnungen bei drohender Ueberschreitung
- **Anonymer Kommunikationskanal** — Sicherer Austausch zwischen Hinweisgeber und Ombudsperson ohne Identitaetspreisgabe
- **Massnahmen-Tracking** — Dokumentation und Nachverfolgung von Folgemaßnahmen
- **Prioritaetsstufen** — Klassifizierung nach Niedrig, Normal, Hoch, Kritisch
- **Audit-Trail** — Lueckenlose, revisionssichere Dokumentation aller Bearbeitungsschritte
- **Kategorisierung** — Vordefinierte Meldekategorien (Korruption, Betrug, Datenschutz, Diskriminierung, Umwelt, Wettbewerb, Produktsicherheit, Steuerhinterziehung)
- **Statistik-Dashboard** — Ueberblick ueber Meldungsaufkommen, Bearbeitungsstand und Fristeneinhaltung
---
## Architektur
### Bearbeitungs-Workflow
```mermaid
stateDiagram-v2
[*] --> Neu: Meldung eingereicht
Neu --> Bestaetigt: Eingangsbestaetigung (≤ 7 Tage)
Bestaetigt --> InPruefung: Inhaltliche Pruefung
InPruefung --> Untersuchung: Formelle Untersuchung
Untersuchung --> Massnahmen: Folgemaßnahmen eingeleitet
Massnahmen --> Abgeschlossen: Rueckmeldung (≤ 3 Monate)
InPruefung --> Abgelehnt: Unbegruendet / nicht zustaendig
Abgeschlossen --> [*]
Abgelehnt --> [*]
```
### Komponenten
| Komponente | Technologie | Beschreibung |
|------------|-------------|--------------|
| Frontend (Admin) | Next.js / React | SDK-Seite unter `/sdk/whistleblower` mit Tabs: Uebersicht, Neue Meldungen, In Untersuchung, Abgeschlossen, Einstellungen |
| API-Proxy | Next.js API Route | `/api/sdk/v1/whistleblower/[[...path]]/route.ts` — Proxy zum Backend |
| Backend-Handlers | Go / Gin | `whistleblower_handlers.go` — REST API fuer Meldungen, Nachrichten, Statistiken |
| Datenschicht | Go | `store.go` — PostgreSQL-Operationen, prepared statements |
| Datenmodell | Go | `models.go` — Structs fuer Report, Message, Measure, AuditEntry |
| TypeScript Types | TypeScript | `lib/sdk/whistleblower/types.ts` — Frontend-Typen, Deadline-Utilities |
| API Client | TypeScript | `lib/sdk/whistleblower/api.ts` — SDK-API-Aufrufe |
| DB-Schema | SQL | `migrations/009_whistleblower_schema.sql` |
---
## API Endpoints
Alle unter `/api/v1/whistleblower/`, benoetigen `X-Tenant-ID` Header.
### Admin-Endpoints
| Method | Endpoint | Beschreibung |
|--------|----------|-------------|
| GET | `/reports` | Meldungen auflisten |
| POST | `/reports` | Neue Meldung erstellen |
| GET | `/reports/{id}` | Meldungsdetails |
| PUT | `/reports/{id}/status` | Status aktualisieren |
| POST | `/reports/{id}/messages` | Nachricht hinzufuegen |
| GET | `/reports/{id}/messages` | Nachrichten abrufen |
| GET | `/statistics` | Statistiken |
| GET | `/reports` | Meldungen auflisten (mit Filter und Paginierung) |
| POST | `/reports` | Neue Meldung erfassen |
| GET | `/reports/{id}` | Meldungsdetails inkl. Nachrichten, Massnahmen, Audit-Trail |
| PUT | `/reports/{id}` | Meldung aktualisieren (Status, Prioritaet, Zuweisung) |
| DELETE | `/reports/{id}` | Meldung loeschen |
| POST | `/reports/{id}/messages` | Nachricht an Hinweisgeber senden (Ombudsperson-Rolle) |
| GET | `/reports/{id}/messages` | Nachrichten-Verlauf abrufen |
| GET | `/statistics` | Statistiken (Gesamt, nach Kategorie, nach Status, ueberfaellige) |
### Oeffentliche Endpoints (fuer Hinweisgeber)
| Method | Endpoint | Beschreibung |
|--------|----------|-------------|
| POST | `/public/reports` | Anonyme/namentliche Meldung einreichen |
| GET | `/public/reports/{accessKey}` | Meldungsstatus mit Zugangscode abfragen |
| POST | `/public/reports/{accessKey}/messages` | Nachricht als Hinweisgeber senden |
---
## Frontend
Seite unter `/sdk/whistleblower` mit Meldungsuebersicht, Falldetails und Statistik-Dashboard.
### SDK Admin-Seite (`/sdk/whistleblower`)
Die Seite bietet fuenf Tabs:
| Tab | Inhalt |
|-----|--------|
| **Uebersicht** | Statistik-Cards, HinSchG-Info-Box mit Fristen und Anwendungsbereich, Fristenwarnungen, alle Meldungen |
| **Neue Meldungen** | Gefilterte Ansicht: nur Status "Neu" — Eingangsbestaetigung steht aus |
| **In Untersuchung** | Gefilterte Ansicht: Status "Bestaetigt", "In Pruefung", "Untersuchung", "Massnahmen" |
| **Abgeschlossen** | Gefilterte Ansicht: Status "Abgeschlossen" und "Abgelehnt" |
| **Einstellungen** | Konfiguration (in spaeteren Versionen) |
### Funktionen
- **Meldung erfassen**: Modal-Dialog fuer Titel, Beschreibung, Kategorie, Prioritaet, anonym/namentlich
- **Falldetail-Drawer**: Seitenleiste mit Beschreibung, Badges, Status-Transitions, Zuweisungen, Kommentare, Nachrichten-Verlauf
- **Filter**: Kategorie, Status, Prioritaet — kombinierbar
- **Sortierung**: Ueberfaellige Meldungen zuerst, dann nach Prioritaet, dann nach Datum
- **Fristenwarnungen**: Rote Alerts bei ueberschrittenen 7-Tage- oder 3-Monate-Fristen
---
## Datenbank
Migration `009_whistleblower_schema.sql` erstellt Tabellen fuer Meldungen, Nachrichten und Bearbeitungsschritte.
### Schema (Migration `009_whistleblower_schema.sql`)
#### Tabelle: `whistleblower_reports`
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| `id` | UUID | Primaerschluessel |
| `tenant_id` | UUID | Mandanten-Zuordnung |
| `reference_number` | VARCHAR | Referenznummer (z.B. "WB-2026-000042") |
| `access_key` | VARCHAR | Anonymer Zugangscode (XXXX-XXXX-XXXX) |
| `category` | VARCHAR | Meldekategorie |
| `status` | VARCHAR | Bearbeitungsstatus |
| `priority` | VARCHAR | Prioritaetsstufe |
| `title` | VARCHAR | Meldungstitel |
| `description` | TEXT | Detailbeschreibung |
| `is_anonymous` | BOOLEAN | Anonyme Meldung |
| `reporter_name` | VARCHAR | Name (optional) |
| `reporter_email` | VARCHAR | E-Mail (optional) |
| `assigned_to` | VARCHAR | Zustaendige Person |
| `received_at` | TIMESTAMP | Eingangszeitpunkt |
| `acknowledged_at` | TIMESTAMP | Eingangsbestaetigung |
| `deadline_acknowledgment` | TIMESTAMP | 7-Tage-Frist (automatisch berechnet) |
| `deadline_feedback` | TIMESTAMP | 3-Monate-Frist (automatisch berechnet) |
| `closed_at` | TIMESTAMP | Abschlusszeitpunkt |
#### Tabelle: `whistleblower_messages`
Anonymer Kommunikationskanal zwischen Hinweisgeber und Ombudsperson.
#### Tabelle: `whistleblower_measures`
Dokumentation von Folgemaßnahmen mit Status-Tracking (geplant, in Bearbeitung, abgeschlossen).
#### Tabelle: `whistleblower_audit_trail`
Lueckenlose, revisionssichere Protokollierung aller Bearbeitungsschritte.
---
## Meldekategorien
| Kategorie | Beschreibung | Beispiele |
|-----------|--------------|-----------|
| Korruption | Bestechung, Vorteilsnahme | Schmiergeldzahlungen, Kickback-Vereinbarungen |
| Betrug | Vermoegensdelikte | Urkundenfaelschung, Bilanzbetrug |
| Datenschutz | DSGVO/BDSG-Verstoesse | Unerlaubte Datenweitergabe, fehlende Einwilligung |
| Diskriminierung | Benachteiligung | Mobbing, sexuelle Belaestigung, AGG-Verstoesse |
| Umwelt | Umweltvergehen | Illegale Entsorgung, Emissionsverstoesse |
| Wettbewerb | Kartellrecht | Preisabsprachen, Marktmanipulation |
| Produktsicherheit | Sicherheitsmaengel | Mangelhafte Produkte, fehlende Warnhinweise |
| Steuerhinterziehung | Steuerverstoesse | Steuerhinterziehung, illegale Steuergestaltung |
| Sonstiges | Weitere Verstoesse | Interne Richtlinienverstoesse |
---
## Fristen-Tracking
Das System berechnet Fristen automatisch und warnt bei drohender Ueberschreitung:
| Frist | Berechnung | Warnstufe |
|-------|------------|-----------|
| 7-Tage-Eingangsbestaetigung | `received_at + 7 Tage` | Orange ab 2 Tage vorher, Rot bei Ueberschreitung |
| 3-Monate-Rueckmeldung | `acknowledged_at + 3 Monate` | Orange ab 14 Tage vorher, Rot bei Ueberschreitung |
Utility-Funktionen in `types.ts`:
- `getDaysUntilAcknowledgment(report)` — Verbleibende Tage bis Eingangsbestaetigung
- `getDaysUntilFeedback(report)` — Verbleibende Tage bis Rueckmeldungsfrist
- `isAcknowledgmentOverdue(report)` — Prueft 7-Tage-Frist
- `isFeedbackOverdue(report)` — Prueft 3-Monate-Frist
- `generateAccessKey()` — Erzeugt Zugangscode im Format XXXX-XXXX-XXXX
---
## Datei-Referenz
| Datei | Beschreibung |
|-------|--------------|
| `admin-compliance/app/sdk/whistleblower/page.tsx` | Frontend-Seite (Tabs, Filter, Modals, Detail-Drawer) |
| `admin-compliance/app/api/sdk/v1/whistleblower/[[...path]]/route.ts` | API-Proxy zum Backend |
| `admin-compliance/lib/sdk/whistleblower/types.ts` | TypeScript-Typen, Enums, Deadline-Utilities |
| `admin-compliance/lib/sdk/whistleblower/api.ts` | API-Client fuer SDK-Backend |
| `ai-compliance-sdk/internal/whistleblower/models.go` | Go-Datenmodelle |
| `ai-compliance-sdk/internal/whistleblower/store.go` | PostgreSQL-Store (CRUD, Queries) |
| `ai-compliance-sdk/internal/api/handlers/whistleblower_handlers.go` | REST-API-Handler |
| `ai-compliance-sdk/migrations/009_whistleblower_schema.sql` | Datenbankschema |