from sqlalchemy import Column, Integer, DateTime, Boolean, Text, ForeignKey, Enum from sqlalchemy.orm import relationship from sqlalchemy.sql import func from enum import Enum as PyEnum from app.db.base import Base class MessageType(PyEnum): TEXT = "text" IMAGE = "image" VIDEO = "video" AUDIO = "audio" FILE = "file" SYSTEM = "system" # For system messages like "User joined" class MessageStatus(PyEnum): SENT = "sent" DELIVERED = "delivered" READ = "read" FAILED = "failed" class Message(Base): __tablename__ = "messages" id = Column(Integer, primary_key=True, index=True) chat_id = Column(Integer, ForeignKey("chats.id"), nullable=False) sender_id = Column(Integer, ForeignKey("users.id"), nullable=False) reply_to_id = Column(Integer, ForeignKey("messages.id"), nullable=True) # For replies content = Column(Text, nullable=True) # Encrypted content content_type = Column(Enum(MessageType), default=MessageType.TEXT) status = Column(Enum(MessageStatus), default=MessageStatus.SENT) is_edited = Column(Boolean, default=False) is_deleted = Column(Boolean, default=False) edited_at = Column(DateTime(timezone=True), nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) # Relationships chat = relationship("Chat", back_populates="messages") sender = relationship("User", foreign_keys=[sender_id], back_populates="sent_messages") reply_to = relationship("Message", remote_side=[id]) media_files = relationship("Media", back_populates="message", cascade="all, delete-orphan") mentions = relationship("Mention", back_populates="message", cascade="all, delete-orphan")