Implements Spec 110 Ops‑UX Enforcement and applies the repo‑wide “enterprise” standard for operation start + dedup surfaces. Key points - Start surfaces: only ephemeral queued toast (no DB notifications for started/queued/running). - Dedup paths: canonical “already queued” toast. - Progress refresh: dispatch run-enqueued browser event so the global widget updates immediately. - Completion: exactly-once terminal DB notification on completion (per Ops‑UX contract). Tests & formatting - Full suite: 1738 passed, 8 skipped (8477 assertions). - Pint: `vendor/bin/sail bin pint --dirty --format agent` (pass). Notable change - Removed legacy `RunStatusChangedNotification` (replaced by the terminal-only completion notification policy). Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #134
1.4 KiB
1.4 KiB
Phase 1 Design: Data Model (No Schema Changes)
This feature does not introduce schema changes. It enforces consistent usage of existing entities.
Entity: OperationRun (operation_runs)
Ownership/scoping:
- Tenant-scoped operational artifact.
- Initiator user is optional (system/scheduled runs).
Key fields (existing):
idworkspace_id/tenant_id(scoping)user_id(initiator; nullable)type(operation type string)status(queued/running/completed)outcome(terminal outcome; nullable until completed)started_at,completed_atsummary_counts(JSON/array of numeric-only whitelisted keys)failure_summary(sanitized bounded array)context(additional metadata; mutable)
Invariants enforced by this feature:
- All transitions of
statusandoutcomehappen throughOperationRunService::updateRun(). - The only operation-related DB notification is the terminal
OperationRunCompleted, emitted when transitioning intocompletedand only whenuser_idexists.
Entity: Database Notifications (notifications)
Ownership/scoping:
- User-scoped records (
notifiable_type=User), used for persistent notification audit.
Invariants enforced by this feature:
- No queued/running state notifications are persisted.
- Exactly one terminal operation completion notification is persisted per OperationRun + initiator.