## 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
99 lines
3.3 KiB
Markdown
99 lines
3.3 KiB
Markdown
# Data Model — Operations Auto-Refresh Pass
|
|
|
|
## Overview
|
|
This feature does not add new tables or columns. It reuses existing persisted state to decide whether two UI surfaces should continue polling.
|
|
|
|
## Entities
|
|
|
|
### OperationRun
|
|
- **Purpose**: Canonical record for queued, running, and completed operational work shown in Monitoring → Operations.
|
|
- **Relevant fields**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id` (nullable for tenantless/canonical monitoring)
|
|
- `type`
|
|
- `status`
|
|
- `outcome`
|
|
- `context`
|
|
- `summary_counts`
|
|
- `failure_summary`
|
|
- `created_at`
|
|
- `started_at`
|
|
- `completed_at`
|
|
- **Relationships**:
|
|
- Belongs to `Workspace`
|
|
- Belongs to `Tenant` (optional)
|
|
- Belongs to initiating `User` (optional)
|
|
- **Polling rule**:
|
|
- Poll while UX-normalized status is `queued` or `running`
|
|
- Stop polling for normalized terminal states such as `succeeded`, `partial`, or `failed`
|
|
- **Derived constraints**:
|
|
- Polling on run-detail surfaces must continue to respect hidden-tab and mounted-action guards
|
|
- No direct lifecycle mutation is added; `OperationRunService` remains the only lifecycle transition owner
|
|
|
|
### ReviewPack
|
|
- **Purpose**: Persisted output of tenant review pack generation for a tenant-scoped admin surface.
|
|
- **Relevant fields**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id`
|
|
- `operation_run_id`
|
|
- `initiated_by_user_id`
|
|
- `status`
|
|
- `options`
|
|
- `summary`
|
|
- `generated_at`
|
|
- `expires_at`
|
|
- `file_path`
|
|
- `file_disk`
|
|
- `file_size`
|
|
- `created_at`
|
|
- `updated_at`
|
|
- **Relationships**:
|
|
- Belongs to `Workspace`
|
|
- Belongs to `Tenant`
|
|
- Belongs to `OperationRun`
|
|
- Belongs to initiating `User`
|
|
- **Polling rule**:
|
|
- Poll while `status` is `queued` or `generating`
|
|
- Stop polling when `status` is `ready`, `failed`, or `expired`
|
|
- Do not poll when no review pack exists for the tenant
|
|
|
|
## Derived View State
|
|
|
|
### Run detail polling state
|
|
- **Source**: `OperationRun` + `RunDetailPolling::interval()`
|
|
- **Output**: `1s`, `5s`, `10s`, or `null`
|
|
- **Rules**:
|
|
- `null` when the run is terminal
|
|
- `null` when the tab is hidden
|
|
- `null` when Filament action modals are mounted
|
|
|
|
### Review pack card polling state
|
|
- **Source**: latest `ReviewPack` for the current tenant
|
|
- **Output**: `10s` or `null`
|
|
- **Rules**:
|
|
- `10s` when the latest pack is `queued` or `generating`
|
|
- `null` otherwise
|
|
|
|
## State Transitions
|
|
|
|
### OperationRun lifecycle relevant to polling
|
|
1. `queued` → active polling enabled
|
|
2. `running` → active polling enabled
|
|
3. `completed` + terminal outcome (`succeeded`, `failed`, `partially_succeeded`) → polling disabled
|
|
4. Any unrecognized or missing status normalization → treated as non-active for polling decisions
|
|
|
|
### ReviewPack lifecycle relevant to polling
|
|
1. `queued` → polling enabled
|
|
2. `generating` → polling enabled
|
|
3. `ready` → polling disabled
|
|
4. `failed` → polling disabled
|
|
5. `expired` → polling disabled
|
|
|
|
## Validation Rules
|
|
- Polling must never start for unauthorized users; existing page and widget access checks remain authoritative.
|
|
- Polling must stop automatically once terminal state is reached.
|
|
- Polling decisions must be derived from persisted state only; no external API call is required during render.
|
|
- Terminal-state rendering must remain stable and must not trigger repeated refresh loops.
|