Metadata-Version: 2.4
Name: boomerang-alert-engine
Version: 1.0.0
Summary: Boomerang alert engine.
License: Apache-2.0
License-File: LICENSE
Author: Julien Weber
Author-email: jpkwbr@protonmail.com
Requires-Python: >=3.11,<4.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Requires-Dist: boomerang-contracts (>=2.0.0,<3.0.0)
Requires-Dist: kontiki (>=2.0.0,<3.0.0)
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
Project-URL: Homepage, https://github.com/kontiki-org/boomerang
Project-URL: Repository, https://github.com/kontiki-org/boomerang
Description-Content-Type: text/markdown

# Alert Engine Service

`alert-engine-service` turns a `NormalizedAlert` into channel-ready
`NotificationRequest` events for notifier services.

## What it does

- Ingest alerts via:
  - AMQP event `alert.normalized`
  - HTTP `POST /alerts` (Bearer token = `app.http.token`)
- Resolve recipients via RPC `subscription-service.get_recipients_for_alert`.
- Build one `NotificationRequest` per `(channel, endpoint_key)`.
- Publish `{channel}.alerting.notification.requested` (e.g.
  `email.alerting.notification.requested`,
  `telegram.alerting.notification.requested`).

## Stack

- Config: `stack/alert_engine.yaml`
- HTTP: port **8005** → `POST /alerts` only (no auto OpenAPI page unless the
  route sets `version=` — Kontiki docs are version-scoped)
- Token: `app.http.token` (default in stack: `change-me`)

## Payload and contract notes

- Inbound: `boomerang_contracts.alert.normalized.NormalizedAlert`
  (validated with Pydantic on both AMQP and HTTP paths).
- Outbound: `boomerang_contracts.notification.message.NotificationRequest`.
- Message `title` / `body` come from the alert; `context.kind` is `"alert"` and
  `context.data` carries `alert_id`, `category`, `event_type`, `severity`,
  `attributes`.
- The full alert is sent to `get_recipients_for_alert` for subscription matching.

