TenantAtlas/specs/172-deferred-operator-surfaces-retrofit/data-model.md
ahmido 671abbed53 feat: retrofit deferred operator surfaces (#203)
## Summary
- retrofit the tenant detail recent-operations and verification surfaces to keep one clear primary inspect path per state
- keep onboarding workflow actions on the wizard step while moving previous-run and advanced monitoring links into diagnostics-only technical details
- add focused spec 172 design artifacts, feature coverage, and a dedicated browser smoke test for the deferred operator surface retrofit

## Testing
- `vendor/bin/sail artisan test --compact tests/Browser/Spec172DeferredOperatorSurfacesSmokeTest.php tests/Browser/OnboardingDraftRefreshTest.php tests/Browser/OnboardingDraftVerificationResumeTest.php`

## Notes
- base branch: `dev`
- branch head: `172-deferred-operator-surfaces-retrofit`
- browser smoke pack passed locally after the final changes

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #203
2026-04-02 09:22:44 +00:00

180 lines
10 KiB
Markdown

# Data Model: Deferred Operator Surfaces Retrofit
## Overview
This feature introduces no new persisted entity, no new table, and no new state family. It reuses existing `OperationRun` truth plus existing tenant-detail and onboarding presentation state to enforce clearer CTA hierarchy and scope signals.
## Entity: OperationRun
- **Type**: Existing persisted model
- **Purpose in this feature**: Canonical record whose existing admin-plane collection/detail routes remain the inspect targets for tenant-detail and onboarding embedded surfaces.
### Relevant Fields
| Field | Type | Notes |
|-------|------|-------|
| `id` | integer | Existing operation identifier used by embedded links and labels. |
| `type` | string | Continues to determine the operation label and UX guidance. |
| `workspace_id` | integer nullable | Preserves workspace-context routing and entitlement checks. |
| `tenant_id` | integer nullable | Preserves tenant-context entitlement and embedded-surface filtering. |
| `status` | string | Drives whether the current run is still active. |
| `outcome` | string | Drives blocked/failed/succeeded summary presentation. |
| `context` | array/json | Already carries target-scope, verification-report, and next-step metadata used by the affected surfaces. |
| `created_at` | timestamp | Used for recency display on recent-operations surfaces. |
| `started_at` / `completed_at` | timestamp nullable | Used for in-progress vs completed display and technical details. |
### Relationships
| Relationship | Target | Purpose |
|--------------|--------|---------|
| `tenant` | `Tenant` | Keeps tenant entitlement and tenant detail context explicit. |
| `workspace` | `Workspace` | Preserves workspace-context authorization for onboarding and admin viewers. |
| `initiator` | `User` / platform initiator context | Remains unchanged; no notification or lifecycle behavior changes in this feature. |
### Feature-Specific Invariants
- `/admin/operations` and `/admin/operations/{run}` remain the canonical collection/detail destinations.
- No new `OperationRun` type, state transition, notification timing, or summary-count behavior is introduced.
- Embedded surfaces may change CTA hierarchy and nearby scope copy, but not the underlying destination semantics.
### State Transitions Used By This Feature
| Transition | Preconditions | Result |
|------------|---------------|--------|
| Render inspect link for existing record | A covered surface already has a current `OperationRun` reference | No state change; surface exposes a single primary inspect path for that record. |
| Render workflow-start action | Covered surface has no current `OperationRun` reference and the operator can start the workflow | No state change; surface exposes one next-step CTA such as `Start verification`. |
## Derived Surface State: Tenant Detail Recent Operations Summary
- **Type**: Existing derived widget state, not persisted
- **Sources**:
- `app/Filament/Resources/TenantResource/Pages/ViewTenant.php`
- `app/Filament/Widgets/Tenant/RecentOperationsSummary.php`
- `resources/views/filament/widgets/tenant/recent-operations-summary.blade.php`
- `app/Support/OperationRunLinks.php`
### Relevant Fields
| Field | Type | Purpose |
|-------|------|---------|
| `tenant` | `Tenant` | Provides the current tenant context for filtering and copy. |
| `runs` | collection of `OperationRun` | Existing recent operation records rendered in the embedded summary. |
| `operationsIndexUrl` | string | Existing admin-plane collection destination. |
| `rowOperationUrl` | string derived | Existing admin-plane detail destination per rendered run. |
| `hasRuns` | boolean derived | Distinguishes empty vs populated summary state. |
### Feature-Specific Invariants
- Row-level `Open operation` remains the primary inspect affordance for displayed records.
- Any collection drill-in that remains visible is secondary and must make the broader admin scope explicit through placement or nearby helper text.
- The table-based recent-operations widget on `/admin/t/{tenant}` remains out of scope for this model.
### State Rules
| State | Preconditions | Primary CTA | Secondary CTA |
|-------|---------------|-------------|---------------|
| Empty summary | `runs` is empty | None or a single next-step/collection affordance if retained | Admin-scope collection link only if clearly secondary |
| Populated summary | `runs` is not empty | Per-row `Open operation` for each visible record | One secondary collection affordance at most |
## Derived Surface State: Tenant Verification Widget
- **Type**: Existing derived widget state, not persisted
- **Sources**:
- `app/Filament/Resources/TenantResource/Pages/ViewTenant.php`
- `app/Filament/Widgets/Tenant/TenantVerificationReport.php`
- `resources/views/filament/widgets/tenant/tenant-verification-report.blade.php`
### Relevant Fields
| Field | Type | Purpose |
|-------|------|---------|
| `run` | `OperationRun` nullable | Current verification-backed operation, if one exists. |
| `runUrl` | string nullable | Canonical inspect path for the current run. |
| `report` | array nullable | Stored verification report payload displayed read-only. |
| `isInProgress` | boolean | Distinguishes active vs completed run state. |
| `showStartAction` | boolean | Whether the embedded surface may expose a workflow-start CTA in empty-state conditions. |
| `canStart` | boolean | Whether the current actor can start verification. |
| `startTooltip` | string nullable | Existing permission helper text for disabled start states. |
| `lifecycleNotice` | string nullable | Existing archived/inactive-tenant explanation when starting work is not allowed. |
### Feature-Specific Invariants
- When no run exists and the tenant can be operated, the widget exposes one primary `Start verification` CTA.
- When a run exists, the widget exposes one primary inspect CTA for that run and does not compete with an inline rerun CTA.
- The existing tenant-detail header action remains the rerun/start path when the page still needs one outside the embedded widget.
- Archived or inoperable tenants may show explanation text, but no new inspect or start path is introduced by this feature.
### State Matrix
| State | Preconditions | Primary CTA | Secondary Inline CTA |
|-------|---------------|-------------|----------------------|
| No run / start allowed | `run` is null and `showStartAction && canStart` | `Start verification` | None |
| No run / cannot start | `run` is null and `! canStart` | None | None |
| Active run | `run` exists and `isInProgress` | `Open operation` | None |
| Completed or stale run | `run` exists and `! isInProgress` | `Open operation` | None |
| Archived / inactive tenant | `showStartAction` is false and `lifecycleNotice` is present | None | None |
## Derived Surface State: Onboarding Verification Surface
- **Type**: Existing guided-flow report state, not persisted
- **Sources**:
- `app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`
- `resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php`
- `resources/views/filament/modals/onboarding-verification-technical-details.blade.php`
- `managed_tenant_onboarding_sessions.state[verification_operation_run_id]`
### Relevant Fields
| Field | Type | Purpose |
|-------|------|---------|
| `verification_operation_run_id` | integer nullable | Existing onboarding-session pointer to the current verification run. |
| `run` | array nullable | Read-only operation data rendered in the onboarding report. |
| `runUrl` | string nullable | Canonical inspect path for the current run. |
| `previousRunUrl` | string nullable | Secondary link to the previously relevant run, when retained. |
| `report` | array nullable | Stored verification report payload rendered in the onboarding step. |
| `workflowPrimaryAction` | derived string nullable | Existing step-level CTA such as `Start verification` or `Refresh`. |
| `technicalDetailsVisible` | boolean derived | Controls whether advanced monitoring/context affordances are available. |
### Feature-Specific Invariants
- The wizard step owns workflow-next-step controls such as `Start verification` and `Refresh`.
- The embedded report/technical-details surfaces may expose one inspect CTA for the current run, but previous-run and monitoring links remain diagnostics-secondary only.
- Any advanced monitoring/admin destination is visible only when the destination is legitimate for the current operator and remains explicitly labeled as advanced.
- No new onboarding state, session field, or workflow branch is introduced.
### State Matrix
| State | Preconditions | Workflow CTA | Inspect CTA | Diagnostics CTA |
|-------|---------------|--------------|-------------|-----------------|
| No run | onboarding session has no current verification run | `Start verification` | None | None |
| Active run | current verification run exists and is not completed | `Refresh` | One current-run inspect link if retained on the report surface | Advanced monitoring only in technical details |
| Completed run | current verification run exists and is completed | None or existing step progression controls | One current-run inspect link | Previous-run and monitoring links remain secondary |
## Governance Artifact: Deferred Surface Exemption And Conformance Coverage
- **Type**: Existing registry and test coverage, not persisted
- **Sources**:
- `app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php`
- `tests/Feature/Guards/ActionSurfaceContractTest.php`
- focused widget/onboarding feature tests listed in the plan
### Relevant Fields
| Field | Type | Purpose |
|-------|------|---------|
| `className` | string | Exempted page/component class still outside declaration-backed discovery. |
| `reason` | string | Concrete justification for the current exemption. |
| `focusedTests` | derived list | Dedicated conformance coverage that protects the exempted surface behavior. |
### Feature-Specific Invariants
- `ManagedTenantOnboardingWizard` may remain baseline-exempt if the reason continues to point to dedicated conformance tests.
- This feature does not introduce a new widget declaration system or a new validator mode.
- Governance for the retrofitted surfaces should become narrower and more explicit, not broader.
## Persistence Impact
- **Schema changes**: None
- **Data migration**: None
- **New indexes**: None
- **Retention impact**: None