from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import text from sqlalchemy.orm import Session from core_domain import ServiceHealth from app.application.services import ToolApplicationService from app.db.session import get_db from app.domain.repositories import ToolBindingRepository, ToolDefinitionRepository, ToolVersionRepository from app.schemas.tool import ( ToolBindingCreateRequest, ToolBindingDetailResponse, ToolBindingResponse, ToolCreateRequest, ToolResponse, ToolVersionCreateRequest, ToolVersionResponse, ) router = APIRouter() def get_tool_application_service(db: Session = Depends(get_db)) -> ToolApplicationService: return ToolApplicationService( tool_definition_repository=ToolDefinitionRepository(db), tool_version_repository=ToolVersionRepository(db), tool_binding_repository=ToolBindingRepository(db), ) @router.get("/health", response_model=ServiceHealth) def health_check(db: Session = Depends(get_db)) -> ServiceHealth: db.execute(text("SELECT 1")) return ServiceHealth(service="tool-service", status="ok", database="ok") @router.post("", response_model=ToolResponse) def create_tool_definition( payload: ToolCreateRequest, service: ToolApplicationService = Depends(get_tool_application_service), ) -> ToolResponse: entity = service.create_tool_definition(payload) return ToolResponse.from_entity(entity) @router.get("", response_model=list[ToolResponse]) def list_tool_definitions( tenant_id: str = Query(...), service: ToolApplicationService = Depends(get_tool_application_service), ) -> list[ToolResponse]: return [ToolResponse.from_entity(item) for item in service.list_tool_definitions(tenant_id)] @router.post("/versions", response_model=ToolVersionResponse) def create_tool_version( payload: ToolVersionCreateRequest, service: ToolApplicationService = Depends(get_tool_application_service), ) -> ToolVersionResponse: entity = service.create_tool_version(payload) return ToolVersionResponse.from_entity(entity) @router.get("/versions", response_model=list[ToolVersionResponse]) def list_tool_versions( tenant_id: str = Query(...), tool_id: str = Query(...), service: ToolApplicationService = Depends(get_tool_application_service), ) -> list[ToolVersionResponse]: return [ ToolVersionResponse.from_entity(item) for item in service.list_tool_versions(tenant_id=tenant_id, tool_id=tool_id) ] @router.post("/bindings", response_model=ToolBindingResponse) def create_tool_binding( payload: ToolBindingCreateRequest, service: ToolApplicationService = Depends(get_tool_application_service), ) -> ToolBindingResponse: entity = service.create_tool_binding(payload) return ToolBindingResponse.from_entity(entity) @router.get("/bindings", response_model=list[ToolBindingResponse]) def list_tool_bindings( tenant_id: str = Query(...), app_id: str | None = Query(default=None), service: ToolApplicationService = Depends(get_tool_application_service), ) -> list[ToolBindingResponse]: return [ ToolBindingResponse.from_entity(item) for item in service.list_tool_bindings(tenant_id=tenant_id, app_id=app_id) ] @router.get("/bindings/{binding_id}", response_model=ToolBindingDetailResponse) def get_tool_binding_detail( binding_id: str, tenant_id: str = Query(...), service: ToolApplicationService = Depends(get_tool_application_service), ) -> ToolBindingDetailResponse: result = service.get_tool_binding_detail(tenant_id=tenant_id, binding_id=binding_id) if result is None: raise HTTPException(status_code=404, detail=f"tool_binding not found: {binding_id}") binding, tool_version, tool_definition = result return ToolBindingDetailResponse( binding=ToolBindingResponse.from_entity(binding), tool_version=ToolVersionResponse.from_entity(tool_version), tool_definition=ToolResponse.from_entity(tool_definition), )