# 017 — Alert definitions & settings persistence ## Summary Foundation for the alerting feature: a persisted `AlertRule` model plus CRUD, following the shape `Settings` already uses for `CssEntry`/`Profiles` ([008](008-settings-model.md)) — one process-wide list, saved to disk on every mutation. An `AlertRule` has: - A **condition** (see [018](018-alert-trigger-evaluation.md) for the types and how they're evaluated) — for this ticket, just store it as an opaque, already parsed/validated value; don't implement evaluation here. - A **sink**: for now, only `Ntfy { topic: String, server: Option }` (`server` defaults to `https://ntfy.sh` when absent) — modeled as an enum so [additional sinks](020-alerts-webapp-ui.md) can be added later without reshaping `AlertRule`. - Bookkeeping: `id`, `name`, `enabled: bool`. ## Scope - `AlertRule` struct (or similar) in a new `src/alerts.rs`, `Vec` added to `Settings` (`src/settings.rs`), persisted the same way `css_entries`/`profiles` already are. - CRUD methods on `Settings` (create/update/delete/list), mirroring `import_css`/`remove_css`'s pattern: mutate in memory, then `self.save(...)`. - HTTP endpoints in `src/api.rs` for CRUD, matching the existing settings endpoints' conventions (routes, status codes, error JSON shape). - Id generation: reuse the approach in `generate_imported_css_id` (hash name+content+timestamp) rather than adding a `uuid` dependency. ## Acceptance criteria - Alert rules round-trip through `save`/`load` like the rest of `Settings` (see `round_trips_through_save_and_load` for the existing pattern to extend). - CRUD endpoints create, list, update, and delete rules, and reject unknown ids the same way `CssError::NotFound` does today. - No evaluation or delivery logic lives here — this ticket only stores rules. ## Depends on - [008 — Settings model](008-settings-model.md) ## Depended on by - [018 — Alert trigger evaluation](018-alert-trigger-evaluation.md) - [019 — Ntfy sink delivery](019-ntfy-sink-delivery.md) - [020 — Alerts webapp UI](020-alerts-webapp-ui.md)