from uuid import UUID from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from app.api.schemas import ( CriterionDefinitionIn, CriterionMappingIn, CriterionMappingPatch, DiscoverySearchIn, DiscoverySearchPatch, SourceAttributeMappingIn, SourceAttributeMappingPatch, ) from app.persistence.db import get_session from app.services.catalog_service import CatalogService from app.services.discovery_service import ( CriterionDefinitionService, CriterionMappingService, DiscoverySearchService, SourceAttributeMappingService, TaxonomyService, ) router = APIRouter(prefix="/api/v1") @router.get("/sources/{source_id}/categories") def list_source_categories(source_id: str, session: Session = Depends(get_session)): return {"items": CatalogService(session).source_categories(source_id)} @router.post("/sources/{source_id}/categories/{category}/discover-taxonomy", status_code=201) def discover_taxonomy(source_id: str, category: str, session: Session = Depends(get_session)): return TaxonomyService(session).discover(source_id, category) @router.get("/sources/{source_id}/categories/{category}/taxonomy-status") def taxonomy_status(source_id: str, category: str, session: Session = Depends(get_session)): return TaxonomyService(session).taxonomy_status(source_id, category) @router.get("/sources/{source_id}/categories/{category}/filters") def list_filters(source_id: str, category: str, session: Session = Depends(get_session)): return TaxonomyService(session).filters(source_id, category) @router.post("/criterion-definitions", status_code=201) def create_criterion_definition(payload: CriterionDefinitionIn, session: Session = Depends(get_session)): return CriterionDefinitionService(session).create(payload.model_dump()) @router.get("/criterion-definitions") def list_criterion_definitions(category: str | None = None, session: Session = Depends(get_session)): return {"items": CriterionDefinitionService(session).list(category)} @router.get("/criterion-mappings") def list_mappings(source_category_id: UUID | None = None, session: Session = Depends(get_session)): return {"items": CriterionMappingService(session).list(source_category_id)} @router.post("/criterion-mappings", status_code=201) def create_mapping(payload: CriterionMappingIn, session: Session = Depends(get_session)): return CriterionMappingService(session).create(payload.model_dump()) @router.patch("/criterion-mappings/{mapping_id}") def patch_mapping(mapping_id: UUID, payload: CriterionMappingPatch, session: Session = Depends(get_session)): return CriterionMappingService(session).patch(mapping_id, payload.model_dump(exclude_unset=True)) @router.get("/source-attribute-mappings") def list_attribute_mappings(session: Session = Depends(get_session)): return {"items": SourceAttributeMappingService(session).list()} @router.post("/source-attribute-mappings", status_code=201) def create_attribute_mapping(payload: SourceAttributeMappingIn, session: Session = Depends(get_session)): return SourceAttributeMappingService(session).create(payload.model_dump()) @router.patch("/source-attribute-mappings/{mapping_id}") def patch_attribute_mapping( mapping_id: UUID, payload: SourceAttributeMappingPatch, session: Session = Depends(get_session), ): return SourceAttributeMappingService(session).patch(mapping_id, payload.model_dump(exclude_unset=True)) @router.post("/discovery-searches", status_code=201) def create_search(payload: DiscoverySearchIn, session: Session = Depends(get_session)): return DiscoverySearchService(session).create(payload.model_dump()) @router.get("/discovery-searches") def list_searches(due: bool = Query(default=False), session: Session = Depends(get_session)): service = DiscoverySearchService(session) return {"items": service.list_due() if due else service.list_all()} @router.get("/discovery-searches/{search_id}") def get_search(search_id: UUID, session: Session = Depends(get_session)): return DiscoverySearchService(session).get(search_id) @router.patch("/discovery-searches/{search_id}") def patch_search(search_id: UUID, payload: DiscoverySearchPatch, session: Session = Depends(get_session)): return DiscoverySearchService(session).patch(search_id, payload.model_dump(exclude_unset=True)) @router.post("/discovery-searches/{search_id}/generate-query") def generate_query(search_id: UUID, session: Session = Depends(get_session)): return DiscoverySearchService(session).generate_query(search_id) @router.post("/discovery-searches/{search_id}/run", status_code=201) def run_search(search_id: UUID, session: Session = Depends(get_session)): return DiscoverySearchService(session).run(search_id) @router.get("/discovery-searches/{search_id}/runs") def list_runs(search_id: UUID, session: Session = Depends(get_session)): return {"items": DiscoverySearchService(session).list_runs(search_id)} @router.get("/search-runs/{run_id}") def get_run(run_id: UUID, session: Session = Depends(get_session)): return DiscoverySearchService(session).get_run(run_id)