## Summary - converge finding, queued, and completed database notifications on one shared `OperationUxPresenter` presentation contract - preserve existing finding and operation deep-link authorities while standardizing title, body, status/icon treatment, and single primary action - add focused notification, findings, and guard coverage plus the full feature 230 spec artifacts ## Validation - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php tests/Feature/Notifications/OperationRunNotificationTest.php tests/Feature/Notifications/FindingNotificationLinkTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingsNotificationEventTest.php tests/Feature/Findings/FindingsNotificationRoutingTest.php tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.php` ## Filament / Platform Notes - Livewire v4.0+ compliance preserved on Filament v5 primitives - provider registration remains unchanged in `apps/platform/bootstrap/providers.php` - no globally searchable resource behavior changed in this feature - no destructive actions were introduced - asset strategy is unchanged; the existing `cd apps/platform && php artisan filament:assets` deploy step remains sufficient Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #265
17 KiB
Tasks: Findings Notification Presentation Convergence
Input: Design documents from /specs/230-findings-notification-convergence/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/findings-notification-convergence.logical.openapi.yaml, quickstart.md
Tests: Required. This feature changes runtime behavior in operator-facing database notification payload composition and preserved route targeting, so Pest coverage must be added or updated in apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php, apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php, apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php, apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php, apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php, and apps/platform/tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.php.
Operations: No new OperationRun is introduced. Existing queued and terminal operation notification consumers remain in scope only for presentation convergence in apps/platform/app/Notifications/OperationRunQueued.php and apps/platform/app/Notifications/OperationRunCompleted.php; emit policy and run lifecycle semantics must remain unchanged.
RBAC: Finding notifications stay on the tenant /admin/t/{tenant}/findings/{finding} plane and operation notifications keep their current admin /admin/operations/{run} or platform /system/ops/runs/{run} destinations. The implementation must preserve non-member or hidden-scope 404, in-scope missing-capability 403, tenant-safe deep links, and current plane-specific visibility semantics.
UI / Surface Guardrails: The existing Filament database-notification drawer remains the only collection surface and is a global-context-shell seam. Every in-scope card must keep exactly one primary action, no row click, no destructive action, and no custom notification shell.
Filament UI Action Surfaces: FindingEventNotification, OperationRunQueued, and OperationRunCompleted remain utility or system notification entry points with one inspect model each. No new page family, no new action group, and no second notification center may be introduced.
Badges: Existing severity, status, and outcome semantics remain authoritative. This feature must not introduce ad-hoc badge mappings or a new status taxonomy.
Organization: Tasks are grouped by user story so each slice stays incrementally testable once the shared seam from earlier phases is present. Recommended delivery order is US1 -> US2 -> US3 because the shared primary card structure must stabilize before route-truth and future-bypass guardrails are extended.
Test Governance Checklist
- Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
- Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
- Planned validation commands cover the change without pulling in unrelated lane cost.
- The declared surface test profile or
standard-native-filamentrelief is explicit. - Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.
Phase 1: Setup (Shared Notification Test Surfaces)
Purpose: Prepare the focused regression surfaces that will prove the shared notification contract.
- T001 [P] Create the shared contract test scaffold in
apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php - T002 [P] Extend the finding notification test scaffold in
apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php - T003 [P] Extend the operation notification test scaffold in
apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php
Checkpoint: Shared contract, finding notification, and operation notification test surfaces are ready for implementation work.
Phase 2: Foundational (Blocking Shared Presentation Seam)
Purpose: Establish the canonical shared presentation path and repo guardrails before any story implementation begins.
CRITICAL: No user story work should begin until this phase is complete.
- T004 Implement the shared operator database-notification builder, status-to-icon mapping, and supporting-line composition in
apps/platform/app/Support/OpsUx/OperationUxPresenter.php - T005 Add baseline cross-consumer contract assertions for shared structure and status-to-icon treatment in
apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php - T006 Extend the in-scope local-payload bypass guard in
apps/platform/tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.php
Checkpoint: The shared presentation seam exists, the baseline contract is testable, and CI can detect direct local bypasses of the in-scope notification family.
Phase 3: User Story 1 - Scan Notifications Without Relearning The Surface (Priority: P1)
Goal: Give finding and operation notifications one shared primary card structure so operators can read both without reinterpreting the surface.
Independent Test: Trigger one finding notification and one operation notification, then verify both render the same primary structure: a title naming the target object, a primary body summarizing the change, one status emphasis with the existing Filament icon treatment, exactly one primary action, and optional supporting context that stays secondary.
Tests for User Story 1
- T007 [P] [US1] Add finding shared-card structure and status-to-icon assertions in
apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php - T008 [P] [US1] Add queued and completed run shared-card structure and status-to-icon assertions in
apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php
Implementation for User Story 1
- T009 [P] [US1] Route
apps/platform/app/Notifications/Findings/FindingEventNotification.phpthrough the shared presentation builder while preservingfinding_eventmetadata - T010 [P] [US1] Route
apps/platform/app/Notifications/OperationRunQueued.phpthrough the shared presentation builder while preserving queued-state copy and one primary action - T011 [P] [US1] Normalize
apps/platform/app/Notifications/OperationRunCompleted.phponto the same primary structure while keeping summary and reason translation as secondary context
Checkpoint: User Story 1 is independently functional and finding plus operation notifications share one primary card grammar.
Phase 4: User Story 2 - Trust Notification Actions And Scope Rules (Priority: P1)
Goal: Preserve correct finding and operation destinations plus current 404 versus 403 behavior while the shared presentation seam is introduced.
Independent Test: After US1 is in place, open finding and operation notification actions as entitled and non-entitled users, then verify the correct tenant, admin, tenantless, or system destination opens and existing authorization semantics remain unchanged.
Tests for User Story 2
- T012 [P] [US2] Add tenant-safe
404versus403action-link assertions inapps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php - T013 [P] [US2] Add admin, tenantless, and system-plane action-link assertions in
apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php - T014 [P] [US2] Keep Spec 224 finding event and routing behavior covered under the new presentation path in
apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.phpandapps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php
Implementation for User Story 2
- T015 [US2] Preserve the
Open findinglabel and tenant detail route authority inapps/platform/app/Notifications/Findings/FindingEventNotification.php - T016 [US2] Preserve admin, tenantless, and platform-user system destinations in
apps/platform/app/Notifications/OperationRunQueued.phpandapps/platform/app/Notifications/OperationRunCompleted.php - T017 [US2] Verify canonical operation action labels and route helpers remain authoritative in
apps/platform/app/Support/OperationRunLinks.phpandapps/platform/app/Support/System/SystemOperationRunLinks.php, applying only minimal normalization if the shared contract requires it
Checkpoint: User Story 2 is independently functional and the shared card structure does not alter route truth or authorization semantics.
Phase 5: User Story 3 - Keep Future Work-Update Notifications Familiar (Priority: P2)
Goal: Lock the new shared contract in place so later in-scope notification consumers cannot silently reintroduce a local primary grammar.
Independent Test: After US1 and US2 are in place, assert that the in-scope finding and operation consumers expose exactly one primary action through the shared contract and that guard coverage fails if a future in-scope consumer builds its primary payload locally.
Tests for User Story 3
- T018 [P] [US3] Add regression assertions that all in-scope consumers expose exactly one primary action, keep shared status-to-icon treatment, and keep secondary metadata namespaced in
apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php - T019 [P] [US3] Extend future-bypass and FR-015 boundary guard coverage in
apps/platform/tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.php
Implementation for User Story 3
- T020 [US3] Encapsulate consumer input mapping for finding, queued-run, and completed-run notifications inside
apps/platform/app/Support/OpsUx/OperationUxPresenter.php - T021 [US3] Keep consumer-specific metadata secondary in
apps/platform/app/Notifications/Findings/FindingEventNotification.phpandapps/platform/app/Notifications/OperationRunCompleted.php - T022 [US3] Keep queued notification supporting context minimal and inside the shared contract in
apps/platform/app/Notifications/OperationRunQueued.phpandapps/platform/app/Support/OpsUx/OperationUxPresenter.php
Checkpoint: User Story 3 is independently functional and future in-scope notification work is steered toward the shared contract instead of local payload composition.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Finish copy review, formatting, and the narrow proving workflow for the full feature.
- T023 Review operator-facing notification copy, status-emphasis grammar, and one-primary-action ordering in
apps/platform/app/Support/OpsUx/OperationUxPresenter.php,apps/platform/app/Notifications/Findings/FindingEventNotification.php,apps/platform/app/Notifications/OperationRunQueued.php, andapps/platform/app/Notifications/OperationRunCompleted.php - T024 Run formatting for
apps/platform/app/Support/OpsUx/OperationUxPresenter.php,apps/platform/app/Notifications/Findings/FindingEventNotification.php,apps/platform/app/Notifications/OperationRunQueued.php,apps/platform/app/Notifications/OperationRunCompleted.php,apps/platform/app/Support/OperationRunLinks.php,apps/platform/app/Support/System/SystemOperationRunLinks.php,apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php,apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php,apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php,apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php,apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php, andapps/platform/tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.phpwithcd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent - T025 Run the focused validation workflow from
specs/230-findings-notification-convergence/quickstart.mdagainstapps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php,apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php,apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php,apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php,apps/platform/tests/Feature/Findings/FindingsNotificationRoutingTest.php, andapps/platform/tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.php
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): Starts immediately and prepares the focused test surfaces.
- Foundational (Phase 2): Depends on Setup and blocks all user story work until the shared presentation seam and baseline guard are in place.
- User Story 1 (Phase 3): Depends on Foundational completion and is the recommended MVP cut.
- User Story 2 (Phase 4): Depends on User Story 1 because route and scope truth must be validated against the converged primary structure, not the pre-convergence local grammars.
- User Story 3 (Phase 5): Depends on User Story 1 and User Story 2 because spread-control guardrails must lock the final shared contract and preserved route behavior, not an intermediate shape.
- Polish (Phase 6): Depends on all desired user stories being complete.
User Story Dependencies
- US1: No dependencies beyond Foundational.
- US2: Follow-on slice after US1 establishes the shared primary structure.
- US3: Follow-on slice after US1 and US2 establish the settled contract and preserved route rules.
Within Each User Story
- Write the story tests first and confirm they fail before implementation is considered complete.
- Keep
apps/platform/app/Support/OpsUx/OperationUxPresenter.phpauthoritative for shared primary structure instead of duplicating card grammar in notification classes. - Finish story-level verification before moving to the next priority slice.
Parallel Opportunities
T001,T002, andT003can run in parallel during Setup.T007andT008can run in parallel for User Story 1, followed byT009,T010, andT011in parallel afterT004is complete.T012,T013, andT014can run in parallel for User Story 2.T018andT019can run in parallel for User Story 3.
Parallel Example: User Story 1
# User Story 1 tests in parallel
T007 apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php
T008 apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php
# User Story 1 implementation in parallel after T004
T009 apps/platform/app/Notifications/Findings/FindingEventNotification.php
T010 apps/platform/app/Notifications/OperationRunQueued.php
T011 apps/platform/app/Notifications/OperationRunCompleted.php
Parallel Example: User Story 2
# User Story 2 tests in parallel
T012 apps/platform/tests/Feature/Notifications/FindingNotificationLinkTest.php
T013 apps/platform/tests/Feature/Notifications/OperationRunNotificationTest.php
T014 apps/platform/tests/Feature/Findings/FindingsNotificationEventTest.php
Parallel Example: User Story 3
# User Story 3 guard and contract tests in parallel
T018 apps/platform/tests/Feature/Notifications/SharedDatabaseNotificationContractTest.php
T019 apps/platform/tests/Feature/OpsUx/Constitution/LegacyNotificationGuardTest.php
Implementation Strategy
MVP First (User Story 1 Only)
- Complete Phase 1: Setup.
- Complete Phase 2: Foundational.
- Complete Phase 3: User Story 1.
- Validate the feature against the focused US1 tests before widening the slice.
Incremental Delivery
- Ship US1 to converge the primary card structure across findings and operations.
- Add US2 to prove route truth and authorization semantics stayed intact.
- Add US3 to lock the shared contract in place for future in-scope notification work.
- Finish with copy review, formatting, and the focused validation pack.
Parallel Team Strategy
- One contributor can prepare the shared contract test and guard work while another extends finding and operation notification test surfaces.
- After Foundational work lands, finding, queued-run, and completed-run notification classes can be aligned in parallel against the shared presenter seam.
- Route-truth tests can proceed in parallel with preserved-link implementation once the shared primary structure is stable.
Notes
[P]tasks target different files and can be worked independently once upstream blockers are cleared.[US1],[US2], and[US3]map directly to the feature specification user stories.- The suggested MVP scope is Phase 1 through Phase 3 only.
- All implementation tasks above follow the required checklist format with task ID, optional parallel marker, story label where applicable, and exact file paths.