""" Modell-Radar-Schnittstellen (Box-Wart, Umbau 09/2026). GET /api/radar Nächster und letzter Test, Kandidaten, Test-Verlauf POST /api/radar/suche Jetzt suchen (Merkliste + Hugging-Face-Entdeckung) — als Auftrag, antwortet sofort POST /api/radar/{id}/uebernehmen Bestandenen Kandidaten in Betrieb nehmen (Modell-Tausch) POST /api/radar/{id}/verwerfen Kandidaten verwerfen (Dateien weg, nie wieder testen) POST /api/radar/{id}/testen Jetzt testen (seit 25.09.2026; nur wenn er samt Coder in den Speicher passt) Dünn: die Logik liegt in services/radar.py. Getestet wird nachts (backend/radar_lauf.py) oder auf Knopfdruck. """ from fastapi import APIRouter, HTTPException from services import radar router = APIRouter(prefix="/api", tags=["radar"]) def _antwort(ergebnis: dict) -> dict: if not ergebnis.get("ok"): raise HTTPException(status_code=int(ergebnis.get("status") or 409), detail=ergebnis.get("detail") or "Das ging nicht.") return ergebnis @router.get("/radar") def radar_stand() -> dict: return radar.uebersicht() @router.post("/radar/suche") def radar_suche() -> dict: """Startet die Suche als Auftrag (sie kann Minuten dauern) und antwortet sofort mit der Auftrags-ID.""" return radar.suche_starten() @router.post("/radar/{kandidat_id}/uebernehmen") def radar_uebernehmen(kandidat_id: str) -> dict: return _antwort(radar.uebernehmen(kandidat_id)) @router.post("/radar/{kandidat_id}/testen") def radar_testen(kandidat_id: str) -> dict: """„Jetzt testen“ (seit 25.09.2026): nur, wenn der Kandidat samt Coder neben das Warm-Set passt und nicht in der Nacht-Sperre — sonst 409 mit Grund. Antwortet sofort mit der Auftrags-ID.""" return _antwort(radar.test_starten(kandidat_id)) @router.post("/radar/{kandidat_id}/verwerfen") def radar_verwerfen(kandidat_id: str) -> dict: return _antwort(radar.verwerfen(kandidat_id))