TenantAtlas/specs/136-admin-canonical-tenant/data-model.md
2026-03-12 23:26:32 +01:00

7.1 KiB

Data Model: Spec 136 Admin Panel Canonical Tenant Resolution Full Rollout

Overview

This feature introduces no new database tables or persisted business objects. Its data model is request-time and behavioral: it formalizes how surface classification, panel mode, canonical admin tenant context, session-backed filter state, and sensitive actions combine into one deterministic tenant outcome.

Entity: Surface Inventory Entry

Purpose: Represents one admin-visible or admin-reachable surface in the rollout manifest.

Fields:

  • surface_name
  • class_name
  • surface_kind enum: resource, page, widget, shared_helper, guarded_file
  • classification enum: type_a, type_b, type_c
  • visibility_mode enum: admin_visible, shared_code_path, tenant_panel_only_but_reviewed
  • has_persisted_tenant_filters boolean
  • has_global_search boolean
  • has_sensitive_actions boolean
  • guard_required boolean

Relationships:

  • may reference one resource, page, or widget class
  • may depend on one or more support-layer resolver or filter-state helpers

Validation rules:

  • Every rollout surface must have exactly one classification.
  • Type A and Type B surfaces must be guard-covered unless explicitly documented as an exception.
  • Type C surfaces must not acquire hidden tenant enforcement in read or write paths.

Entity: Canonical Admin Tenant Context

Purpose: Represents the single tenant context used by workspace-admin tenant-sensitive flows.

Source fields:

  • workspace_id
  • panel_id
  • route_tenant_id nullable
  • filament_tenant_id nullable
  • remembered_tenant_id nullable
  • resolved_tenant_id nullable
  • resolution_source enum: route, filament, remembered, none
  • is_entitled boolean

Relationships:

  • belongs to one current workspace
  • may resolve to one entitled tenant
  • drives header context, queries, filter defaults, widgets, links, and sensitive actions for Type A and Type B admin surfaces

Validation rules:

  • resolved_tenant_id must be null when no entitled tenant exists.
  • The same resolved tenant must drive every tenant-sensitive element of the same admin surface.
  • When the panel is admin, raw panel-native tenant reads are not valid substitutes for this entity.

Entity: Panel Resolver Contract

Purpose: Encodes which resolver is allowed in a given panel mode.

Fields:

  • panel_id
  • allowed_source enum: operate_hub_shell, filament_tenant, none
  • fallback_behavior enum: remembered_allowed, no_fallback, safe_none
  • applies_to enum: admin, tenant, shared_surface

Validation rules:

  • Admin panel uses operate_hub_shell.
  • Tenant panel uses filament_tenant.
  • Shared surfaces must branch by current panel rather than blending both rules.

Entity: Persisted Tenant Filter Session State

Purpose: Represents session-backed filter state whose validity depends on the current canonical admin tenant.

Fields:

  • filters_session_key
  • tenant_sensitive_filters array
  • previous_resolved_tenant_id nullable
  • current_resolved_tenant_id nullable
  • resolution_action enum: apply, reseed, clear
  • has_invalid_values boolean

Relationships:

  • belongs to one table or page surface
  • depends on one Canonical Admin Tenant Context

Validation rules:

  • Tenant-sensitive filter values must be cleared or reseeded when resolved tenant changes.
  • If current_resolved_tenant_id is null, tenant-specific filter state must not remain active.
  • Workspace-wide Type B surfaces may preserve non-tenant filters while clearing or reseeding tenant-specific ones.

Entity: Sensitive Action Scope Contract

Purpose: Represents the tenant parity requirement between visible surface context and a sensitive action target.

Fields:

  • surface_name
  • action_name
  • visible_tenant_id nullable
  • query_tenant_id nullable
  • action_tenant_id nullable
  • authorization_outcome enum: ok, not_found, forbidden
  • confirmation_required boolean

Relationships:

  • belongs to one rollout surface
  • depends on one resolved tenant context and one authorization decision

Validation rules:

  • action_tenant_id must equal visible_tenant_id for Type A surfaces.
  • Out-of-scope or missing tenant access must remain not_found when membership is not established.
  • Existing destructive-like actions must still require confirmation and server-side authorization.

Entity: Search and Record Resolution Contract

Purpose: Represents list, detail, deep-link, and global-search parity for tenant-sensitive resources.

Fields:

  • surface_name
  • access_path enum: list, detail, direct_url, deep_link, global_search
  • panel_mode enum: admin, tenant
  • resolved_tenant_id nullable
  • record_tenant_id nullable
  • parity_outcome enum: aligned, disabled, not_found, forbidden

Validation rules:

  • Detail and direct access must never be broader than list scope.
  • Global search must either match list/detail parity or be disabled.
  • Admin no-context behavior must be explicit and deterministic per surface class.

Entity: Guard Coverage Entry

Purpose: Documents whether a file is enforced by the admin tenant resolver guard or allowed as an exception.

Fields:

  • relative_path
  • surface_name
  • guard_status enum: guarded, exception
  • exception_reason nullable
  • review_owner

Validation rules:

  • Exceptions must be explicit and stable.
  • Admin-only files are not valid exceptions for raw Filament::getTenant() or Tenant::current() reads.
  • Guard output must clearly distinguish true violations from approved tenant-panel-native usage.

State Transitions

Canonical admin tenant state

  1. none
  • No entitled route, Filament, or remembered tenant is available.
  • Outcome: safe no-tenant-selected behavior by surface type.
  1. remembered
  • Only remembered tenant is valid and entitled.
  • Outcome: remembered tenant becomes the canonical admin tenant for the full request.
  1. filament
  • A Filament tenant is valid and entitled.
  • Outcome: Filament tenant becomes the canonical admin tenant for the full request.
  1. route
  • A route tenant parameter is present and entitled for a tenant-panel or shared route.
  • Outcome: route tenant governs the request where panel-native semantics apply.

Persisted filter synchronization state

  1. unchanged
  • Previous and current resolved tenant IDs match.
  • Outcome: persisted tenant filter values may remain.
  1. tenant_switched
  • Previous and current resolved tenant IDs differ.
  • Outcome: tenant-sensitive filter values are cleared or reseeded.
  1. tenant_removed
  • Current resolved tenant ID becomes null.
  • Outcome: tenant-sensitive filter values are cleared.

Invariants

  • One workspace-admin surface uses one tenant source for every tenant-sensitive element.
  • Shared resources must branch by panel mode instead of mixing admin and tenant rules inside one execution path.
  • Persisted tenant filter state is never trusted without synchronization.
  • Search, list, detail, and deep-link behavior cannot exceed the same tenant boundary.
  • Existing destructive or governance-sensitive actions keep their confirmations and authorization while gaining tenant-target parity.