from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Path, Query, Request from backend.data.gateway import MarketDataUnavailable from backend.data.providers.base import ProviderError from backend.features.accounts.auth import ( AdminPrincipal, AdminWritePrincipal, AuthenticatedPrincipal, ) from backend.features.market.events import MarketEventError from backend.features.operations.schemas import ( BackfillInput, EventRevisionInput, JobRunResponse, OperationResult, RuntimeStatusResponse, ) from backend.features.operations.service import OperationsError from backend.http.errors import AppError router = APIRouter(tags=["operations"]) @router.get("/operations/status", response_model=RuntimeStatusResponse) def public_status(request: Request, _principal: AuthenticatedPrincipal) -> dict: return request.app.state.container.operations.public_status() @router.get("/admin/operations/jobs", response_model=list[JobRunResponse]) def jobs(request: Request, _principal: AdminPrincipal) -> list[dict]: return request.app.state.container.operations.jobs() @router.post("/admin/operations/backfill", response_model=OperationResult) def backfill( payload: BackfillInput, request: Request, _principal: AdminWritePrincipal ) -> dict: try: return request.app.state.container.operations.backfill( payload.start_date.isoformat(), payload.end_date.isoformat() ) except OperationsError as exc: raise AppError("invalid_operation", str(exc), 400) from exc @router.post("/admin/operations/events/supplement", response_model=OperationResult) def supplement_events( request: Request, _principal: AdminWritePrincipal, trade_date: Annotated[str, Query(alias="date")], ) -> dict: try: return request.app.state.container.operations.supplement_events(trade_date) except (OperationsError, MarketEventError) as exc: raise AppError("invalid_operation", str(exc), 400) from exc except (MarketDataUnavailable, ProviderError) as exc: raise AppError("event_service_unavailable", str(exc), 503) from exc @router.put( "/admin/operations/events/{trade_date}/{identifier}", response_model=OperationResult, ) def revise_event( payload: EventRevisionInput, request: Request, principal: AdminWritePrincipal, trade_date: Annotated[str, Path()], identifier: Annotated[str, Path(min_length=1, max_length=20)], ) -> dict: try: return request.app.state.container.operations.revise_event( principal.user.id, trade_date=trade_date, identifier=identifier, **payload.model_dump(), ) except (OperationsError, MarketEventError) as exc: raise AppError("invalid_event_revision", str(exc), 400) from exc @router.get( "/admin/operations/events/{trade_date}/{identifier}/history", response_model=list[OperationResult], ) def event_history( request: Request, _principal: AdminPrincipal, trade_date: Annotated[str, Path()], identifier: Annotated[str, Path(min_length=1, max_length=20)], ) -> list[dict]: return request.app.state.container.operations.event_history(trade_date, identifier)