3.7 KiB
3.7 KiB
Data Model — 099 Alerts v1 (Teams + Email)
Scope: workspace-owned configuration and tenant-owned delivery history. Deliveries are always tenant-scoped (tenant_id NOT NULL) and must only be listed/viewed for tenants the actor is entitled to (non-entitled tenants are treated as not found / 404 semantics).
Entities
AlertDestination (workspace-owned)
Purpose: reusable delivery target.
Fields:
idworkspace_id(FK, required)name(string, required)type(enum:teams_webhook|email, required)is_enabled(bool, default true)config(encrypted:array, required)- for
teams_webhook:{ "webhook_url": "https://..." } - for
email:{ "recipients": ["a@example.com", "b@example.com"] }
- for
- timestamps
Validation rules:
name: required, max lengthtype: required, in allowed valuesconfig.webhook_url: required if type is teams; must be URLconfig.recipients: required if type is email; array of valid email addresses; must be non-empty
Security:
configmust never be logged or included in audit metadata.
AlertRule (workspace-owned)
Purpose: routing + noise controls.
Fields:
idworkspace_id(FK, required)name(string, required)is_enabled(bool, default true)event_type(enum:high_drift|compare_failed|sla_due, required)minimum_severity(enum:low|medium|high|critical, required)tenant_scope_mode(enum:all|allowlist, required)tenant_allowlist(array, default empty)cooldown_seconds(int, nullable)quiet_hours_enabled(bool, default false)quiet_hours_start(string, e.g.22:00, nullable)quiet_hours_end(string, e.g.06:00, nullable)quiet_hours_timezone(IANA TZ string, nullable)- timestamps
Validation rules:
name: requiredevent_type: requiredminimum_severity: requiredtenant_allowlist: required iftenant_scope_mode=allowlist- quiet hours:
- if enabled: start/end required, valid HH:MM, timezone optional
Notes:
- Quiet-hours timezone resolution:
- rule timezone if set
- else workspace timezone
- else
config('app.timezone')
AlertRuleDestination (workspace-owned pivot)
Fields:
idworkspace_id(FK, required)alert_rule_id(FK)alert_destination_id(FK)- timestamps
Constraints:
- Unique
(alert_rule_id, alert_destination_id)
AlertDelivery (tenant-owned history)
Purpose: immutable record of queued/sent/failed/deferred/suppressed deliveries.
Fields:
idworkspace_id(FK, required)tenant_id(FK, required)alert_rule_id(FK, required)alert_destination_id(FK, required)fingerprint_hash(string, required)status(enum:queued|deferred|sent|failed|suppressed|canceled)send_after(timestamp, nullable)attempt_count(int, default 0)last_error_code(string, nullable)last_error_message(string, nullable; sanitized)sent_at(timestamp, nullable)- timestamps
Indexes:
(workspace_id, created_at)for history listing(workspace_id, status, send_after)for dispatching due deferred deliveries(workspace_id, alert_rule_id, fingerprint_hash)for dedupe/cooldown checks
Retention:
- Default prune: 90 days.
Relationships
AlertRulehasManyAlertRuleDestinationand belongsToManyAlertDestination.AlertDestinationbelongsToManyAlertRule.AlertDeliverybelongsToAlertRule, belongsToAlertDestination, and belongsToTenant.
State transitions
AlertDelivery.status transitions:
queued→sent|failed|suppressed|canceleddeferred→queued(when window opens) →sent|failed…
Terminal states: sent, failed, suppressed, canceled.