TenantAtlas/specs/123-operations-auto-refresh/research.md
2026-03-08 11:34:09 +01:00

48 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Research — Operations Auto-Refresh Pass
## Decision: Reuse the shared run-detail polling helper for the tenantless operation run viewer
### Rationale
- The canonical operation detail surface already centralizes conditional polling in `App\Support\OpsUx\RunDetailPolling`.
- `OperationRunResource::infolist()` already applies the established safeguards: stop polling when the browser tab is hidden and when Filament action modals are mounted.
- `TenantlessOperationRunViewer` already delegates its infolist rendering to `OperationRunResource`, so the least-risk implementation path is to keep the tenantless page aligned with that shared detail-view contract instead of introducing a second polling policy.
- Existing tests already cover the helpers active-versus-terminal behavior, which reduces the amount of new logic that needs fresh regression coverage.
### Alternatives considered
- **Hard-code a new fixed `10s` interval inside `TenantlessOperationRunViewer`** — rejected because it would fork the run-detail behavior from the canonical operation detail pattern and risk drifting from the shared hidden-tab and modal-open guards.
- **Duplicate the `RunDetailPolling` logic inside the page class** — rejected because it would create a second source of truth for active run polling.
## Decision: Treat review pack `queued` and `generating` as the only active card states
### Rationale
- `ReviewPackStatus` defines a card-specific lifecycle: `queued`, `generating`, `ready`, `failed`, `expired`.
- The widget view already renders `queued` and `generating` as the same in-progress state and renders `ready`, `failed`, and `expired` as terminal states.
- `ReviewPackService` creates new records in `queued`, and `GenerateReviewPackJob` advances them into `generating` before landing in `ready` or `failed`.
- Using the review-pack lifecycle directly avoids over-polling when unrelated tenant operation runs are active.
### Alternatives considered
- **Drive the card from tenant-wide `ActiveRuns::existForTenant()`** — rejected because this would keep the card polling for unrelated operations even when review-pack generation is not active.
- **Poll whenever any review pack exists** — rejected because terminal states must remain stable and stop refreshing.
## Decision: Attach review-pack polling at the widget root using the existing simple-widget Blade pattern
### Rationale
- `TenantReviewPackCard` is a plain Filament `Widget`, not a table or stats widget.
- The closest established pattern is `NeedsAttention`, which computes a `pollingInterval` in PHP and conditionally emits `wire:poll.{interval}` on the root Blade element.
- A root-level `wire:poll.10s` keeps the implementation small, readable, and consistent with the other lightweight dashboard widgets in the product.
### Alternatives considered
- **Introduce a new shared global polling framework** — rejected because the spec explicitly excludes a broader polling rewrite.
- **Move review-pack polling into JavaScript or browser events** — rejected because the product already relies on Livewire/Filament polling for similar surfaces and the requested scope is intentionally small.
## Decision: Extend existing helper and widget tests instead of inventing new verification infrastructure
### Rationale
- `tests/Feature/OpsUx/RunDetailPollingStopsOnTerminalTest.php` already verifies the canonical helper stops polling on terminal operation states and remains active for `queued`/`running` runs.
- `tests/Feature/ReviewPack/ReviewPackWidgetTest.php` already covers the widgets empty, active, and terminal render states and is the most direct place to add polling assertions.
- `tests/Feature/Operations/TenantlessOperationRunViewerTest.php` already covers tenantless access semantics and is the right page-level companion if markup-level assertions are needed.
### Alternatives considered
- **Add a brand-new standalone polling test suite** — rejected because the affected behavior already belongs to well-scoped existing helper and widget tests.
- **Rely on manual QA only** — rejected because the spec requires automated coverage for active-versus-terminal polling behavior.