BuyingAgent/backend/app/api/discovery.py
Lars d784248e28
Some checks failed
Deploy Development / deploy (push) Successful in 55s
Test Suite / pytest-backend (push) Failing after 30s
Test Suite / smoke-dev (push) Successful in 0s
Test Suite / frontend-checks (push) Successful in 26s
Schliesse das Notebook-Source-Mapping, damit Wizard und Taxonomie ohne leere Kategorie starten.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 14:17:56 +02:00

131 lines
5.0 KiB
Python

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)