diff --git a/docs-src/services/sdk-modules/dsfa.md b/docs-src/services/sdk-modules/dsfa.md index 41a5305..feb43ca 100644 --- a/docs-src/services/sdk-modules/dsfa.md +++ b/docs-src/services/sdk-modules/dsfa.md @@ -1,9 +1,10 @@ # DSFA — Datenschutz-Folgenabschätzung (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 - **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` - **Risikostufen:** `low` / `medium` / `high` / `critical` -- **Datenkategorien:** Mehrfachauswahl der verarbeiteten Datenkategorien (JSONB) -- **Empfänger:** Dokumentation der Datenempfänger (JSONB) -- **Schutzmaßnahmen:** Erfassung technischer und organisatorischer Maßnahmen (JSONB) +- **Datenkategorien, Empfänger, Schutzmaßnahmen:** JSONB-Arrays +- **Risiken & Mitigationen:** Strukturierte JSONB-Arrays mit Risiko-IDs +- **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 - **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 -- **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/audit-log` | Audit-Trail (limit, offset) | | `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) | | `PATCH` | `/api/v1/dsfa/{id}/status` | Schnell-Statuswechsel | @@ -71,8 +76,6 @@ natürlicher Personen mit sich bringt. Typische Fälle: ### Validierung -Folgende Felder werden gegen erlaubte Werte geprüft (HTTP 422 bei Verstoß): - | Feld | Erlaubte Werte | |------|----------------| | `status` | `draft`, `in-review`, `approved`, `needs-update` | @@ -82,45 +85,152 @@ Folgende Felder werden gegen erlaubte Werte geprüft (HTTP 422 bei Verstoß): ## Datenmodell -### DSFA-Objekt (Response) +### DSFA-Objekt (Response) — vollständig ```json { "id": "uuid", "tenant_id": "default", "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", "risk_level": "high", "processing_activity": "Automatisierte Bewertung von Bewerbungsunterlagen", - "data_categories": ["Kontaktdaten", "Beruflicher Werdegang", "Qualifikationen"], - "recipients": ["HR-Abteilung", "Fachabteilungen"], - "measures": ["Verschlüsselung", "Zugriffskontrolle", "Menschliche Prüfung"], + "data_categories": ["Kontaktdaten", "Beruflicher Werdegang"], + "recipients": ["HR-Abteilung"], + "measures": ["Verschlüsselung", "Menschliche Prüfung"], "approved_by": null, "approved_at": null, - "created_by": "system", - "created_at": "2026-03-04T10:00:00", - "updated_at": "2026-03-04T10:00:00" + "created_by": "admin", + "created_at": "2026-03-05T10: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 { "title": "DSFA - Video-Überwachung Büro", - "description": "Datenschutz-Folgenabschätzung für Videoüberwachung", "status": "draft", "risk_level": "medium", "processing_activity": "Videoüberwachung zu Sicherheitszwecken", "data_categories": ["Bilddaten", "Bewegungsdaten"], - "recipients": ["Sicherheitsdienst"], - "measures": ["Löschfristen", "Zugangsbeschränkung", "Hinweisschilder"], "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 { @@ -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 @@ -165,38 +253,60 @@ stateDiagram-v2 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 -| Tabelle | Modus | Migration | Beschreibung | -|---------|-------|-----------|--------------| -| `compliance_dsfas` | read/write | 024_dsfa.sql | DSFA-Datensätze mit JSONB-Feldern | -| `compliance_dsfa_audit_log` | write | 024_dsfa.sql | Audit-Trail aller Aktionen | +| Tabelle | Migration | Beschreibung | +|---------|-----------|--------------| +| `compliance_dsfas` | 024, 028, 030 | DSFA-Datensätze (62 Spalten) | +| `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 -CREATE TABLE compliance_dsfas ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - tenant_id VARCHAR(255) NOT NULL, - title VARCHAR(500) NOT NULL, - description TEXT DEFAULT '', - status VARCHAR(50) NOT NULL DEFAULT 'draft', - risk_level VARCHAR(50) NOT NULL DEFAULT 'low', - processing_activity VARCHAR(500) DEFAULT '', - data_categories JSONB DEFAULT '[]', - recipients JSONB DEFAULT '[]', - measures JSONB DEFAULT '[]', - approved_by VARCHAR(255), - approved_at TIMESTAMPTZ, - created_by VARCHAR(255) DEFAULT 'system', - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -); +-- Basisfelder (Migration 024) +id, tenant_id, title, description, status, risk_level, +processing_activity, data_categories, recipients, measures, +approved_by, approved_at, created_by, created_at, updated_at + +-- Section 1 (Migration 030) +processing_description, processing_purpose, legal_basis, legal_basis_details + +-- Section 2 (Migration 030) +necessity_assessment, proportionality_assessment, data_minimization, +alternatives_considered, retention_justification + +-- Section 3 (Migration 030) +involves_ai, overall_risk_level, risk_score + +-- 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 | |-------|--------------| -| `backend-compliance/migrations/024_dsfa.sql` | DB-Migration | -| `backend-compliance/compliance/api/dsfa_routes.py` | FastAPI-Router (8 Endpoints) | +| `backend-compliance/migrations/024_dsfa.sql` | Basistabelle + Audit-Log | +| `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/sdk/dsfa/page.tsx` | Frontend (vollständig API-verdrahtet) | -| `backend-compliance/tests/test_dsfa_routes.py` | 52 Unit-Tests | +| `admin-compliance/app/(sdk)/sdk/dsfa/[id]/page.tsx` | 8-Section-Editor | +| `backend-compliance/tests/test_dsfa_routes.py` | 101 Unit-Tests | --- ## Tests ```bash -# DSFA-Tests (52 Tests) +# DSFA-Tests (101 Tests) cd backend-compliance && python3 -m pytest tests/test_dsfa_routes.py -v # Vollständiger Lauf python3 -m pytest tests/ -v --ignore=tests/test_company_profile_routes.py -# → 680 Tests, alle grün ``` **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 | | `TestValidStatusValues` | 6 | Erlaubte/verbotene Status-Werte | | `TestValidRiskLevels` | 6 | Erlaubte/verbotene Risiko-Stufen | +| `TestDSFARouterConfig` | 3 | Prefix, Tags, Registrierung | | `TestDSFAStatsResponse` | 5 | Felder, Typen, Zähler | | `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 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. ### KI-Modul-Typen @@ -284,18 +397,19 @@ Jedes KI-System erhält ein eigenes Modul mit 7 Tabs. ### Art. 22 DSGVO Assessment Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet: + - Toggle: Automatisierte Entscheidung mit Rechtswirkung? - Ausnahmetatbestand (Art. 22 Abs. 2 lit. a/b/c) - Schutzmaßnahmen-Checklist (Menschliche Überprüfung Pflicht!) ### AI Act Risikoklassen -| Klasse | Label | Anforderungen | -|--------|-------|---------------| -| `unacceptable` | Unannehmbares Risiko | VERBOTEN | -| `high_risk` | Hochrisiko | Art. 9-15 AI Act | -| `limited` | Begrenztes Risiko | Transparenz Art. 52 AI Act | -| `minimal` | Minimales Risiko | Keine spezifischen AI-Act-Anforderungen | +| Klasse | Anforderungen | +|--------|---------------| +| `unacceptable` | VERBOTEN (Art. 5 AI Act) | +| `high_risk` | Strenge Auflagen: Art. 9–15 AI Act | +| `limited` | Transparenzpflicht Art. 52 AI Act | +| `minimal` | Keine spezifischen AI-Act-Anforderungen | ### `ai_use_case_modules` JSONB-Schema @@ -305,24 +419,23 @@ Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet: "id": "uuid", "use_case_type": "generative_ai", "name": "GPT-Assistent Kundenservice", - "model_description": "LLM-basierter Chatbot mit RAG...", + "model_description": "LLM-basierter Chatbot mit RAG", "model_type": "GPT-4o", "provider": "OpenAI", "third_country_transfer": true, "provider_country": "USA", "input_data_categories": ["Anfragetexte", "Kundennummer"], - "output_data_categories": ["Antworttext", "Intent-Klassifikation"], + "output_data_categories": ["Antworttext"], "involves_special_categories": false, - "data_subjects": ["Kunden", "Interessenten"], + "data_subjects": ["Kunden"], "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": { "applies": false, "safeguards": [] }, "risk_criteria": [ - { "id": "adm_profiling", "applies": false, "severity": "high" }, - { "id": "systematic_monitoring", "applies": false, "severity": "high" } + { "id": "adm_profiling", "applies": false, "severity": "high" } ], "ai_act_risk_class": "limited", "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 -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 ```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" -# Nur Text-Dokumente (ohne Download) +# Nur Text-Dokumente, ohne PDF-Download-Versuch 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 | |----|-----------|---------|