Files
leocrm/app/models/compliance.py
T
Agent Zero e59db34a6d 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
2026-08-21 01:58:46 +02:00

60 lines
2.2 KiB
Python

"""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
)