# ADR-0005: Reuse `TmsCore.AlertsCore` for SLA-breach notifications

## Status

Accepted

## Context

Phase 2 of the DPS implementation plan adds SLA management: detecting dispute cases past their `response_due_date` and notifying the right people, with escalation if unacknowledged (the infographic's "SLA Management" and "Notifications & Alerts" capabilities).

Two precedents already exist in the codebase for this kind of thing:

1. **`TmsCore.AlertsCore`** — a full alert-rule / notification-template / escalation-policy pipeline (`apps/tms_core/lib/tms_core/alerts_core.ex` and its schemas: `Alert`, `AlertRule`, `EscalationPolicy`, `NotificationTemplate`, `ChannelSettings`, `AlertDelivery`; workers: `RuleEvaluator`, `EscalationWorker`, `DeliveryWorker`). Public entry point: `TmsCore.AlertsCore.open_or_bump_alert(%AlertRule{}, hit_attrs)`, which dedupes by fingerprint, respects a configurable cooldown, broadcasts `{:alert_fired, alert}` over PubSub, and dispatches through configured notification channels. Escalation policies define multi-step, delay-based, multi-channel escalation (`TmsCore.AlertsCore.EscalationPolicy`, driven by the `EscalationWorker` Oban cron job).
2. **`SettlementCore.Workers.SlaMonitorWorker` + `PlatformWeb.SettlementNotifier`** — a simpler, single-purpose pattern: an Oban cron worker directly emails a fixed recipient via `SettlementNotifier.send_sla_breach_alert/2`, with no dedup, no escalation, no configurability.

## Decision

Use `TmsCore.AlertsCore.open_or_bump_alert/2` for dispute SLA-breach notifications, via a new `DisputeCore.Workers.SlaMonitorWorker` Oban cron worker (scheduling pattern mirrors `SettlementCore.Workers.SlaMonitorWorker`, but the notification call goes through `AlertsCore` rather than a direct email).

## Alternatives considered

- **Copy the `SettlementCore.Workers.SlaMonitorWorker` / direct-email pattern.** Rejected — no dedup (would re-notify every cron tick for the same breach), no escalation if unacknowledged, and no per-user/channel configurability. Acceptable for settlement's narrower use case; not acceptable for a feature the infographic explicitly calls out as needing SLA tracking *and* escalation.
- **Build a third, DPS-specific notification path.** Rejected — `AlertsCore` already solves dedup, escalation, multi-channel delivery, and templating generically; a third bespoke implementation would duplicate that work and fragment where ops staff have to look for alerts.

## Consequences

- Dispute SLA breaches show up in the same place, with the same dedup/escalation/channel behavior, as other TMS alerts — one alerting system for ops to learn, not three.
- `dispute_core`'s SLA worker takes a dependency on `TmsCore.AlertsCore`'s public API (`open_or_bump_alert/2` and whatever `AlertRule`/fingerprint conventions it expects) — this is a call-only dependency (`dispute_core → tms_core`), consistent with the one-directional dependency principle in ADR-0002; `tms_core` does not depend back on `dispute_core`.
- Requires defining an `AlertRule` (or equivalent config) for the dispute-SLA-breach case as part of Phase 2 implementation, not just wiring the worker.
