TenantAtlas/specs/146-central-tenant-status-presentation/data-model.md
2026-03-16 19:17:35 +01:00

4.3 KiB

Data Model: Central Tenant Status Presentation

1. TenantLifecycleState

  • Purpose: The canonical tenant lifecycle domain value already defined by Spec 143 and implemented in TenantLifecycle.
  • Source: Existing tenant domain model.
  • Fields:
    • value: enum string
      • Allowed values: draft, onboarding, active, archived
    • label: string
      • Allowed values: Draft, Onboarding, Active, Archived
  • Relationships:
    • Derived from one Tenant
    • Referenced by one TenantLifecyclePresentation
  • Validation rules:
    • Must be one of the four canonical lifecycle values for normal presentation flow
    • Non-canonical values must bypass canonical rendering and enter invalid-data fallback only
  • State transitions:
    • Not defined here; owned by Spec 143 and the tenant domain

2. TenantLifecyclePresentation

  • Purpose: The authoritative UI presentation contract for a lifecycle state.
  • Ownership: Presentation layer only; no persistence required.
  • Fields:
    • value: canonical lifecycle value
    • label: canonical operator-facing label
    • badge_color: concise badge/chip color token
    • badge_icon: icon token for badge or chip rendering
    • short_description: concise explanatory text for detail or selector surfaces
    • long_description: longer helper text for infolists, banners, or canonical viewers
    • is_invalid_fallback: boolean flag reserved for corrupted or unexpected input
  • Relationships:
    • Belongs to one TenantLifecycleState when canonical
    • May be constructed from a referenced tenant in a canonical viewer
  • Validation rules:
    • Canonical values must always produce is_invalid_fallback = false
    • Invalid fallback must never be used for draft, onboarding, active, or archived
    • label must match the canonical lifecycle vocabulary for canonical values

3. TenantLifecyclePresentationVariant

  • Purpose: Surface-specific density derived from the same underlying lifecycle meaning.
  • Ownership: Presentation composition only.
  • Fields:
    • surface: enum-like string
      • Expected values: table, detail, selector, canonical_viewer, banner
    • show_badge: boolean
    • show_short_description: boolean
    • show_long_description: boolean
    • show_context_note: boolean
  • Relationships:
    • Belongs to one TenantLifecyclePresentation
  • Validation rules:
    • Must not alter value or label
    • May change density only, never meaning

4. ReferencedTenantLifecycleContext

  • Purpose: Captures how lifecycle is shown when a tenant appears as context on another record, such as an operation run.
  • Ownership: Canonical viewer presentation only.
  • Fields:
    • tenant_id: integer or null
    • tenant_name: string or null
    • lifecycle_value: canonical lifecycle value or invalid raw value
    • viewer_context: string
      • Expected examples: operation_run, report, audit_reference
    • context_note: optional explanatory text describing why the referenced tenant may be non-active
  • Relationships:
    • References one Tenant
    • Uses one TenantLifecyclePresentation
  • Validation rules:
    • Must only be constructed after existing viewer authorization succeeds
    • Must not imply the canonical record is invalid when the tenant lifecycle is onboarding or archived

5. Existing Domain Models in Scope

Tenant

  • Existing model: App\Models\Tenant
  • Relevant existing fields:
    • status
    • deleted_at / soft-delete state
    • workspace_id
    • name
    • domain
    • app_status
    • rbac_status
  • Relevant derived methods:
    • lifecycle()
    • isDraft()
    • isOnboarding()
    • isArchived()

OperationRun

  • Existing model: App\Models\OperationRun
  • Relevant existing fields:
    • tenant_id
    • workspace_id
    • status
    • outcome
    • context
  • Role in this feature:
    • Supplies referenced tenant context only
    • No lifecycle ownership changes
    • No OperationRun state machine changes

6. Invariants

  • Tenant lifecycle presentation must remain exhaustive for canonical states.
  • Lifecycle presentation must not redefine lifecycle transitions or authorization.
  • Lifecycle and health-like domains must remain separate in the rendered UI.
  • Surface-specific rendering may change density, but not label or semantic meaning.
  • Invalid fallback is reserved exclusively for non-canonical lifecycle data.