import uuid from datetime import datetime, timezone from typing import Optional from fastapi import APIRouter, HTTPException, Depends from app.models import AlertRule, AlertRuleUpdate from app.internal import firestore as fstore from app.internal.auth import require_admin_token router = APIRouter(tags=["alerts"]) # --------------------------------------------------------------------------- # Alert events (triggered alerts) # --------------------------------------------------------------------------- @router.get("/alerts") async def list_alerts(acknowledged: Optional[bool] = None): filters = {} if acknowledged is not None: filters["acknowledged"] = acknowledged return await fstore.collection_list("alert_events", **filters) @router.post("/alerts/{alert_id}/acknowledge") async def acknowledge_alert(alert_id: str): doc = await fstore.doc_get("alert_events", alert_id) if not doc: raise HTTPException(404, f"Alert '{alert_id}' not found.") await fstore.doc_update("alert_events", alert_id, {"acknowledged": True}) return {"ok": True} # --------------------------------------------------------------------------- # Alert rules # --------------------------------------------------------------------------- @router.get("/alert-rules") async def list_alert_rules(): return await fstore.collection_list("alert_rules") @router.post("/alert-rules") async def create_alert_rule(body: AlertRule, _: dict = Depends(require_admin_token)): rule_id = str(uuid.uuid4()) doc = { "rule_id": rule_id, "name": body.name, "keywords": body.keywords, "talkgroup_ids": body.talkgroup_ids, "enabled": body.enabled, "discord_webhook": body.discord_webhook, "created_at": datetime.now(timezone.utc).isoformat(), } await fstore.doc_set("alert_rules", rule_id, doc, merge=False) return doc @router.put("/alert-rules/{rule_id}") async def update_alert_rule(rule_id: str, body: AlertRuleUpdate, _: dict = Depends(require_admin_token)): doc = await fstore.doc_get("alert_rules", rule_id) if not doc: raise HTTPException(404, f"Alert rule '{rule_id}' not found.") updates = body.model_dump(exclude_none=True) await fstore.doc_update("alert_rules", rule_id, updates) return {**doc, **updates} @router.delete("/alert-rules/{rule_id}") async def delete_alert_rule(rule_id: str, _: dict = Depends(require_admin_token)): doc = await fstore.doc_get("alert_rules", rule_id) if not doc: raise HTTPException(404, f"Alert rule '{rule_id}' not found.") await fstore.doc_delete("alert_rules", rule_id) return {"ok": True}