## Summary - harden the canonical operation run viewer so mismatched, missing, archived, onboarding, and selector-excluded tenant context no longer invalidates authorized canonical run viewing - extend canonical route, header-context, deep-link, and presentation coverage for Spec 144 and add the full spec artifact set under `specs/144-canonical-operation-viewer-context-decoupling/` - harden onboarding draft provider-connection resume logic so stale persisted provider connections fall back to the connect-provider step instead of resuming invalid state - add architecture-audit follow-up candidate material and prompt assets for the next governance hardening wave ## Testing - `vendor/bin/sail bin pint --dirty --format agent` - `vendor/bin/sail artisan test --compact tests/Feature/144/CanonicalOperationViewerContextMismatchTest.php tests/Feature/144/CanonicalOperationViewerDeepLinkTrustTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/OpsUx/OperateHubShellTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/RunAuthorizationTenantIsolationTest.php tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php tests/Feature/Monitoring/HeaderContextBarTest.php tests/Feature/Monitoring/OperationRunResolvedReferencePresentationTest.php tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Unit/Onboarding/OnboardingDraftStageResolverTest.php tests/Unit/Onboarding/OnboardingLifecycleServiceTest.php` ## Notes - branch: `144-canonical-operation-viewer-context-decoupling` - base: `dev` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #173
99 lines
4.2 KiB
Markdown
99 lines
4.2 KiB
Markdown
# Data Model: Canonical Operation Viewer Context Decoupling
|
|
|
|
## Overview
|
|
|
|
This feature introduces no database schema changes. The design work is centered on clarifying how existing records and session state combine to produce canonical run-view behavior.
|
|
|
|
## Core Entities
|
|
|
|
### OperationRun
|
|
|
|
- **Ownership**: Workspace-owned canonical monitoring record
|
|
- **Existing fields used by this feature**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `tenant_id` nullable
|
|
- `type`
|
|
- `status`
|
|
- `outcome`
|
|
- `context`
|
|
- `summary_counts`
|
|
- `initiator_name`
|
|
- **Relationships**:
|
|
- Belongs to `workspace`
|
|
- Optionally belongs to `tenant`
|
|
- Optionally belongs to `user`
|
|
- **Feature rule**: Route legitimacy is derived from the run itself plus direct entitlement checks, not from remembered tenant context.
|
|
|
|
### Tenant
|
|
|
|
- **Ownership**: Workspace-owned durable record
|
|
- **Existing fields used by this feature**:
|
|
- `id`
|
|
- `workspace_id`
|
|
- `name`
|
|
- `external_id`
|
|
- lifecycle state as derived by the tenant operability and lifecycle presentation layer
|
|
- **Feature rule**: A tenant linked to a run may be active, onboarding, archived, or otherwise non-selectable as current context and still remain a valid tenant reference for the canonical run viewer.
|
|
|
|
### RememberedTenantContext
|
|
|
|
- **Ownership**: Session-backed operator preference state
|
|
- **Existing sources used by this feature**:
|
|
- Current Filament tenant when present and entitled
|
|
- Workspace remembered tenant when no entitled Filament tenant is present
|
|
- **Feature rule**: This state may influence labels, back links, and optional information banners, but it never decides whether the canonical run exists or is viewable.
|
|
|
|
## Derived Viewer State
|
|
|
|
The implementation should model a lightweight derived view state rather than adding persistence.
|
|
|
|
### CanonicalRunViewerState
|
|
|
|
- **Inputs**:
|
|
- `OperationRun $run`
|
|
- current workspace membership
|
|
- direct tenant entitlement for `$run->tenant_id` when present
|
|
- current remembered or selected header tenant context
|
|
- **Derived outputs**:
|
|
- `authorization_outcome`: allowed, deny-as-not-found, forbidden
|
|
- `run_tenant_state`: tenantless, active, onboarding, archived, other non-selectable
|
|
- `header_context_state`: no selected tenant, selected tenant matches run tenant, selected tenant differs from run tenant
|
|
- `banner_message`: null or an informational message explaining mismatch or lifecycle framing
|
|
- `follow_up_affordance_state`: available, partially available, unavailable because of lifecycle or entitlement
|
|
|
|
## Authorization State Matrix
|
|
|
|
| Run Exists | Workspace Member | Tenant Entitled | Capability Granted | Result |
|
|
|------------|------------------|-----------------|--------------------|--------|
|
|
| No | N/A | N/A | N/A | 404 not found |
|
|
| Yes | No | N/A | N/A | 404 deny-as-not-found |
|
|
| Yes | Yes | No for linked tenant | N/A | 404 deny-as-not-found |
|
|
| Yes | Yes | Yes or tenantless | No when capability is required | 403 forbidden |
|
|
| Yes | Yes | Yes or tenantless | Yes or no capability required | Render viewer |
|
|
|
|
## Presentation State Matrix
|
|
|
|
| Run Tenant | Header Tenant Context | Viewer Valid | Expected Messaging |
|
|
|------------|-----------------------|--------------|--------------------|
|
|
| Tenantless | None | Yes | Workspace-level framing only |
|
|
| Tenantless | Selected tenant present | Yes | Optional note that run is workspace-level and not tied to the selected tenant |
|
|
| Active tenant | Matching selected tenant | Yes | No mismatch banner required |
|
|
| Active tenant | Different selected tenant | Yes | Non-blocking mismatch message |
|
|
| Onboarding or archived tenant | None | Yes | Lifecycle-aware canonical workspace framing |
|
|
| Onboarding or archived tenant | Different selected tenant | Yes | Lifecycle-aware mismatch message |
|
|
|
|
## Validation Rules
|
|
|
|
- A run with `workspace_id <= 0` remains invalid and is denied as not found.
|
|
- A tenant-linked run must never reveal tenant-linked details to an actor who lacks entitlement to that tenant.
|
|
- A tenantless run must remain viewable based on workspace access and any resolved capability requirement for the run type.
|
|
- Remembered tenant context must never be mutated as a side effect of viewing a canonical run.
|
|
|
|
## No Schema Change Confirmation
|
|
|
|
- No new tables
|
|
- No new columns
|
|
- No new indexes
|
|
- No data backfill
|
|
- No migration work required |