TenantAtlas/specs/123-operations-auto-refresh/research.md
ahmido 4db73e872e Spec 123: operations auto-refresh pass (#149)
## 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
2026-03-08 11:11:26 +00:00

48 lines
4.1 KiB
Markdown
Raw Permalink 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.