# ProdDash Alerts A module that sees something a tech must act on *now* — a timer overrun, a meter past its limit, timecode gone — raises an **alert**, and every dashboard listening to its channel flashes until it is over. This page is the whole feature: what an operator sees and sets, and what a module does to raise one. The module-side contract also lives in the [Module Guide](MODULE-GUIDE.md#raising-alerts), which is the authority on how modules are written. ## What an alert looks like On a dashboard that listens to the alert's channel: - The **menu bar** flashes between two colours, with the alert's text in bold across its middle (and a small boxed number saying which channel it came on). If the bar was hidden — by its notch, or because the screen is in fullscreen — it comes out for the alert and goes back when it ends. - A **frame round the whole screen** flashes with it, so a fullscreen wall where the bar is the only chrome still carries the flash to its edges. - For **low** and **medium**, that is all: the tiles and the board they sit on are left alone. A **critical** alert floods the **board behind the tiles** as well — in a muted cut of its two colours, mixed well toward the page background and showing faintly through the tiles' own panels — so the flash reaches the middle of a screen the tiles cover entirely, while everything written on a tile keeps its contrast. A module's content is never recoloured. The **level** sets the cadence. The two colours each level flashes between are the admin's choice (below). | Level | Cadence | For | | --- | --- | --- | | **Low** | a slow fade between the two colours, about three seconds a cycle; bar and frame only | something to know about | | **Medium** | a faster fade, about one second a cycle; bar and frame only | something to deal with soon | | **Critical** | no fade — the colours snap, twice a second; bar, frame and the board behind the tiles | something to deal with now | When several alerts a dashboard listens to are on at once, the bar shows the most severe (the newest among equals) and a **+1** says how many more there are. ## Channels There are **six channels**, numbered 1 to 6, and nothing else: a channel carries no meaning of its own. A booth gives them meaning — "1 is the stage, 2 is video, 3 is the lobby" — by pointing modules at them (a module that raises alerts makes its channel an admin setting) and by choosing which channels each dashboard listens to. **Choosing channels:** on the dashboard, open the Layouts menu (the grid icon) and the **Alerts** row — it says which channels this screen listens to and opens to six numbered buttons that toggle them. The choice is part of the arrangement, like the grid size and auto-hide: it saves with this browser's layout and with a named layout on the server, so a booth that loads its "Stage" layout gets the stage's channels with it. A fresh dashboard listens to nothing. ## One alert per channel A channel shows one alert at a time. A new alert on a channel replaces whatever was on it, whoever raised it; clearing a channel ends whatever is on it. Two modules pointed at one channel will talk over each other — give them channels of their own. An alert ends when its **duration** runs out (1 to 600 seconds; 15 when the module gives none), or when the module that raised it clears it early, or when that module stops (a disable, an uninstall, a config save that re-inits it): a module's alerts never outlive it. A module may hold an alert **until cleared** (duration 0) for a condition it will notice ending — timecode lost, a feed down — and clear it when the condition does. ## Admin → Alerts The admin page's **Alerts** section (folded by default, near the bottom) holds two colour pickers per level — the two colours that level flashes between — with a swatch beside each row running that level's cadence, so a pair can be judged before it is tried. A change saves when the picker closes and reaches every open dashboard at once. The row below sends a **test alert** of any level on any channel: eight seconds of whatever the dashboards listening to that channel will see. The colours are kept as `alerts.colors` in the data directory's `proddash.json` (see the README's *Where settings are kept*); they hold across restarts and updates. The defaults are a blue pair for low, amber for medium and red against near-black for critical. ## For module authors Raise from the server entry, which is where a condition is usually noticed — `shell.alert({ channel, level, text, duration })` and `shell.clearAlert(channel)` on the `shell` object `init()`, `routes()` and `tiles()` receive — or from a tile with `moduleApi.alert(...)` and `moduleApi.clearAlert(...)`, which go through the server. The fields, what each is for, and the rules that keep alerts worth looking at (raise on the transition, make it a setting, it is not a status) are in the [Module Guide](MODULE-GUIDE.md#raising-alerts). ## The HTTP API Everything above rides on three public routes and two admin ones. They are open to anything that can reach ProdDash, like a module's own routes: an alert is a flash on screens in this building and nothing more. | Route | Does | | --- | --- | | `GET /api/alerts` | `{ channels: 6, levels, colors: { low: [a, b], … }, active: [ … ] }` — what is flashing and the colours. Dashboards read it on load and whenever their stream reconnects. | | `POST /api/alerts` | `{ channel, level, text, duration?, source? }` as `application/json`. Answers `200 { ok, alert }` or `400 { error }` saying what was wrong. `source` is the module id (anything else is recorded as `api`). | | `DELETE /api/alerts/` | Ends the alert on that channel. `{ ok, cleared }` — `cleared` is false when nothing was on it. | | `POST /api/admin/alerts` | `{ colors: { low: [a, b], medium: [a, b], critical: [a, b] } }` — a missing or malformed colour takes its default. Behind the admin PIN. | | `POST /api/admin/alerts/test` | `{ level, channel }` — an eight-second test alert. Behind the admin PIN. | Open dashboards learn of changes over the shell stream (`/api/events`): `alert` carries an alert as raised (`{ id, channel, level, text, source, startedAt, duration, endsAt, remainingMs }` — a browser counts down from `remainingMs`, so the clocks need not agree), `alert-clear` carries `{ channel, id }` when one ends, and `alerts-config` carries `{ colors }` when the admin changes them. ## Trying it With ProdDash running, from the repo: ```bash node tools/alert.js -c 1 -l critical "LTC lost" ``` raises a critical alert on channel 1 for the default 15 seconds; `-d 0` holds it, `node tools/alert.js -c 1 --clear` ends it, `--list` shows what is on. Open a dashboard, choose channel 1 in its Layouts menu → Alerts, and watch; a second browser listening to channel 2 should stay quiet. The admin page's **Test** buttons do the same from the browser. `node tools/alerts.test.js` runs the server's side of all this end to end.