## 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
302 lines
27 KiB
Markdown
302 lines
27 KiB
Markdown
# Implementation Plan: Provider Capability Registry
|
|
|
|
**Branch**: `283-provider-capability-registry` | **Date**: 2026-05-08 | **Spec**: [spec.md](./spec.md)
|
|
**Input**: Feature specification from `specs/283-provider-capability-registry/spec.md`
|
|
|
|
## Summary
|
|
|
|
Prepare the next reserved provider-boundary slice by introducing one provider capability registry and derived capability-evaluation path over the repo's existing provider connection, required-permissions, onboarding, blocked-operation, and support-diagnostic seams. The narrow implementation path reuses the current provider operation registry, provider operation start gate, required-permissions matrix, provider reason translation, provider-connections resource, onboarding wizard, and support links while explicitly rejecting a provider-capability table, a provider framework, a user RBAC rewrite, a broader taxonomy, and adjacent cutover work from Specs `284` through `287`.
|
|
|
|
This plan is intentionally bounded. Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, `ProviderConnectionResource` remains non-globally-searchable, existing destructive provider-connection actions stay confirmation-protected and server-authorized, and raw Graph permission names remain provider-owned evidence rather than the new primary operator vocabulary.
|
|
|
|
## Inherited Baseline / Explicit Delta
|
|
|
|
### Inherited baseline
|
|
|
|
- Spec `279` already completed the managed-environment core cutover and is historical prerequisite context only.
|
|
- Spec `280` already prepared the workspace-first shell and remains separate adjacent context only.
|
|
- Spec `281` already prepared the provider-neutral target-scope and provider-identity baseline and is an implementation prerequisite for `283`.
|
|
- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` already exists with `List`, `Create`, `View`, and `Edit` pages, remains `protected static bool $isGloballySearchable = false;`, and already groups mutating actions behind confirmation-protected Filament actions.
|
|
- `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php` already lives under the workspace-first managed-environment route shell and already keeps its actions inside the page body rather than the page header.
|
|
- `apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php` already groups raw permission rows into diagnostic clusters such as admin consent, directory/groups, Intune configuration, apps, RBAC, and scripts, but it does not yet publish workflow capability truth.
|
|
- `apps/platform/app/Services/Providers/ProviderOperationRegistry.php` already maps operation types to user RBAC capability requirements and provider bindings, but it does not yet map those operations to provider application capabilities.
|
|
- `apps/platform/app/Services/Providers/ProviderOperationStartGate.php` already blocks or starts provider-backed work through one shared path, but it still explains missing prerequisites through reason codes and raw requirement detail rather than a stable capability contract.
|
|
- `apps/platform/app/Support/Providers/ProviderReasonTranslator.php`, contextual-help catalog or resolver seams, and support-diagnostic consumers already translate provider blockers and route operators to `RequiredPermissionsLinks`, but they still lead with provider-specific requirement language in several cases.
|
|
- `apps/platform/app/Models/ProviderConnection.php` already persists consent state, verification state, `scopes_granted`, and metadata, so `283` must treat provider capability state as derived truth rather than add another table.
|
|
|
|
### Explicit delta in this plan
|
|
|
|
- Introduce one bounded provider capability definition and evaluation layer over the existing provider connection, required-permissions, and blocked-operation seams.
|
|
- Keep provider capability state derived and request-time or snapshot-derived; do not add a provider-capability table or ledger.
|
|
- Map the current provider-backed operation types to explicit provider capability keys.
|
|
- Reuse the required-permissions page as the canonical diagnostic deep dive, but group or summarize raw requirement rows under shared capability headings and statuses.
|
|
- Reuse `ProviderConnectionResource` and `ManagedTenantOnboardingWizard` as the operator-facing summary consumers for the new capability contract.
|
|
- Reuse `ProviderReasonTranslator`, `ProviderNextStepsRegistry`, and existing support or product-knowledge links so blocked-operation and diagnostic guidance adopts the same capability vocabulary.
|
|
- Keep raw Graph permission names, Intune RBAC prerequisite detail, consent links, and provider portal metadata nested inside provider-owned remediation or evidence blocks.
|
|
- Keep Specs `284` through `287` explicitly deferred.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4.15, Laravel 12.52
|
|
**Primary Dependencies**: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, existing provider operation, provider reason, onboarding, and required-permissions seams
|
|
**Storage**: PostgreSQL, no new persistence or schema change in this slice
|
|
**Testing**: Pest unit tests, Pest feature tests, and one Pest browser smoke
|
|
**Validation Lanes**: fast-feedback, confidence, browser
|
|
**Target Platform**: Laravel monolith in `apps/platform`
|
|
**Project Type**: web application
|
|
**Performance Goals**: preserve current provider-connection, onboarding, and required-permissions responsiveness while changing only derived capability evaluation and summary presentation; no new remote inline work or asset path is introduced
|
|
**Constraints**: no provider-capability table, no provider framework, no user RBAC changes, no route-cutover work from Spec `280`, no provider-identity extraction work from Spec `281`, provider registration stays in `apps/platform/bootstrap/providers.php`, and `ProviderConnectionResource` stays non-globally-searchable
|
|
**Scale/Scope**: one shared capability contract over the existing Microsoft provider implementation and current provider-backed workflows only
|
|
|
|
## Likely Affected Repo Surfaces
|
|
|
|
- `apps/platform/app/Services/Providers/ProviderOperationRegistry.php`
|
|
- `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`
|
|
- `apps/platform/app/Support/Providers/ProviderReasonCodes.php`
|
|
- `apps/platform/app/Support/Providers/ProviderReasonTranslator.php`
|
|
- `apps/platform/app/Support/Providers/ProviderNextStepsRegistry.php`
|
|
- `apps/platform/app/Support/Verification/TenantPermissionCheckClusters.php`
|
|
- `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php`
|
|
- `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php`
|
|
- `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`
|
|
- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`
|
|
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php`
|
|
- `apps/platform/app/Support/Links/RequiredPermissionsLinks.php`
|
|
- `apps/platform/app/Support/ProductKnowledge/ContextualHelpCatalog.php`
|
|
- `apps/platform/app/Support/ProductKnowledge/ContextualHelpResolver.php`
|
|
- `apps/platform/app/Support/TenantDashboard/TenantDashboardSummaryBuilder.php` if that surface already consumes the shared provider prerequisite explanation and must stay aligned without becoming a separate dashboard initiative
|
|
- `apps/platform/config/provider_boundaries.php`
|
|
- `apps/platform/config/intune_permissions.php` only if the implementation needs to read existing provider-owned requirement identifiers from the current config rather than re-declare them locally
|
|
- new bounded support files under `apps/platform/app/Support/Providers/Capabilities/` only if implementation needs a small dedicated namespace for the registry, status enum, and evaluator
|
|
- representative proof files under `apps/platform/tests/Unit/Providers/`, `apps/platform/tests/Unit/Verification/`, `apps/platform/tests/Feature/Providers/`, `apps/platform/tests/Feature/Filament/`, `apps/platform/tests/Feature/Onboarding/`, `apps/platform/tests/Feature/RequiredPermissions/`, `apps/platform/tests/Feature/SupportDiagnostics/`, and `apps/platform/tests/Browser/`
|
|
|
|
## Filament v5 / Capability Surface Notes
|
|
|
|
- **Livewire v4.0+ compliance**: all touched Filament work remains on Filament v5 with Livewire v4.
|
|
- **Provider registration location**: provider registration stays in `apps/platform/bootstrap/providers.php`; nothing moves to `bootstrap/app.php`.
|
|
- **Global search rule**: `ProviderConnectionResource` remains non-globally-searchable and keeps its `View` and `Edit` pages. No new searchable resource is introduced by this slice.
|
|
- **Destructive actions**: touched provider-connection mutations keep the existing `->action(...)`, `->requiresConfirmation()`, and server-authorization contracts. `Grant admin consent` remains navigation-only.
|
|
- **Asset strategy**: no new asset registration or deploy-step change is planned.
|
|
|
|
## Provider Capability Contract Fit
|
|
|
|
- Introduce one bounded capability definition source for current-release provider-backed workflows only.
|
|
- Keep the shared capability-key inventory limited to the workflows already present in repo truth:
|
|
- `provider_connection_check`
|
|
- `inventory_read`
|
|
- `configuration_read`
|
|
- `restore_execute`
|
|
- `directory_groups_read`
|
|
- `directory_role_definitions_read`
|
|
- Keep capability status values limited to the derived family from the spec: `supported`, `missing`, `blocked`, `unknown`, and `not_applicable`.
|
|
- Keep capability definitions platform-core, but keep provider requirement mappings provider-owned. That means capability definitions can point to provider-owned requirement keys such as cluster identifiers or Graph permission names without promoting those raw identifiers into the top-level operator vocabulary.
|
|
- Prefer one small code-first registry plus evaluator namespace over a new config-first framework or a new table. If implementation discovers that one small code-first registry cannot stay reviewable, that change must be re-justified rather than added silently.
|
|
- Reuse existing permission-cluster evidence and provider-connection state as inputs. The capability layer should not replace those inputs; it should standardize how they are interpreted by workflow consumers.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: changed surfaces
|
|
- **Native vs custom classification summary**: mixed native Filament resource plus existing custom onboarding wizard
|
|
- **Shared-family relevance**: provider summary, blocked guidance, onboarding readiness, required-permissions diagnostics, support translation
|
|
- **State layers in scope**: page, detail, modal, Livewire state, URL-query
|
|
- **Audience modes in scope**: operator-MSP, support-platform
|
|
- **Decision/diagnostic/raw hierarchy plan**: capability-first summary, diagnostics-second evidence, provider-raw-third remediation detail
|
|
- **Raw/support gating plan**: provider-specific requirement detail stays nested or lower-priority; raw permission rows stay on the diagnostic page rather than the top-level summary
|
|
- **One-primary-action / duplicate-truth control**: provider-connections and onboarding surface one dominant next step from the capability result and delegate the full proof to the required-permissions page
|
|
- **Handling modes by drift class or surface**: review-mandatory
|
|
- **Repository-signal treatment**: review-mandatory until provider-connections, onboarding, required-permissions, and blocked-operation messaging all use the same capability labels
|
|
- **Special surface test profiles**: standard-native-filament, workflow-hub, shared-detail-family
|
|
- **Required tests or browser smoke**: functional-core, state-contract, browser-smoke
|
|
- **Exception path and spread control**: none; the slice removes explanation drift rather than adding a new exception
|
|
- **Active feature PR close-out entry**: Guardrail
|
|
|
|
## Shared Pattern & System Fit
|
|
|
|
- **Cross-cutting feature marker**: yes
|
|
- **Systems touched**: provider operation registry, provider operation start gate, required-permissions diagnostics, onboarding readiness, provider connection summaries, provider reason translation, contextual help, and support-diagnostic guidance
|
|
- **Shared abstractions reused**: `ProviderOperationRegistry`, `ProviderOperationStartGate`, `ProviderReasonTranslator`, `ProviderNextStepsRegistry`, `TenantPermissionCheckClusters`, `TenantRequiredPermissionsViewModelBuilder`, `ProviderConnectionSurfaceSummary`, and `RequiredPermissionsLinks`
|
|
- **New abstraction introduced? why?**: one small registry plus evaluator namespace is expected because multiple existing shared consumers need one stable capability contract and no current shared abstraction owns that concept yet
|
|
- **Why the existing abstraction was sufficient or insufficient**: existing abstractions already own provider connection state, permission evidence, or blocked-operation explanation, but none of them own the workflow-capability concept across all current consumers
|
|
- **Bounded deviation / spread control**: provider-owned Graph permission names, Intune RBAC detail, consent links, and portal metadata remain nested evidence only and must not define the shared capability contract
|
|
|
|
## OperationRun UX Impact
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: yes
|
|
- **Central contract reused**: `ProviderOperationStartGate`, `ProviderOperationStartResultPresenter`, `OperationUxPresenter`, and the current `OperationRunService` lifecycle path
|
|
- **Delegated UX behaviors**: blocked-versus-started behavior, queued intent messaging, run links, capability-driven remediation hints, and provider-safe follow-up routing stay delegated to the existing shared provider-operation path
|
|
- **Surface-owned behavior kept local**: `ProviderConnectionResource` and `ManagedTenantOnboardingWizard` keep only initiation affordances, summary placement, and assist entry points
|
|
- **Queued DB-notification policy**: `N/A`
|
|
- **Terminal notification path**: existing central lifecycle mechanism
|
|
- **Exception path**: none
|
|
|
|
## Provider Boundary & Portability Fit
|
|
|
|
- **Shared provider/platform boundary touched?**: yes
|
|
- **Provider-owned seams**: raw Graph permission names, Intune RBAC remediation detail, admin-consent links, required-permissions URLs, portal links, and any provider-specific troubleshooting metadata
|
|
- **Platform-core seams**: capability definitions, capability status evaluation, operation-to-capability mapping, blocked-operation capability summary, shared capability labels, and shared diagnostic grouping
|
|
- **Neutral platform terms / contracts preserved**: `provider capability`, `capability key`, `capability status`, `provider connection`, `managed environment`, `target workflow`, and `provider requirement`
|
|
- **Retained provider-specific semantics and why**: the current Microsoft provider still needs its own raw permission names, consent guidance, and Intune RBAC detail for operators to fix blockers. Those details remain explicit provider-owned evidence.
|
|
- **Bounded extraction or follow-up path**: no broader taxonomy or multi-provider framework work in this slice; that remains with Specs `284` through `287`
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before implementation begins and again after design artifacts are complete.*
|
|
|
|
- Inventory-first / snapshot truth: PASS. The slice derives capability truth from existing provider and permission evidence.
|
|
- Read/write separation: PASS. No new remote-write workflow is introduced.
|
|
- Graph contract path: PASS. No new Graph endpoint or contract-registry work is added.
|
|
- Deterministic capabilities: PASS with implementation condition. Capability evaluation must be testable and deterministic from the existing provider and permission inputs.
|
|
- RBAC-UX plane separation: PASS. `/admin` versus `/system` remains unchanged.
|
|
- Workspace isolation: PASS. Workspace membership remains the first boundary.
|
|
- Managed-environment isolation: PASS. Managed-environment entitlement remains the second boundary.
|
|
- Destructive action discipline: PASS by preservation. Existing confirmation-protected provider-connection mutations remain unchanged.
|
|
- Global search safety: PASS. `ProviderConnectionResource` stays non-globally-searchable.
|
|
- OperationRun / Ops-UX: PASS. The slice reuses the shared provider-operation start path and changes only its prerequisite contract.
|
|
- Data minimization: PASS. No new persistence or provider-capability ledger is introduced.
|
|
- Test governance: PASS. Proof stays bounded to unit, feature, and one browser smoke.
|
|
- Proportionality / no premature abstraction: PASS with implementation condition. Any new support namespace must stay narrow and current-release only.
|
|
- Persisted truth / behavioral state: PASS. One new derived state family is introduced; no new persistence is introduced.
|
|
- UI semantics / shared pattern first / Filament-native UI: PASS. Existing resource, page, and wizard surfaces remain the primary operator paths.
|
|
- Provider boundary: PASS with implementation condition. Raw provider requirement detail must remain secondary evidence rather than reappearing as the primary shared label set.
|
|
|
|
**Gate evaluation**: PASS.
|
|
|
|
**Post-design re-check**: PASS while `research.md`, `data-model.md`, `quickstart.md`, `contracts/provider-capability-registry.logical.openapi.yaml`, and `checklists/requirements.md` stay aligned on the same capability keys, status family, derived-truth posture, and proof commands.
|
|
|
|
## Test Governance Check
|
|
|
|
- **Test purpose / classification by changed surface**: Unit, Feature, Browser
|
|
- **Affected validation lanes**: fast-feedback, confidence, browser
|
|
- **Why this lane mix is the narrowest sufficient proof**: the registry and evaluator logic are pure derivation and deserve unit proof; the shared start gate, provider-connections, onboarding, required-permissions page, and support translation need feature proof; one browser smoke is enough to prove the real operator path from provider connection or onboarding into the diagnostic page
|
|
- **Narrowest proving command(s)**:
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/Providers/ProviderCapabilityRegistryTest.php tests/Unit/Verification/TenantPermissionCapabilityMappingTest.php)`
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Providers/ProviderCapabilityEvaluationTest.php tests/Feature/Providers/ProviderOperationCapabilityGateTest.php tests/Feature/Filament/ProviderConnectionCapabilitySummaryTest.php tests/Feature/Onboarding/ManagedTenantOnboardingCapabilityAssistTest.php tests/Feature/RequiredPermissions/RequiredPermissionsCapabilityGroupingTest.php tests/Feature/SupportDiagnostics/ProviderCapabilityReasonTranslationTest.php)`
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec283ProviderCapabilityRegistrySmokeTest.php)`
|
|
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)`
|
|
- **Fixture / helper / factory / seed / context cost risks**: moderate because proof needs workspace, managed environment, provider connection, permission evidence, and blocked-operation context without widening shared fixture defaults
|
|
- **Expensive defaults or shared helper growth introduced?**: no; any new capability test helper should stay feature-local and opt-in
|
|
- **Heavy-family additions, promotions, or visibility changes**: none beyond one bounded browser smoke
|
|
- **Surface-class relief / special coverage rule**: standard-native-filament relief for provider-connections and required-permissions; one workflow-hub smoke for onboarding continuity
|
|
- **Closing validation and reviewer handoff**: rerun the commands above, verify that no provider-capability table appears, verify that the registry stays current-release-only, verify that provider-connections and onboarding use the same capability labels, verify that the required-permissions page groups evidence under those same labels, verify that blocked-operation context carries capability information, and verify that raw Graph permission names remain secondary evidence
|
|
- **Budget / baseline / trend follow-up**: contained feature-local increase only
|
|
- **Review-stop questions**: did the implementation add persistence, did it invent future-facing capability keys, did it widen into RBAC or taxonomy work, did any touched surface keep a page-local permission vocabulary, did blocked-operation context stay on reason-only or raw permission language
|
|
- **Escalation path**: `reject-or-split` if implementation introduces persistence, a provider framework, a user RBAC rewrite, or broader cutover work from adjacent specs
|
|
- **Active feature PR close-out entry**: Guardrail
|
|
- **Why no dedicated follow-up spec is needed**: adjacent follow-up work already exists as Specs `284` through `287`; `283` only needs the bounded capability slice itself
|
|
|
|
## Review Checklist Status
|
|
|
|
- **Review checklist artifact**: `checklists/requirements.md`
|
|
- **Review outcome class**: `implementation-ready`
|
|
- **Workflow outcome**: `keep`
|
|
- **Test-governance outcome**: `keep`
|
|
- **Escalation rule**: if implementation adds persistence, broad future-facing keys, or adjacent-spec scope, flip the workflow outcome to `split` or `reject-or-split`
|
|
|
|
## Rollout Considerations
|
|
|
|
- Land the registry definitions, evaluator, and shared consumer updates as one bounded slice so provider-connections, onboarding, required-permissions diagnostics, and provider-operation blocking all converge atomically.
|
|
- Update the shared evaluation and translation seams before polishing page copy so the touched surfaces inherit the same contract rather than reformatting raw evidence separately.
|
|
- Keep provider-owned evidence and remediation nested from the start; otherwise the later UI pass will still have to untangle raw Microsoft-first summaries.
|
|
- Keep dashboard or support surfaces limited to consumers of the shared capability contract and do not let them grow into a separate productization initiative in this slice.
|
|
|
|
## Risk Controls
|
|
|
|
- Reject any implementation that introduces a provider-capability table, ledger, or snapshot model.
|
|
- Reject any implementation that creates a future-facing provider framework or tries to solve multi-provider routing, taxonomy, or UI copy in the same slice.
|
|
- Reject any implementation that leaves provider-connections, onboarding, and required-permissions diagnostics on different capability or requirement vocabularies.
|
|
- Reject any implementation that collapses user RBAC capability failures into provider application capability failures.
|
|
- Reject any implementation that promotes raw Graph permission names back into the primary operator summary on touched surfaces.
|
|
|
|
## Research & Design Outputs
|
|
|
|
- `research.md` records the bounded derivation decisions, the capability-key inventory, the provider-owned evidence rules, and the rejected alternatives.
|
|
- `data-model.md` captures the derived capability definition, result, evidence, grouped diagnostic view, and operation-gate contracts.
|
|
- `quickstart.md` gives reviewers the bounded proof flow and exact commands.
|
|
- `contracts/provider-capability-registry.logical.openapi.yaml` models the logical capability summary, diagnostic grouping, onboarding assist, support explanation, and operation-start contract.
|
|
- `checklists/requirements.md` records package readiness, boundedness, and outcome state.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/283-provider-capability-registry/
|
|
├── checklists/
|
|
│ └── requirements.md
|
|
├── contracts/
|
|
│ └── provider-capability-registry.logical.openapi.yaml
|
|
├── data-model.md
|
|
├── plan.md
|
|
├── quickstart.md
|
|
├── research.md
|
|
├── spec.md
|
|
└── tasks.md
|
|
```
|
|
|
|
### Source Code (expected implementation surfaces)
|
|
|
|
```text
|
|
apps/platform/
|
|
├── app/
|
|
│ ├── Filament/
|
|
│ │ ├── Pages/
|
|
│ │ │ ├── TenantRequiredPermissions.php
|
|
│ │ │ └── Workspaces/
|
|
│ │ │ └── ManagedTenantOnboardingWizard.php
|
|
│ │ └── Resources/
|
|
│ │ └── ProviderConnectionResource.php
|
|
│ ├── Models/
|
|
│ │ └── ProviderConnection.php
|
|
│ ├── Services/
|
|
│ │ ├── Intune/
|
|
│ │ │ └── TenantRequiredPermissionsViewModelBuilder.php
|
|
│ │ └── Providers/
|
|
│ │ ├── ProviderOperationRegistry.php
|
|
│ │ └── ProviderOperationStartGate.php
|
|
│ └── Support/
|
|
│ ├── Links/
|
|
│ │ └── RequiredPermissionsLinks.php
|
|
│ ├── ProductKnowledge/
|
|
│ │ ├── ContextualHelpCatalog.php
|
|
│ │ └── ContextualHelpResolver.php
|
|
│ ├── Providers/
|
|
│ │ ├── ProviderNextStepsRegistry.php
|
|
│ │ ├── ProviderReasonCodes.php
|
|
│ │ ├── ProviderReasonTranslator.php
|
|
│ │ ├── TargetScope/
|
|
│ │ │ └── ProviderConnectionSurfaceSummary.php
|
|
│ │ └── Capabilities/
|
|
│ │ ├── ProviderCapabilityRegistry.php
|
|
│ │ ├── ProviderCapabilityResult.php
|
|
│ │ ├── ProviderCapabilityStatus.php
|
|
│ │ └── ProviderCapabilityEvaluator.php
|
|
│ ├── TenantDashboard/
|
|
│ │ └── TenantDashboardSummaryBuilder.php
|
|
│ └── Verification/
|
|
│ └── TenantPermissionCheckClusters.php
|
|
├── config/
|
|
│ ├── intune_permissions.php
|
|
│ └── provider_boundaries.php
|
|
└── tests/
|
|
├── Browser/
|
|
│ └── Spec283ProviderCapabilityRegistrySmokeTest.php
|
|
├── Feature/
|
|
│ ├── Filament/
|
|
│ │ └── ProviderConnectionCapabilitySummaryTest.php
|
|
│ ├── Onboarding/
|
|
│ │ └── ManagedTenantOnboardingCapabilityAssistTest.php
|
|
│ ├── Providers/
|
|
│ │ ├── ProviderCapabilityEvaluationTest.php
|
|
│ │ └── ProviderOperationCapabilityGateTest.php
|
|
│ ├── RequiredPermissions/
|
|
│ │ └── RequiredPermissionsCapabilityGroupingTest.php
|
|
│ └── SupportDiagnostics/
|
|
│ └── ProviderCapabilityReasonTranslationTest.php
|
|
└── Unit/
|
|
├── Providers/
|
|
│ └── ProviderCapabilityRegistryTest.php
|
|
└── Verification/
|
|
└── TenantPermissionCapabilityMappingTest.php
|
|
```
|
|
|
|
**Structure Decision**: keep the implementation inside `apps/platform` and add only one small support namespace for provider capability definitions and derived evaluation. Reuse existing Filament, provider-operation, required-permissions, and support-diagnostic seams instead of creating a new module or package. |