from datetime import datetime, timezone import uuid from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Text from sqlalchemy.orm import relationship from app.db.base_class import Base def generate_uuid() -> str: return uuid.uuid4().hex def utc_now() -> datetime: return datetime.now(timezone.utc).replace(tzinfo=None) class User(Base): __tablename__ = "users" id = Column(String, primary_key=True, index=True, default=generate_uuid) login = Column(String, unique=True, index=True, nullable=False) hashed_password = Column(String, nullable=False) is_active = Column(Boolean, default=True) sessions = relationship("Session", back_populates="user", cascade="all, delete-orphan") chats = relationship("Chat", back_populates="user", cascade="all, delete-orphan") class Session(Base): __tablename__ = "sessions" id = Column(String, primary_key=True, index=True, default=generate_uuid) user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True) expires_at = Column(DateTime, nullable=False) user = relationship("User", back_populates="sessions") class Chat(Base): __tablename__ = "chats" id = Column(String, primary_key=True, index=True, default=generate_uuid) user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True) title = Column(String, nullable=False, default="New Chat") model_alias = Column(String, nullable=False) created_at = Column(DateTime, nullable=False, default=utc_now) updated_at = Column(DateTime, nullable=False, default=utc_now, onupdate=utc_now) user = relationship("User", back_populates="chats") messages = relationship("Message", back_populates="chat", cascade="all, delete-orphan", order_by="Message.created_at") class Message(Base): __tablename__ = "messages" id = Column(String, primary_key=True, index=True, default=generate_uuid) chat_id = Column(String, ForeignKey("chats.id"), nullable=False, index=True) role = Column(String, nullable=False) # system, user, assistant content = Column(Text, nullable=False) created_at = Column(DateTime, nullable=False, default=utc_now) chat = relationship("Chat", back_populates="messages") attachments = relationship("Attachment", back_populates="message", cascade="all, delete-orphan") class Attachment(Base): __tablename__ = "attachments" id = Column(String, primary_key=True, index=True, default=generate_uuid) message_id = Column(String, ForeignKey("messages.id"), nullable=False, index=True) filename = Column(String, nullable=False) content_type = Column(String, nullable=False) file_path = Column(String, nullable=False) created_at = Column(DateTime, nullable=False, default=utc_now) message = relationship("Message", back_populates="attachments")