import enum import uuid from datetime import datetime from sqlalchemy import DateTime, Enum, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base def _uuid() -> str: return str(uuid.uuid4()) def _now() -> datetime: return datetime.utcnow() class DocumentStatus(str, enum.Enum): pending = "pending" processing = "processing" completed = "completed" failed = "failed" class KnowledgeBase(Base): __tablename__ = "knowledge_bases" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid) tenant_id: Mapped[str] = mapped_column( String(36), ForeignKey("tenants.id"), nullable=False, index=True ) name: Mapped[str] = mapped_column(String(200), nullable=False) description: Mapped[str | None] = mapped_column(Text, nullable=True) embedding_model: Mapped[str] = mapped_column(String(100), default="text-embedding-3-small") created_at: Mapped[datetime] = mapped_column(DateTime, default=_now) updated_at: Mapped[datetime] = mapped_column(DateTime, default=_now, onupdate=_now) documents: Mapped[list["Document"]] = relationship( back_populates="knowledge_base", cascade="all, delete-orphan", lazy="selectin" ) tenant = relationship("Tenant", lazy="selectin") class Document(Base): __tablename__ = "documents" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_uuid) knowledge_base_id: Mapped[str] = mapped_column( String(36), ForeignKey("knowledge_bases.id"), nullable=False, index=True ) filename: Mapped[str] = mapped_column(String(500), nullable=False) file_type: Mapped[str] = mapped_column(String(20), nullable=False) file_size: Mapped[int] = mapped_column(Integer, default=0) chunk_count: Mapped[int] = mapped_column(Integer, default=0) status: Mapped[DocumentStatus] = mapped_column( Enum(DocumentStatus), default=DocumentStatus.pending ) error_message: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, default=_now) updated_at: Mapped[datetime] = mapped_column(DateTime, default=_now, onupdate=_now) knowledge_base: Mapped["KnowledgeBase"] = relationship(back_populates="documents")