Implements feature 100 (Alert Targets): - US1: “Send test message” action (RBAC + confirmation + rate limit + audit + async job) - US2: Derived “Last test” status badge (Never/Sent/Failed/Pending) on view + edit surfaces - US3: “View last delivery” deep link + deliveries viewer filters (event_type, destination) incl. tenantless test deliveries Tests: - Full suite green (1348 passed, 7 skipped) - Added focused feature tests for send test, last test resolver/badges, and deep-link filters Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #122
80 lines
2.6 KiB
Markdown
80 lines
2.6 KiB
Markdown
# Phase 1 — Data Model (099.1 Add-on)
|
|
|
|
## Entities
|
|
|
|
### AlertDestination (existing)
|
|
|
|
- **Table**: `alert_destinations`
|
|
- **Ownership**: workspace-owned
|
|
- **Key fields (relevant here)**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `type` (e.g. Teams webhook, Email)
|
|
- `config` (Teams webhook URL or list of recipients)
|
|
- `is_enabled`
|
|
|
|
### AlertDelivery (existing, extended for test sends)
|
|
|
|
- **Table**: `alert_deliveries`
|
|
- **Ownership**:
|
|
- v1 deliveries for real alerts remain tenant-associated
|
|
- **test deliveries for this add-on are tenantless** (workspace-only)
|
|
|
|
- **Key fields (relevant here)**:
|
|
- `id`
|
|
- `workspace_id` (required)
|
|
- `tenant_id` (**nullable for test deliveries**)
|
|
- `alert_rule_id` (**nullable for test deliveries**)
|
|
- `alert_destination_id` (required)
|
|
- `event_type` (string, includes `alerts.test`)
|
|
- `status` (`queued|deferred|sent|failed|suppressed|canceled`)
|
|
- `send_after` (nullable; used for deferral/backoff)
|
|
- `sent_at` (nullable)
|
|
- `attempt_count`
|
|
- `last_error_code`, `last_error_message` (sanitized)
|
|
- `payload` (array/json)
|
|
- timestamps: `created_at`, `updated_at`
|
|
|
|
## Relationships
|
|
|
|
- `AlertDelivery` → `AlertDestination` (belongsTo via `alert_destination_id`)
|
|
- `AlertDelivery` → `AlertRule` (belongsTo via `alert_rule_id`, nullable)
|
|
- `AlertDelivery` → `Tenant` (belongsTo via `tenant_id`, nullable)
|
|
|
|
## New derived concepts (no storage)
|
|
|
|
### LastTestStatus (derived)
|
|
|
|
Derived from the most recent `alert_deliveries` record where:
|
|
- `alert_destination_id = {destination}`
|
|
- `event_type = 'alerts.test'`
|
|
|
|
Mapping:
|
|
- no record → `Never`
|
|
- `status in (queued, deferred)` → `Pending`
|
|
- `status = sent` → `Sent`
|
|
- `status = failed` → `Failed`
|
|
|
|
Associated timestamp (derived):
|
|
- Sent → `sent_at`
|
|
- Failed → `updated_at`
|
|
- Pending → `send_after` (fallback `created_at`)
|
|
|
|
## Validation / invariants
|
|
|
|
- Creating a test delivery requires:
|
|
- `alert_destination_id` exists and belongs to current workspace
|
|
- destination is enabled (if disabled, refuse test request)
|
|
- rate limit: no prior test delivery for this destination in last 60 seconds
|
|
- Test delivery record must not persist secrets in payload or error message.
|
|
|
|
## Migration notes
|
|
|
|
To support tenantless test deliveries:
|
|
- Make `alert_deliveries.tenant_id` nullable and adjust the FK behavior.
|
|
- Make `alert_deliveries.alert_rule_id` nullable and adjust the FK behavior.
|
|
- Add or adjust indexes for efficient status lookup per destination + event type:
|
|
- `(workspace_id, alert_destination_id, event_type, created_at)`
|
|
|
|
(Exact migration steps and DB constraint changes are specified in the implementation plan.)
|