## Summary - add conditional polling support for the tenantless operation run viewer and tenant review pack card - add focused Pest coverage for active vs terminal polling behavior and related review pack access regressions - add the full Spec Kit artifacts for Spec 123, including spec, plan, research, data model, contracts, quickstart, tasks, and checklist ## Testing - `vendor/bin/sail artisan test --compact tests/Feature/OpsUx/RunDetailPollingStopsOnTerminalTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/ReviewPack/ReviewPackWidgetTest.php tests/Feature/ReviewPack/ReviewPackGenerationTest.php tests/Feature/ReviewPack/ReviewPackRbacTest.php` - `vendor/bin/sail bin pint --dirty --format agent` ## Notes - Manual QA task `T014` in the Spec Kit checklist remains to be completed outside this automated flow. - Livewire v4.0+ compliance is unchanged. - No panel provider changes were made; provider registration remains in `bootstrap/providers.php`. - No global-search behavior was changed. - No destructive actions were added or modified. - No new Filament assets were introduced; existing deployment expectations for `php artisan filament:assets` remain unchanged. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #149
48 lines
4.1 KiB
Markdown
48 lines
4.1 KiB
Markdown
# 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 helper’s 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 widget’s 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.
|