"""ORM model for download jobs (plan §6.1). Tracks a queued download through its lifecycle. ``retry_count`` supports the exponential-backoff retries that yt-dlp needs; ``progress`` drives the UI download manager. """ import uuid from sqlalchemy import Float, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column from app.infrastructure.db.base import Base from app.infrastructure.db.models.enums import DownloadStatus from app.infrastructure.db.models.mixins import TimestampMixin, UUIDPrimaryKeyMixin class DownloadJobModel(UUIDPrimaryKeyMixin, TimestampMixin, Base): __tablename__ = "download_jobs" source: Mapped[str] = mapped_column(String(32), nullable=False) source_id: Mapped[str | None] = mapped_column(String(512), nullable=True) query: Mapped[str | None] = mapped_column(String(1024), nullable=True) requested_by: Mapped[uuid.UUID | None] = mapped_column( ForeignKey("users.id", ondelete="SET NULL"), index=True, nullable=True, ) status: Mapped[str] = mapped_column( String(16), index=True, nullable=False, default=DownloadStatus.QUEUED.value, ) progress: Mapped[float] = mapped_column(Float, nullable=False, default=0.0) error_message: Mapped[str | None] = mapped_column(Text, nullable=True) retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) # Set once the download finishes and the track is imported — lets the UI # link a completed job to its library track. track_id: Mapped[uuid.UUID | None] = mapped_column( ForeignKey("tracks.id", ondelete="SET NULL"), nullable=True, )