## Summary
Implements Spec 145 for tenant action taxonomy and lifecycle-safe visibility.
This PR:
- adds a central tenant action policy surface and supporting value objects
- aligns tenant list, detail, edit, onboarding, and widget surfaces around lifecycle-safe actions
- standardizes operator-facing lifecycle wording around View, Resume onboarding, Archive, Restore, and Complete onboarding
- tightens onboarding and tenant lifecycle authorization semantics, including honest 404 vs 403 behavior
- updates related regression coverage and spec artifacts for Spec 145
- fixes follow-on full-suite regressions uncovered during validation, including onboarding browser flows, provider consent fixtures, workspace redirect DI expectations, and critical table/action/UI expectation drift
## Validation
Executed and passed:
- vendor/bin/sail bin pint --dirty --format agent
- vendor/bin/sail artisan test --compact
Result:
- 2581 passed
- 8 skipped
- 13534 assertions
## Notes
- Base branch: dev
- Feature branch commit: a33a41b
- Filament v5 / Livewire v4 compliance preserved
- No panel provider registration changes; Laravel 12 provider registration remains in bootstrap/providers.php
- No new globally searchable resource behavior added in this slice
- Destructive lifecycle actions remain confirmation-gated and authorization-protected
Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #174
4.9 KiB
Data Model: Tenant Action Taxonomy and Lifecycle-Safe Visibility
1. Tenant
Type: Existing persisted model (App\Models\Tenant)
Core fields:
idworkspace_idexternal_idtenant_idnamestatus(draft,onboarding,active,archived)deleted_atis_current
Relationships:
- belongs to
Workspace - has many
TenantOnboardingSession - has many provider/operational records already used elsewhere in the admin plane
Validation / invariants:
workspace_idis requiredstatusmust resolve to a canonicalTenantLifecycle- soft-delete implies archived semantics on lifecycle-sensitive surfaces
- only active tenants are selectable as remembered tenant context
Lifecycle transitions relevant to this feature:
draft -> onboarding: onboarding workflow progresses after tenant identificationonboarding -> active: onboarding completes through workflow activation semanticsonboarding -> draft: last resumable onboarding draft is cancelled and linked tenant is normalized back to draftactive -> archived: archive action soft-deletes tenant and sets archived semanticsarchived -> active: restore action reactivates archived tenant
2. TenantOnboardingSession
Type: Existing persisted model (App\Models\TenantOnboardingSession)
Core fields:
idworkspace_idtenant_idnullable until linkedentra_tenant_idcurrent_steplifecycle_statecurrent_checkpointlast_completed_checkpointstateJSONcompleted_atcancelled_atversion
Relationships:
- belongs to
Workspace - belongs to
Tenantoptionally - belongs to
startedByUser - belongs to
updatedByUser
Validation / invariants:
- workspace entitlement always required
- tenant entitlement required once a linked tenant exists
- resumability is workflow-derived, not inferred only from tenant lifecycle
- activation readiness is determined by
OnboardingLifecycleService
Lifecycle semantics relevant to this feature:
- drives
Resume onboarding - drives
Complete onboardingavailability - must remain distinct from archive/restore semantics
3. TenantActionContext
Type: New derived domain object or array DTO proposed by this plan
Purpose: Encapsulate the inputs needed to decide whether an action is visible, enabled, grouped, or executable on a specific surface.
Fields:
tenant_idworkspace_idtenant_lifecyclesurface(tenant_index_row,tenant_view_header,tenant_edit_header,onboarding_index_row,onboarding_detail_header,widget,context_menu)page_categoryhas_related_onboarding_sessionrelated_onboarding_is_resumableis_memberhas_capabilityis_archived
Derivation sources:
TenantOperabilityServiceOnboardingLifecycleServiceTenantOnboardingSessionPolicyUiEnforcement/ capability resolvers
4. TenantActionDescriptor
Type: New derived domain object or array DTO proposed by this plan
Purpose: Normalized description of one operator-facing action returned by the tenant-action policy surface.
Fields:
key(view,resume_onboarding,archive,restore,view_operations,verify,grant_admin_consent)family(neutral,onboarding_workflow,lifecycle_management,readiness)labelvisibleenableddestructiverequires_confirmationcapabilityaudit_action_idnullablereason_codenullable when hidden or disabledpriorityorgroupto distinguish primary versus overflow actionsurlorhandlermetadata depending on surface
Invariants:
- label must match domain semantics
- archive and restore are mutually exclusive for one tenant on one surface
- onboarding-only actions and active-only actions are mutually exclusive except in explicit workflow context
requires_confirmationmust be true for destructive-like lifecycle mutations
5. TenantActionPolicySurface
Type: New service/resolver proposed by this plan
Purpose: Produce TenantActionDescriptor collections from TenantActionContext and central lifecycle/workflow/RBAC rules.
Responsibilities:
- resolve primary and overflow actions per surface
- enforce lifecycle-safe visibility before RBAC helper decoration
- keep onboarding workflow actions distinct from archive/restore
- provide reusable predicates for
canArchiveTenant,canRestoreTenant,canResumeOnboardingTenant,canShowActivationAction, andcanShowReadinessActions
Non-responsibilities:
- executing mutations
- replacing server-side authorization
- persisting lifecycle state
6. Audit Lifecycle Events
Type: Existing enum-backed audit vocabulary
Relevant values:
tenant.archivedtenant.restoredtenant.returned_to_draftmanaged_tenant_onboarding.resumemanaged_tenant_onboarding.cancelledmanaged_tenant_onboarding.activation
Requirement:
- UI action taxonomy must stay aligned with these events so operator intent can be reconstructed from audit history.