# 019 — Ntfy sink delivery ## Summary Deliver a fired alert ([018](018-alert-trigger-evaluation.md)) to the [ntfy](https://ntfy.sh) topic configured on its `AlertRule` ([017](017-ntfy-alerts.md)): a plain HTTP POST of the notification body to `{server}/{topic}`, no SDK needed. ## Scope - A small async sender: `POST {server}/{topic}` with the alert's message as the request body (ntfy's plain-text publish API — no auth, no extra dependency beyond an HTTP client ottyl can already reach for, or a minimal one if none exists yet). - Message content: rule name plus enough context to be useful (matched log line for Immediate/New value, current value vs. threshold for Threshold/Ratio). - Delivery runs off the ingest hot path — spawn it (e.g. `tokio::spawn`/an mpsc queue) so a slow or unreachable ntfy server never blocks log ingestion. - Failure handling: log the error to stderr and drop the notification — no retry queue or backoff for this ticket (matches the project's existing "best-effort, log and move on" style, e.g. `remove_css`'s file-removal fallback). ## Acceptance criteria - A fired alert results in exactly one HTTP POST to the rule's configured `{server}/{topic}`. - Ntfy being unreachable/erroring is logged but does not panic, block ingestion, or crash the process. - Covered by a test against a local mock HTTP server asserting the request path/body. ## Depends on - [017 — Alert definitions & settings persistence](017-ntfy-alerts.md) - [018 — Alert trigger evaluation](018-alert-trigger-evaluation.md) ## Depended on by - [020 — Alerts webapp UI](020-alerts-webapp-ui.md) (for a "send test notification" action)