222 lines
8.7 KiB
Markdown
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. |