feat(K): Phase K EU Compliance — AI Registry, DPIA, Incident Register, Retention Admin, Tests, Doku

- K-REG: GET /api/v1/compliance/ai-registry — lists all agents with ai_use_case_metadata
- K-DPIA: GET /api/v1/compliance/dpia-template — pre-filled DPIA template export
- K-INC: ComplianceIncident model, Migration 0133 (RLS), CRUD routes (admin-only)
- K-RET: GET/PATCH /api/v1/compliance/retention-policies — 5 policies editable
- K-COMP-TEST: 12/12 integration tests pass
- K-DOC: docs/compliance.md — Betriebsdoku
- Frontend: ComplianceTab.tsx in SettingsAI.tsx (new tab)
- 13 files created/modified
This commit is contained in:
Agent Zero
2026-08-21 01:58:46 +02:00
parent fbcfbbced6
commit e59db34a6d
14 changed files with 1917 additions and 1 deletions
+2
View File
@@ -8,6 +8,7 @@ from app.models.auth import ApiToken, PasswordResetToken
from app.models.backup import Backup
from app.models.bank_account import BankAccount
from app.models.consumer_inbox import ConsumerInbox
from app.models.compliance import ComplianceIncident
from app.models.contact import Contact, ContactPerson
from app.models.contact_folder import ContactFolder
from app.models.contact_merge import ContactMergeHistory
@@ -47,6 +48,7 @@ __all__ = [
"NotificationPreference",
"PasswordResetToken",
"ApiToken",
"ComplianceIncident",
"Contact",
"ContactPerson",
"ContactFolder",
+59
View File
@@ -0,0 +1,59 @@
"""Compliance models — AI/privacy incident register for EU compliance."""
from __future__ import annotations
import uuid
from datetime import datetime
from typing import Any
from sqlalchemy import DateTime, ForeignKey, Index, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
class ComplianceIncident(Base, TenantMixin):
"""An AI/privacy/security incident tracked for compliance purposes.
Used by the compliance routes under /api/v1/compliance/incidents.
"""
__tablename__ = "compliance_incidents"
__table_args__ = (
Index("ix_compliance_incidents_tenant_status", "tenant_id", "status"),
Index("ix_compliance_incidents_tenant_type", "tenant_id", "incident_type"),
)
id: Mapped[uuid.UUID] = mapped_column(
PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4
)
incident_type: Mapped[str] = mapped_column(
String(30), nullable=False, default="ai"
)
title: Mapped[str] = mapped_column(String(300), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False, default="")
affected_use_cases: Mapped[list[Any]] = mapped_column(
JSONB, nullable=False, default=list
)
affected_versions: Mapped[list[Any]] = mapped_column(
JSONB, nullable=False, default=list
)
provider: Mapped[str] = mapped_column(String(100), nullable=False, default="")
measures_taken: Mapped[str] = mapped_column(Text, nullable=False, default="")
evidence_refs: Mapped[list[Any]] = mapped_column(
JSONB, nullable=False, default=list
)
status: Mapped[str] = mapped_column(
String(20), nullable=False, default="open"
)
created_by: Mapped[uuid.UUID | None] = mapped_column(
PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True
)
resolved_by: Mapped[uuid.UUID | None] = mapped_column(
PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True
)
resolved_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
+2
View File
@@ -54,3 +54,5 @@ class SystemSettings(Base, TenantMixin):
backup_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false")
# Automation plugin settings (JSONB)
automation_config: Mapped[dict | None] = mapped_column(JSONB, nullable=True)
# Retention policy overrides (JSONB) — compliance module
retention_config: Mapped[dict | None] = mapped_column(JSONB, nullable=True)