# Data Model: Tenant Selector and Remembered Context Enforcement ## Overview This feature does not introduce a new persistence model. It formalizes how existing workspace, tenant, route, and remembered-context concepts interact at the shell and routing layers. ## Entities ### 1. Workspace Context **Represents**: The primary operating boundary for the current admin session. **Key fields**: - `workspace_id` - `workspace.slug` - `workspace.archived_at` **Relationships**: - Owns many tenants - Owns many canonical workspace records such as operation runs - Owns one session-scoped remembered tenant preference map entry per user session **Validation rules**: - Must exist - Must not be archived for active selection - Actor must be a workspace member or the request resolves as deny-as-not-found ### 2. Tenant **Represents**: A workspace-owned tenant record that may be active, onboarding, draft, or archived. **Key fields**: - `id` - `workspace_id` - `external_id` - `status` - `deleted_at` - operator-facing identity fields such as `name`, `domain`, `environment` **Relationships**: - Belongs to one workspace - May be a route subject on tenant-bound pages - May be referenced by canonical workspace records such as operation runs - May be persisted as remembered active-lane context only when selector-eligible **Validation rules**: - For standard active selector use, tenant must belong to current workspace, remain entitled to the actor, exist, and satisfy active-lane eligibility - For tenant-bound route validity, tenant must satisfy workspace and entitlement checks; selector eligibility is not required ### 3. Remembered Tenant Context **Represents**: A workspace-scoped user/session preference for the last active-lane tenant. **Key fields**: - `workspace_last_tenant_ids[workspace_id]` session entry - optional persisted recency signals through `users.last_tenant_id` or `user_tenant_preferences.last_used_at` **Relationships**: - Belongs logically to one workspace context - References one tenant candidate for active-lane convenience **Validation rules**: - Must only be read inside an established workspace context - Must resolve to an existing tenant in the current workspace - Must satisfy entitlement-sensitive access checks - Must satisfy active-lane eligibility checks - Invalid values must be cleared or ignored deterministically ### 4. Active Selector Option **Represents**: A tenant that is eligible to appear in the standard active tenant selector. **Derived from**: - `TenantOperabilityDecision.canSelectAsContext` **Required attributes**: - tenant identity - lifecycle presentation - selector-safe label and helper copy **Validation rules**: - Must not include `draft`, `onboarding`, or `archived` tenants under the current lifecycle model - Must not include tenants outside the current workspace - Must not include tenants the actor cannot access ### 5. Route Subject **Represents**: The record made authoritative by the current route. **Variants**: - tenant-bound route subject: `Tenant` - canonical workspace record subject: `OperationRun` or other workspace-owned records **Validation rules**: - Route subject legitimacy is resolved from route record identity plus policy checks - Remembered tenant context may influence convenience UI only and must not replace route authority ## Derived Domain Objects ### Tenant Operability Decision **Represents**: The existing lifecycle-aware rule set produced by `TenantOperabilityService`. **Relevant flags for this feature**: - `canSelectAsContext` - `canViewTenantSurface` - `canReferenceInWorkspaceMonitoring` ### Shell Context Resolution Result **Represents**: The runtime decision for what tenant, if any, the shell should treat as active convenience context. **Possible states**: - `route_authoritative_tenant` - `validated_selected_tenant` - `no_selected_tenant` - `stale_context_cleared` ## State Transitions ### Remembered Tenant Context Lifecycle 1. `unset` - No remembered tenant exists for the current workspace. 2. `remembered_active` - An active-lane-eligible tenant is selected and stored for the current workspace. 3. `revalidated_active` - A later request reads the remembered tenant and confirms workspace match, entitlement, existence, and selector eligibility. 4. `invalidated_cleared` - A later request detects stale or ineligible remembered tenant context and clears or ignores it. 5. `no_selected_tenant` - The shell falls back to a legitimate workspace-level no-tenant state. **Invalidation triggers**: - workspace switch - tenant no longer exists - tenant no longer belongs to current workspace - tenant no longer satisfies active-lane eligibility - actor no longer has tenant entitlement where required ### Page Semantics By Category #### Workspace-level page - Accepts `remembered_active`, `invalidated_cleared`, or `no_selected_tenant` - Selected tenant may become a filter only #### Tenant-bound page - Route tenant is authoritative - Selected tenant may match, differ, or be absent #### Canonical workspace record viewer - Route record is authoritative - Referenced tenant may differ from selected tenant without invalidating the page ## Invariants - Workspace is always the primary context boundary. - Remembered tenant context never broadens authorization. - Standard selector membership never implies universal tenant discoverability. - Route legitimacy always outranks selected tenant context. - No-selected-tenant is a valid workspace shell state.