157 lines
11 KiB
Markdown
157 lines
11 KiB
Markdown
# Feature Specification: Alert Targets Test Actions
|
||
|
||
**Feature Branch**: `feat/100-alert-target-test-actions`
|
||
**Created**: 2026-02-18
|
||
**Status**: Draft
|
||
**Input**: User description: "099.1 — Alert Targets: Send Test Message + Last Test Status (Teams + Email)"
|
||
|
||
## Spec Scope Fields *(mandatory)*
|
||
|
||
- **Scope**: workspace
|
||
- **Primary Routes**: Alert Target View, Alert Target Edit, Deliveries viewer (filtered deep links)
|
||
- **Data Ownership**:
|
||
- Workspace-owned: alert targets
|
||
- Tenant-owned: alert delivery history (non-test)
|
||
- Workspace-scoped: test deliveries (`event_type=alerts.test`) may be tenantless (`tenant_id` nullable)
|
||
- **RBAC**:
|
||
- Workspace membership is required to access Alert Targets and Deliveries.
|
||
- Users with manage capability can request a test send.
|
||
- Users with view-only capability can see test status but cannot request a test send.
|
||
|
||
For canonical-view specs, the spec MUST define:
|
||
|
||
- **Default filter behavior when tenant-context is active**: Not applicable (workspace scope).
|
||
- **Explicit entitlement checks preventing cross-tenant leakage**: Targets and deliveries are only visible within the current workspace; non-members must not receive any existence hints.
|
||
|
||
## Clarifications
|
||
|
||
### Session 2026-02-18
|
||
|
||
- Q: Which timestamps should the “Last test … at <timestamp>” subtext use? → A: Sent → `sent_at`; Failed → `updated_at`; Pending → `send_after`.
|
||
- Q: What should the test-send rate limit be per target? → A: 60 seconds per target.
|
||
- Q: What should “View last delivery” open? → B: Deliveries list viewer filtered to `alert_destination_id` + `event_type=alerts.test`.
|
||
- Q: When should “View last delivery” be shown on the Alert Target pages? → B: Show only if at least one test delivery exists.
|
||
|
||
## User Scenarios & Testing *(mandatory)*
|
||
|
||
### User Story 1 - Send a test message for a target (Priority: P1)
|
||
|
||
As an admin, I want to send a test alert to a configured Alert Target so I can verify the integration works before relying on it in production.
|
||
|
||
**Why this priority**: This is the fastest way to detect misconfiguration (wrong destination, blocked network path, invalid credentials) and reduce support/incident time.
|
||
|
||
**Independent Test**: Can be fully tested by requesting a test send and confirming a new test delivery record exists and can be inspected.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** I am a workspace member with manage permission, **When** I confirm “Send test message” on an Alert Target, **Then** the system creates exactly one new test delivery record for that target and indicates the request was queued.
|
||
2. **Given** I am a workspace member without manage permission, **When** I attempt to execute “Send test message”, **Then** the action is blocked and no delivery record is created.
|
||
3. **Given** I have requested a test very recently for the same target, **When** I attempt another test immediately, **Then** the system refuses the request and does not create a new delivery record.
|
||
|
||
---
|
||
|
||
### User Story 2 - See the last test status at a glance (Priority: P2)
|
||
|
||
As an admin, I want to see whether the last test send for an Alert Target succeeded, failed, was never executed, or is still pending so I can assess health without digging through deliveries.
|
||
|
||
**Why this priority**: Health visibility reduces troubleshooting time and prevents silent failures.
|
||
|
||
**Independent Test**: Can be fully tested by viewing a target with (a) no test deliveries, (b) a successful test delivery, (c) a failed test delivery and verifying the badge and timestamp.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** a target has no test delivery records, **When** I open the target View or Edit page, **Then** I see a badge “Last test: Never”.
|
||
2. **Given** the most recent test delivery record is successful, **When** I open the target View or Edit page, **Then** I see a badge “Last test: Sent” and an associated timestamp.
|
||
3. **Given** the most recent test delivery record is failed, **When** I open the target View or Edit page, **Then** I see a badge “Last test: Failed” and an associated timestamp.
|
||
4. **Given** the most recent test delivery record is queued or deferred, **When** I open the target View or Edit page, **Then** I see a badge “Last test: Pending”.
|
||
|
||
---
|
||
|
||
### User Story 3 - Jump from target to the relevant delivery details (Priority: P3)
|
||
|
||
As an admin, I want a quick link from the Alert Target to the most recent test delivery details so I can troubleshoot outcomes efficiently.
|
||
|
||
**Why this priority**: It reduces clicks and prevents mistakes when searching through delivery history.
|
||
|
||
**Independent Test**: Can be tested by clicking a “View last delivery” link and verifying the deliveries view is pre-filtered for this target and the test event type.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** a target has at least one test delivery record, **When** I click “View last delivery” from the target page, **Then** I am taken to the deliveries list viewer scoped to the same workspace and filtered to that target and the test event type.
|
||
|
||
### Edge Cases
|
||
|
||
- Target exists but has never been tested.
|
||
- Target has multiple test deliveries; only the most recent one is used for status.
|
||
- The most recent test delivery is queued/deferred; status must show pending without implying success.
|
||
- Users without workspace membership attempt to access targets or deliveries (must be deny-as-not-found).
|
||
- Failure details must not expose secrets (destination URLs, recipients).
|
||
- Rapid repeated test requests (anti-spam / rate limiting) must not create additional delivery records.
|
||
|
||
## Requirements *(mandatory)*
|
||
|
||
**Constitution alignment (required):** This feature introduces a user-triggered action that creates a delivery record and schedules work to be executed asynchronously.
|
||
The spec requires: confirmation, RBAC enforcement, anti-spam rate limiting, audit logging, tenant/workspace isolation, and tests.
|
||
|
||
**Constitution alignment (RBAC-UX):**
|
||
|
||
- Authorization planes involved: Admin UI (workspace-scoped).
|
||
- 404 vs 403 semantics:
|
||
- Non-member / not entitled to workspace scope → 404 (deny-as-not-found)
|
||
- Workspace member but missing manage capability → 403 for executing the test action
|
||
- All mutations (test request) require server-side authorization.
|
||
|
||
**Constitution alignment (BADGE-001):** “Last test: Sent/Failed/Pending/Never” MUST use centralized badge semantics (no ad-hoc mappings).
|
||
|
||
**Constitution alignment (Filament Action Surfaces):** This feature modifies Filament pages (Alert Target view/edit) and therefore includes a UI Action Matrix.
|
||
|
||
### Functional Requirements
|
||
|
||
- **FR-001 (Derived status, no new fields)**: The system MUST display a “Last test status” indicator on Alert Target View and Edit pages derived solely from existing alert delivery records.
|
||
- **FR-002 (Deterministic selection)**: The “Last test status” MUST be derived from the single most recent delivery record for the given target where the delivery event type is “alerts.test”, ordered by `created_at` (desc) then `id` (desc).
|
||
- **FR-003 (Status mapping)**: The system MUST map the most recent test delivery record to one of: Never (no record), Sent, Failed, or Pending.
|
||
- **FR-004 (Timestamp semantics)**: The UI MUST display a timestamp that reflects when the outcome occurred: Sent → `sent_at`; Failed → `updated_at`; Pending → `send_after`.
|
||
- **FR-005 (DB-only UI)**: Requesting a test send MUST not perform synchronous external delivery attempts in the user’s request/response flow.
|
||
- **FR-006 (Confirmation)**: The “Send test message” action MUST require explicit confirmation, explaining that it will contact the configured destination.
|
||
- **FR-007 (Anti-spam rate limit)**: The system MUST prevent repeated test requests for the same target within 60 seconds.
|
||
- **FR-008 (RBAC)**: Only workspace members with manage permission can request a test send; view-only users can see the action but cannot execute it.
|
||
- **FR-009 (Deny-as-not-found)**: Users without workspace membership MUST receive deny-as-not-found behavior for targets and deliveries.
|
||
- **FR-010 (Auditability)**: The system MUST record an audit event when a test is requested, without including destination secrets.
|
||
- **FR-011 (Deep link)**: The system SHOULD provide a “View last delivery” link from the target to the Deliveries list viewer filtered to that target and `event_type=alerts.test`.
|
||
- **FR-012 (Deep link visibility)**: The system SHOULD show “View last delivery” only when at least one test delivery exists for the target.
|
||
|
||
### Assumptions
|
||
|
||
- Alerts v1 already provides Alert Targets, Alert Deliveries, and a Deliveries viewer.
|
||
- A test send is represented as a delivery record with event type “alerts.test”.
|
||
|
||
### Non-Goals
|
||
|
||
- No new database fields for storing “last test status”.
|
||
- No bulk “test all targets” feature.
|
||
- No destination setup wizard.
|
||
- No per-row list view badge (avoids performance/N+1 concerns in v1).
|
||
|
||
## UI Action Matrix *(mandatory when Filament is changed)*
|
||
|
||
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|
||
|---|---|---|---|---|---|---|---|---|---|---|
|
||
| Alert Target (View) | Alert Target view page | Send test message (confirm, manage-only), View last delivery (navigate) | Not changed in this feature | Not changed in this feature | None | None | Same as Header Actions | Not applicable | Yes | View-only users see disabled “Send test message”. |
|
||
| Alert Target (Edit) | Alert Target edit page | Send test message (confirm, manage-only), View last delivery (navigate) | Not changed in this feature | Not changed in this feature | None | None | Same as Header Actions | Existing save/cancel | Yes | “Last test status” appears above the form. |
|
||
| Deliveries viewer | Deliveries list/details | None (existing) | Filtered via deep link | Existing row actions | Existing | Existing | Existing | Not applicable | Existing | Must remain workspace-scoped. |
|
||
|
||
### Key Entities *(include if feature involves data)*
|
||
|
||
- **Alert Target**: A destination configuration for alerts (e.g., Teams webhook or email destination), scoped to a workspace.
|
||
- **Alert Delivery**: A delivery attempt record that captures event type (including “alerts.test”), status, timestamps, and safe diagnostic details.
|
||
- **Audit Event**: A workspace-scoped audit entry representing a user-triggered test request.
|
||
|
||
## Success Criteria *(mandatory)*
|
||
|
||
### Measurable Outcomes
|
||
|
||
- **SC-001**: An admin can determine “last test status” for a target within 5 seconds from the target page.
|
||
- **SC-002**: An admin can request a test send in under 30 seconds (including confirmation) without leaving the target page.
|
||
- **SC-003**: A test request always results in either (a) a new test delivery record being created, or (b) a clear refusal due to rate limiting or missing permissions.
|
||
- **SC-004**: Troubleshooting time for “alerts not delivered” issues is reduced because the last test outcome and a direct link to details are immediately available.
|