from __future__ import annotations from datetime import datetime from typing import TYPE_CHECKING from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, UniqueConstraint, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.database import Base from app.utils.ids import prefixed_id if TYPE_CHECKING: from app.models.document import Document class DocumentChunk(Base): __tablename__ = "document_chunks" __table_args__ = ( UniqueConstraint("document_id", "chunk_index", name="uq_document_chunk_index"), ) id: Mapped[str] = mapped_column( String(40), primary_key=True, default=lambda: prefixed_id("chunk"), ) document_id: Mapped[str] = mapped_column( String(40), ForeignKey("documents.id", ondelete="CASCADE"), index=True, nullable=False, ) chunk_index: Mapped[int] = mapped_column(Integer, nullable=False) chunk_text: Mapped[str] = mapped_column(Text, nullable=False) token_estimate: Mapped[int] = mapped_column(Integer, nullable=False) page_number: Mapped[int | None] = mapped_column(Integer, nullable=True) heading: Mapped[str | None] = mapped_column(String(255), nullable=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False, ) embedding: Mapped[str | None] = mapped_column(Text, nullable=True) document: Mapped["Document"] = relationship("Document", back_populates="chunks")