# 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.