## Summary - add an in-place Required Permissions assist to the onboarding Verify Access step via a Filament slideover - route permission-related verification remediation links into the assist first and keep deep-dive links opening in a new tab - add view-model and link-behavior helpers plus focused feature, browser, RBAC, and unit coverage for the new assist ## Scope - onboarding wizard Verify Access UX - Required Permissions assist rendering and link behavior - Spec 139 artifacts, contracts, and checklist updates ## Notes - branch: `139-verify-access-permissions-assist` - commit: `b4193f1` - worktree was clean at PR creation time Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #168
116 lines
5.1 KiB
Markdown
116 lines
5.1 KiB
Markdown
# Data Model — Spec 139 (Verify Access Required Permissions Assist)
|
|
|
|
## Existing persisted entities reused
|
|
|
|
### TenantOnboardingSession (existing)
|
|
- Source: `app/Models/TenantOnboardingSession.php`
|
|
- Role in this feature:
|
|
- Anchors the current onboarding draft and current wizard step.
|
|
- Holds the selected provider connection and latest verification run reference in `state`.
|
|
- Relevant persisted state:
|
|
- `tenant_id`
|
|
- `current_step`
|
|
- `state.provider_connection_id`
|
|
- `state.verification_operation_run_id`
|
|
|
|
### OperationRun (existing)
|
|
- Source: `app/Models/OperationRun.php`
|
|
- Role in this feature:
|
|
- Supplies the latest stored verification result used by Verify Access.
|
|
- Remains the source of truth for the existing verification report.
|
|
- Relevant persisted context:
|
|
- `context.provider_connection_id`
|
|
- `context.target_scope`
|
|
- `context.verification_report`
|
|
|
|
### TenantPermission dataset (existing)
|
|
- Source: `tenant_permissions` via `TenantPermissionService::compare(... persist: false, liveCheck: false)`
|
|
- Role in this feature:
|
|
- Supplies the current DB-only permission diagnostics summary and missing-permission breakdown used by the assist and full page.
|
|
|
|
## Computed view models
|
|
|
|
### VerificationAssistVisibility (computed)
|
|
- Purpose: determines whether the Verify Access step should expose `View required permissions`.
|
|
- Inputs:
|
|
- Stored verification report overall/check state.
|
|
- Existing permission diagnostics summary.
|
|
- Stale verification context for the selected provider connection.
|
|
- Shape:
|
|
- `is_visible: bool`
|
|
- `reason: 'permission_blocked' | 'permission_attention' | 'hidden_ready' | 'hidden_irrelevant'`
|
|
|
|
### VerificationAssistViewModel (computed)
|
|
- Purpose: compact payload rendered inside the slideover.
|
|
- Derived from:
|
|
- `verificationReportViewData()` output
|
|
- `TenantRequiredPermissionsViewModelBuilder::build($tenant, ...)`
|
|
- Shape:
|
|
- `tenant: { id: int, external_id: string, name: string }`
|
|
- `verification: { overall: string|null, status: string|null, is_stale: bool, stale_reason: string|null }`
|
|
- `overview: { overall: string, counts: { missing_application: int, missing_delegated: int, present: int, error: int }, freshness: { last_refreshed_at: string|null, is_stale: bool } }`
|
|
- `missing_permissions: { application: PermissionRow[], delegated: PermissionRow[] }`
|
|
- `copy: { application: string, delegated: string }`
|
|
- `actions: AssistActions`
|
|
- `fallback: { has_incomplete_detail: bool, message: string|null }`
|
|
|
|
### PermissionRow (existing computed shape reused)
|
|
- Source: `TenantRequiredPermissionsViewModelBuilder`
|
|
- Shape:
|
|
- `key: string`
|
|
- `type: 'application' | 'delegated'`
|
|
- `description: string|null`
|
|
- `features: string[]`
|
|
- `status: 'granted' | 'missing' | 'error'`
|
|
- `details: array|null`
|
|
|
|
### AssistActions (computed)
|
|
- Purpose: explicit, authorization-safe actions shown in the slideover.
|
|
- Shape:
|
|
- `full_page: { label: string, url: string, opens_in_new_tab: true, is_secondary: true }`
|
|
- `copy_application: { label: string, payload: string, available: bool }`
|
|
- `copy_delegated: { label: string, payload: string, available: bool }`
|
|
- `grant_admin_consent: { label: string, url: string|null, opens_in_new_tab: bool, available: bool }`
|
|
- `manage_provider_connection: { label: string, url: string|null, opens_in_new_tab: bool, available: bool }`
|
|
- `rerun_verification: { label: string, handled_by_existing_wizard: true }`
|
|
|
|
### VerificationLinkBehavior (computed)
|
|
- Purpose: normalize how Verify Access next-step links are rendered.
|
|
- Shape:
|
|
- `label: string`
|
|
- `url: string`
|
|
- `kind: 'external' | 'internal-diagnostic' | 'internal-inline-safe'`
|
|
- `opens_in_new_tab: bool`
|
|
- `show_new_tab_hint: bool`
|
|
|
|
## State transitions
|
|
|
|
### Assist visibility transition
|
|
- Hidden → Visible when:
|
|
- verification report indicates permission-related blockers or relevant needs-attention state, and
|
|
- the current user remains authorized for the underlying tenant context.
|
|
- Visible → Hidden when:
|
|
- verification becomes fully ready with no relevant permission guidance, or
|
|
- authorization context no longer permits the assist.
|
|
|
|
### Wizard continuity invariant
|
|
- Opening the assist does not change `TenantOnboardingSession.current_step`.
|
|
- Closing the assist does not mutate onboarding draft state.
|
|
- Opening the full page from the assist does not navigate the current onboarding tab away from the wizard.
|
|
|
|
### Copy-action availability invariant
|
|
- A copy action is available only when the corresponding `copy.*` payload is a non-empty string.
|
|
- Empty payloads result in omitted or replaced controls, not broken actions.
|
|
|
|
## Authorization model reuse
|
|
|
|
- Onboarding wizard access continues to depend on workspace membership plus onboarding capability rules.
|
|
- Required Permissions deep-dive access continues to depend on tenant entitlement and existing page authorization.
|
|
- The assist is visible only when both contexts are valid enough to avoid leaking tenant or permission detail.
|
|
|
|
## No persistence changes
|
|
|
|
- No new tables.
|
|
- No new route-backed models.
|
|
- No new onboarding-only permissions store.
|
|
- No mutation to the existing Required Permissions page role. |