"""Audit trail for notes posted to PSA systems.""" import uuid from datetime import datetime, timezone from typing import Optional from sqlalchemy import String, DateTime, Text, Integer, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import UUID from app.core.database import Base class PsaPostLog(Base): __tablename__ = "psa_post_log" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) # Legacy sessions FK (nullable for AI sessions) session_id: Mapped[Optional[uuid.UUID]] = mapped_column( UUID(as_uuid=True), ForeignKey("sessions.id", ondelete="CASCADE"), nullable=True, index=True, ) # AI sessions FK (Phase 2) ai_session_id: Mapped[Optional[uuid.UUID]] = mapped_column( UUID(as_uuid=True), ForeignKey("ai_sessions.id", ondelete="CASCADE"), nullable=True, index=True, ) psa_connection_id: Mapped[Optional[uuid.UUID]] = mapped_column( UUID(as_uuid=True), ForeignKey("psa_connections.id", ondelete="SET NULL"), nullable=True, ) account_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("accounts.id", ondelete="CASCADE"), nullable=False, index=True, ) ticket_id: Mapped[str] = mapped_column(String(100), nullable=False) note_type: Mapped[str] = mapped_column(String(50), nullable=False) content_posted: Mapped[str] = mapped_column(Text, nullable=False) external_note_id: Mapped[Optional[str]] = mapped_column( String(100), nullable=True ) status: Mapped[str] = mapped_column( String(20), nullable=False ) # 'success', 'failed', 'pending_retry' error_message: Mapped[Optional[str]] = mapped_column(Text, nullable=True) retry_count: Mapped[int] = mapped_column( Integer, nullable=False, default=0, comment="Number of retry attempts for failed PSA pushes", ) next_retry_at: Mapped[Optional[datetime]] = mapped_column( DateTime(timezone=True), nullable=True, comment="When to attempt the next retry", ) status_changed_from: Mapped[Optional[str]] = mapped_column( String(100), nullable=True ) status_changed_to: Mapped[Optional[str]] = mapped_column( String(100), nullable=True ) posted_by: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=False ) posted_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc), ) # Relationships session = relationship("Session", foreign_keys=[session_id]) ai_session = relationship("AISession", foreign_keys=[ai_session_id]) psa_connection = relationship("PsaConnection", foreign_keys=[psa_connection_id]) user = relationship("User", foreign_keys=[posted_by])