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