diff --git a/drb-c2-core/app/routers/calls.py b/drb-c2-core/app/routers/calls.py index d815a14..9c5959d 100644 --- a/drb-c2-core/app/routers/calls.py +++ b/drb-c2-core/app/routers/calls.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, HTTPException, Query +from fastapi import APIRouter, BackgroundTasks, HTTPException, Query from typing import Optional from app.internal import firestore as fstore @@ -27,3 +27,27 @@ async def get_call(call_id: str): if not call: raise HTTPException(404, f"Call '{call_id}' not found.") return call + + +@router.post("/{call_id}/reprocess") +async def reprocess_call(call_id: str, background_tasks: BackgroundTasks): + """Re-run the full intelligence pipeline (transcription → extraction → correlation) for a call.""" + call = await fstore.doc_get("calls", call_id) + if not call: + raise HTTPException(404, f"Call '{call_id}' not found.") + + from app.routers.upload import _run_intelligence_pipeline, _public_url_to_gcs_uri + + audio_url = call.get("audio_url") + gcs_uri = _public_url_to_gcs_uri(audio_url) if audio_url else None + + background_tasks.add_task( + _run_intelligence_pipeline, + call_id=call_id, + node_id=call.get("node_id"), + system_id=call.get("system_id"), + talkgroup_id=call.get("talkgroup_id"), + talkgroup_name=call.get("talkgroup_name"), + gcs_uri=gcs_uri, + ) + return {"ok": True, "call_id": call_id} diff --git a/drb-c2-core/app/routers/incidents.py b/drb-c2-core/app/routers/incidents.py index 9e6db43..726d463 100644 --- a/drb-c2-core/app/routers/incidents.py +++ b/drb-c2-core/app/routers/incidents.py @@ -1,7 +1,7 @@ import uuid from datetime import datetime, timezone from typing import Optional -from fastapi import APIRouter, HTTPException, Depends +from fastapi import APIRouter, BackgroundTasks, HTTPException, Depends from app.models import IncidentCreate, IncidentUpdate from app.internal import firestore as fstore from app.internal.auth import require_admin_token @@ -19,6 +19,14 @@ async def list_incidents(status: Optional[str] = None, type: Optional[str] = Non return await fstore.collection_list("incidents", **filters) +@router.post("/summarize") +async def summarize_all_stale(background_tasks: BackgroundTasks): + """Immediately run the summarizer pass on all stale incidents (don't wait for the next interval).""" + from app.internal.summarizer import _run_summary_pass + background_tasks.add_task(_run_summary_pass) + return {"ok": True} + + @router.get("/{incident_id}") async def get_incident(incident_id: str): doc = await fstore.doc_get("incidents", incident_id) @@ -67,6 +75,17 @@ async def delete_incident(incident_id: str, _: dict = Depends(require_admin_toke return {"ok": True} +@router.post("/{incident_id}/summarize") +async def summarize_incident(incident_id: str, background_tasks: BackgroundTasks): + """Immediately run the summarizer for a specific incident.""" + from app.internal.summarizer import _summarize_incident + inc = await fstore.doc_get("incidents", incident_id) + if not inc: + raise HTTPException(404, f"Incident '{incident_id}' not found.") + background_tasks.add_task(_summarize_incident, inc) + return {"ok": True, "incident_id": incident_id} + + @router.post("/{incident_id}/calls/{call_id}") async def link_call_to_incident(incident_id: str, call_id: str, _: dict = Depends(require_admin_token)): doc = await fstore.doc_get("incidents", incident_id)