Rescue Paperjet v1 implementation

This commit is contained in:
Elijah 2026-08-14 21:05:22 -07:00
parent 7ff5c8130d
commit db9e2ca51b
83 changed files with 6186 additions and 3894 deletions

View file

@ -5,9 +5,9 @@ All models use UUIDv4 string primary keys (except the singleton settings row).
Timestamps are stored as ISO8601 TEXT columns.
"""
from app.models.settings import Settings
from app.models.document import Document
from app.models.annotation_state import AnnotationState
from app.models.document import Document
from app.models.settings import Settings
from app.models.version import Version
__all__ = ["Settings", "Document", "AnnotationState", "Version"]
__all__ = ["AnnotationState", "Document", "Settings", "Version"]

View file

@ -1,15 +1,19 @@
"""AnnotationState model — current working annotation layer per document."""
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import TYPE_CHECKING
from sqlalchemy import ForeignKey, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db import Base
if TYPE_CHECKING:
from app.models.document import Document
def _now_iso() -> str:
return datetime.now(timezone.utc).isoformat()
return datetime.now(UTC).isoformat()
class AnnotationState(Base):

View file

@ -1,20 +1,25 @@
"""Document model — uploaded PDFs with soft-delete support."""
import uuid
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import TYPE_CHECKING
from sqlalchemy import Index, Integer, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db import Base
if TYPE_CHECKING:
from app.models.annotation_state import AnnotationState
from app.models.version import Version
def _uuid() -> str:
return str(uuid.uuid4())
def _now_iso() -> str:
return datetime.now(timezone.utc).isoformat()
return datetime.now(UTC).isoformat()
class Document(Base):

View file

@ -1,6 +1,6 @@
"""Settings model — singleton row for app-wide configuration."""
from datetime import datetime, timezone
from datetime import UTC, datetime
from sqlalchemy import Integer, Text
from sqlalchemy.orm import Mapped, mapped_column
@ -22,10 +22,10 @@ class Settings(Base):
password_hash: Mapped[str | None] = mapped_column(Text, nullable=True, default=None)
created_at: Mapped[str] = mapped_column(
Text,
default=lambda: datetime.now(timezone.utc).isoformat(),
default=lambda: datetime.now(UTC).isoformat(),
)
updated_at: Mapped[str] = mapped_column(
Text,
default=lambda: datetime.now(timezone.utc).isoformat(),
onupdate=lambda: datetime.now(timezone.utc).isoformat(),
default=lambda: datetime.now(UTC).isoformat(),
onupdate=lambda: datetime.now(UTC).isoformat(),
)

View file

@ -1,20 +1,24 @@
"""Version model — annotation state snapshots for history/recovery."""
import uuid
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import TYPE_CHECKING
from sqlalchemy import ForeignKey, Index, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.db import Base
if TYPE_CHECKING:
from app.models.document import Document
def _uuid() -> str:
return str(uuid.uuid4())
def _now_iso() -> str:
return datetime.now(timezone.utc).isoformat()
return datetime.now(UTC).isoformat()
class Version(Base):
@ -40,6 +44,4 @@ class Version(Base):
# Relationships
document: Mapped["Document"] = relationship("Document", back_populates="versions")
__table_args__ = (
Index("ix_versions_document_created", "document_id", "created_at"),
)
__table_args__ = (Index("ix_versions_document_created", "document_id", "created_at"),)