"""Version model — annotation state snapshots for history/recovery.""" import uuid from datetime import datetime, timezone from sqlalchemy import ForeignKey, Index, 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 Version(Base): """ A snapshot of a document's annotation state at a point in time. Versions serve as a safety net for accidental annotation loss. `kind` is either 'manual' (user-created) or 'auto' (system-created at safety boundaries like document close or before destructive ops). """ __tablename__ = "versions" id: Mapped[str] = mapped_column(Text, primary_key=True, default=_uuid) document_id: Mapped[str] = mapped_column( Text, ForeignKey("documents.id", ondelete="CASCADE"), nullable=False ) label: Mapped[str | None] = mapped_column(Text, nullable=True, default=None) data: Mapped[str] = mapped_column(Text, nullable=False) # JSON snapshot kind: Mapped[str] = mapped_column(Text, nullable=False) # 'manual' | 'auto' created_at: Mapped[str] = mapped_column(Text, default=_now_iso) # Relationships document: Mapped["Document"] = relationship("Document", back_populates="versions") __table_args__ = ( Index("ix_versions_document_created", "document_id", "created_at"), )