--- description: "Task list for 100 — Alert Targets: Send Test Message + Last Test Status (input: 099.1)" --- # Tasks: Alert Targets — Send Test Message + Last Test Status (Teams + Email) **Input**: Design documents from `specs/100-alert-target-test-actions/` **Prerequisites**: - `specs/100-alert-target-test-actions/spec.md` (user stories + priorities) - `specs/100-alert-target-test-actions/plan.md` (implementation approach) - `specs/100-alert-target-test-actions/research.md` (decisions) - `specs/100-alert-target-test-actions/data-model.md` (tenantless test deliveries) - `specs/100-alert-target-test-actions/contracts/` (event type + deep link filters) **Tests**: REQUIRED (Pest) for all runtime behavior changes. ## Format: `- [ ] [TaskID] [P?] [Story?] Description with file path` - **[P]**: can run in parallel (different files, no dependencies on incomplete tasks) - **[US1] [US2] [US3]**: user story mapping (required for story phases) --- ## Phase 1: Setup (Shared) **Purpose**: Ensure local dev/test workflow is concrete for this feature. - [X] T001 Update test quickstart commands in specs/100-alert-target-test-actions/quickstart.md --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Enable tenantless test deliveries + keep workspace isolation and RBAC correct. - [X] T002 Create migration to allow tenantless test deliveries + add supporting index in database/migrations/2026_02_18_000001_make_alert_deliveries_tenant_and_rule_nullable_for_test_deliveries.php - [X] T003 Create tenant-optional workspace isolation trait in app/Support/Concerns/DerivesWorkspaceIdFromTenantWhenPresent.php - [X] T004 Switch AlertDelivery to tenant-optional isolation in app/Models/AlertDelivery.php - [X] T005 Add AlertDeliveryFactory support for tenantless deliveries in database/factories/AlertDeliveryFactory.php - [X] T006 Add audit action id for test request in app/Support/Audit/AuditActionId.php **Checkpoint**: Tenantless `alert_deliveries` records can be created safely, and audit IDs exist. --- ## Phase 3: User Story 1 — Send a test message for a target (Priority: P1) 🎯 MVP **Goal**: Capability-gated “Send test message” action creates a test delivery record and queues delivery asynchronously. **Independent Test**: A manage-capable workspace member can request a test send; a new `alert_deliveries` row exists with `event_type=alerts.test`, and the queue has a `DeliverAlertsJob`. ### Tests (write first) - [X] T007 [P] [US1] Add send-test action happy-path test in tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php - [X] T008 [P] [US1] Add rate-limit refusal test in tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php - [X] T009 [P] [US1] Add authorization (readonly forbidden) test in tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php - [X] T010 [P] [US1] Add non-member deny-as-not-found (404) regression test in tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php - [X] T011 [P] [US1] Add audit log assertion test in tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php - [X] T012 [P] [US1] Add confirmation requirement test for the Filament action in tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php ### Implementation - [X] T013 [US1] Add canonical test event type constant in app/Models/AlertDelivery.php - [X] T014 [US1] Implement test delivery creation service in app/Services/Alerts/AlertDestinationTestMessageService.php - [X] T015 [US1] Add "Send test message" header action on edit page in app/Filament/Resources/AlertDestinationResource/Pages/EditAlertDestination.php **Checkpoint**: US1 passes its feature tests and performs no outbound calls in the request thread. --- ## Phase 4: User Story 2 — See the last test status at a glance (Priority: P2) **Goal**: Show derived “Last test: Never/Sent/Failed/Pending” badge with deterministic, DB-only semantics. **Independent Test**: With controlled `alert_deliveries` rows, the target page shows the correct derived status and timestamp without external calls. ### Tests (write first) - [X] T016 [P] [US2] Add badge semantics tests for delivery + last-test domains in tests/Feature/Badges/AlertDeliveryAndLastTestBadgeSemanticsTest.php - [X] T017 [P] [US2] Add derived last-test mapping test (never/sent/failed/pending) in tests/Feature/Alerts/AlertDestinationLastTestStatusTest.php ### Implementation - [ ] T018 [P] [US2] Add last-test status enum + result DTO in app/Support/Alerts/AlertDestinationLastTestStatus.php - [ ] T019 [US2] Implement last-test resolver (latest alerts.test row) in app/Services/Alerts/AlertDestinationLastTestResolver.php - [ ] T020 [US2] Add badge domains for alert delivery + destination last-test in app/Support/Badges/BadgeDomain.php - [ ] T021 [US2] Register new badge mappers in app/Support/Badges/BadgeCatalog.php - [ ] T022 [P] [US2] Implement badge mapper for delivery status in app/Support/Badges/Domains/AlertDeliveryStatusBadge.php - [ ] T023 [P] [US2] Implement badge mapper for destination last-test status in app/Support/Badges/Domains/AlertDestinationLastTestStatusBadge.php - [ ] T024 [US2] Refactor delivery status badges to use BadgeCatalog in app/Filament/Resources/AlertDeliveryResource.php - [ ] T025 [US2] Add read-only View page for alert destinations in app/Filament/Resources/AlertDestinationResource/Pages/ViewAlertDestination.php - [ ] T026 [US2] Register view page and route view-only users from list in app/Filament/Resources/AlertDestinationResource.php - [ ] T027 [US2] Render “Last test” badge + timestamp on view page in app/Filament/Resources/AlertDestinationResource/Pages/ViewAlertDestination.php - [ ] T028 [US2] Render “Last test” badge + timestamp on edit page in app/Filament/Resources/AlertDestinationResource/Pages/EditAlertDestination.php **Checkpoint**: US2 is fully readable by view-only users (via View page) and meets BADGE-001. --- ## Phase 5: User Story 3 — Jump from target to the relevant delivery details (Priority: P3) **Goal**: Provide a “View last delivery” deep link into the Deliveries viewer filtered by `alerts.test` and destination. **Independent Test**: When at least one test delivery exists, the link appears and routes to `/admin/alert-deliveries` with the correct `filters[...]` query string. ### Tests (write first) - [X] T029 [P] [US3] Add deep-link visibility + URL contract test in tests/Feature/Alerts/AlertDestinationViewLastDeliveryLinkTest.php - [X] T030 [P] [US3] Add deliveries viewer filter coverage test in tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php ### Implementation - [X] T031 [US3] Add table filters for event_type + alert_destination_id in app/Filament/Resources/AlertDeliveryResource.php - [X] T032 [US3] Allow tenantless deliveries in deliveries list query in app/Filament/Resources/AlertDeliveryResource.php - [X] T033 [US3] Update tenant entitlement policy to allow tenantless delivery records in app/Policies/AlertDeliveryPolicy.php - [X] T034 [US3] Add "View last delivery" header action (view page) in app/Filament/Resources/AlertDestinationResource/Pages/ViewAlertDestination.php - [X] T035 [US3] Add "View last delivery" header action (edit page) in app/Filament/Resources/AlertDestinationResource/Pages/EditAlertDestination.php **Checkpoint**: US3 deep links match the contract in specs/100-alert-target-test-actions/contracts/filament-deep-link-filters.md. --- ## Phase 6: Polish & Cross-Cutting Concerns - [X] T036 [P] Run Pint on changed files with vendor/bin/sail bin pint --dirty - [X] T037 Run focused test suite for this feature with vendor/bin/sail artisan test --compact tests/Feature/Alerts/AlertDestinationSendTestMessageTest.php - [X] T038 Run focused badge tests with vendor/bin/sail artisan test --compact tests/Feature/Badges/AlertDeliveryAndLastTestBadgeSemanticsTest.php --- ## Dependencies & Execution Order ### Dependency graph (user stories) ```mermaid graph TD F[Phase 2: Foundational] --> US1[US1: Send test message] F --> US2[US2: Last test status] US2 --> US3[US3: View last delivery deep link] ``` - **Foundational (Phase 2)** blocks all user stories. - **US1** can be delivered as MVP after Phase 2. - **US2** adds read-only visibility and centralized badge semantics. - **US3** depends on US2 resolver/view surface (or duplicate a small existence query if needed). --- ## Parallel execution examples ### US1 - `T007–T012` can be written in parallel (single test file, but separate assertions can be split across commits). - `T013` (model constant) and `T014` (service) can be done before `T015` (Filament action). ### US2 - `T022` and `T023` (badge mappers) can be implemented in parallel. - `T018` (enum/DTO) and `T019` (resolver) can be done before wiring UI. ### US3 - `T031–T033` (deliveries viewer plumbing) can proceed in parallel with `T034–T035` (target header actions) once the resolver is available. --- ## Implementation strategy ### MVP first 1. Complete Phase 2 (Foundational) 2. Implement and ship US1 (Send test message) 3. Validate with focused tests ### Incremental delivery - Add US2 (Last test status + View page) after US1 is stable - Add US3 (Deep link + deliveries filters) last