TenantAtlas/specs/145-tenant-action-taxonomy-lifecycle-safe-visibility/data-model.md

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.