feat(phase 3.1): /health dashboard — single self-contained HTML page #26

Merged
deco merged 1 commit from feat/phase-3.1-health-dashboard into main 2026-05-21 22:46:02 +03:00
Owner

Summary

Phase 3.1 of the Stream-a-Thon plan. Operators get a green/red per-stream view at http://127.0.0.1:8080/ (same host/port as /health, just the root path). The page is a single self-contained HTML file with vanilla JS — no build step, no external deps — polling /health once per second and rendering overall status (ok / degraded / unreachable), per-stream status with restart counts, and the OBS UDP input URL.

Closes the Phase 3.1 acceptance: "Ops can see green/red per stream."

How it works

  • dashboard.html lives in scripts/streamlink-supervisor/ next to the server code.
  • index.ts reads it from disk on startup with fs.readFileSync (fileURLToPath + __dirname resolution for ESM/CJS parity under tsx).
  • It's passed through startRuntime → startHealthServer as dashboardHtml.
  • healthServer serves it at GET / and GET /dashboard; the /health JSON path is unchanged.
  • If the HTML file is missing on the host, the supervisor logs a warning and returns 404 at //health JSON is still served.

Files

  • scripts/streamlink-supervisor/dashboard.html — the page
  • scripts/streamlink-supervisor/healthServer.ts — accept dashboardHtml in context; serve at GET / and GET /dashboard
  • scripts/streamlink-supervisor/runtime.ts — thread dashboardHtml through
  • scripts/streamlink-supervisor/index.ts — load the HTML on startup; warn-and-continue on missing
  • scripts/streamlink-supervisor/__tests__/healthServer.test.ts — +5 tests covering the new route, content type, missing-config path, method-not-allowed, and leak-isolation from /health
  • scripts/streamlink-supervisor/README.md — document the route + behavior

Test plan

  • 189/189 jest tests pass (+5 new dashboard-route tests)
  • tsc --noEmit clean
  • npm run audit:sqlite-opens clean
  • Smoke on the production OBS host: open http://127.0.0.1:8080/ after supervisor starts; rows should match /health JSON
## Summary Phase 3.1 of the Stream-a-Thon plan. Operators get a green/red per-stream view at `http://127.0.0.1:8080/` (same host/port as `/health`, just the root path). The page is a single self-contained HTML file with vanilla JS — no build step, no external deps — polling `/health` once per second and rendering overall status (ok / degraded / unreachable), per-stream status with restart counts, and the OBS UDP input URL. Closes the Phase 3.1 acceptance: \"Ops can see green/red per stream.\" ## How it works - `dashboard.html` lives in `scripts/streamlink-supervisor/` next to the server code. - `index.ts` reads it from disk on startup with `fs.readFileSync` (`fileURLToPath` + `__dirname` resolution for ESM/CJS parity under tsx). - It's passed through `startRuntime → startHealthServer` as `dashboardHtml`. - `healthServer` serves it at `GET /` and `GET /dashboard`; the `/health` JSON path is unchanged. - If the HTML file is missing on the host, the supervisor logs a warning and returns 404 at `/` — `/health` JSON is still served. ## Files - `scripts/streamlink-supervisor/dashboard.html` — the page - `scripts/streamlink-supervisor/healthServer.ts` — accept `dashboardHtml` in context; serve at `GET /` and `GET /dashboard` - `scripts/streamlink-supervisor/runtime.ts` — thread `dashboardHtml` through - `scripts/streamlink-supervisor/index.ts` — load the HTML on startup; warn-and-continue on missing - `scripts/streamlink-supervisor/__tests__/healthServer.test.ts` — +5 tests covering the new route, content type, missing-config path, method-not-allowed, and leak-isolation from /health - `scripts/streamlink-supervisor/README.md` — document the route + behavior ## Test plan - [x] 189/189 jest tests pass (+5 new dashboard-route tests) - [x] `tsc --noEmit` clean - [x] `npm run audit:sqlite-opens` clean - [ ] Smoke on the production OBS host: open `http://127.0.0.1:8080/` after supervisor starts; rows should match `/health` JSON
feat(phase 3.1): /health dashboard — single self-contained HTML page
All checks were successful
Lint and Build / build (pull_request) Successful in 4m41s
235d7830a6
Operators get a green/red per-stream view at http://127.0.0.1:8080/
(same host/port as /health, just the root). The page is a single
self-contained HTML file with vanilla JS — no build step, no
external dependencies — polling /health once per second and
rendering overall status (ok/degraded/unreachable), per-stream
status with restart counts, and the OBS UDP input URL.

Closes the Phase 3.1 acceptance: ops can see green/red per stream
from a single source.

- scripts/streamlink-supervisor/dashboard.html: the page.
- scripts/streamlink-supervisor/healthServer.ts: accept
  dashboardHtml in context; serve at GET / and GET /dashboard;
  return 404 when not configured. /health JSON path unchanged.
- scripts/streamlink-supervisor/runtime.ts: pass dashboardHtml
  through to startHealthServer.
- scripts/streamlink-supervisor/index.ts: read dashboard.html from
  disk on startup; warn-and-continue if missing (JSON endpoint
  still works); update the startup log to surface both URLs.
- scripts/streamlink-supervisor/__tests__/healthServer.test.ts:
  +5 tests covering the new route + leak-isolation from /health.
- scripts/streamlink-supervisor/README.md: document the dashboard
  route.

189/189 jest tests pass; type-check and audit:sqlite-opens clean.
Lint warning in obsClient.test.js is pre-existing.
deco merged commit cdb7be89d6 into main 2026-05-21 22:46:02 +03:00
deco deleted branch feat/phase-3.1-health-dashboard 2026-05-21 22:46:02 +03:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
deco/cuesheet!26
No description provided.