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 32s
CI / test-python-backend-compliance (push) Successful in 30s
CI / test-python-document-crawler (push) Successful in 21s
CI / test-python-dsms-gateway (push) Successful in 18s
6-Phasen-Implementation fuer cloud-faehiges, mandantenfaehiges Compliance SDK:
Phase 1: Multi-Tenancy Fix
- Shared tenant_utils.py Dependency (UUID-Validierung, kein "default" mehr)
- VVT tenant_id Column + tenant-scoped Queries
- DSFA/Vendor DEFAULT_TENANT_ID von "default" auf UUID migriert
- Migration 035
Phase 2: Stammdaten-Erweiterung
- Company Profile um JSONB-Felder erweitert (processing_systems, ai_systems, technical_contacts)
- Regulierungs-Flags (NIS2, AI Act, ISO 27001)
- GET /template-context Endpoint
- Migration 036
Phase 3: Dokument-Versionierung
- 5 Versions-Tabellen (DSFA, VVT, TOM, Loeschfristen, Obligations)
- Shared versioning_utils.py Helper
- /{id}/versions Endpoints auf allen 5 Dokumenttypen
- Migration 037
Phase 4: Change-Request System
- Zentrale CR-Inbox mit CRUD + Accept/Reject/Edit Workflow
- Regelbasierte CR-Engine (VVT DPIA → DSFA CR, Datenkategorien → Loeschfristen CR)
- Audit-Trail
- Migration 038
Phase 5: Dokumentengenerierung
- 5 Template-Generatoren (DSFA, VVT, TOM, Loeschfristen, Obligations)
- Preview + Apply Endpoints (erzeugt CRs, keine direkten Dokumente)
Phase 6: Frontend-Integration
- Change-Request Inbox Page mit Stats, Filtern, Modals
- VersionHistory Timeline-Komponente
- SDKSidebar CR-Badge (60s Polling)
- Company Profile: 2 neue Wizard-Steps + "Dokumente generieren" CTA
Docs: 5 neue MkDocs-Seiten, CLAUDE.md aktualisiert
Tests: 97 neue Tests (alle bestanden)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
83 lines
3.3 KiB
Python
83 lines
3.3 KiB
Python
"""DSFA template generator — creates DSFA skeleton from company profile."""
|
|
|
|
|
|
def generate_dsfa_draft(ctx: dict) -> dict:
|
|
"""Generate a DSFA draft document from template context.
|
|
|
|
Args:
|
|
ctx: Flat dict from company-profile/template-context endpoint
|
|
|
|
Returns:
|
|
Dict with DSFA fields ready for creation
|
|
"""
|
|
company = ctx.get("company_name", "Unbekannt")
|
|
dpo = ctx.get("dpo_name", "")
|
|
dpo_email = ctx.get("dpo_email", "")
|
|
|
|
sections = {
|
|
"section_1": {
|
|
"title": "Beschreibung der Verarbeitung",
|
|
"content": f"Die {company} führt eine Datenschutz-Folgenabschätzung gemäß Art. 35 DSGVO durch.\n\n"
|
|
f"**Verantwortlicher:** {company}\n"
|
|
f"**Datenschutzbeauftragter:** {dpo} ({dpo_email})\n"
|
|
f"**Zuständige Aufsichtsbehörde:** {ctx.get('supervisory_authority', 'Nicht angegeben')}",
|
|
},
|
|
"section_2": {
|
|
"title": "Notwendigkeit und Verhältnismäßigkeit",
|
|
"content": "Die Verarbeitung ist zur Erreichung des beschriebenen Zwecks erforderlich. "
|
|
"Alternative, weniger eingriffsintensive Maßnahmen wurden geprüft.",
|
|
},
|
|
"section_3": {
|
|
"title": "Risiken für die Rechte und Freiheiten",
|
|
"content": _generate_risk_section(ctx),
|
|
},
|
|
"section_6": {
|
|
"title": "Stellungnahme des DSB",
|
|
"content": f"Der Datenschutzbeauftragte ({dpo}) wurde konsultiert." if dpo else
|
|
"Ein Datenschutzbeauftragter wurde noch nicht benannt.",
|
|
},
|
|
}
|
|
|
|
ai_systems = ctx.get("ai_systems", [])
|
|
involves_ai = len(ai_systems) > 0
|
|
|
|
return {
|
|
"title": f"DSFA — {company}",
|
|
"description": f"Automatisch generierte Datenschutz-Folgenabschätzung für {company}",
|
|
"status": "draft",
|
|
"risk_level": "high" if involves_ai else "medium",
|
|
"involves_ai": involves_ai,
|
|
"dpo_name": dpo,
|
|
"sections": sections,
|
|
"processing_systems": [s.get("name", "") for s in ctx.get("processing_systems", [])],
|
|
"ai_systems_summary": [
|
|
{"name": s.get("name"), "risk": s.get("risk_category", "unknown")}
|
|
for s in ai_systems
|
|
],
|
|
}
|
|
|
|
|
|
def _generate_risk_section(ctx: dict) -> str:
|
|
lines = ["## Risikoanalyse\n"]
|
|
|
|
if ctx.get("has_ai_systems"):
|
|
lines.append("### KI-Systeme\n")
|
|
for s in ctx.get("ai_systems", []):
|
|
risk = s.get("risk_category", "unbekannt")
|
|
lines.append(f"- **{s.get('name', 'N/A')}**: Zweck: {s.get('purpose', 'N/A')}, "
|
|
f"Risiko: {risk}, Human Oversight: {'Ja' if s.get('has_human_oversight') else 'Nein'}")
|
|
lines.append("")
|
|
|
|
if ctx.get("subject_to_ai_act"):
|
|
lines.append("**Hinweis:** Das Unternehmen unterliegt dem EU AI Act. "
|
|
"KI-spezifische Risiken müssen gemäß der KI-Verordnung bewertet werden.\n")
|
|
|
|
if ctx.get("subject_to_nis2"):
|
|
lines.append("**Hinweis:** NIS2-Richtlinie ist anwendbar. "
|
|
"Cybersicherheitsrisiken sind zusätzlich zu bewerten.\n")
|
|
|
|
if not ctx.get("has_ai_systems") and not ctx.get("subject_to_nis2"):
|
|
lines.append("Standardrisiken der Datenverarbeitung sind zu bewerten.\n")
|
|
|
|
return "\n".join(lines)
|