Repository navigation
feat(alerts): build escalation chains in the dashboard and see them on incidents - #2305
Merged
Merged
Maple Review Bot / Maple / review
succeeded
Nov 7, 2026 in 3m 22s
Confidence 8/10 · No issues found
🟢 Confidence 8/10 · likely safe to merge. Held at 8 because 2 reviewed files were not read.
no findings · tests covered · risk medium · 2/3 new units observable −1 · 2 files not read · 1 fix not yet re-checked against the whole diff
Adds escalation chains to the dashboard: a Routing-tab section with create/edit/delete, a per-tier picker in the rule editor, an escalation block on the incident rail, and a nullable escalation on v2 alert incidents filled from one batched run query per page. Safe to merge.
listIncidentEscalationsreads a page's latest runs in one query and v2 incidents exposeescalation- Routing tab gains the chains section, the chain dialog and a 409 delete naming its blockers
- Rule editor tiers get an escalation-chain picker beside their destinations
- Incident rail shows escalating, paused or finished, re-read once a step is due
Fixed since the last review
- ✅
F24 · A refused chain delete can name the wrong rules and miss the one blocking it
Production impact
Production traffic of the changed files (last 7 days)
| File | Calls/day | Busiest operations |
|---|---|---|
packages/backend/src/services/alerts/AlertReadModelsService.ts |
182 | AlertReadModelsService.listRuleChecks 182/day, 0.0% err |
Telemetry this change adds and removes (1)
- ➕ span name
AlertReadModelsService.listIncidentEscalations·packages/backend/src/services/alerts/AlertReadModelsService.ts:295
What was checked
- A refused delete re-reads the chains and rebuilds the message from the fresh
rule_ids(hub/update.ts:867-874, testhub-chains.scene.test.ts:167-179) listIncidentEscalationsfiltersorgIdand is served byalert_escalation_runs_org_incident_idx(packages/db/src/tables/escalation-chains.ts:73)- The chain picker's values are decoded internal ids, so a pick reaches the rule payload as
EscalationChainId(view-notifications.ts:92,escalation-test-fixtures.ts:54); dialog limits match the AP…
Observability coverage: 2 of 3 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| AlertReadModelsService.listIncidentEscalations (Postgres read) | database query | yes | Effect.fn("AlertReadModelsService.listIncidentEscalations") plus annotateCurrentSpan({ orgId, "maple.alert.incident_count" }) at AlertReadModelsService.ts:295-298 |
| v2 alert-incident list/retrieve/ack attaching escalation | HTTP handler | yes | Existing HttpApiBuilder server spans; acknowledge and unacknowledge keep Effect.withSpan (alert-incidents.http.ts:203,210) |
| Dashboard chains section, chain dialog, tier picker, incident rail | browser UI | no | apps/web has no client OTel bootstrap (@opentelemetry appears only in docs snippets); their reads show up as API server spans |
Files not reviewed (2)
The review ended before it read these diffs, so nothing above vouches for them.
apps/ios/Packages/MapleAPI/Sources/MapleAPI/openapi.jsonapps/web/src/lab/escalation-lab.ts
f92b112 · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading