TenantAtlas/specs/179-provider-truth-cleanup/data-model.md
2026-04-05 02:41:27 +02:00

222 lines
8.7 KiB
Markdown

# Phase 1 Data Model: Provider Readiness Source-of-Truth Cleanup
## Overview
This feature adds no table, no new enum, and no persisted readiness artifact. It reclassifies which already-stored fields are allowed to act as leading operator truth on tenant and provider connection surfaces.
## Persistent Source Truths
### Tenant
**Purpose**: Tenant identity and lifecycle boundary for all tenant-facing operator surfaces.
**Key fields**:
- `id`
- `workspace_id`
- `external_id`
- `name`
- `status`
- `app_status` (legacy tenant-level projection)
- `rbac_status`
**Relationships**:
- `Tenant` has many `ProviderConnection`
**Validation rules**:
- `status` remains the authoritative tenant lifecycle input and maps through `TenantLifecycle`.
- `app_status` remains persisted but is no longer allowed to act as leading operator truth on targeted tenant surfaces.
- `rbac_status` remains a separate domain and must not substitute for provider readiness.
### ProviderConnection
**Purpose**: Canonical stored provider-connection record for tenant-scoped provider integration state.
**Key fields**:
- `id`
- `tenant_id`
- `workspace_id`
- `provider`
- `display_name`
- `is_default`
- `connection_type`
- `consent_status`
- `verification_status`
- `status` (legacy connection-state projection)
- `health_status` (legacy health projection)
- `last_health_check_at`
- `last_error_reason_code`
- `last_error_message`
- `migration_review_required`
**Relationships**:
- `ProviderConnection` belongs to `Tenant`
- `ProviderConnection` belongs to `Workspace`
- `ProviderConnection` has one `ProviderCredential`
**Validation rules**:
- `consent_status` is the primary stored truth for consent progression.
- `verification_status` is the primary stored truth for current provider verification outcome.
- `status` and `health_status` may remain persisted and updated by existing projections, but targeted operator surfaces must treat them as secondary diagnostics only.
- `is_default` remains the routing anchor for tenant-facing provider summaries where a single connection must be chosen.
### ProviderCredential
**Purpose**: Encrypted credential storage associated with a provider connection.
**Key fields**:
- `provider_connection_id`
- encrypted credential payload fields
**Relationships**:
- `ProviderCredential` belongs to `ProviderConnection`
**Validation rules**:
- This spec does not change credential persistence, mutation rules, or encryption handling.
- Credential presence may continue to influence diagnostic projections, but it is not itself rendered as a leading readiness label on the targeted surfaces.
### OperationRun / Verification Report
**Purpose**: Stored verification evidence used by tenant verification and provider check surfaces.
**Key fields**:
- `tenant_id`
- `type` with `provider.connection.check`
- `status`
- `outcome`
- `context`
- stored verification report payload derived from the run
**Relationships**:
- `OperationRun` belongs to `Tenant` when tenant-bound
**Validation rules**:
- The latest stored verification report remains the deep-dive verification surface for tenant detail.
- This spec does not change run lifecycle, queueing, or verification report persistence.
## Existing Domain State Families
### TenantLifecycle
**Values**:
- `draft`
- `onboarding`
- `active`
- `archived`
**Rule**:
- Lifecycle answers whether the tenant is in the normal lifecycle. It does not answer provider consent, provider verification, or provider readiness.
### ProviderConsentStatus
**Values**:
- `unknown`
- `required`
- `granted`
- `failed`
- `revoked`
**Rule**:
- Consent answers whether the permission or consent step has been completed. It does not prove provider verification health.
### ProviderVerificationStatus
**Values**:
- `unknown`
- `pending`
- `healthy`
- `degraded`
- `blocked`
- `error`
**Rule**:
- Verification is the primary current provider-state axis for whether a connection has been checked and what that check currently proves.
### Legacy Diagnostic Projections
**Known provider projection values in current surfaces**:
- `status`: commonly `connected`, `needs_consent`, `error`, `disabled`
- `health_status`: commonly `ok`, `degraded`, `down`, `unknown`
**Rule**:
- These values remain diagnostics or projections. They must not compete with consent and verification as primary operator truth on targeted surfaces.
## Derived Surface Contracts
### Tenant List Row Truth (derived, non-persisted)
**Purpose**: Minimal row-level truth for `/admin/tenants`.
| Field | Type | Required | Description |
|------|------|----------|-------------|
| `tenantId` | integer | yes | Tenant identifier |
| `tenantLabel` | string | yes | Tenant name |
| `lifecycle` | string | yes | Lifecycle label derived from `TenantLifecycle` |
| `providerSignal` | object nullable | no | Optional bounded provider summary derived from current truth; may be absent in this slice |
| `legacyAppStatusVisible` | boolean | yes | Must be `false` on default-visible tenant list surfaces |
| `primaryInspectUrl` | string | yes | Canonical tenant detail destination |
**Validation rules**:
- `providerSignal` may be omitted when a truthful single-row summary cannot be stated without inventing a readiness model.
- `legacyAppStatusVisible` must be `false` for the default tenant list configuration.
### Tenant Detail Provider Summary (derived, non-persisted)
**Purpose**: Compact provider-state summary rendered inside the tenant detail `Provider` section.
| Field | Type | Required | Description |
|------|------|----------|-------------|
| `connectionPresence` | enum | yes | `missing`, `configured`, or `default_configured` |
| `ctaUrl` | string | yes | Canonical provider-connections destination |
| `displayName` | string nullable | no | Default or chosen connection display name |
| `provider` | string nullable | no | Provider label |
| `consentStatus` | string nullable | no | Current consent state from the chosen connection |
| `verificationStatus` | string nullable | no | Current verification state from the chosen connection |
| `lastCheckedAt` | string nullable | no | Stored last-check timestamp |
| `lastErrorReasonCode` | string nullable | no | Diagnostic reason code when present |
| `legacyStatus` | string nullable | no | Legacy diagnostic projection |
| `legacyHealthStatus` | string nullable | no | Legacy health projection |
**Validation rules**:
- Consent and verification are the leading fields in this summary.
- Legacy status and health may remain available only as diagnostics.
- When no default Microsoft provider connection exists, the summary must explicitly say action is needed and must not invent a healthy or ready label.
### Provider Connection Surface Truth (derived, non-persisted)
**Purpose**: Shared truth hierarchy for provider connection list, view, and edit surfaces.
| Field | Type | Required | Description |
|------|------|----------|-------------|
| `connectionId` | integer | yes | Provider connection identifier |
| `tenantLabel` | string nullable | no | Tenant label when rendered on tenantless canonical surfaces |
| `displayName` | string | yes | Connection display name |
| `provider` | string | yes | Provider key or label |
| `connectionType` | string | yes | Platform or dedicated |
| `isDefault` | boolean | yes | Default designation |
| `consentStatus` | string | yes | Leading consent truth |
| `verificationStatus` | string | yes | Leading verification truth |
| `legacyStatus` | string nullable | no | Secondary diagnostic projection |
| `legacyHealthStatus` | string nullable | no | Secondary diagnostic projection |
| `migrationReviewRequired` | boolean | yes | Secondary diagnostic flag |
| `lastCheckedAt` | string nullable | no | Last stored check timestamp |
| `lastErrorReasonCode` | string nullable | no | Stored diagnostic reason code |
**Validation rules**:
- List, view, and edit surfaces must display `consentStatus` and `verificationStatus` before any legacy projection fields.
- Legacy fields may remain filterable or visible only when clearly marked and positioned as diagnostics.
- `connectionType` and `isDefault` remain supporting facts, not substitutes for readiness.
## Surface Truth Hierarchy Rules
1. Tenant lifecycle is the primary tenant-state axis.
2. Provider consent and provider verification are the primary provider-state axes.
3. RBAC remains a separate tenant-management domain.
4. Legacy tenant app status, provider status, and provider health are diagnostic-only on targeted surfaces.
5. No derived surface contract in this feature may collapse `active`, `connected`, or `consented` into a synthetic `ready` value.
## No New Persistence
- No new table is introduced.
- No new enum or reason family is introduced.
- No new persisted readiness summary is introduced.
- Existing persisted legacy fields remain for compatibility, but their surface role is reduced.