## Summary - implement the provider capability registry and derived capability evaluation flow - update provider connections, onboarding, required-permissions diagnostics, and provider blocker translation to use capability-first summaries - add bounded unit, feature, and browser test coverage plus the prepared Spec 283 artifacts ## Notes - branch: `283-provider-capability-registry` - commit: `74e75c3e` - no additional validation commands were run in this git/PR flow step Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #342
192 lines
8.9 KiB
Markdown
192 lines
8.9 KiB
Markdown
# 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<string> | Current repo operations that depend on the capability |
|
|
| `provider_requirement_keys` | list<string> | Provider-owned identifiers backing the capability, such as cluster keys or raw permission keys |
|
|
| `primary_reason_codes` | list<string> | 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<string> | 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<string,int> | 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<string> | Provider-owned raw requirements still missing |
|
|
| `rows` | list<PermissionEvidenceRow> | 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<ProviderCapabilityResult> | 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<string> | Capability keys needed by the operation |
|
|
| `capabilities` | list<ProviderCapabilityResult> | 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<ProviderCapabilityResult> | 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 |