Skip to content

feat(admin): add Network Health panel to observability dashboard - #764

Open
Ferryx349 wants to merge 6 commits into
mainfrom
feat/admin-network-health-panel
Open

feat(admin): add Network Health panel to observability dashboard#764
Ferryx349 wants to merge 6 commits into
mainfrom
feat/admin-network-health-panel

Conversation

@Ferryx349

Copy link
Copy Markdown
Collaborator

Description

This PR adds the Network Health panel to the admin observability dashboard. It also polls /admin/network-health and renders NIP-66 probe results (DNS, TLS, WS RTT, NIP-11) per target.

Related Issue

Closes #698.
And stacked on #753 chain.

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Video demonstration : https://github.com/user-attachments/assets/c63e043f-6c0b-49d4-badb-9dfdf3639f5b

Screenshot 2026-09-08 at 19 10 03 Screenshot 2026-09-08 at 19 09 39

Types of changes

  • Non-functional change (docs, style, minor refactor)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my code changes.
  • I added a changeset, or this is docs-only and I added an empty changeset.
  • All new and existing tests passed.

@changeset-bot

changeset-bot Bot commented Sep 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2386e20

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
nostream Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment thread src/routes/admin/index.ts
router.get(
'/network-health',
adminRateLimitMiddleware,
adminAuthMiddleware,
Comment thread resources/admin/assets/dashboard.js Fixed
Comment thread resources/admin/assets/dashboard.js Fixed
@coveralls

coveralls commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Coverage Status

coverage: 72.36% (+0.1%) from 72.235% — feat/admin-network-health-panel into main

@phoenix-server

Copy link
Copy Markdown
Collaborator

Verdict: Approve with comments — no blocking defects; land it after #753 merges.

Stacking / merge order (process)

#753 (feat/admin-network-health-api, OPEN) is a direct ancestor of this branch, so the 805-line diff vs main conflates both PRs. Diffing against #753's head, #764's own delta is only the dashboard frontend: resources/admin/dashboard.html (+27), dashboard.css (+44), dashboard.js (+190), and .changeset/admin-network-health-panel.md — the controller, publisher, nip66-events.ts, monitor-identity.ts, worker wiring, route, and backend tests belong to #753. Merging #764 as-is would silently land #753's backend outside its own review. Recommended: merge #753 first, then rebase this branch so the merge diff is panel-only (branch is BEHIND main but MERGEABLE — update before merging). Findings below cover the full stack since this merge delivers it all; backend findings are equally actionable on #753.

Blocking

None. Auth and rate limiting are correct (adminRateLimitMiddleware + adminAuthMiddleware, same as /health and /metrics — the CodeQL rate-limit alerts are stale against the final revision; admin.spec.ts:189-198 asserts 401 + limiter calls), signing reuses the repo's signEvent/identifyEvent, persistence reuses the ON-CONFLICT upsert guard, remote data rendering is XSS-safe (all remote strings via textContent; innerHTML sites receive static/Date-derived values only), and publishing is fail-safe without a monitor key. The two CodeQL unused-variable alerts are also stale — the identifiers don't exist in the final revision.

Important

  1. NIP-66 events are persisted but never broadcast to live subscriberssrc/services/nip66-event-publisher.ts:75-93. The monitor runs as a cluster worker (app.ts:111-115); both existing internal publishers (dvm-orchestrator-worker.ts:255-278, payments-service.ts:236-241) follow persist → broadcastEvent. As written, clients with open kinds:[30166] subscriptions only see results after re-issuing a REQ. Suggest gating on the upsert count like ParameterizedReplaceableEventStrategy.execute() does (and add broadcastEvent to the import).

  2. Kind 10002 bootstrap relay list points at the first probe target, not the relay's own URLnip66-event-publisher.ts:66. With nip66.targets configured, the r tags advertise a monitored external relay where this monitor never publishes — NIP-65/66 clients can't discover the monitor's feed there. Prefer settings.info.relay_url first:

    const relayUrl = settings.info?.relay_url?.trim() || resolveProbeTargets(settings)[0]
  1. Closes #698 overstates deliverydashboard.js:469-490 omits several of the issue's explicit display goals: network-type badge (data is on the payload), TLS < 14 days warning state, DNS records + TTL (panel shows a bare count), NIP-11/NIPs-mismatch warning. Either add them or change the link to "Part of feat(admin): add Network Health panel to observability dashboard #698" so the issue isn't auto-closed half-implemented.

Minor

  1. frequency tag ignores the scheduler's 60s clampnip66-events.ts:60 vs getProbeIntervalMs (relay-monitor-worker.ts:28-33): a 10s config would announce frequency: 10 while actually probing every 60s.
  2. Bootstrap flag set with no TTLnip66-event-publisher.ts:60-71: Redis eviction/flush permanently silences kind 0/10002 re-publishing; consider a long TTL or periodic presence check.
  3. timeout tag order follows NIP-66's prose, not its examplenip66-events.ts:67-72; the NIP's own example shows ["timeout","open","5000"]. Worth tracking as the draft settles.
  4. No unit spec for Nip66EventPublisher lifecycle (bootstrap-once, missing-key skip) — covered only incidentally by the integration feature.

Nit

Summary: a well-tested, XSS-safe dashboard panel on a spec-compliant NIP-66 publisher. The real gate is sequencing with #753; the substantive comments are the missing subscriber broadcast, the 10002 relay-list target, and the #698 scope.

After each probe run, sign and store NIP-66 relay discovery and monitor announcement events from the monitor identity, bootstrap kind 0/10002 on first run, and persist via the parameterized replaceable event path.

Fixes #696
Knex already parses jsonb event_tags as an array; JSON.parse on that value caused CI failures. Assert the d tag via the event_tags table instead.
Render NIP-66 probe snapshots in the admin Metrics view with per-target
DNS/TLS/WS/NIP-11 cards and 60s polling.
CodeQL flagged unused getElementById bindings; run status and target
count are updated via setStatusText/setMetricValue instead.
Broadcast newly persisted NIP-66 events, prefer relay_url in bootstrap
relay list, clamp frequency tags to the worker minimum, add bootstrap TTL,
and complete Network Health dashboard coverage for issue #698.
@Ferryx349
Ferryx349 force-pushed the feat/admin-network-health-panel branch from 4442db8 to 2386e20 Compare September 8, 2026 20:53
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.

feat(admin): add Network Health panel to observability dashboard

4 participants