"""Domain models - SQLAlchemy entities.""" from sqlalchemy import Column, String, Integer, DateTime, ForeignKey, Text, Float, LargeBinary from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime import uuid Base = declarative_base() def generate_uuid(): return str(uuid.uuid4()) class User(Base): __tablename__ = "users" id = Column(String, primary_key=True, default=generate_uuid) clerk_user_id = Column(String, unique=True, nullable=False, index=True) email = Column(String, nullable=False) org_id = Column(String, nullable=False, index=True) created_at = Column(DateTime, default=datetime.utcnow) documents = relationship("Document", back_populates="user", cascade="all, delete-orphan") chats = relationship("Chat", back_populates="user", cascade="all, delete-orphan") class Folder(Base): __tablename__ = "folders" id = Column(String, primary_key=True, default=generate_uuid) name = Column(String, nullable=False) org_id = Column(String, nullable=False, index=True) # parent_id = None means root-level folder parent_id = Column(String, ForeignKey("folders.id"), nullable=True, index=True) created_at = Column(DateTime, default=datetime.utcnow) documents = relationship("Document", back_populates="folder") # Self-referential: children folders children = relationship("Folder", foreign_keys=[parent_id], lazy="select") class Document(Base): __tablename__ = "documents" id = Column(String, primary_key=True, default=generate_uuid) name = Column(String, nullable=False) size = Column(Integer, nullable=False) storage_path = Column(String, nullable=False) file_content = Column(LargeBinary, nullable=True) chunks = Column(Integer, default=0) # Processing status: pending | processing | done | error status = Column(String, default="pending", nullable=False) error_message = Column(Text, nullable=True) folder_id = Column(String, ForeignKey("folders.id"), nullable=True) user_id = Column(String, ForeignKey("users.id"), nullable=False) org_id = Column(String, nullable=False, index=True) created_at = Column(DateTime, default=datetime.utcnow) user = relationship("User", back_populates="documents") folder = relationship("Folder", back_populates="documents") class Chat(Base): __tablename__ = "chats" id = Column(String, primary_key=True, default=generate_uuid) title = Column(String, nullable=False) user_id = Column(String, ForeignKey("users.id"), nullable=False) org_id = Column(String, nullable=False, index=True) created_at = Column(DateTime, default=datetime.utcnow) user = relationship("User", back_populates="chats") messages = relationship("Message", back_populates="chat", cascade="all, delete-orphan") class Message(Base): __tablename__ = "messages" id = Column(String, primary_key=True, default=generate_uuid) chat_id = Column(String, ForeignKey("chats.id"), nullable=False) role = Column(String, nullable=False) content = Column(Text, nullable=False) sources = Column(Text, nullable=True) created_at = Column(DateTime, default=datetime.utcnow) chat = relationship("Chat", back_populates="messages")