""" SQLAlchemy models for TOM — Technisch-Organisatorische Massnahmen (Art. 32 DSGVO). Tables: - compliance_tom_state: Full TOM-Generator state per tenant (JSONB blob) - compliance_tom_measures: Individual TOM measures (flat, queryable) """ import uuid from datetime import datetime from sqlalchemy import ( Column, String, Text, Integer, DateTime, JSON, Index ) from sqlalchemy.dialects.postgresql import UUID from classroom_engine.database import Base class TOMStateDB(Base): """Persists the entire TOM-Generator state per tenant.""" __tablename__ = 'compliance_tom_state' id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(String(100), nullable=False, unique=True) state = Column(JSON, nullable=False, default=dict) version = Column(Integer, nullable=False, default=1) created_at = Column(DateTime(timezone=True), default=datetime.utcnow, nullable=False) updated_at = Column(DateTime(timezone=True), default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index('idx_tom_state_tenant', 'tenant_id'), ) def __repr__(self): return f"" class TOMMeasureDB(Base): """Individual TOM measure — flat, queryable, for reports and export.""" __tablename__ = 'compliance_tom_measures' id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(String(100), nullable=False) control_id = Column(String(50), nullable=False) name = Column(String(300), nullable=False) description = Column(Text) category = Column(String(50), nullable=False) type = Column(String(20), nullable=False) applicability = Column(String(20), default='REQUIRED') applicability_reason = Column(Text) implementation_status = Column(String(20), default='NOT_IMPLEMENTED') responsible_person = Column(String(255)) responsible_department = Column(String(255)) implementation_date = Column(DateTime(timezone=True)) review_date = Column(DateTime(timezone=True)) review_frequency = Column(String(20)) priority = Column(String(20)) complexity = Column(String(20)) linked_evidence = Column(JSON, default=list) evidence_gaps = Column(JSON, default=list) related_controls = Column(JSON, default=dict) verified_at = Column(DateTime(timezone=True)) verified_by = Column(String(200)) effectiveness_rating = Column(String(20)) created_by = Column(String(200), default='system') created_at = Column(DateTime(timezone=True), default=datetime.utcnow, nullable=False) updated_at = Column(DateTime(timezone=True), default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( Index('idx_tom_measures_tenant', 'tenant_id'), Index('idx_tom_measures_category', 'tenant_id', 'category'), Index('idx_tom_measures_status', 'tenant_id', 'implementation_status'), ) def __repr__(self): return f""