# SQLAlchemy models: Document, Chunk (Vector dimension 384), User import uuid from datetime import datetime from sqlalchemy import String, Text, Integer, DateTime, ForeignKey, func from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import UUID from pgvector.sqlalchemy import Vector # type: ignore[import-untyped] from fastapi_users.db import SQLAlchemyBaseUserTableUUID class Base(DeclarativeBase): pass class User(SQLAlchemyBaseUserTableUUID, Base): __tablename__ = "users" created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) documents: Mapped[list["Document"]] = relationship("Document", back_populates="user", cascade="all, delete-orphan") class Document(Base): __tablename__ = "documents" id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) filename: Mapped[str] = mapped_column(String(255), nullable=False) content_hash: Mapped[str] = mapped_column(String(64), nullable=False, unique=True) file_path: Mapped[str] = mapped_column(String(512), nullable=False) status: Mapped[str] = mapped_column(String(20), nullable=False, default="uploading") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) chunks: Mapped[list["Chunk"]] = relationship("Chunk", back_populates="document", cascade="all, delete-orphan") user: Mapped["User"] = relationship("User", back_populates="documents") class Chunk(Base): __tablename__ = "chunks" id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) document_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("documents.id", ondelete="CASCADE"), nullable=False ) content: Mapped[str] = mapped_column(Text, nullable=False) # pgvector column — no native Mapped type exists for Vector embedding = mapped_column(Vector(384), nullable=False) chunk_index: Mapped[int] = mapped_column(Integer, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) document: Mapped["Document"] = relationship("Document", back_populates="chunks")