"""Message models — messages, message reports.""" from sqlalchemy import ( Column, Integer, String, Text, DateTime, ForeignKey, Boolean, Index, ) from sqlalchemy.dialects.postgresql import ENUM from sqlalchemy.orm import relationship from sqlalchemy.sql import func import enum from app.database import Base class MessageReportStatus(str, enum.Enum): PENDING = "pending" RESOLVED = "resolved" DISMISSED = "dismissed" class MessageReportReason(str, enum.Enum): SPAM = "spam" INAPPROPRIATE = "inappropriate" OFF_TOPIC = "off_topic" OTHER = "other" class Message(Base): __tablename__ = "messages" id = Column(Integer, primary_key=True, index=True) sender_id = Column( Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) conversation_id = Column( Integer, ForeignKey("conversations.id", ondelete="CASCADE"), nullable=True ) world_id = Column( Integer, ForeignKey("worlds.id", ondelete="CASCADE"), nullable=True ) room_id = Column(String(36), nullable=True) body = Column(Text, nullable=False) is_filtered = Column(Boolean, default=False, nullable=False) created_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships sender = relationship("User", back_populates="sent_messages") conversation = relationship("Conversation", back_populates="messages") world = relationship("World") reports = relationship( "MessageReport", back_populates="message", cascade="all, delete-orphan" ) # Indexes for history queries __table_args__ = ( Index("ix_messages_conversation_created", "conversation_id", "created_at"), Index("ix_messages_world_created", "world_id", "created_at"), ) class MessageReport(Base): __tablename__ = "message_reports" id = Column(Integer, primary_key=True, index=True) message_id = Column( Integer, ForeignKey("messages.id", ondelete="CASCADE"), nullable=False ) reporter_id = Column( Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=False ) reason = Column( ENUM(MessageReportReason, name="message_report_reason", create_type=False), nullable=False, ) details = Column(Text, nullable=True) status = Column( ENUM(MessageReportStatus, name="message_report_status", create_type=False), default=MessageReportStatus.PENDING, nullable=False, ) moderator_id = Column( Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True ) resolved_at = Column(DateTime(timezone=True), nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships message = relationship("Message", back_populates="reports") reporter = relationship("User", foreign_keys=[reporter_id]) moderator = relationship("User", foreign_keys=[moderator_id])