## 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
6.2 KiB
Data Model: Findings Notification Presentation Convergence
Overview
This feature introduces no new persisted business entity. Existing finding truth, operation-run truth, deep-link helpers, and database-notification rows remain canonical. The new work is a bounded derived presentation layer over those existing records.
Existing Persistent Entities
Database Notification (notifications table)
Purpose: Existing persisted delivery artifact for operator-facing in-app notifications.
Key fields used by this feature:
idtypenotifiable_typenotifiable_iddataread_atcreated_at
Rules relevant to convergence:
- The feature changes only the derived primary payload shape stored in
data. - Existing namespaced metadata such as
finding_event,reason_translation, anddiagnostic_reason_coderemains secondary and consumer-specific. - No new table or projection is added.
Finding
Purpose: Canonical tenant-scoped truth for finding identity, severity, lifecycle, and notification-event context.
Key fields used by this feature:
idtenant_idworkspace_idseveritystatusowner_user_idassignee_user_iddue_at
Rules relevant to convergence:
- The feature does not change how finding events are generated.
- Finding links continue to resolve against the existing tenant-panel detail route.
- Finding-event metadata remains available for downstream consumers and tests.
OperationRun
Purpose: Canonical truth for operation lifecycle, scope, outcome, and supporting notification context.
Key fields used by this feature:
idtypestatusoutcometenant_idcontextsummary_countsfailure_summary
Rules relevant to convergence:
- The feature does not change queued or terminal notification emit rules.
- Existing admin-plane, tenantless, and system-plane link resolution remains authoritative.
- Completed-run guidance and reason translation remain derived from current run truth.
Notifiable Context
Purpose: Determines which route family and supporting context a notification may expose.
Relevant notifiable cases:
- tenant-scoped operator receiving a finding notification
- workspace operator receiving an admin-plane operation notification
- platform user receiving a system-plane operation notification
Rules relevant to convergence:
- Shared presentation must not erase plane-specific destination behavior.
- The shared contract can adapt the action URL by notifiable context, but it cannot widen visibility or flatten authorization semantics.
Derived Models
OperatorDatabaseNotificationPresentation
Purpose: Shared derived contract for the primary structure rendered in the existing Filament notification drawer.
Fields:
titlebodystatusprimaryAction.labelprimaryAction.urlprimaryAction.targetsupportingLines[]metadata
Validation rules:
- Every in-scope consumer provides exactly one primary action.
statusremains the single source for the existing Filament icon treatment; the feature does not introduce a second icon taxonomy.supportingLinesis optional and never replacesbodyor the primary action.metadatamay carry consumer-specific namespaced fields, but the shared primary structure remains stable.
NotificationPrimaryAction
Purpose: Canonical one-action model for secondary context notifications.
Fields:
labelurltarget
Allowed targets:
finding_detailadmin_operation_runtenantless_operation_runsystem_operation_run
Rules:
- There is exactly one primary action per in-scope card.
- The action source remains the existing canonical link helper for that domain and plane.
FindingNotificationPresentationInput
Purpose: Consumer-specific derived input used by the shared contract for FindingEventNotification.
Fields:
findingIdtenantIdeventTypetitlebodyrecipientReasontenantNameseverityfingerprintKeydueCycleKey
Rules:
- Primary wording remains finding-first and uses
Open findingas the action label. recipientReasonstays supporting context, not the headline.
OperationRunNotificationPresentationInput
Purpose: Consumer-specific derived input used by the shared contract for queued and terminal run notifications.
Fields:
runIdoperationTypestatusoutcometargetPlaneopenUrlopenLabelguidanceLines[]summaryLinereasonTranslation
Rules:
- Queued notifications keep their existing queued vocabulary but adopt the shared card structure.
- Completed notifications preserve terminal explanation, summary, and diagnostic fields as supporting context.
- Platform users resolve to the system-panel run detail route; non-platform users keep current admin or tenantless behavior.
Consumer Matrix
| Consumer | Source truth | Primary action target | Required shared fields | Preserved secondary metadata |
|---|---|---|---|---|
FindingEventNotification |
Finding plus existing event envelope |
tenant finding detail | title, body, status with existing icon treatment, Open finding, tenant-safe URL |
finding_event with recipient reason, fingerprint, tenant name, severity |
OperationRunQueued |
OperationRun queued state |
admin or tenantless operation run view | title, body, status with existing icon treatment, open-run label, resolved URL | minimal context derived from current run state only |
OperationRunCompleted |
OperationRun terminal state |
admin, tenantless, or system operation run view | title, body, status with existing icon treatment, open-run label, resolved URL | reason_translation, diagnostic_reason_code, summary lines, failure guidance |
Persistence Boundaries
- No new table, enum-backed persistence, or presentation-only cache is introduced.
- The shared notification contract remains derived from existing finding and operation-run truth.
- Existing
notifications.dataremains the only persisted artifact for in-app delivery. - Existing event semantics from Spec 224 and current operation notification behavior remain unchanged.