docs: DSFA MkDocs aktualisiert — Migration 030, vollständiges Schema, 101 Tests, PDF-Ingest
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 31s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 18s
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 31s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 18s
- Datenmodell: vollständiges Response-JSON mit allen 60+ Feldern (Sections 0-8) - DB-Schema: Migrations-Tabelle (024/028/030), alle Spaltengruppen dokumentiert - API: minimaler Create-Request + Section-Update-Beispiel - Tests: 101 Tests (war: 52), neue Klassen TestAIUseCaseModules + TestDSFAFullSchema - Ingest-Script: PDF-Downloads aktiviert, 10 Behörden mit direkten URLs, Tabelle: Behörden mit PDF vs. Text-Fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
# DSFA — Datenschutz-Folgenabschätzung (Art. 35 DSGVO)
|
# DSFA — Datenschutz-Folgenabschätzung (Art. 35 DSGVO)
|
||||||
|
|
||||||
Das DSFA-Modul implementiert die Datenschutz-Folgenabschätzung gemäß Art. 35 DSGVO.
|
Das DSFA-Modul implementiert die Datenschutz-Folgenabschätzung gemäß Art. 35 DSGVO.
|
||||||
Es ist vollständig backend-persistent mit CRUD-Operationen, Audit-Log und Schnell-Statuswechsel.
|
Es ist vollständig backend-persistent mit CRUD-Operationen, Audit-Log, Schnell-Statuswechsel
|
||||||
|
und einem vollständigen 8-Section-Schema (Migration 030: 62 DB-Spalten).
|
||||||
|
|
||||||
**Route:** `/sdk/dsfa` | **Backend:** `backend-compliance:8002` | **Migration:** `024_dsfa.sql`
|
**Route:** `/sdk/dsfa` | **Backend:** `backend-compliance:8002` | **Migrationen:** `024`, `028`, `030`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -28,17 +29,21 @@ natürlicher Personen mit sich bringt. Typische Fälle:
|
|||||||
## Funktionen
|
## Funktionen
|
||||||
|
|
||||||
- **CRUD-Operationen:** Anlegen, Lesen, Aktualisieren, Löschen von DSFA-Datensätzen
|
- **CRUD-Operationen:** Anlegen, Lesen, Aktualisieren, Löschen von DSFA-Datensätzen
|
||||||
|
- **8-Section-Formular:** Vollständiges Schema für alle DSFA-Phasen (Sections 0–8)
|
||||||
- **Status-Workflow:** `draft` → `in-review` → `approved` / `needs-update`
|
- **Status-Workflow:** `draft` → `in-review` → `approved` / `needs-update`
|
||||||
- **Risikostufen:** `low` / `medium` / `high` / `critical`
|
- **Risikostufen:** `low` / `medium` / `high` / `critical`
|
||||||
- **Datenkategorien:** Mehrfachauswahl der verarbeiteten Datenkategorien (JSONB)
|
- **Datenkategorien, Empfänger, Schutzmaßnahmen:** JSONB-Arrays
|
||||||
- **Empfänger:** Dokumentation der Datenempfänger (JSONB)
|
- **Risiken & Mitigationen:** Strukturierte JSONB-Arrays mit Risiko-IDs
|
||||||
- **Schutzmaßnahmen:** Erfassung technischer und organisatorischer Maßnahmen (JSONB)
|
- **DSB-Konsultation:** `dpo_consulted`, `dpo_opinion`, `dpo_approved`
|
||||||
|
- **Behörden-Konsultation:** `authority_consulted`, `authority_reference`, `authority_decision`
|
||||||
|
- **WP248-Kriterien:** `wp248_criteria_met`, `threshold_analysis`
|
||||||
|
- **Section-Progress:** `section_progress` JSONB für Fortschrittsanzeige
|
||||||
|
- **KI-Anwendungsfälle (Section 8):** `ai_use_case_modules` JSONB mit AI-Act-Bewertung
|
||||||
|
- **Bundesland-Kontext:** `federal_state`, `authority_resource_id`
|
||||||
- **Schnell-Statuswechsel:** PATCH-Endpoint für Status-Übergang ohne vollständiges Update
|
- **Schnell-Statuswechsel:** PATCH-Endpoint für Status-Übergang ohne vollständiges Update
|
||||||
- **Genehmigungsdokumentation:** `approved_by` + `approved_at` bei Status `approved`
|
- **Genehmigungsdokumentation:** `approved_by` + `approved_at` bei Status `approved`
|
||||||
- **Audit-Log:** Nachvollziehbare Protokollierung aller Aktionen (CREATE / UPDATE / DELETE / STATUS_CHANGE)
|
- **Audit-Log:** Protokollierung aller Aktionen (CREATE / UPDATE / DELETE / STATUS_CHANGE)
|
||||||
- **Statistiken:** Zähler nach Status und Risiko-Level
|
- **Statistiken:** Zähler nach Status und Risiko-Level
|
||||||
- **Filter:** Liste filterbar nach `status`, `risk_level`
|
|
||||||
- **Löschung:** DSGVO-Art.-17-konforme Löschung inkl. Audit-Log-Eintrag
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -51,7 +56,7 @@ natürlicher Personen mit sich bringt. Typische Fälle:
|
|||||||
| `GET` | `/api/v1/dsfa/stats` | Statistiken nach Status und Risiko |
|
| `GET` | `/api/v1/dsfa/stats` | Statistiken nach Status und Risiko |
|
||||||
| `GET` | `/api/v1/dsfa/audit-log` | Audit-Trail (limit, offset) |
|
| `GET` | `/api/v1/dsfa/audit-log` | Audit-Trail (limit, offset) |
|
||||||
| `GET` | `/api/v1/dsfa/{id}` | Einzelne DSFA abrufen |
|
| `GET` | `/api/v1/dsfa/{id}` | Einzelne DSFA abrufen |
|
||||||
| `PUT` | `/api/v1/dsfa/{id}` | DSFA vollständig aktualisieren |
|
| `PUT` | `/api/v1/dsfa/{id}` | DSFA aktualisieren (alle Sections) |
|
||||||
| `DELETE` | `/api/v1/dsfa/{id}` | DSFA löschen (Art. 17 DSGVO) |
|
| `DELETE` | `/api/v1/dsfa/{id}` | DSFA löschen (Art. 17 DSGVO) |
|
||||||
| `PATCH` | `/api/v1/dsfa/{id}/status` | Schnell-Statuswechsel |
|
| `PATCH` | `/api/v1/dsfa/{id}/status` | Schnell-Statuswechsel |
|
||||||
|
|
||||||
@@ -71,8 +76,6 @@ natürlicher Personen mit sich bringt. Typische Fälle:
|
|||||||
|
|
||||||
### Validierung
|
### Validierung
|
||||||
|
|
||||||
Folgende Felder werden gegen erlaubte Werte geprüft (HTTP 422 bei Verstoß):
|
|
||||||
|
|
||||||
| Feld | Erlaubte Werte |
|
| Feld | Erlaubte Werte |
|
||||||
|------|----------------|
|
|------|----------------|
|
||||||
| `status` | `draft`, `in-review`, `approved`, `needs-update` |
|
| `status` | `draft`, `in-review`, `approved`, `needs-update` |
|
||||||
@@ -82,45 +85,152 @@ Folgende Felder werden gegen erlaubte Werte geprüft (HTTP 422 bei Verstoß):
|
|||||||
|
|
||||||
## Datenmodell
|
## Datenmodell
|
||||||
|
|
||||||
### DSFA-Objekt (Response)
|
### DSFA-Objekt (Response) — vollständig
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "uuid",
|
"id": "uuid",
|
||||||
"tenant_id": "default",
|
"tenant_id": "default",
|
||||||
"title": "DSFA - Bewerber-Management-System",
|
"title": "DSFA - Bewerber-Management-System",
|
||||||
"description": "Datenschutz-Folgenabschätzung für KI-gestütztes Bewerber-Screening",
|
"description": "DSFA für KI-gestütztes Bewerber-Screening",
|
||||||
"status": "in-review",
|
"status": "in-review",
|
||||||
"risk_level": "high",
|
"risk_level": "high",
|
||||||
"processing_activity": "Automatisierte Bewertung von Bewerbungsunterlagen",
|
"processing_activity": "Automatisierte Bewertung von Bewerbungsunterlagen",
|
||||||
"data_categories": ["Kontaktdaten", "Beruflicher Werdegang", "Qualifikationen"],
|
"data_categories": ["Kontaktdaten", "Beruflicher Werdegang"],
|
||||||
"recipients": ["HR-Abteilung", "Fachabteilungen"],
|
"recipients": ["HR-Abteilung"],
|
||||||
"measures": ["Verschlüsselung", "Zugriffskontrolle", "Menschliche Prüfung"],
|
"measures": ["Verschlüsselung", "Menschliche Prüfung"],
|
||||||
"approved_by": null,
|
"approved_by": null,
|
||||||
"approved_at": null,
|
"approved_at": null,
|
||||||
"created_by": "system",
|
"created_by": "admin",
|
||||||
"created_at": "2026-03-04T10:00:00",
|
"created_at": "2026-03-05T10:00:00",
|
||||||
"updated_at": "2026-03-04T10:00:00"
|
"updated_at": "2026-03-05T10:00:00",
|
||||||
|
|
||||||
|
"processing_description": "Automatisierte Vorauswahl von Bewerbungen mittels KI",
|
||||||
|
"processing_purpose": "Effizienzsteigerung im Recruitingprozess",
|
||||||
|
"legal_basis": "Art. 6 Abs. 1b DSGVO",
|
||||||
|
"legal_basis_details": "Vertragsanbahnung auf Antrag der betroffenen Person",
|
||||||
|
|
||||||
|
"necessity_assessment": "Die Verarbeitung ist für den Bewerbungsprozess notwendig",
|
||||||
|
"proportionality_assessment": "Datenerhebung beschränkt auf Bewerbungsunterlagen",
|
||||||
|
"data_minimization": "Nur für Auswahlentscheidung notwendige Daten",
|
||||||
|
"alternatives_considered": "Manuelle Sichtung aller Bewerbungen nicht skalierbar",
|
||||||
|
"retention_justification": "Löschung nach 6 Monaten gem. § 26 BDSG",
|
||||||
|
|
||||||
|
"involves_ai": true,
|
||||||
|
"overall_risk_level": "high",
|
||||||
|
"risk_score": 7,
|
||||||
|
|
||||||
|
"dpo_consulted": true,
|
||||||
|
"dpo_consulted_at": "2026-03-01T09:00:00",
|
||||||
|
"dpo_name": "Dr. Müller",
|
||||||
|
"dpo_opinion": "DSFA erforderlich, Maßnahmen ausreichend",
|
||||||
|
"dpo_approved": true,
|
||||||
|
"authority_consulted": false,
|
||||||
|
"authority_consulted_at": null,
|
||||||
|
"authority_reference": null,
|
||||||
|
"authority_decision": null,
|
||||||
|
|
||||||
|
"version": 1,
|
||||||
|
"previous_version_id": null,
|
||||||
|
"conclusion": "DSFA abgeschlossen — verbleibendes Risiko akzeptabel",
|
||||||
|
"federal_state": "Bayern",
|
||||||
|
"authority_resource_id": "muss_liste_by",
|
||||||
|
"submitted_for_review_at": "2026-03-04T14:00:00",
|
||||||
|
"submitted_by": "admin",
|
||||||
|
|
||||||
|
"data_subjects": ["Bewerber"],
|
||||||
|
"affected_rights": ["Recht auf Information", "Widerspruchsrecht"],
|
||||||
|
"triggered_rule_codes": ["R-ADM", "R-PROF"],
|
||||||
|
"ai_trigger_ids": ["ai_adm_scoring"],
|
||||||
|
"wp248_criteria_met": ["K1", "K2", "K8"],
|
||||||
|
"art35_abs3_triggered": ["Art35Abs3a"],
|
||||||
|
"tom_references": ["TOM-ENC-01", "TOM-ACC-03"],
|
||||||
|
"risks": [
|
||||||
|
{
|
||||||
|
"id": "R1",
|
||||||
|
"title": "Diskriminierung durch KI-Entscheidung",
|
||||||
|
"likelihood": "medium",
|
||||||
|
"impact": "high",
|
||||||
|
"residual_risk": "medium"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mitigations": [
|
||||||
|
{
|
||||||
|
"id": "M1",
|
||||||
|
"measure": "Menschliche Endentscheidung bei allen Ablehnungen",
|
||||||
|
"risk_ref": "R1",
|
||||||
|
"implemented": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stakeholder_consultations": [],
|
||||||
|
"review_triggers": [
|
||||||
|
{"trigger": "model_update", "description": "Bei Modell-Update", "monitoring_interval": "quarterly"}
|
||||||
|
],
|
||||||
|
"review_comments": [],
|
||||||
|
|
||||||
|
"ai_use_case_modules": [],
|
||||||
|
"section_8_complete": false,
|
||||||
|
|
||||||
|
"threshold_analysis": {
|
||||||
|
"wp248_criteria_count": 3,
|
||||||
|
"dsfa_required": true,
|
||||||
|
"justification": "≥2 WP248-Kriterien erfüllt"
|
||||||
|
},
|
||||||
|
"consultation_requirement": {
|
||||||
|
"required": false,
|
||||||
|
"reason": "Risiko durch Maßnahmen ausreichend reduziert"
|
||||||
|
},
|
||||||
|
"review_schedule": {
|
||||||
|
"next_review": "2027-03-01",
|
||||||
|
"frequency": "annual",
|
||||||
|
"responsible": "DSB"
|
||||||
|
},
|
||||||
|
"section_progress": {
|
||||||
|
"section_0": true,
|
||||||
|
"section_1": true,
|
||||||
|
"section_2": true,
|
||||||
|
"section_3": true,
|
||||||
|
"section_4": false,
|
||||||
|
"section_5": false,
|
||||||
|
"section_6": true,
|
||||||
|
"section_7": false,
|
||||||
|
"section_8": false
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create-Request (POST)
|
### Minimaler Create-Request (POST)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"title": "DSFA - Video-Überwachung Büro",
|
"title": "DSFA - Video-Überwachung Büro",
|
||||||
"description": "Datenschutz-Folgenabschätzung für Videoüberwachung",
|
|
||||||
"status": "draft",
|
"status": "draft",
|
||||||
"risk_level": "medium",
|
"risk_level": "medium",
|
||||||
"processing_activity": "Videoüberwachung zu Sicherheitszwecken",
|
"processing_activity": "Videoüberwachung zu Sicherheitszwecken",
|
||||||
"data_categories": ["Bilddaten", "Bewegungsdaten"],
|
"data_categories": ["Bilddaten", "Bewegungsdaten"],
|
||||||
"recipients": ["Sicherheitsdienst"],
|
|
||||||
"measures": ["Löschfristen", "Zugangsbeschränkung", "Hinweisschilder"],
|
|
||||||
"created_by": "admin"
|
"created_by": "admin"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Status-Update-Request (PATCH /{id}/status)
|
### Section-Update (PUT /{id})
|
||||||
|
|
||||||
|
Alle Felder sind optional — es werden nur gesendete Felder aktualisiert:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"processing_description": "Verarbeitung von Kundendaten zur Risikoanalyse",
|
||||||
|
"legal_basis": "Art. 6 Abs. 1f DSGVO",
|
||||||
|
"dpo_consulted": true,
|
||||||
|
"dpo_name": "Dr. Müller",
|
||||||
|
"risks": [
|
||||||
|
{"id": "R1", "title": "Datenpanne", "likelihood": "low", "impact": "high"}
|
||||||
|
],
|
||||||
|
"section_progress": {"section_1": true, "section_6": true}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Status-Update (PATCH /{id}/status)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -129,28 +239,6 @@ Folgende Felder werden gegen erlaubte Werte geprüft (HTTP 422 bei Verstoß):
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Stats-Response (GET /stats)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"total": 5,
|
|
||||||
"by_status": {
|
|
||||||
"draft": 2,
|
|
||||||
"in-review": 1,
|
|
||||||
"approved": 2
|
|
||||||
},
|
|
||||||
"by_risk_level": {
|
|
||||||
"low": 1,
|
|
||||||
"medium": 2,
|
|
||||||
"high": 2
|
|
||||||
},
|
|
||||||
"draft_count": 2,
|
|
||||||
"in_review_count": 1,
|
|
||||||
"approved_count": 2,
|
|
||||||
"needs_update_count": 0
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Status-Workflow
|
## Status-Workflow
|
||||||
@@ -165,38 +253,60 @@ stateDiagram-v2
|
|||||||
approved --> needs-update: Erneut prüfen
|
approved --> needs-update: Erneut prüfen
|
||||||
```
|
```
|
||||||
|
|
||||||
Der Statuswechsel kann über den `PATCH /{id}/status`-Endpoint vorgenommen werden.
|
|
||||||
Bei Status `approved` wird `approved_at` automatisch auf den aktuellen Zeitstempel gesetzt.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## DB-Tabellen
|
## DB-Tabellen
|
||||||
|
|
||||||
| Tabelle | Modus | Migration | Beschreibung |
|
| Tabelle | Migration | Beschreibung |
|
||||||
|---------|-------|-----------|--------------|
|
|---------|-----------|--------------|
|
||||||
| `compliance_dsfas` | read/write | 024_dsfa.sql | DSFA-Datensätze mit JSONB-Feldern |
|
| `compliance_dsfas` | 024, 028, 030 | DSFA-Datensätze (62 Spalten) |
|
||||||
| `compliance_dsfa_audit_log` | write | 024_dsfa.sql | Audit-Trail aller Aktionen |
|
| `compliance_dsfa_audit_log` | 024 | Audit-Trail aller Aktionen |
|
||||||
|
|
||||||
### Schema: compliance_dsfas
|
### Migrations-Übersicht
|
||||||
|
|
||||||
|
| Migration | Inhalt |
|
||||||
|
|-----------|--------|
|
||||||
|
| `024_dsfa.sql` | Basistabelle: 15 Kernfelder, Audit-Log-Tabelle |
|
||||||
|
| `028_dsfa_ai_use_cases.sql` | `ai_use_case_modules` JSONB, `section_8_complete` |
|
||||||
|
| `030_dsfa_full_schema.sql` | +45 Felder: alle Sections 1–7, JSONB-Arrays, Versionierung |
|
||||||
|
|
||||||
|
### Schema: compliance_dsfas (Stand Migration 030)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE TABLE compliance_dsfas (
|
-- Basisfelder (Migration 024)
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id, tenant_id, title, description, status, risk_level,
|
||||||
tenant_id VARCHAR(255) NOT NULL,
|
processing_activity, data_categories, recipients, measures,
|
||||||
title VARCHAR(500) NOT NULL,
|
approved_by, approved_at, created_by, created_at, updated_at
|
||||||
description TEXT DEFAULT '',
|
|
||||||
status VARCHAR(50) NOT NULL DEFAULT 'draft',
|
-- Section 1 (Migration 030)
|
||||||
risk_level VARCHAR(50) NOT NULL DEFAULT 'low',
|
processing_description, processing_purpose, legal_basis, legal_basis_details
|
||||||
processing_activity VARCHAR(500) DEFAULT '',
|
|
||||||
data_categories JSONB DEFAULT '[]',
|
-- Section 2 (Migration 030)
|
||||||
recipients JSONB DEFAULT '[]',
|
necessity_assessment, proportionality_assessment, data_minimization,
|
||||||
measures JSONB DEFAULT '[]',
|
alternatives_considered, retention_justification
|
||||||
approved_by VARCHAR(255),
|
|
||||||
approved_at TIMESTAMPTZ,
|
-- Section 3 (Migration 030)
|
||||||
created_by VARCHAR(255) DEFAULT 'system',
|
involves_ai, overall_risk_level, risk_score
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
-- Section 6 (Migration 030)
|
||||||
);
|
dpo_consulted, dpo_consulted_at, dpo_name, dpo_opinion, dpo_approved,
|
||||||
|
authority_consulted, authority_consulted_at, authority_reference, authority_decision
|
||||||
|
|
||||||
|
-- Versionierung & Metadaten (Migration 030)
|
||||||
|
version, previous_version_id, conclusion, federal_state,
|
||||||
|
authority_resource_id, submitted_for_review_at, submitted_by
|
||||||
|
|
||||||
|
-- JSONB Arrays (Migration 030)
|
||||||
|
data_subjects, affected_rights, triggered_rule_codes, ai_trigger_ids,
|
||||||
|
wp248_criteria_met, art35_abs3_triggered, tom_references,
|
||||||
|
risks, mitigations, stakeholder_consultations, review_triggers, review_comments
|
||||||
|
|
||||||
|
-- JSONB Objekte (Migration 030)
|
||||||
|
threshold_analysis, consultation_requirement, review_schedule,
|
||||||
|
section_progress, metadata
|
||||||
|
|
||||||
|
-- Section 8 / KI (Migration 028)
|
||||||
|
ai_use_case_modules, section_8_complete
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -205,23 +315,24 @@ CREATE TABLE compliance_dsfas (
|
|||||||
|
|
||||||
| Datei | Beschreibung |
|
| Datei | Beschreibung |
|
||||||
|-------|--------------|
|
|-------|--------------|
|
||||||
| `backend-compliance/migrations/024_dsfa.sql` | DB-Migration |
|
| `backend-compliance/migrations/024_dsfa.sql` | Basistabelle + Audit-Log |
|
||||||
| `backend-compliance/compliance/api/dsfa_routes.py` | FastAPI-Router (8 Endpoints) |
|
| `backend-compliance/migrations/028_dsfa_ai_use_cases.sql` | Section-8-Felder |
|
||||||
|
| `backend-compliance/migrations/030_dsfa_full_schema.sql` | Vollständiges Schema (+45 Spalten) |
|
||||||
|
| `backend-compliance/compliance/api/dsfa_routes.py` | FastAPI-Router (8 Endpoints, 60+ Felder) |
|
||||||
| `admin-compliance/app/api/sdk/v1/dsfa/[[...path]]/route.ts` | Next.js Proxy |
|
| `admin-compliance/app/api/sdk/v1/dsfa/[[...path]]/route.ts` | Next.js Proxy |
|
||||||
| `admin-compliance/app/sdk/dsfa/page.tsx` | Frontend (vollständig API-verdrahtet) |
|
| `admin-compliance/app/(sdk)/sdk/dsfa/[id]/page.tsx` | 8-Section-Editor |
|
||||||
| `backend-compliance/tests/test_dsfa_routes.py` | 52 Unit-Tests |
|
| `backend-compliance/tests/test_dsfa_routes.py` | 101 Unit-Tests |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# DSFA-Tests (52 Tests)
|
# DSFA-Tests (101 Tests)
|
||||||
cd backend-compliance && python3 -m pytest tests/test_dsfa_routes.py -v
|
cd backend-compliance && python3 -m pytest tests/test_dsfa_routes.py -v
|
||||||
|
|
||||||
# Vollständiger Lauf
|
# Vollständiger Lauf
|
||||||
python3 -m pytest tests/ -v --ignore=tests/test_company_profile_routes.py
|
python3 -m pytest tests/ -v --ignore=tests/test_company_profile_routes.py
|
||||||
# → 680 Tests, alle grün
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Test-Klassen:**
|
**Test-Klassen:**
|
||||||
@@ -235,9 +346,11 @@ python3 -m pytest tests/ -v --ignore=tests/test_company_profile_routes.py
|
|||||||
| `TestDsfaToResponse` | 9 | Helper: null-safety, JSONB, ISO-Datum |
|
| `TestDsfaToResponse` | 9 | Helper: null-safety, JSONB, ISO-Datum |
|
||||||
| `TestValidStatusValues` | 6 | Erlaubte/verbotene Status-Werte |
|
| `TestValidStatusValues` | 6 | Erlaubte/verbotene Status-Werte |
|
||||||
| `TestValidRiskLevels` | 6 | Erlaubte/verbotene Risiko-Stufen |
|
| `TestValidRiskLevels` | 6 | Erlaubte/verbotene Risiko-Stufen |
|
||||||
|
| `TestDSFARouterConfig` | 3 | Prefix, Tags, Registrierung |
|
||||||
| `TestDSFAStatsResponse` | 5 | Felder, Typen, Zähler |
|
| `TestDSFAStatsResponse` | 5 | Felder, Typen, Zähler |
|
||||||
| `TestAuditLogEntry` | 4 | Schema, Null-Felder |
|
| `TestAuditLogEntry` | 4 | Schema, Null-Felder |
|
||||||
| `TestDSFARouterConfig` | 3 | Prefix, Tags, Registrierung |
|
| `TestAIUseCaseModules` | 22 | Section 8: KI-Module, Art22, AI-Act-Klassen |
|
||||||
|
| `TestDSFAFullSchema` | 27 | Migration-030-Felder, Pydantic + Response |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -265,7 +378,7 @@ graph LR
|
|||||||
|
|
||||||
## Section 8: KI-Anwendungsfälle
|
## Section 8: KI-Anwendungsfälle
|
||||||
|
|
||||||
Section 8 ist ein optionaler modularer Anhang zur DSFA für KI-spezifische Verarbeitungen.
|
Section 8 ist ein modularer Anhang zur DSFA für KI-spezifische Verarbeitungen.
|
||||||
Jedes KI-System erhält ein eigenes Modul mit 7 Tabs.
|
Jedes KI-System erhält ein eigenes Modul mit 7 Tabs.
|
||||||
|
|
||||||
### KI-Modul-Typen
|
### KI-Modul-Typen
|
||||||
@@ -284,18 +397,19 @@ Jedes KI-System erhält ein eigenes Modul mit 7 Tabs.
|
|||||||
### Art. 22 DSGVO Assessment
|
### Art. 22 DSGVO Assessment
|
||||||
|
|
||||||
Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet:
|
Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet:
|
||||||
|
|
||||||
- Toggle: Automatisierte Entscheidung mit Rechtswirkung?
|
- Toggle: Automatisierte Entscheidung mit Rechtswirkung?
|
||||||
- Ausnahmetatbestand (Art. 22 Abs. 2 lit. a/b/c)
|
- Ausnahmetatbestand (Art. 22 Abs. 2 lit. a/b/c)
|
||||||
- Schutzmaßnahmen-Checklist (Menschliche Überprüfung Pflicht!)
|
- Schutzmaßnahmen-Checklist (Menschliche Überprüfung Pflicht!)
|
||||||
|
|
||||||
### AI Act Risikoklassen
|
### AI Act Risikoklassen
|
||||||
|
|
||||||
| Klasse | Label | Anforderungen |
|
| Klasse | Anforderungen |
|
||||||
|--------|-------|---------------|
|
|--------|---------------|
|
||||||
| `unacceptable` | Unannehmbares Risiko | VERBOTEN |
|
| `unacceptable` | VERBOTEN (Art. 5 AI Act) |
|
||||||
| `high_risk` | Hochrisiko | Art. 9-15 AI Act |
|
| `high_risk` | Strenge Auflagen: Art. 9–15 AI Act |
|
||||||
| `limited` | Begrenztes Risiko | Transparenz Art. 52 AI Act |
|
| `limited` | Transparenzpflicht Art. 52 AI Act |
|
||||||
| `minimal` | Minimales Risiko | Keine spezifischen AI-Act-Anforderungen |
|
| `minimal` | Keine spezifischen AI-Act-Anforderungen |
|
||||||
|
|
||||||
### `ai_use_case_modules` JSONB-Schema
|
### `ai_use_case_modules` JSONB-Schema
|
||||||
|
|
||||||
@@ -305,24 +419,23 @@ Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet:
|
|||||||
"id": "uuid",
|
"id": "uuid",
|
||||||
"use_case_type": "generative_ai",
|
"use_case_type": "generative_ai",
|
||||||
"name": "GPT-Assistent Kundenservice",
|
"name": "GPT-Assistent Kundenservice",
|
||||||
"model_description": "LLM-basierter Chatbot mit RAG...",
|
"model_description": "LLM-basierter Chatbot mit RAG",
|
||||||
"model_type": "GPT-4o",
|
"model_type": "GPT-4o",
|
||||||
"provider": "OpenAI",
|
"provider": "OpenAI",
|
||||||
"third_country_transfer": true,
|
"third_country_transfer": true,
|
||||||
"provider_country": "USA",
|
"provider_country": "USA",
|
||||||
"input_data_categories": ["Anfragetexte", "Kundennummer"],
|
"input_data_categories": ["Anfragetexte", "Kundennummer"],
|
||||||
"output_data_categories": ["Antworttext", "Intent-Klassifikation"],
|
"output_data_categories": ["Antworttext"],
|
||||||
"involves_special_categories": false,
|
"involves_special_categories": false,
|
||||||
"data_subjects": ["Kunden", "Interessenten"],
|
"data_subjects": ["Kunden"],
|
||||||
"processing_purpose": "Automatisierte Beantwortung von Kundenanfragen",
|
"processing_purpose": "Automatisierte Beantwortung von Kundenanfragen",
|
||||||
"legal_basis": "Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)",
|
"legal_basis": "Art. 6 Abs. 1b DSGVO",
|
||||||
"art22_assessment": {
|
"art22_assessment": {
|
||||||
"applies": false,
|
"applies": false,
|
||||||
"safeguards": []
|
"safeguards": []
|
||||||
},
|
},
|
||||||
"risk_criteria": [
|
"risk_criteria": [
|
||||||
{ "id": "adm_profiling", "applies": false, "severity": "high" },
|
{ "id": "adm_profiling", "applies": false, "severity": "high" }
|
||||||
{ "id": "systematic_monitoring", "applies": false, "severity": "high" }
|
|
||||||
],
|
],
|
||||||
"ai_act_risk_class": "limited",
|
"ai_act_risk_class": "limited",
|
||||||
"ai_act_justification": "Chatbot mit Transparenzpflicht nach Art. 52 AI Act",
|
"ai_act_justification": "Chatbot mit Transparenzpflicht nach Art. 52 AI Act",
|
||||||
@@ -338,43 +451,51 @@ Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet:
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Migration
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Migration 028 ausführen (auf Mac Mini)
|
|
||||||
ssh macmini "/usr/local/bin/docker exec bp-compliance-backend python3 -c \"
|
|
||||||
import sys; sys.path.insert(0, '/app')
|
|
||||||
from compliance.database import engine
|
|
||||||
from sqlalchemy import text
|
|
||||||
sql = '''
|
|
||||||
ALTER TABLE compliance.compliance_dsfas
|
|
||||||
ADD COLUMN IF NOT EXISTS ai_use_case_modules JSONB DEFAULT '[]'::jsonb,
|
|
||||||
ADD COLUMN IF NOT EXISTS section_8_complete BOOLEAN DEFAULT FALSE;
|
|
||||||
'''
|
|
||||||
with engine.connect() as conn:
|
|
||||||
conn.execute(text(sql))
|
|
||||||
conn.commit()
|
|
||||||
print('Migration 028 OK')
|
|
||||||
\""
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## RAG-Corpus bp_dsfa_corpus
|
## RAG-Corpus bp_dsfa_corpus
|
||||||
|
|
||||||
DSFA-spezifische Rechtsdokumente sind im Corpus `bp_dsfa_corpus` indexiert.
|
DSFA-spezifische Rechtsdokumente aller 16 Bundesländer + BfDI sind im Corpus `bp_dsfa_corpus` indexiert.
|
||||||
|
|
||||||
### Ingest-Script
|
### Ingest-Script
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Auf Mac Mini ausführen
|
# Vollständiger Ingest inkl. PDF-Downloads (auf Mac Mini)
|
||||||
ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh"
|
ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh"
|
||||||
|
|
||||||
# Nur Text-Dokumente (ohne Download)
|
# Nur Text-Dokumente, ohne PDF-Download-Versuch
|
||||||
ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh --only-text"
|
ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh --only-text"
|
||||||
|
|
||||||
|
# Ohne erneute Downloads (bereits heruntergeladene PDFs nutzen)
|
||||||
|
ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh --skip-download"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bundesland-Behörden (16 Bundesländer + BfDI)
|
**Ablauf des Scripts:**
|
||||||
|
|
||||||
|
1. Text-Zusammenfassungen erstellen (immer, als Fallback)
|
||||||
|
2. PDFs von 16 direkten Behörden-URLs herunterladen (curl, max. 30s/URL)
|
||||||
|
3. Für jeden Ingest: PDF bevorzugen → Text-Fallback wenn PDF fehlt/fehlgeschlagen
|
||||||
|
4. Verifikation: Testsuche im Corpus
|
||||||
|
|
||||||
|
**Behörden mit direkten PDF-URLs (10 von 17):**
|
||||||
|
|
||||||
|
| Key | Behörde | Dokument |
|
||||||
|
|-----|---------|----------|
|
||||||
|
| `bfdi_public` | BfDI Bund | Art.-35-Verarbeitungsliste |
|
||||||
|
| `bw_privat` | LfDI BW | Nicht-öffentlicher Bereich |
|
||||||
|
| `be_public` / `be_privat` | BlnBDI | Öffentlich + Nicht-öffentlich |
|
||||||
|
| `bb_public` / `bb_privat` | LDA Brandenburg | Beide Bereiche |
|
||||||
|
| `hb_public` / `hb_privat` | LfDI Bremen | Beide Bereiche |
|
||||||
|
| `hh_public` / `hh_privat` | HmbBfDI | Beide Bereiche |
|
||||||
|
| `mv_public` | LfDI MV | Öffentlicher Bereich |
|
||||||
|
| `ni_public` / `ni_privat` | LfD Niedersachsen | Beide Bereiche |
|
||||||
|
| `sl_privat` | UfD Saarland | Nicht-öffentlicher Bereich |
|
||||||
|
| `st_public` / `st_privat` | LfD Sachsen-Anhalt | Beide Bereiche |
|
||||||
|
|
||||||
|
**Behörden mit Text-Zusammenfassungen** (BY, NW, HE, RP, SN, SH, TH + WP248):
|
||||||
|
Generiert aus DSK-Positionspapieren und öffentlichen Orientierungshilfen.
|
||||||
|
|
||||||
|
### Bundesland-Behörden (vollständig)
|
||||||
|
|
||||||
| ID | Bundesland | Behörde |
|
| ID | Bundesland | Behörde |
|
||||||
|----|-----------|---------|
|
|----|-----------|---------|
|
||||||
|
|||||||
Reference in New Issue
Block a user