97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
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)
|