Files
main_backend/cpv3/modules/jobs/router.py
T
2026-03-17 18:11:23 +03:00

175 lines
5.8 KiB
Python

from __future__ import annotations
import uuid
from fastapi import APIRouter, Depends, HTTPException, Response, status
from sqlalchemy.ext.asyncio import AsyncSession
from cpv3.infrastructure.auth import get_current_user
from cpv3.db.session import get_db
from cpv3.modules.jobs.schemas import (
JobCreate,
JobEventCreate,
JobEventRead,
JobEventUpdate,
JobRead,
JobUpdate,
)
from cpv3.modules.jobs.service import JobService
from cpv3.modules.tasks.service import TaskService
from cpv3.modules.users.models import User
jobs_router = APIRouter(prefix="/api/jobs", tags=["jobs"])
events_router = APIRouter(prefix="/api/jobs", tags=["events"])
@jobs_router.get("/jobs/", response_model=list[JobRead])
async def list_jobs_endpoint(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> list[JobRead]:
service = JobService(db)
jobs = await service.list_jobs(requester=current_user)
return [JobRead.model_validate(j) for j in jobs]
@jobs_router.post("/jobs/", response_model=JobRead, status_code=status.HTTP_201_CREATED)
async def create_job_endpoint(
body: JobCreate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> JobRead:
service = JobService(db)
job = await service.create_job(requester=current_user, data=body)
return JobRead.model_validate(job)
@jobs_router.get("/jobs/{job_id}/", response_model=JobRead)
async def retrieve_job_endpoint(
job_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> JobRead:
service = JobService(db)
job = await service.get_job(job_id)
if job is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
if not current_user.is_staff and job.user_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")
return JobRead.model_validate(job)
@jobs_router.patch("/jobs/{job_id}/", response_model=JobRead)
async def patch_job_endpoint(
job_id: uuid.UUID,
body: JobUpdate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> JobRead:
service = JobService(db)
job = await service.get_job(job_id)
if job is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
if not current_user.is_staff and job.user_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")
if body.status == "CANCELLED":
task_service = TaskService(db)
job = await task_service.cancel_job(job)
return JobRead.model_validate(job)
job = await service.update_job(job, body)
return JobRead.model_validate(job)
@jobs_router.delete("/jobs/{job_id}/", status_code=status.HTTP_204_NO_CONTENT)
async def delete_job_endpoint(
job_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> Response:
service = JobService(db)
job = await service.get_job(job_id)
if job is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
if not current_user.is_staff and job.user_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")
await service.deactivate_job(job)
return Response(status_code=status.HTTP_204_NO_CONTENT)
@events_router.get("/events/", response_model=list[JobEventRead])
async def list_events_endpoint(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> list[JobEventRead]:
_ = current_user
service = JobService(db)
events = await service.list_job_events()
return [JobEventRead.model_validate(e) for e in events]
@events_router.post("/events/", response_model=JobEventRead, status_code=status.HTTP_201_CREATED)
async def create_event_endpoint(
body: JobEventCreate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> JobEventRead:
_ = current_user
service = JobService(db)
event = await service.create_job_event(body)
return JobEventRead.model_validate(event)
@events_router.get("/events/{event_id}/", response_model=JobEventRead)
async def retrieve_event_endpoint(
event_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> JobEventRead:
_ = current_user
service = JobService(db)
event = await service.get_job_event(event_id)
if event is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
return JobEventRead.model_validate(event)
@events_router.patch("/events/{event_id}/", response_model=JobEventRead)
async def patch_event_endpoint(
event_id: uuid.UUID,
body: JobEventUpdate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> JobEventRead:
_ = current_user
service = JobService(db)
event = await service.get_job_event(event_id)
if event is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
event = await service.update_job_event(event, body)
return JobEventRead.model_validate(event)
@events_router.delete("/events/{event_id}/", status_code=status.HTTP_204_NO_CONTENT)
async def delete_event_endpoint(
event_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> Response:
_ = current_user
service = JobService(db)
event = await service.get_job_event(event_id)
if event is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
await service.deactivate_job_event(event)
return Response(status_code=status.HTTP_204_NO_CONTENT)