arka7's picture
Deploy Discord RAG Bot with Gradio Dashboard
8442ef1
Raw History Blame Contribute Delete
5.54 kB
from datetime import datetime, timezone
from sqlalchemy import (
Column,
String,
Integer,
BigInteger,
Boolean,
DateTime,
ForeignKey,
Text,
Index
)
from sqlalchemy.orm import relationship
from database.database import Base
def utc_now():
"""Helper to return current timezone-aware UTC datetime."""
return datetime.now(timezone.utc)
class Guild(Base):
__tablename__ = "guilds"
guild_id = Column(BigInteger, primary_key=True)
name = Column(String(100), nullable=False)
created_at_db = Column(DateTime, default=utc_now)
updated_at_db = Column(DateTime, default=utc_now, onupdate=utc_now)
# Relationships
channels = relationship("Channel", back_populates="guild", cascade="all, delete-orphan")
messages = relationship("Message", back_populates="guild", cascade="all, delete-orphan")
class Channel(Base):
__tablename__ = "channels"
channel_id = Column(BigInteger, primary_key=True)
guild_id = Column(BigInteger, ForeignKey("guilds.guild_id", ondelete="CASCADE"), nullable=False)
name = Column(String(100), nullable=False)
created_at_db = Column(DateTime, default=utc_now)
updated_at_db = Column(DateTime, default=utc_now, onupdate=utc_now)
# Relationships
guild = relationship("Guild", back_populates="channels")
messages = relationship("Message", back_populates="channel", cascade="all, delete-orphan")
ingestion_state = relationship("IngestionState", back_populates="channel", uselist=False, cascade="all, delete-orphan")
class User(Base):
__tablename__ = "users"
author_id = Column(BigInteger, primary_key=True)
name = Column(String(100), nullable=False)
display_name = Column(String(100), nullable=True)
discriminator = Column(String(10), nullable=True)
avatar_url = Column(String(255), nullable=True)
is_bot = Column(Boolean, default=False)
created_at_db = Column(DateTime, default=utc_now)
updated_at_db = Column(DateTime, default=utc_now, onupdate=utc_now)
# Relationships
messages = relationship("Message", back_populates="author")
class Message(Base):
__tablename__ = "messages"
message_id = Column(BigInteger, primary_key=True)
guild_id = Column(BigInteger, ForeignKey("guilds.guild_id", ondelete="CASCADE"), nullable=True)
channel_id = Column(BigInteger, ForeignKey("channels.channel_id", ondelete="CASCADE"), nullable=False)
author_id = Column(BigInteger, ForeignKey("users.author_id", ondelete="RESTRICT"), nullable=False)
content = Column(Text, nullable=False)
created_at = Column(DateTime, nullable=False) # Discord message creation time (UTC)
edited_at = Column(DateTime, nullable=True) # Discord message edit time (UTC)
deleted_at = Column(DateTime, nullable=True) # Soft delete timestamp (UTC)
reply_to_message_id = Column(BigInteger, nullable=True)
message_url = Column(String(255), nullable=True)
is_deleted = Column(Boolean, default=False, nullable=False)
created_at_db = Column(DateTime, default=utc_now)
updated_at_db = Column(DateTime, default=utc_now, onupdate=utc_now)
# Relationships
guild = relationship("Guild", back_populates="messages")
channel = relationship("Channel", back_populates="messages")
author = relationship("User", back_populates="messages")
attachments = relationship("Attachment", back_populates="message", cascade="all, delete-orphan")
embedding = relationship("MessageEmbedding", back_populates="message", uselist=False, cascade="all, delete-orphan")
# Indexes
__table_args__ = (
Index("idx_messages_guild_id", "guild_id"),
Index("idx_messages_channel_id", "channel_id"),
Index("idx_messages_author_id", "author_id"),
Index("idx_messages_created_at", "created_at"),
Index("idx_messages_reply_to_message_id", "reply_to_message_id"),
)
class Attachment(Base):
__tablename__ = "attachments"
attachment_id = Column(BigInteger, primary_key=True)
message_id = Column(BigInteger, ForeignKey("messages.message_id", ondelete="CASCADE"), nullable=False)
filename = Column(String(255), nullable=False)
url = Column(String(1024), nullable=False)
content_type = Column(String(100), nullable=True)
size = Column(Integer, nullable=False)
created_at_db = Column(DateTime, default=utc_now)
# Relationships
message = relationship("Message", back_populates="attachments")
class IngestionState(Base):
__tablename__ = "ingestion_state"
channel_id = Column(BigInteger, ForeignKey("channels.channel_id", ondelete="CASCADE"), primary_key=True)
last_processed_message_id = Column(BigInteger, nullable=True)
last_processed_timestamp = Column(DateTime, nullable=True)
last_sync_time = Column(DateTime, nullable=True)
status = Column(String(20), default="PENDING", nullable=False) # PENDING, SYNCING, COMPLETED, FAILED
error = Column(Text, nullable=True)
updated_at_db = Column(DateTime, default=utc_now, onupdate=utc_now)
# Relationships
channel = relationship("Channel", back_populates="ingestion_state")
class MessageEmbedding(Base):
__tablename__ = "message_embeddings"
message_id = Column(BigInteger, ForeignKey("messages.message_id", ondelete="CASCADE"), primary_key=True)
embedding = Column(Text, nullable=False) # Stored as serialized JSON list of 1024 floats
created_at_db = Column(DateTime, default=utc_now)
# Relationships
message = relationship("Message", back_populates="embedding")