126 lines
4.8 KiB
Python
126 lines
4.8 KiB
Python
|
|
from uuid import UUID
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends, Query
|
||
|
|
from sqlalchemy.orm import Session
|
||
|
|
|
||
|
|
from app.api.schemas import (
|
||
|
|
BuyingProjectIn,
|
||
|
|
BuyingProjectPatch,
|
||
|
|
DiscoverySearchIn,
|
||
|
|
ProjectCriteriaIn,
|
||
|
|
page,
|
||
|
|
parse_page,
|
||
|
|
)
|
||
|
|
from app.persistence.db import get_session
|
||
|
|
from app.services.catalog_service import CatalogService
|
||
|
|
from app.services.discovery_service import CandidateRankingService, DiscoverySearchService
|
||
|
|
from app.services.project_service import ProjectService
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/api/v1")
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/product-categories")
|
||
|
|
def list_product_categories(session: Session = Depends(get_session)):
|
||
|
|
return {"items": CatalogService(session).list_product_categories()}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/product-categories/{product_category_id}/sources")
|
||
|
|
def list_category_sources(product_category_id: str, session: Session = Depends(get_session)):
|
||
|
|
return {"items": CatalogService(session).sources_for_category(product_category_id)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/product-categories/{product_category_id}/available-criteria")
|
||
|
|
def available_criteria_for_category(
|
||
|
|
product_category_id: str,
|
||
|
|
source: str = Query(...),
|
||
|
|
session: Session = Depends(get_session),
|
||
|
|
):
|
||
|
|
return CatalogService(session).available_criteria(product_category_id, source)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-templates")
|
||
|
|
def list_buying_templates(session: Session = Depends(get_session)):
|
||
|
|
return {"items": CatalogService(session).list_templates()}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/buying-projects", status_code=201)
|
||
|
|
def create_buying_project(payload: BuyingProjectIn, session: Session = Depends(get_session)):
|
||
|
|
return ProjectService(session).create(payload.model_dump())
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects")
|
||
|
|
def list_buying_projects(limit: int = 50, offset: int = 0, session: Session = Depends(get_session)):
|
||
|
|
limit, offset = parse_page(limit, offset)
|
||
|
|
items, total = ProjectService(session).list(limit, offset)
|
||
|
|
return page(items, limit, offset, total)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}")
|
||
|
|
def get_buying_project(project_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return ProjectService(session).get(project_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.patch("/buying-projects/{project_id}")
|
||
|
|
def patch_buying_project(project_id: UUID, payload: BuyingProjectPatch, session: Session = Depends(get_session)):
|
||
|
|
return ProjectService(session).patch(project_id, payload.model_dump(exclude_unset=True))
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/buying-projects/{project_id}/criteria", status_code=201)
|
||
|
|
def add_buying_project_criteria(
|
||
|
|
project_id: UUID,
|
||
|
|
payload: ProjectCriteriaIn,
|
||
|
|
session: Session = Depends(get_session),
|
||
|
|
):
|
||
|
|
return ProjectService(session).replace_criteria(project_id, payload.model_dump())
|
||
|
|
|
||
|
|
|
||
|
|
@router.put("/buying-projects/{project_id}/criteria")
|
||
|
|
def put_buying_project_criteria(
|
||
|
|
project_id: UUID,
|
||
|
|
payload: ProjectCriteriaIn,
|
||
|
|
session: Session = Depends(get_session),
|
||
|
|
):
|
||
|
|
return ProjectService(session).replace_criteria(project_id, payload.model_dump())
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/criteria")
|
||
|
|
def get_buying_project_criteria(project_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return ProjectService(session).get_criteria(project_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/available-criteria")
|
||
|
|
def available_criteria(project_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return ProjectService(session).available_criteria(project_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/discovery-searches")
|
||
|
|
def list_project_searches(project_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return {"items": DiscoverySearchService(session).list_for_project(project_id)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/buying-projects/{project_id}/discovery-searches", status_code=201)
|
||
|
|
def create_project_search(project_id: UUID, payload: DiscoverySearchIn, session: Session = Depends(get_session)):
|
||
|
|
body = payload.model_dump()
|
||
|
|
body["buying_project_id"] = project_id
|
||
|
|
return DiscoverySearchService(session).create(body)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/candidates")
|
||
|
|
def list_candidates(project_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return {"items": CandidateRankingService(session).list_candidates(project_id)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/candidates/{candidate_id}")
|
||
|
|
def get_candidate(project_id: UUID, candidate_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return CandidateRankingService(session).get_candidate(project_id, candidate_id)
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/candidates/{candidate_id}/observations")
|
||
|
|
def list_candidate_observations(project_id: UUID, candidate_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return {"items": CandidateRankingService(session).list_observations(project_id, candidate_id)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/buying-projects/{project_id}/shortlist")
|
||
|
|
def list_shortlist(project_id: UUID, session: Session = Depends(get_session)):
|
||
|
|
return {"items": CandidateRankingService(session).list_candidates(project_id, shortlisted_only=True)}
|