TenantAtlas/specs/145-tenant-action-taxonomy-lifecycle-safe-visibility/data-model.md
ahmido 440e63edff feat: implement tenant action taxonomy lifecycle visibility (#174)
## 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
2026-03-16 00:57:17 +00:00

150 lines
4.9 KiB
Markdown

# Data Model: Tenant Action Taxonomy and Lifecycle-Safe Visibility
## 1. Tenant
**Type**: Existing persisted model (`App\Models\Tenant`)
**Core fields**:
- `id`
- `workspace_id`
- `external_id`
- `tenant_id`
- `name`
- `status` (`draft`, `onboarding`, `active`, `archived`)
- `deleted_at`
- `is_current`
**Relationships**:
- belongs to `Workspace`
- has many `TenantOnboardingSession`
- has many provider/operational records already used elsewhere in the admin plane
**Validation / invariants**:
- `workspace_id` is required
- `status` must resolve to a canonical `TenantLifecycle`
- 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 identification
- `onboarding -> active`: onboarding completes through workflow activation semantics
- `onboarding -> draft`: last resumable onboarding draft is cancelled and linked tenant is normalized back to draft
- `active -> archived`: archive action soft-deletes tenant and sets archived semantics
- `archived -> active`: restore action reactivates archived tenant
## 2. TenantOnboardingSession
**Type**: Existing persisted model (`App\Models\TenantOnboardingSession`)
**Core fields**:
- `id`
- `workspace_id`
- `tenant_id` nullable until linked
- `entra_tenant_id`
- `current_step`
- `lifecycle_state`
- `current_checkpoint`
- `last_completed_checkpoint`
- `state` JSON
- `completed_at`
- `cancelled_at`
- `version`
**Relationships**:
- belongs to `Workspace`
- belongs to `Tenant` optionally
- 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 onboarding` availability
- 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_id`
- `workspace_id`
- `tenant_lifecycle`
- `surface` (`tenant_index_row`, `tenant_view_header`, `tenant_edit_header`, `onboarding_index_row`, `onboarding_detail_header`, `widget`, `context_menu`)
- `page_category`
- `has_related_onboarding_session`
- `related_onboarding_is_resumable`
- `is_member`
- `has_capability`
- `is_archived`
**Derivation sources**:
- `TenantOperabilityService`
- `OnboardingLifecycleService`
- `TenantOnboardingSessionPolicy`
- `UiEnforcement` / 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`)
- `label`
- `visible`
- `enabled`
- `destructive`
- `requires_confirmation`
- `capability`
- `audit_action_id` nullable
- `reason_code` nullable when hidden or disabled
- `priority` or `group` to distinguish primary versus overflow actions
- `url` or `handler` metadata 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_confirmation` must 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`, and `canShowReadinessActions`
**Non-responsibilities**:
- executing mutations
- replacing server-side authorization
- persisting lifecycle state
## 6. Audit Lifecycle Events
**Type**: Existing enum-backed audit vocabulary
**Relevant values**:
- `tenant.archived`
- `tenant.restored`
- `tenant.returned_to_draft`
- `managed_tenant_onboarding.resume`
- `managed_tenant_onboarding.cancelled`
- `managed_tenant_onboarding.activation`
**Requirement**:
- UI action taxonomy must stay aligned with these events so operator intent can be reconstructed from audit history.