# 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 ” 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.