diff --git a/backend/routers/portal.py b/backend/routers/portal.py index 6f86108..412a7f5 100644 --- a/backend/routers/portal.py +++ b/backend/routers/portal.py @@ -242,6 +242,34 @@ async def portal_location_events(location_id: str, limit: int = 20, return {"status": "ok", "events": events, "active": sum(1 for e in events if e.get("status") == "active")} +# Whitelist of alert-rule fields shown to a client (the active limits, no cooldown/ +# hysteresis internals). +_PORTAL_RULE_FIELDS = ("name", "metric", "comparison", "threshold_db", "duration_s", + "schedule_start", "schedule_end", "schedule_days") + + +@router.get("/api/location/{location_id}/thresholds") +async def portal_location_thresholds(location_id: str, + client: Client = Depends(get_current_client), + db: Session = Depends(get_db)): + """The active alert limits for a location the client owns (enabled rules only), + so the client can see what they're being alerted on. Read-only, scrubbed.""" + resolve_client_location(client, location_id, db) + unit_id = active_unit_for_location(location_id, db) + if not unit_id: + return {"status": "ok", "rules": []} + try: + async with httpx.AsyncClient(timeout=5.0) as hc: + r = await hc.get(f"{SLMM_BASE_URL}/api/nl43/{unit_id}/alerts/rules") + except Exception: + return {"status": "ok", "rules": []} + if r.status_code != 200: + return {"status": "ok", "rules": []} + raw = (r.json() or {}).get("rules", []) + rules = [{k: x.get(k) for k in _PORTAL_RULE_FIELDS} for x in raw if x.get("enabled")] + return {"status": "ok", "rules": rules} + + # -- live stream (fan-out feed, scoped + scrubbed) --------------------------- def _scrub_frame(raw: str) -> str: diff --git a/templates/portal/location.html b/templates/portal/location.html index 88a4f1f..97d5e8b 100644 --- a/templates/portal/location.html +++ b/templates/portal/location.html @@ -69,8 +69,14 @@ + +
+ -