## Summary - retire the remaining tenant-scoped provider-connection legacy routes and update canonical verification and link behavior - complete the provider target-scope fallback cleanup so neutral shared scope data falls back to the managed environment when the raw connection tenant identifier is blank - stop mirroring workspace roles into managed-environment scope persistence and cut the targeted admin-panel test helpers over to the post-cutover context path - add and update the Spec 287 artifact package and targeted regression coverage for route retirement, provider-core neutralization, workspace-first RBAC, and helper cutover ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/ProviderConnections/TenantlessListRouteTest.php tests/Feature/ProviderConnections/TenantlessListScopingTest.php tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - Filament remains on Livewire v4 and provider registration stays unchanged in `apps/platform/bootstrap/providers.php`. - No new asset registration or deployment-step changes are included in this slice. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #346
230 lines
18 KiB
Markdown
230 lines
18 KiB
Markdown
# Implementation Plan: Cutover Prerequisite Completion
|
|
|
|
**Branch**: `287-cutover-prerequisite-completion` | **Date**: 2026-05-10 | **Spec**: [spec.md](./spec.md)
|
|
**Input**: Feature specification from `specs/287-cutover-prerequisite-completion/spec.md`
|
|
|
|
## Summary
|
|
|
|
Complete the remaining runtime and test-harness seams that still block the later quality-gates / no-legacy package. The narrow implementation path retires the legacy provider-connection route family, finishes provider target-scope core neutralization on the shared provider seams, cleans environment-scope role persistence so workspace membership remains the only role-bearing truth, replaces tenant-panel-era test helpers with post-cutover admin or workspace helpers, and validates only those seams with targeted feature and browser coverage.
|
|
|
|
This plan is intentionally not a no-legacy guard package. Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, no new asset or deployment step is introduced, no full-suite baseline is required, and Spec `288` remains the explicit follow-up for quality gates and no-legacy enforcement.
|
|
|
|
## Inherited Baseline / Explicit Delta
|
|
|
|
### Inherited baseline
|
|
|
|
- Spec `279` already owns the managed-environment core cutover and remains historical baseline context only.
|
|
- Spec `280` already owns the workspace-first route and panel-shell convergence, but repo truth still shows a surviving legacy provider-connection route family in `apps/platform/routes/web.php`.
|
|
- Spec `281` already owns provider boundary groundwork, but repo truth still shows Microsoft-shaped shared target-scope and identity fields on platform-core provider seams.
|
|
- Spec `282` already owns governance-artifact retargeting and remains adjacent historical context only.
|
|
- Spec `285` already owns the workspace-first RBAC direction, but repo truth still shows incomplete environment-scope persistence cleanup where managed-environment membership records mirror workspace role values.
|
|
- Spec `286` already owns UI copy cleanup and remains explicitly out of scope for this package.
|
|
|
|
### Explicit delta in this plan
|
|
|
|
- Retire the remaining legacy provider-connection route family instead of guarding it.
|
|
- Finish provider target-scope and identity neutralization on shared provider-core seams instead of leaving that work to a later enforcement slice.
|
|
- Complete the runtime cleanup that keeps workspace membership role-bearing and environment scope narrowing-only.
|
|
- Replace tenant-panel-era shared test helpers and the proof-command consumer tests `apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php` and `apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php` with post-cutover admin or workspace context helpers.
|
|
- Keep proof targeted to changed seams only and hand global enforcement to Spec `288`.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4.15, Laravel 12.52
|
|
**Primary Dependencies**: Pest 4, Filament 5.2.1, Livewire 4.1.4, existing provider target-scope and access-scope services, shared Pest test helpers
|
|
**Storage**: no new persistence; the package completes behavior on existing route, provider-core, access-scope, and test-support seams
|
|
**Testing**: targeted Pest feature tests plus targeted browser validation
|
|
**Validation Lanes**: fast-feedback, confidence, browser
|
|
**Target Platform**: Laravel monolith in `apps/platform`
|
|
**Project Type**: web application
|
|
**Performance Goals**: keep validation limited to the changed seams; no full-suite or broad guard lane work
|
|
**Constraints**: no global guard suite, no full-suite baseline, no package execution, no guided operations, no UI copy cleanup, no provider capability expansion
|
|
**Scale/Scope**: one bounded prerequisite-completion slice immediately preceding Spec `288`
|
|
|
|
## Likely Affected Repo Surfaces
|
|
|
|
- `apps/platform/routes/web.php`
|
|
- `apps/platform/app/Services/Providers/ProviderConnectionResolver.php`
|
|
- `apps/platform/app/Services/Providers/ProviderIdentityResolver.php`
|
|
- `apps/platform/app/Services/Providers/ProviderIdentityResolution.php`
|
|
- `apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php`
|
|
- `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`
|
|
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeNormalizer.php`
|
|
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php`
|
|
- `apps/platform/app/Services/Auth/TenantMembershipManager.php`
|
|
- `apps/platform/app/Services/Auth/ManagedEnvironmentAccessScopeResolver.php`
|
|
- `apps/platform/app/Providers/Filament/AdminPanelProvider.php`
|
|
- `apps/platform/app/Filament/Resources/TenantResource.php`
|
|
- `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php`
|
|
- `apps/platform/app/Support/OperationRunLinks.php`
|
|
- `apps/platform/app/Support/Providers/ProviderReasonTranslator.php`
|
|
- `apps/platform/app/Support/Verification/VerificationLinkBehavior.php`
|
|
- `apps/platform/tests/Pest.php`
|
|
- targeted feature tests in `apps/platform/tests/Feature/ProviderConnections/`, `apps/platform/tests/Feature/Auth/`, `apps/platform/tests/Feature/Rbac/`, `apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php`, and `apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php`
|
|
- targeted browser tests in `apps/platform/tests/Browser/`
|
|
|
|
## Filament v5 / Surface Notes
|
|
|
|
- **Livewire v4.0+ compliance**: all touched surfaces remain on Filament v5 with Livewire v4.
|
|
- **Provider registration location**: provider registration remains in `apps/platform/bootstrap/providers.php`; this package does not add a new panel or change provider registration location.
|
|
- **Global search rule**: this slice introduces no new globally-searchable resource. Existing provider-connection resource behavior remains unchanged from a global-search standpoint.
|
|
- **Destructive actions**: no new destructive action is introduced. Any touched existing destructive actions must keep `->action(...)`, `->requiresConfirmation()`, and server authorization.
|
|
- **Asset strategy**: no new asset registration or deployment step is planned.
|
|
|
|
## Prerequisite Completion Fit
|
|
|
|
- Complete runtime truth first, then let Spec `288` enforce that truth.
|
|
- Prefer canonical replacement over compatibility routes, copied role persistence, or tenant-panel test-only fallbacks.
|
|
- Keep Microsoft-specific detail nested under provider-owned seams instead of the shared provider-core contract.
|
|
- Keep the package bounded to five named prerequisite areas and reject adjacent feature work.
|
|
- Use exact targeted validation commands across `spec.md`, `plan.md`, `tasks.md`, and `quickstart.md`.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**: bounded runtime completion over existing provider-connection and provider-backed operator surfaces
|
|
- **Native vs custom classification summary**: existing native Filament provider-connection surfaces and shared provider summaries only; no new operator-facing page family
|
|
- **Shared-family relevance**: navigation, provider target-scope summaries, run-launch context, and test harness setup
|
|
- **State layers in scope**: route, page, detail, shared provider-core payloads, access-scope persistence, and test-support context helpers
|
|
- **Audience modes in scope**: operator-MSP, support-platform on existing provider surfaces only
|
|
- **Decision/diagnostic/raw hierarchy plan**: keep current provider-owned diagnostics nested; change only the shared contract and canonical route truth
|
|
- **Raw/support gating plan**: preserve existing provider-owned raw detail where current support or consent workflows genuinely need it
|
|
- **One-primary-action / duplicate-truth control**: no new action family is introduced; existing launch and open actions continue to own the workflow
|
|
- **Handling modes by drift class or surface**: implementation-required for the named seams; out of scope for global enforcement and copy cleanup
|
|
- **Repository-signal treatment**: direct runtime completion only; no broad source-scan or lint layer
|
|
- **Special surface test profiles**: standard-native-filament, global-context-shell
|
|
- **Required tests or manual smoke**: functional-core, targeted browser-smoke
|
|
- **Exception path and spread control**: provider-owned Microsoft detail only; no other exception expansion
|
|
- **Active feature PR close-out entry**: RuntimePrerequisite
|
|
|
|
## Shared Pattern & System Fit
|
|
|
|
- **Cross-cutting feature marker**: yes
|
|
- **Systems touched**: provider route ownership, shared provider target-scope and identity resolution, workspace-first access persistence cleanup, and shared test helpers
|
|
- **Shared abstractions reused**: existing provider target-scope and identity helpers, existing workspace access resolver seams, and existing `tests/Pest.php` helper style
|
|
- **New abstraction introduced? why?**: none
|
|
- **Why the existing abstraction was sufficient or insufficient**: the abstractions already exist; the incomplete cutover behavior inside them is the real remaining work
|
|
- **Bounded deviation / spread control**: Microsoft-specific profile detail remains nested only where provider-owned workflows still need it
|
|
|
|
## OperationRun UX Impact
|
|
|
|
- **Touches OperationRun start/completion/link UX?**: yes, as shared provider-backed run context and canonical link truth only
|
|
- **Central contract reused**: `ProviderOperationStartGate`, existing OperationRun context, and canonical operation links
|
|
- **Delegated UX behaviors**: existing queued, blocked, and run-link semantics remain delegated; this slice changes only the prerequisite data and route truth they rely on
|
|
- **Surface-owned behavior kept local**: existing provider launch or open actions only
|
|
- **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**: consent/profile detail, Microsoft-specific identifiers, Graph-specific diagnostics, and provider-owned support metadata
|
|
- **Platform-core seams**: provider-connection route ownership, shared target-scope and identity outputs, provider-backed run context, and workspace-scoped launch truth
|
|
- **Neutral platform terms / contracts preserved**: `provider connection`, `target scope`, `scope kind`, `scope identifier`, `scope display name`, `workspace`, `managed environment`
|
|
- **Retained provider-specific semantics and why**: existing consent and support flows still need Microsoft tenant/profile data, but only as provider-owned nested detail
|
|
- **Bounded extraction or follow-up path**: Spec `288` for no-legacy enforcement after this slice lands
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before implementation begins and again after design artifacts are complete.*
|
|
|
|
- Inventory-first: PASS. No new inventory or snapshot truth is introduced.
|
|
- Read/write separation: PASS. The slice completes existing runtime seams without adding a new workflow surface.
|
|
- Graph contract path: PASS by preservation. No new Graph integration family or registry is introduced.
|
|
- Deterministic capabilities: PASS by preservation. Capability families do not expand.
|
|
- RBAC-UX: PASS. Workspace membership remains role-bearing and environment scope becomes narrowing-only on the completed seams.
|
|
- Workspace isolation: PASS. The package preserves workspace-first routing and entitlement boundaries.
|
|
- Managed-environment isolation: PASS. The package narrows environment scope instead of broadening it.
|
|
- Run observability: PASS. Existing OperationRun lifecycle and links remain central.
|
|
- OperationRun start UX: PASS. No new start or completion UX family is added.
|
|
- Data minimization: PASS. No new persistence or compatibility ledger is introduced.
|
|
- Test governance: PASS. Validation stays targeted and explicit.
|
|
- Proportionality / no premature abstraction: PASS. Existing seams are completed rather than wrapped in new frameworks.
|
|
- Persisted truth / behavioral state: PASS. No new persistence or state family is introduced.
|
|
- Provider boundary: PASS. Shared provider-core contracts become more neutral while provider-owned detail stays bounded.
|
|
|
|
**Gate evaluation**: PASS.
|
|
|
|
**Post-design re-check**: PASS while `spec.md`, `plan.md`, `tasks.md`, and `quickstart.md` keep the same literal proof commands, and `research.md`, `data-model.md`, `contracts/cutover-prerequisite-completion.logical.openapi.yaml`, and `checklists/requirements.md` keep the same seam inventory and Spec `288` follow-up boundary.
|
|
|
|
## Test Governance Check
|
|
|
|
- **Test purpose / classification by changed surface**: Feature, Browser
|
|
- **Affected validation lanes**: fast-feedback, confidence, browser
|
|
- **Why this lane mix is the narrowest sufficient proof**: the changed seams are concrete runtime and test-support paths, so focused feature tests plus a narrow browser smoke are sufficient and honest
|
|
- **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/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/ProviderConnections/TenantlessListRouteTest.php tests/Feature/ProviderConnections/TenantlessListScopingTest.php tests/Feature/Auth/WorkspaceFirstManagedEnvironmentAccessTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php tests/Feature/Rbac/TriageReviewStateAuthorizationTest.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/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.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 only because the shared tenant-panel helper is being replaced on `tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php` and `tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php`
|
|
- **Expensive defaults or shared helper growth introduced?**: no; the helper cutover must reduce dependence on retired panel state rather than add new implicit defaults
|
|
- **Heavy-family additions, promotions, or visibility changes**: none
|
|
- **Surface-class relief / special coverage rule**: `standard-native-filament` and `global-context-shell` remain sufficient; no heavy-governance coverage is justified
|
|
- **Closing validation and reviewer handoff**: rerun the exact commands above, verify Filament stays on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, no asset registration or deployment-step drift was added, no full-suite or guard-family work was added, and confirm Spec `288` remains the explicit follow-up
|
|
- **Budget / baseline / trend follow-up**: contained feature-local increase only
|
|
- **Review-stop questions**: did the implementation widen into no-legacy guards, UI copy cleanup, package execution, guided operations, or provider capability expansion
|
|
- **Escalation path**: `document-in-feature` for contained seam follow-up, `reject-or-split` for scope expansion
|
|
- **Active feature PR close-out entry**: RuntimePrerequisite
|
|
|
|
## Review Checklist Status
|
|
|
|
- **Review checklist artifact**: `checklists/requirements.md`
|
|
- **Review outcome class**: `acceptable-special-case`
|
|
- **Workflow outcome**: `keep`
|
|
- **Test-governance outcome**: `keep`
|
|
- **Resolution note**: the package is implementation-ready as a bounded prerequisite-completion slice and no longer depends on a blocked-by-prerequisites posture
|
|
- **Escalation rule**: if implementation starts adding guard suites, full-suite baselines, or adjacent product features, stop and split the work out of `287`
|
|
|
|
## Rollout Considerations
|
|
|
|
- Retire the legacy provider-connection route family before widening targeted validation so the canonical route truth settles first.
|
|
- Complete provider target-scope neutralization before touching the browser proof so the live provider surfaces already speak the intended shared contract.
|
|
- Cut over the shared test helper before updating `apps/platform/tests/Feature/Reviews/CustomerReviewWorkspaceLaunchLinksTest.php` and `apps/platform/tests/Feature/Rbac/TriageReviewStateAuthorizationTest.php` so targeted tests do not drift through two helper systems.
|
|
- Keep Spec `288` untouched during runtime completion; it should start from the completed baseline produced by this slice.
|
|
|
|
## Risk Controls
|
|
|
|
- Reject any implementation that keeps legacy provider-connection aliases as compatibility routes for convenience.
|
|
- Reject any implementation that solves provider target-scope cleanup by hiding Microsoft-only fields in new platform-core wrappers instead of neutralizing the shared contract.
|
|
- Reject any implementation that preserves copied role-bearing state on environment-scope persistence after the cleanup.
|
|
- Reject any implementation that adds a global guard family, broad source-scan package, or full-suite baseline under this spec.
|
|
|
|
## Research & Design Outputs
|
|
|
|
- `research.md` records the completion-first decisions, bounded runtime scope, rejected guard-suite alternative, and evidence anchors.
|
|
- `data-model.md` captures the derived seam inventory, canonical replacements, and invariants.
|
|
- `quickstart.md` gives reviewers the scope boundary, review scenarios, and exact targeted proof commands.
|
|
- `contracts/cutover-prerequisite-completion.logical.openapi.yaml` models the logical completion seams and the targeted validation contract.
|
|
- `checklists/requirements.md` records the review outcome and bounded scope rules.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/287-cutover-prerequisite-completion/
|
|
├── checklists/
|
|
│ └── requirements.md
|
|
├── contracts/
|
|
│ └── cutover-prerequisite-completion.logical.openapi.yaml
|
|
├── data-model.md
|
|
├── plan.md
|
|
├── quickstart.md
|
|
├── research.md
|
|
├── spec.md
|
|
└── tasks.md
|
|
```
|
|
|
|
### Source Code (repository root)
|
|
|
|
```text
|
|
apps/platform/
|
|
├── app/
|
|
├── routes/
|
|
└── tests/
|
|
├── Browser/
|
|
├── Feature/
|
|
└── Pest.php
|
|
```
|
|
|
|
**Structure Decision**: keep the package inside the existing Laravel app, route, provider, access-service, and Pest test-support structure. No new base directory is needed. |