from fastapi import APIRouter, HTTPException from pydantic import BaseModel from typing import Optional from services.database import get_cycle_runs, get_cycle_run, set_config, get_config from services.auto_cycle import get_status, trigger_manual, restart_scheduler router = APIRouter(prefix="/api/cycle", tags=["cycle"]) @router.get("/status") def cycle_status(): """Current scheduler state + last cycle summary.""" return get_status() @router.get("/history") def cycle_history(limit: int = 20): """List recent cycle runs.""" runs = get_cycle_runs(limit=limit) # Parse commentary JSON for frontend import json for r in runs: if r.get("commentary"): try: r["commentary_parsed"] = json.loads(r["commentary"]) except Exception: r["commentary_parsed"] = {"commentary": r["commentary"]} return {"runs": runs, "count": len(runs)} @router.post("/trigger") def trigger_cycle(): """Manually trigger one cycle immediately (non-blocking).""" key = get_config("openai_api_key") or "" if not key: raise HTTPException(400, "Clé OpenAI non configurée") trigger_manual() return {"triggered": True, "message": "Cycle lancé en arrière-plan"} class CycleConfigRequest(BaseModel): enabled: Optional[bool] = None interval_hours: Optional[float] = None similarity_threshold: Optional[float] = None min_ev_threshold: Optional[float] = None min_score_threshold: Optional[int] = None @router.post("/config") def update_cycle_config(req: CycleConfigRequest): """Update auto-cycle + filter configuration and restart scheduler.""" if req.enabled is not None: set_config("auto_cycle_enabled", "true" if req.enabled else "false") if req.interval_hours is not None: if not (0.5 <= req.interval_hours <= 24): raise HTTPException(400, "interval_hours must be between 0.5 and 24") set_config("auto_cycle_hours", str(req.interval_hours)) if req.similarity_threshold is not None: if not (0.0 <= req.similarity_threshold <= 1.0): raise HTTPException(400, "similarity_threshold must be between 0 and 1") set_config("auto_cycle_similarity_threshold", str(req.similarity_threshold)) if req.min_ev_threshold is not None: if not (0.0 <= req.min_ev_threshold <= 1.0): raise HTTPException(400, "min_ev_threshold must be between 0 and 1") set_config("min_ev_threshold", str(req.min_ev_threshold)) if req.min_score_threshold is not None: if not (0 <= req.min_score_threshold <= 100): raise HTTPException(400, "min_score_threshold must be between 0 and 100") set_config("min_score_threshold", str(req.min_score_threshold)) # Restart scheduler to pick up changes restart_scheduler() return get_status()