from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Text, Boolean from sqlalchemy.orm import relationship from datetime import datetime, timezone from database import Base def _utcnow(): return datetime.now(timezone.utc) class Conversation(Base): __tablename__ = "conversations" id = Column(Integer, primary_key=True, index=True) type = Column(String, nullable=False, default="direct") # 'direct' | 'group' name = Column(String, nullable=True) # required for group is_system = Column(Boolean, nullable=False, default=False) created_by = Column(Integer, ForeignKey("users.id"), nullable=True) created_at = Column(DateTime(timezone=True), default=_utcnow) participants = relationship( "ConversationParticipant", back_populates="conversation", cascade="all, delete-orphan", ) messages = relationship( "ChatMessage", back_populates="conversation", cascade="all, delete-orphan", ) class ConversationParticipant(Base): __tablename__ = "conversation_participants" id = Column(Integer, primary_key=True, index=True) conversation_id = Column(Integer, ForeignKey("conversations.id"), nullable=False) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) joined_at = Column(DateTime(timezone=True), default=_utcnow) last_read_at = Column(DateTime(timezone=True), nullable=True) conversation = relationship("Conversation", back_populates="participants") user = relationship("User") class ChatMessage(Base): __tablename__ = "chat_messages" id = Column(Integer, primary_key=True, index=True) conversation_id = Column(Integer, ForeignKey("conversations.id"), nullable=False) sender_id = Column(Integer, ForeignKey("users.id"), nullable=False) body = Column(Text, nullable=False) sent_at = Column(DateTime(timezone=True), default=_utcnow) deleted_at = Column(DateTime(timezone=True), nullable=True) conversation = relationship("Conversation", back_populates="messages") sender = relationship("User")