"""Download job endpoints (§A5). Heavy work is dispatched to arq workers — these handlers only create/inspect/cancel/retry job records.""" import uuid from fastapi import APIRouter, Query, Response from app.api.deps import CurrentUser, DownloadServiceDep from app.api.schemas.download import DownloadCreate, DownloadCreateResponse, DownloadJobOut from app.api.schemas.pagination import PagedResponse router = APIRouter(prefix="/downloads", tags=["downloads"]) @router.get("") async def list_downloads( service: DownloadServiceDep, user: CurrentUser, status: str | None = Query(default=None), mine: bool = Query(default=False), limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0), ) -> PagedResponse[DownloadJobOut]: jobs, total = await service.list( requested_by=user.id if mine else None, status=status, limit=limit, offset=offset, ) return PagedResponse( items=[DownloadJobOut.from_entity(j) for j in jobs], total=total, limit=limit, offset=offset, ) @router.post("", status_code=202) async def create_download( body: DownloadCreate, service: DownloadServiceDep, user: CurrentUser, ) -> DownloadCreateResponse: result = await service.request( source=body.source, source_id=body.source_id, query=body.query, requested_by=user.id, ) return DownloadCreateResponse( already_in_library=result.already_in_library, track_id=result.track_id, job=DownloadJobOut.from_entity(result.job) if result.job is not None else None, ) @router.get("/{job_id}") async def get_download( job_id: uuid.UUID, service: DownloadServiceDep, _: CurrentUser ) -> DownloadJobOut: job = await service.get(job_id) return DownloadJobOut.from_entity(job) @router.delete("/{job_id}", status_code=204) async def cancel_download( job_id: uuid.UUID, service: DownloadServiceDep, _: CurrentUser ) -> Response: await service.cancel(job_id) return Response(status_code=204) @router.post("/{job_id}/retry") async def retry_download( job_id: uuid.UUID, service: DownloadServiceDep, _: CurrentUser ) -> DownloadJobOut: job = await service.retry(job_id) return DownloadJobOut.from_entity(job)