Alerts: confidence gate before any push, held alerts, release on corroboration (server-26#300)
No confidence field exists anywhere in scene/incident data, so the alerter derives one: match weight (talkgroup 1.0, extracted tag 0.8, raw transcript 0.6) scaled down only when stt_confidence is under ALERT_STT_REFERENCE (0.3), zero for not_speech. Below ALERT_MIN_CONFIDENCE, or high severity (term list, or a major incident) without ALERT_CORROBORATION_MIN_CALLS calls or ALERT_HIGH_SEVERITY_MIN_CONFIDENCE, the match is written to alert_holds (no Firestore rule, admin-only GET /alerts/held) and logged instead of pushed. A needs_corroboration hold is released when a later call brings its incident to the call minimum; a rule pushed by that call supersedes its hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
240bbee5a4
commit
ff0a89e9f1
@@ -28,6 +28,27 @@ async def list_alerts(
|
||||
return await fstore.collection_list("alert_events", **filters)
|
||||
|
||||
|
||||
@router.get("/alerts/held")
|
||||
async def list_held_alerts(
|
||||
status: Optional[str] = Query("held", description="held | released | superseded | rule_gone; empty = all"),
|
||||
org_id: Optional[str] = Query(None, description="Platform-admin only — omit for every org."),
|
||||
_: dict = Depends(require_admin_token),
|
||||
):
|
||||
"""
|
||||
Rule matches the confidence gate kept from being pushed (server-26#300).
|
||||
Admin-only: a held match is by definition one we do not trust enough to
|
||||
show, so it does not belong on any customer surface (and alert_holds has
|
||||
no Firestore rule, so the browser cannot read it directly either).
|
||||
"""
|
||||
filters = {}
|
||||
if status:
|
||||
filters["status"] = status
|
||||
if org_id:
|
||||
filters["org_id"] = org_id
|
||||
holds = await fstore.collection_list("alert_holds", **filters)
|
||||
return sorted(holds, key=lambda h: h.get("triggered_at") or "", reverse=True)
|
||||
|
||||
|
||||
@router.post("/alerts/{alert_id}/acknowledge")
|
||||
async def acknowledge_alert(alert_id: str, decoded: dict = Depends(require_service_or_firebase_token)):
|
||||
doc = await fstore.doc_get("alert_events", alert_id)
|
||||
|
||||
Reference in New Issue
Block a user