# Data Model: Provider Capability Registry ## Existing persisted truth reused ### ProviderConnection Existing persisted fields already provide most capability inputs: - `workspace_id` - `managed_environment_id` - `provider` - `entra_tenant_id` as provider-owned Microsoft detail, not the new shared capability vocabulary - `connection_type` - `consent_status` - `verification_status` - `scopes_granted` - `last_error_reason_code` - `last_error_message` - `last_health_check_at` - `metadata` ### Required-permissions evidence Existing required-permissions and verification seams already expose row-level or grouped evidence: - permission key - permission type (`application` or `delegated`) - status (`granted`, `missing`, `error`) - description - features - freshness and verification timing - `required_permissions_url` ### Provider-backed operation definitions Existing provider-backed operation definitions already provide: - `operation_type` - `module` - `label` - user RBAC `required_capability` - provider binding metadata These remain separate from provider application capability truth. ## Canonical initial capability inventory and mapping The initial inventory is bounded to current repo workflows only. | Capability Key | Operator Label | Current Operation Types | Initial Provider Requirement Keys | |---|---|---|---| | `provider_connection_check` | Provider connection check | `provider.connection.check` | `permissions.admin_consent` | | `inventory_read` | Inventory read | `inventory.sync` | `permissions.intune_configuration`, `permissions.intune_apps` | | `configuration_read` | Configuration read | `compliance.snapshot` | `permissions.intune_configuration` | | `restore_execute` | Restore execute | `restore.execute` | `permissions.intune_configuration`, `permissions.intune_rbac_assignments` | | `directory_groups_read` | Directory groups read | `directory.groups.sync` | `permissions.directory_groups` | | `directory_role_definitions_read` | Directory role definitions read | `directory.role_definitions.sync` | `provider.directory_role_definitions`, `permissions.admin_consent` | `provider.directory_role_definitions` is intentionally modeled as a provider-owned requirement key because the current diagnostic cluster inventory does not yet expose a narrower shared cluster for that workflow. Capability evaluation may additionally inspect provider connection lifecycle, consent, and verification state when resolving `blocked`, `unknown`, or `supported`, but those state inputs remain evaluator inputs rather than new top-level requirement keys. ## New derived contracts ### ProviderCapabilityDefinition Represents one business-facing provider workflow capability. | Field | Type | Notes | |---|---|---| | `key` | string | Stable platform-core capability key from the bounded six-key inventory above | | `label` | string | Operator-facing label | | `operation_types` | list | Current repo operations that depend on the capability | | `provider_requirement_keys` | list | Provider-owned identifiers backing the capability, such as cluster keys or raw permission keys | | `primary_reason_codes` | list | Existing provider reason codes that commonly explain missing, blocked, or unknown states | | `remediation_route_kind` | string | Logical hint for where the operator should go next, e.g. `required_permissions` | ### ProviderCapabilityStatus Derived status enum with the bounded set: - `supported` - `missing` - `blocked` - `unknown` - `not_applicable` Definitions: - `supported`: current provider and permission evidence is sufficient for the workflow - `missing`: required provider-owned prerequisites are absent - `blocked`: prerequisites exist, but provider connection or provider state blocks execution anyway - `unknown`: evidence is stale, absent, or not trustworthy enough to decide - `not_applicable`: the capability does not apply to the current provider binding or current workflow ### ProviderCapabilityResult Represents the derived result of evaluating one capability for one managed environment and optional provider connection. | Field | Type | Notes | |---|---|---| | `provider_capability_key` | string | Shared capability key | | `status` | enum | `ProviderCapabilityStatus` | | `reason_code` | string or null | Existing provider reason code when the result is blocked, missing, or unknown | | `provider_requirement_keys` | list | The provider-owned requirement identifiers used to justify the result | | `last_checked_at` | string or null | Derived from the freshest relevant source timestamp | | `primary_message` | string | Short operator-facing explanation | | `provider_hint` | string or null | Provider-owned remediation hint | | `evidence_counts` | array | Optional counts for required, granted, missing, or error evidence | ### RequiredPermissionsCapabilityGroup Used by the required-permissions page to group raw permission evidence under one capability heading. | Field | Type | Notes | |---|---|---| | `provider_capability_key` | string | Shared capability key | | `label` | string | Display label | | `status` | enum | Capability status | | `summary` | string | Top-level explanation | | `missing_requirement_keys` | list | Provider-owned raw requirements still missing | | `rows` | list | Supporting row-level evidence | ### ProviderConnectionCapabilitySummary Derived provider-connection summary aggregate used by provider-connections list and detail surfaces. | Field | Type | Notes | |---|---|---| | `provider_connection_id` | integer | Current provider connection | | `primary_capability_key` | string | Capability surfaced first on the summary card or row | | `primary_capability_selection_rule` | string | Bounded rule: highest-risk status first, then current surface relevance | | `capabilities` | list | Capability results available for the current connection | | `next_step` | string or null | One dominant next action for the summary surface | ### OperationCapabilityGateResult Derived operation-start contract used before dispatch. | Field | Type | Notes | |---|---|---| | `operation_type` | string | Current repo operation type | | `required_provider_capability_keys` | list | Capability keys needed by the operation | | `capabilities` | list | Evaluated capability results | | `decision` | string | `allow`, `block`, or `unknown` | | `next_step` | string or null | Shared next-step hint, usually the required-permissions path | ### OnboardingCapabilityAssist Derived onboarding-ready summary for a selected provider connection or target workflow. | Field | Type | Notes | |---|---|---| | `managed_environment_id` | integer | Current managed environment | | `provider_connection_id` | integer or null | Selected provider connection when present | | `primary_capability_key` | string | Capability that currently blocks or informs the onboarding step | | `capabilities` | list | Capability results relevant to the current onboarding step | | `next_step` | string or null | Usually the required-permissions path or a connection-management action | ### ProviderCapabilityExplanation Derived capability-first explanation used by support or contextual-help consumers. | Field | Type | Notes | |---|---|---| | `provider_capability_key` | string | Shared capability key | | `reason_code` | string or null | Existing provider reason code | | `primary_message` | string | Capability-first explanation | | `provider_hint` | string or null | Provider-owned remediation hint | | `required_permissions_url` | string or null | Existing diagnostic or remediation link | ## Relationships - One `ProviderConnection` can produce many `ProviderCapabilityResult` values. - One provider capability can support many operation types, but the initial slice keeps the mapping bounded to current repo workflows only. - One required-permissions page can render many `RequiredPermissionsCapabilityGroup` values, each backed by many raw permission rows. - One operation-start request can depend on one or more provider capability keys, but the initial mapping should stay as small as current repo workflows require. ## Status mapping rules - `missing` is driven by provider-owned requirement evidence that is absent. - `blocked` is driven by connection-state or provider-state blockers such as disabled connections, consent revoked, or review-required states even when some requirements exist. - `unknown` is driven by stale or absent evidence where the system cannot safely claim `supported` or `missing`. - `not_applicable` is used only when the workflow does not apply to the active provider binding. - Existing user RBAC capability failures are not represented here and remain a separate authorization outcome. ## Explicit non-goals for data modeling - no `provider_capabilities` table - no persisted capability snapshots - no new provider-profile entity - no artifact taxonomy or broader governed-subject taxonomy