Some checks failed
Main Confidence / confidence (push) Failing after 51s
## 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
190 lines
6.2 KiB
Markdown
190 lines
6.2 KiB
Markdown
# 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**:
|
|
|
|
- `id`
|
|
- `type`
|
|
- `notifiable_type`
|
|
- `notifiable_id`
|
|
- `data`
|
|
- `read_at`
|
|
- `created_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`, and `diagnostic_reason_code` remains 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**:
|
|
|
|
- `id`
|
|
- `tenant_id`
|
|
- `workspace_id`
|
|
- `severity`
|
|
- `status`
|
|
- `owner_user_id`
|
|
- `assignee_user_id`
|
|
- `due_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**:
|
|
|
|
- `id`
|
|
- `type`
|
|
- `status`
|
|
- `outcome`
|
|
- `tenant_id`
|
|
- `context`
|
|
- `summary_counts`
|
|
- `failure_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**:
|
|
|
|
- `title`
|
|
- `body`
|
|
- `status`
|
|
- `primaryAction.label`
|
|
- `primaryAction.url`
|
|
- `primaryAction.target`
|
|
- `supportingLines[]`
|
|
- `metadata`
|
|
|
|
**Validation rules**:
|
|
|
|
- Every in-scope consumer provides exactly one primary action.
|
|
- `status` remains the single source for the existing Filament icon treatment; the feature does not introduce a second icon taxonomy.
|
|
- `supportingLines` is optional and never replaces `body` or the primary action.
|
|
- `metadata` may carry consumer-specific namespaced fields, but the shared primary structure remains stable.
|
|
|
|
### NotificationPrimaryAction
|
|
|
|
**Purpose**: Canonical one-action model for secondary context notifications.
|
|
|
|
**Fields**:
|
|
|
|
- `label`
|
|
- `url`
|
|
- `target`
|
|
|
|
**Allowed targets**:
|
|
|
|
- `finding_detail`
|
|
- `admin_operation_run`
|
|
- `tenantless_operation_run`
|
|
- `system_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**:
|
|
|
|
- `findingId`
|
|
- `tenantId`
|
|
- `eventType`
|
|
- `title`
|
|
- `body`
|
|
- `recipientReason`
|
|
- `tenantName`
|
|
- `severity`
|
|
- `fingerprintKey`
|
|
- `dueCycleKey`
|
|
|
|
**Rules**:
|
|
|
|
- Primary wording remains finding-first and uses `Open finding` as the action label.
|
|
- `recipientReason` stays supporting context, not the headline.
|
|
|
|
### OperationRunNotificationPresentationInput
|
|
|
|
**Purpose**: Consumer-specific derived input used by the shared contract for queued and terminal run notifications.
|
|
|
|
**Fields**:
|
|
|
|
- `runId`
|
|
- `operationType`
|
|
- `status`
|
|
- `outcome`
|
|
- `targetPlane`
|
|
- `openUrl`
|
|
- `openLabel`
|
|
- `guidanceLines[]`
|
|
- `summaryLine`
|
|
- `reasonTranslation`
|
|
|
|
**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.data` remains the only persisted artifact for in-app delivery.
|
|
- Existing event semantics from Spec 224 and current operation notification behavior remain unchanged. |