openapi: 3.1.0 info: title: Canonical Provider Connection State Cleanup Internal Contract version: 0.1.0 summary: Internal planning contract for the hard cut from legacy provider status and health to canonical lifecycle, consent, and verification description: | This contract is an internal planning artifact for Spec 188. The affected routes continue to render HTML. The schemas below describe the canonical provider-state contract that must be derivable before rendering and before runtime gates execute. Legacy `status` and `health_status` do not appear in any schema because the feature requires a hard cut with no compatibility payload. servers: - url: /internal x-cutover-order: - runtime_readers - runtime_writers - shared_presenters_and_badges - factories_helpers_and_tests - schema_removal x-runtime-readers: - surface: resolver_and_runtime_gates guardScope: - app/Services/Providers/ProviderConnectionResolver.php - app/Jobs/ScanEntraAdminRolesJob.php - app/Filament/Resources/ProviderConnectionResource.php expectedContract: - lifecycle_reads_is_enabled_only - consent_inference_reads_consent_status_only - verification_inference_reads_verification_status_only - surface: tenant_and_system_summaries guardScope: - app/Filament/Resources/TenantResource.php - resources/views/filament/infolists/entries/provider-connection-state.blade.php - app/Filament/System/Pages/Directory/Tenants.php - app/Filament/System/Pages/Directory/ViewTenant.php - resources/views/filament/system/pages/directory/view-tenant.blade.php expectedContract: - helper_payload_has_no_legacy_status_keys - system_rollups_derive_from_verification_and_permission_truth - admin_and_system_planes_tell_the_same_provider_state_story x-runtime-writers: - surface: onboarding_and_consent_bootstrap writerScope: - app/Http/Controllers/TenantOnboardingController.php - app/Http/Controllers/AdminConsentCallbackController.php - app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php expectedContract: - initialize_is_enabled - initialize_or_update_consent_status - initialize_verification_status_without_legacy_projection - surface: verification_and_health_check writerScope: - app/Services/Verification/StartVerification.php - app/Jobs/ProviderConnectionHealthCheckJob.php - app/Services/Providers/Contracts/HealthResult.php - app/Services/Providers/MicrosoftProviderHealthCheck.php - app/Services/Providers/ProviderConnectionStateProjector.php expectedContract: - verification_contract_uses_canonical_status - verification_writes_update_only_canonical_fields_and_diagnostics - surface: provider_mutations writerScope: - app/Services/Providers/ProviderConnectionMutationService.php - app/Filament/Resources/ProviderConnectionResource.php expectedContract: - enable_disable_mutations_write_lifecycle_not_legacy_status - credential_mutations_reset_or_block_verification_without_legacy_projection x-legacy-removal-scope: removed_columns: - provider_connections.status - provider_connections.health_status removed_badge_domains: - provider_connection.status - provider_connection.health removed_helper_keys: - status - health_status paths: /admin/provider-connections: get: summary: Render the canonical provider-connections list with lifecycle, consent, and verification as the only state axes operationId: viewCanonicalProviderConnections responses: '200': description: Provider-connections list rendered from canonical provider-state truth only content: text/html: schema: type: string application/vnd.tenantpilot.provider-connections-canonical+json: schema: $ref: '#/components/schemas/ProviderConnectionListTruthBundle' '302': description: Existing admin tenant-scoping redirects still apply '404': description: Workspace or tenant scope is outside entitlement /admin/provider-connections/{record}: get: summary: Render canonical provider connection detail without legacy provider status or health operationId: viewCanonicalProviderConnection parameters: - name: record in: path required: true schema: type: - integer - string responses: '200': description: Provider connection detail rendered from lifecycle, consent, verification, and diagnostics only content: text/html: schema: type: string application/vnd.tenantpilot.provider-connection-canonical+json: schema: $ref: '#/components/schemas/ProviderConnectionDetailTruthModel' '403': description: Actor is in scope but lacks the capability required for protected actions '404': description: Provider connection is outside entitlement scope /admin/provider-connections/{record}/edit: get: summary: Render canonical provider connection edit context with lifecycle, consent, and verification operationId: editCanonicalProviderConnection parameters: - name: record in: path required: true schema: type: - integer - string responses: '200': description: Provider connection edit rendered without legacy status or health fields content: text/html: schema: type: string application/vnd.tenantpilot.provider-connection-edit-canonical+json: schema: $ref: '#/components/schemas/ProviderConnectionDetailTruthModel' '403': description: Actor is in scope but lacks manage capability '404': description: Provider connection is outside entitlement scope /admin/tenants/{tenant}: get: summary: Render tenant detail provider summary from canonical provider-state truth only operationId: viewCanonicalTenantProviderSummary parameters: - name: tenant in: path required: true schema: type: string responses: '200': description: Tenant detail rendered with a canonical provider summary and no legacy provider-state payload content: text/html: schema: type: string application/vnd.tenantpilot.tenant-provider-summary-canonical+json: schema: $ref: '#/components/schemas/TenantProviderSummary' '404': description: Tenant is outside entitlement scope /system/directory/tenants: get: summary: Render system tenant directory with health rollups derived from canonical verification and permission truth operationId: viewSystemTenantDirectoryCanonicalHealth responses: '200': description: System directory list rendered without legacy provider health aggregation content: text/html: schema: type: string application/vnd.tenantpilot.system-tenant-directory-canonical+json: schema: $ref: '#/components/schemas/SystemTenantDirectoryTruthBundle' '404': description: Platform actor lacks directory access or tenant scope is unavailable /system/directory/tenants/{tenant}: get: summary: Render system tenant detail with canonical provider rows operationId: viewSystemTenantCanonicalProviderRows parameters: - name: tenant in: path required: true schema: type: - integer - string responses: '200': description: System tenant detail rendered with canonical provider-state rows only content: text/html: schema: type: string application/vnd.tenantpilot.system-tenant-canonical-provider-rows+json: schema: $ref: '#/components/schemas/SystemTenantDetailTruthModel' '404': description: Platform actor lacks directory access or tenant is unavailable components: schemas: LifecycleState: type: string enum: - enabled - disabled ProviderConsentState: type: string enum: - unknown - required - granted - failed - revoked ProviderVerificationState: type: string enum: - unknown - pending - healthy - degraded - blocked - error ProviderDiagnostics: type: object required: - migrationReviewRequired properties: lastCheckedAt: type: - string - 'null' lastErrorReasonCode: type: - string - 'null' lastErrorMessage: type: - string - 'null' consentErrorCode: type: - string - 'null' consentErrorMessage: type: - string - 'null' migrationReviewRequired: type: boolean CanonicalProviderConnectionState: type: object required: - lifecycle - isEnabled - consentStatus - verificationStatus - diagnostics properties: lifecycle: $ref: '#/components/schemas/LifecycleState' isEnabled: type: boolean consentStatus: oneOf: - $ref: '#/components/schemas/ProviderConsentState' - type: 'null' verificationStatus: oneOf: - $ref: '#/components/schemas/ProviderVerificationState' - type: 'null' diagnostics: $ref: '#/components/schemas/ProviderDiagnostics' ProviderConnectionRow: type: object required: - id - displayName - provider - connectionType - isDefault - state properties: id: type: integer tenantLabel: type: - string - 'null' displayName: type: string provider: type: string connectionType: type: string isDefault: type: boolean state: $ref: '#/components/schemas/CanonicalProviderConnectionState' ProviderConnectionListTruthBundle: type: object required: - rows properties: rows: type: array items: $ref: '#/components/schemas/ProviderConnectionRow' ProviderConnectionDetailTruthModel: type: object required: - id - displayName - provider - connectionType - isDefault - state properties: id: type: integer displayName: type: string provider: type: string connectionType: type: string isDefault: type: boolean effectiveAppId: type: - string - 'null' effectiveAppSource: type: - string - 'null' state: $ref: '#/components/schemas/CanonicalProviderConnectionState' TenantProviderSummary: type: object required: - state - ctaUrl - needsDefaultConnection properties: state: type: string enum: - missing - configured - default_configured ctaUrl: type: string needsDefaultConnection: type: boolean displayName: type: - string - 'null' provider: type: - string - 'null' canonicalState: oneOf: - $ref: '#/components/schemas/CanonicalProviderConnectionState' - type: 'null' SystemTenantDirectoryRow: type: object required: - tenantId - tenantLabel - workspaceLabel - providerConnectionsCount - criticalProviderCount - warningProviderCount - missingPermissionCount - systemHealth properties: tenantId: type: integer tenantLabel: type: string workspaceLabel: type: string providerConnectionsCount: type: integer criticalProviderCount: type: integer warningProviderCount: type: integer missingPermissionCount: type: integer systemHealth: type: string SystemTenantDirectoryTruthBundle: type: object required: - rows properties: rows: type: array items: $ref: '#/components/schemas/SystemTenantDirectoryRow' SystemTenantDetailTruthModel: type: object required: - tenantId - tenantLabel - providerConnections properties: tenantId: type: integer tenantLabel: type: string providerConnections: type: array items: $ref: '#/components/schemas/ProviderConnectionRow'