73 lines
3.7 KiB
Markdown
73 lines
3.7 KiB
Markdown
# Phase 0 Research: Ops-UX Constitution Rollout (v1.3.0 Alignment) (055)
|
||
|
||
**Date**: 2026-01-18
|
||
|
||
## Findings
|
||
|
||
### Current operation-run storage and UX primitives
|
||
|
||
- The repo has a tenant-scoped `operation_runs` table and an `OperationRun` model.
|
||
- Structured “metrics” for this rollout are stored as `operation_runs.summary_counts` (JSONB).
|
||
- Canonical Monitoring entrypoint exists via the Filament resource `OperationRunResource`.
|
||
- Canonical route building already exists in `App\Support\OperationRunLinks`.
|
||
|
||
### Existing progress widget patterns
|
||
|
||
- A bottom-right Livewire widget exists today for bulk operations: `App\Livewire\BulkOperationProgress`.
|
||
- It is injected globally via a Filament render hook in `App\Providers\Filament\AdminPanelProvider`.
|
||
- Current behavior is not constitution-compliant:
|
||
- It shows terminal states and renders terminal wording.
|
||
- It renders percentages and per-run counts unconditionally.
|
||
- It is user-scoped today (filters by `user_id = auth()->id()`).
|
||
|
||
### Notifications
|
||
|
||
- Filament database notifications are already used and are persistent by default.
|
||
- Current code has OperationRun DB notifications (queued + completed), but this rollout requires:
|
||
- no queued DB notifications
|
||
- exactly one terminal notification per run
|
||
- initiator-only audience
|
||
|
||
## Decisions
|
||
|
||
### Decision 1: Tenant-wide progress widget scope
|
||
- **Chosen**: The progress widget shows all active runs for the current tenant (not only runs started by the current user), for users with access to Monitoring → Operations.
|
||
- **Rationale**: Aligns with the constitution’s tenant-scoped operations model and avoids “why don’t I see what’s running?” support loops.
|
||
- **Alternatives considered**:
|
||
- User-only widget: rejected (hides tenant work and defeats the monitoring intent).
|
||
|
||
### Decision 2: Canonical metrics source
|
||
- **Chosen**: Treat `operation_runs.summary_counts` as the canonical “metrics” field for this rollout.
|
||
- **Rationale**: Matches existing schema; avoids adding a new `metrics` column during a UX migration.
|
||
- **Alternatives considered**:
|
||
- New `operation_runs.metrics` column: rejected (scope increase + migration risk).
|
||
|
||
### Decision 3: Unknown operation types in UI
|
||
- **Chosen**: Soft-fail at runtime with label `Unknown operation`, and fail-fast in CI for code-produced operation types.
|
||
- **Rationale**: Keeps Monitoring usable for legacy/dirty data while enforcing discipline for new work.
|
||
- **Alternatives considered**:
|
||
- Throw exception at runtime: rejected (breaks Monitoring for historical data).
|
||
- Render raw type string: rejected (leaks internal naming and encourages drift).
|
||
|
||
### Decision 4: DB notification audience
|
||
- **Chosen**: Initiator-only for terminal DB notifications.
|
||
- **Rationale**: Prevents tenant-wide notification spam; Monitoring remains the tenant-wide audit surface.
|
||
- **Alternatives considered**:
|
||
- Tenant-wide fan-out: rejected (noisy; not necessary for monitoring).
|
||
|
||
### Decision 5: No queued DB notifications
|
||
- **Chosen**: Ban queued DB notifications repo-wide for OperationRuns.
|
||
- **Rationale**: Simplifies dedupe; queued intent belongs to the toast surface.
|
||
- **Alternatives considered**:
|
||
- Allow queued DB notifications with dedupe: rejected (still noisy; adds edge cases).
|
||
|
||
### Decision 6: Migration approach for progress widget
|
||
- **Chosen**: Reuse the existing “global Livewire progress widget via render hook” pattern, but migrate it to query `OperationRun` and apply constitution rules.
|
||
- **Rationale**: Low-risk way to ship a single widget surface across the app.
|
||
- **Alternatives considered**:
|
||
- Per-feature widgets/pages: rejected (violates the “three surfaces only” rule).
|
||
|
||
## Open Questions
|
||
|
||
None (all clarifications captured in the feature spec).
|