"""SQLAlchemy models for report generation Tables: - tr_generated_reports: Stores report metadata and generation status Note: All tables use 'tr_' prefix to avoid conflicts in shared database. """ from sqlalchemy import Column, String, Text, DateTime, Integer, ForeignKey, Index, JSON from sqlalchemy.orm import relationship from datetime import datetime import uuid import enum from app.core.database import Base class ReportStatus(str, enum.Enum): """Report generation status""" PENDING = "pending" COLLECTING_DATA = "collecting_data" GENERATING_CONTENT = "generating_content" ASSEMBLING_DOCUMENT = "assembling_document" COMPLETED = "completed" FAILED = "failed" class GeneratedReport(Base): """Generated report model for incident reports""" __tablename__ = "tr_generated_reports" report_id = Column( String(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="Unique report identifier (UUID)" ) room_id = Column( String(36), ForeignKey("tr_incident_rooms.room_id", ondelete="CASCADE"), nullable=False, comment="Reference to incident room" ) # Generation metadata generated_by = Column( String(255), nullable=False, comment="User email who triggered report generation" ) generated_at = Column( DateTime, default=datetime.utcnow, nullable=False, comment="Report generation timestamp" ) # Status tracking status = Column( String(30), default=ReportStatus.PENDING.value, nullable=False, comment="Current generation status" ) error_message = Column( Text, nullable=True, comment="User-friendly error message if generation failed" ) # DIFY AI metadata dify_message_id = Column( String(100), nullable=True, comment="DIFY API message ID for tracking" ) dify_conversation_id = Column( String(100), nullable=True, comment="DIFY conversation ID" ) prompt_tokens = Column( Integer, nullable=True, comment="Number of prompt tokens used" ) completion_tokens = Column( Integer, nullable=True, comment="Number of completion tokens used" ) # Report content report_title = Column( String(255), nullable=True, comment="Generated report title" ) report_json = Column( JSON, nullable=True, comment="Parsed AI output as JSON" ) docx_storage_path = Column( String(500), nullable=True, comment="Path to generated .docx file in MinIO or local storage" ) # Relationship room = relationship("IncidentRoom", backref="reports") # Indexes __table_args__ = ( Index("ix_tr_generated_reports_room_date", "room_id", "generated_at"), Index("ix_tr_generated_reports_status", "status"), ) def __repr__(self): return f""