from fastapi import APIRouter, HTTPException, Query, Request, status as http_status from app.models import StrategyStartRequest from app.services.strategy_service import ( start_strategy, resume_strategy, stop_strategy, get_strategy_status, get_strategy_summary, get_engine_status, get_market_status, get_strategy_logs as fetch_strategy_logs, ) from app.services.tenant import get_request_user_id router = APIRouter(prefix="/api") def _raise_strategy_error(payload: dict, *, default_status: int) -> None: message = payload.get("message") or payload.get("detail") or "Strategy operation failed" raise HTTPException( status_code=default_status, detail={ "status": payload.get("status", "error"), "message": message, "run_id": payload.get("run_id"), "redirect_url": payload.get("redirect_url"), "broker": payload.get("broker"), }, ) @router.post("/strategy/start") def start(req: StrategyStartRequest, request: Request): user_id = get_request_user_id(request) return start_strategy(req, user_id) @router.post("/strategy/stop") def stop(request: Request): try: user_id = get_request_user_id(request) result = stop_strategy(user_id) if result.get("status") not in {"stopped", "already_stopped"}: _raise_strategy_error(result, default_status=http_status.HTTP_409_CONFLICT) return result except HTTPException: raise except Exception as exc: print(f"[STRATEGY] unhandled stop route failure: {exc}", flush=True) raise HTTPException( status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"status": "stop_failed", "message": f"Unable to stop strategy: {exc}"}, ) from exc @router.post("/strategy/resume") def resume(request: Request): try: user_id = get_request_user_id(request) result = resume_strategy(user_id) success_statuses = {"resumed", "already_running"} if result.get("status") == "broker_auth_required": _raise_strategy_error(result, default_status=http_status.HTTP_401_UNAUTHORIZED) if result.get("status") not in success_statuses: _raise_strategy_error(result, default_status=http_status.HTTP_409_CONFLICT) return result except HTTPException: raise except Exception as exc: print(f"[STRATEGY] unhandled resume route failure: {exc}", flush=True) raise HTTPException( status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR, detail={"status": "resume_failed", "message": f"Unable to resume strategy: {exc}"}, ) from exc @router.get("/strategy/status") def status(request: Request): user_id = get_request_user_id(request) return get_strategy_status(user_id) @router.get("/strategy/summary") def summary(request: Request): user_id = get_request_user_id(request) return get_strategy_summary(user_id) @router.get("/engine/status") def engine_status(request: Request): user_id = get_request_user_id(request) return get_engine_status(user_id) @router.get("/market/status") def market_status(): return get_market_status() @router.get("/logs") def get_logs(request: Request, since_seq: int = Query(0)): user_id = get_request_user_id(request) return fetch_strategy_logs(user_id, since_seq) @router.get("/strategy/logs") def get_strategy_logs_endpoint(request: Request, since_seq: int = Query(0)): user_id = get_request_user_id(request) return fetch_strategy_logs(user_id, since_seq)