Skip to content

feat(dashboard): live anomaly badge — background poll every 30s#154

Merged
surpradhan merged 3 commits into
mainfrom
feat/dashboard-live-anomaly
Jun 26, 2026
Merged

feat(dashboard): live anomaly badge — background poll every 30s#154
surpradhan merged 3 commits into
mainfrom
feat/dashboard-live-anomaly

Conversation

@surpradhan

Copy link
Copy Markdown
Owner

What does this PR do?

Keeps the anomaly badge and Analyze nav dot current without requiring the user to visit the Anomalies sub-tab. A 30-second background poll fetches the anomaly count after page load and updates the UI silently.

Changes

src/public/dashboard.html only — no backend changes

  • ANOMALY_POLL_MS = 30_000 constant
  • refreshAnomalyBadge() — fetches GET /analytics/anomalies (with current threshold if set); if the user is already on the Anomalies tab it calls renderAnomalies() for a full refresh, otherwise updates only the badge count and pdot-analyze dot
  • startAnomalyPoll() — clears any prior interval, fires an immediate fetch, then schedules repeats
  • Wired into loadAll() after first successful data fetch (authenticated path only)
  • Errors are silenced — badge stays stale rather than flashing on transient network issues

How to test

npm run ingest
# open dashboard — Anomalies badge starts at 0 (or current count)
# emit events that trigger anomalies; without switching tabs, observe
# the badge and Analyze dot update within 30s

Checklist

  • Tests pass (243/243, no new tests needed — pure UI behaviour)
  • Lint clean
  • No backend changes, no new CI jobs, no schema migrations

Part of UX polish sprint (PR-D of 4, stacked on PR-C)

@surpradhan surpradhan left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R1 findings (all addressed in 21ce12e): (1) poll kept running after 401 → now clears interval on Unauthorized; (2) badge queried different range than panel → now reads shared-since/shared-until via toIso(); (3) poll fired while tab hidden → early return on document.hidden; (4) duplicate banner line + bare fire-and-forget call → fixed (void keyword). R2: both reviewers approve, zero actionable items. 243/243, lint clean. Approve.

Start a 30-second poll after initial page load that fetches
GET /analytics/anomalies and keeps the anomalies-badge count and
pdot-analyze alert dot current without requiring a tab visit.

- refreshAnomalyBadge(): fetches the count, updates badge + dot;
  if the user is already on the Anomalies tab it delegates to
  renderAnomalies() for a full refresh instead
- startAnomalyPoll(): clears any prior interval, fires an immediate
  fetch, then schedules repeats at ANOMALY_POLL_MS (30s)
- Wired into loadAll() after first successful data fetch so the poll
  only starts once the user is authenticated
- Respects the current sensitivity threshold (ad-threshold) input so
  the badge reflects the same cutoff the user configured
- Errors silenced — badge stays stale rather than flashing on transient
  network hiccups
- Stop poll on 401: clearInterval when fetchJson throws Unauthorized so
  a re-auth page stop issuing background requests; poll restarts via
  startAnomalyPoll() on the next successful loadAll()
- Include shared-since/shared-until in the badge query so the count
  matches the same filter set the Anomalies panel uses; prevents badge
  showing a different number than the panel when date filters are active
- Skip tick when document.hidden to avoid background network requests
  while the tab is backgrounded or screen is locked
- Remove duplicate separator banner line before the block comment
- Use void refreshAnomalyBadge() in startAnomalyPoll() to mark the
  intentional fire-and-forget clearly
@surpradhan surpradhan force-pushed the feat/dashboard-live-anomaly branch from 21ce12e to bb2d1be Compare June 26, 2026 07:47
@surpradhan surpradhan changed the base branch from feat/dashboard-windowed-metrics to main June 26, 2026 07:47
@surpradhan surpradhan merged commit 0d4ac08 into main Jun 26, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant