Spaces:
Sleeping
Sleeping
| from datetime import UTC, datetime | |
| from enum import StrEnum | |
| from typing import Any | |
| from uuid import UUID, uuid4 | |
| from sqlalchemy import BigInteger, DateTime, ForeignKey, String, Text, Uuid | |
| from sqlalchemy.dialects.postgresql import JSONB | |
| from sqlalchemy.orm import Mapped, mapped_column, relationship | |
| from app.auth.models import User | |
| from app.db.base import Base | |
| def _utcnow() -> datetime: | |
| return datetime.now(UTC) | |
| class DocumentStatus(StrEnum): | |
| UPLOADED = "uploaded" | |
| PROCESSING = "processing" | |
| PROCESSED = "processed" | |
| FAILED = "failed" | |
| class Document(Base): | |
| __tablename__ = "documents" | |
| id: Mapped[UUID] = mapped_column(Uuid, primary_key=True, default=uuid4) | |
| user_id: Mapped[UUID] = mapped_column( | |
| Uuid, | |
| ForeignKey("users.id", ondelete="CASCADE"), | |
| nullable=False, | |
| index=True, | |
| ) | |
| filename: Mapped[str] = mapped_column(String(512), nullable=False) | |
| content_type: Mapped[str] = mapped_column(String(128), nullable=False) | |
| size_bytes: Mapped[int] = mapped_column(BigInteger, nullable=False) | |
| storage_key: Mapped[str] = mapped_column(String(1024), nullable=False) | |
| status: Mapped[DocumentStatus] = mapped_column( | |
| String(32), nullable=False, default=DocumentStatus.UPLOADED | |
| ) | |
| extracted_text: Mapped[str | None] = mapped_column(Text, nullable=True) | |
| # Set by the worker on the FAILED path so the UI can surface *why* a | |
| # document failed (e.g. "Video must be under 5 minutes"). Null on | |
| # success and on legacy FAILED rows from before this column existed. | |
| error_message: Mapped[str | None] = mapped_column(Text, nullable=True) | |
| # Populated by the summarization agent; null when no summary has been | |
| # generated or stored yet. | |
| summary_tldr: Mapped[str | None] = mapped_column(Text, nullable=True) | |
| summary_key_points: Mapped[list[Any] | None] = mapped_column(JSONB, nullable=True) | |
| summary_topics: Mapped[list[Any] | None] = mapped_column(JSONB, nullable=True) | |
| created_at: Mapped[datetime] = mapped_column( | |
| DateTime(timezone=True), default=_utcnow, nullable=False | |
| ) | |
| updated_at: Mapped[datetime] = mapped_column( | |
| DateTime(timezone=True), | |
| default=_utcnow, | |
| onupdate=_utcnow, | |
| nullable=False, | |
| ) | |
| user: Mapped[User] = relationship(lazy="noload") | |
| def summary(self) -> dict[str, Any] | None: | |
| if not self.summary_tldr and not self.summary_key_points and not self.summary_topics: | |
| return None | |
| return { | |
| "tldr": self.summary_tldr or "", | |
| "key_points": list(self.summary_key_points or []), | |
| "topics": list(self.summary_topics or []), | |
| } | |