Paperjet/backend/app/models/document.py
Elijah eb8a302222
Some checks failed
Automated Container Build / build-and-push (push) Failing after 2s
CI / Backend (Python) (push) Failing after 9s
CI / Frontend (TypeScript) (push) Failing after 4m46s
Fix bugs, convert thumbnail to png, add context menu
2026-06-10 19:06:28 -07:00

70 lines
2.1 KiB
Python

"""Document model — uploaded PDFs with soft-delete support."""
import uuid
from datetime import datetime, timezone
from sqlalchemy import Index, Integer, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db import Base
def _uuid() -> str:
return str(uuid.uuid4())
def _now_iso() -> str:
return datetime.now(timezone.utc).isoformat()
class Document(Base):
"""
A single uploaded PDF document.
Supports soft deletion via `deleted_at` — when set, the document
is in the trash and can be restored or permanently purged.
"""
__tablename__ = "documents"
id: Mapped[str] = mapped_column(Text, primary_key=True, default=_uuid)
title: Mapped[str] = mapped_column(Text, nullable=False)
original_filename: Mapped[str] = mapped_column(Text, nullable=False)
file_path: Mapped[str] = mapped_column(Text, nullable=False)
thumbnail_path: Mapped[str | None] = mapped_column(Text, nullable=True, default=None)
size_bytes: Mapped[int] = mapped_column(Integer, nullable=False)
page_count: Mapped[int] = mapped_column(Integer, nullable=False)
created_at: Mapped[str] = mapped_column(Text, default=_now_iso)
updated_at: Mapped[str] = mapped_column(Text, default=_now_iso, onupdate=_now_iso)
deleted_at: Mapped[str | None] = mapped_column(Text, nullable=True, default=None)
@property
def in_trash(self) -> bool:
return self.deleted_at is not None
@property
def filename(self) -> str:
return self.original_filename
@property
def mime_type(self) -> str:
return "application/pdf"
# Relationships
annotation_state: Mapped["AnnotationState"] = relationship(
"AnnotationState",
back_populates="document",
uselist=False,
cascade="all, delete-orphan",
)
versions: Mapped[list["Version"]] = relationship(
"Version",
back_populates="document",
cascade="all, delete-orphan",
order_by="Version.created_at.desc()",
)
__table_args__ = (
Index("ix_documents_updated_at", "updated_at"),
Index("ix_documents_deleted_at", "deleted_at"),
)