Files
content-factory/apps/backend/src/presentation/routes/plans.py
T

181 lines
5.8 KiB
Python

from __future__ import annotations
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, status
from src.application.plans import (
approve_plan,
edit_plan,
generate_plan,
get_plan,
list_plans,
request_plan_revision,
)
from src.application.research import list_research_runs, start_research_run
from src.domain.auth import EDITOR_OR_ADMIN_ROLES
from src.domain.contracts import (
CurrentUser,
PlanListResponse,
PlanResponse,
PlanRevisionRequest,
PlanUpdateRequest,
ResearchListResponse,
ResearchStartResponse,
ReviewActionResponse,
)
from src.infrastructure.object_storage import open_object_storage_client
from src.infrastructure.repositories import BackendRepository
from src.presentation.dependencies import get_repository, require_roles
router = APIRouter(prefix="/api", tags=["plans"])
@router.post(
"/articles/{article_id}/plan/generate",
response_model=PlanResponse,
status_code=status.HTTP_201_CREATED,
)
def post_generate_plan(
article_id: UUID,
current_user: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> PlanResponse:
try:
return generate_plan(repository, article_id=article_id, current_user=current_user)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
except PermissionError as error:
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(error)) from error
@router.get("/articles/{article_id}/plans", response_model=PlanListResponse)
def get_plans(
article_id: UUID,
_: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> PlanListResponse:
try:
return list_plans(repository, article_id=article_id)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
@router.get("/articles/{article_id}/plans/{plan_id}", response_model=PlanResponse)
def get_plan_route(
article_id: UUID,
plan_id: UUID,
_: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> PlanResponse:
try:
return get_plan(repository, article_id=article_id, plan_id=plan_id)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
@router.patch(
"/articles/{article_id}/plans/{plan_id}",
response_model=PlanResponse,
status_code=status.HTTP_201_CREATED,
)
def patch_plan(
article_id: UUID,
plan_id: UUID,
request: PlanUpdateRequest,
current_user: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> PlanResponse:
try:
return edit_plan(
repository,
article_id=article_id,
plan_id=plan_id,
request=request,
current_user=current_user,
)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
@router.post(
"/articles/{article_id}/plans/{plan_id}/approve",
response_model=ReviewActionResponse,
)
def post_approve_plan(
article_id: UUID,
plan_id: UUID,
current_user: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> ReviewActionResponse:
try:
return approve_plan(
repository,
article_id=article_id,
plan_id=plan_id,
current_user=current_user,
)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
@router.post(
"/articles/{article_id}/plans/{plan_id}/request-revision",
response_model=ReviewActionResponse,
)
def post_request_plan_revision(
article_id: UUID,
plan_id: UUID,
request: PlanRevisionRequest,
current_user: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> ReviewActionResponse:
try:
return request_plan_revision(
repository,
article_id=article_id,
plan_id=plan_id,
request=request,
current_user=current_user,
)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
@router.post(
"/articles/{article_id}/research/start",
response_model=ResearchStartResponse,
status_code=status.HTTP_201_CREATED,
)
def post_start_research(
article_id: UUID,
_: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> ResearchStartResponse:
try:
return start_research_run(
repository,
article_id=article_id,
object_storage=open_object_storage_client(),
)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error
except PermissionError as error:
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(error)) from error
@router.get(
"/articles/{article_id}/research",
response_model=ResearchListResponse,
)
def get_research(
article_id: UUID,
_: CurrentUser = Depends(require_roles(EDITOR_OR_ADMIN_ROLES)),
repository: BackendRepository = Depends(get_repository),
) -> ResearchListResponse:
try:
return list_research_runs(repository, article_id=article_id)
except LookupError as error:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not Found") from error