""" API endpoints for the breakout signal monitor. GET /api/signal/status — current state (enabled, recent signals) POST /api/signal/toggle — flip the on/off switch (requires X-Ingest-Key) GET /api/signal/history — last N signals (fired regardless of enabled state) """ from fastapi import APIRouter, Header, HTTPException from typing import Optional from app.config import settings from app.services.funding_signal import ( set_enabled, is_enabled, get_recent_signals, get_status, ) router = APIRouter(prefix="/signal", tags=["signal"]) def _require_ingest_key(x_ingest_key: Optional[str]) -> None: """Fail-closed operator-only guard (same pattern as signals.py).""" expected = settings.ingest_api_key if not expected: raise HTTPException(503, "toggle disabled (INGEST_API_KEY not configured)") if not x_ingest_key: raise HTTPException(401, "missing X-Ingest-Key header") if x_ingest_key != expected: raise HTTPException(401, "invalid X-Ingest-Key") @router.get("/status") async def status(): return get_status() @router.post("/toggle") async def toggle(enabled: bool, x_ingest_key: Optional[str] = Header(default=None)): """ Operator-only toggle — requires X-Ingest-Key header (same secret as signal ingest). Example: POST /api/signal/toggle?enabled=true -H 'X-Ingest-Key: …' """ _require_ingest_key(x_ingest_key) set_enabled(enabled) return {"enabled": is_enabled()} @router.get("/history") async def history(limit: int = 20): return get_recent_signals(limit)