from __future__ import annotations from dataclasses import dataclass from enum import Enum from typing import Any class JobStatus(str, Enum): QUEUED = "queued" RUNNING = "running" PAUSE_REQUESTED = "pause_requested" PAUSED = "paused" COMPLETED = "completed" COMPLETED_WITH_ERRORS = "completed_with_errors" FAILED = "failed" CANCELED = "canceled" class StageStatus(str, Enum): PENDING = "pending" RUNNING = "running" PAUSE_REQUESTED = "pause_requested" PAUSED = "paused" COMPLETED = "completed" FAILED = "failed" SKIPPED = "skipped" class ItemStatus(str, Enum): PENDING = "pending" RUNNING = "running" SUCCEEDED = "succeeded" FAILED = "failed" INTERRUPTED = "interrupted" SKIPPED = "skipped" CANCELED = "canceled" @dataclass(frozen=True) class JobRun: id: int job_type: str status: JobStatus priority: int requested_by: str | None config_snapshot: dict[str, Any] sources: list[str] download_sources: list[str] playlist_scope: dict[str, Any] created_at: str | None started_at: str | None ended_at: str | None last_error: str | None resume_token: str | None @dataclass(frozen=True) class JobStage: id: int job_run_id: int stage_type: str seq_no: int status: StageStatus total_items: int pending_items: int running_items: int success_items: int failed_items: int skipped_items: int started_at: str | None ended_at: str | None last_error: str | None @dataclass(frozen=True) class JobItem: id: int job_stage_id: int item_type: str item_key: str playlist_pool_id: int | None playlist_id: int | None song_id: int | None file_location_id: int | None status: ItemStatus attempt_count: int max_attempts: int worker_id: int | None started_at: str | None ended_at: str | None last_error: str | None last_error_code: str | None payload: dict[str, Any]