19 KiB
Tasks: Canonical Provider Connection State Cleanup
Input: Design documents from /specs/188-provider-connection-state-cleanup/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/provider-connection-state-cleanup.openapi.yaml, quickstart.md
Tests: Required. Write or update Pest coverage before each behavior change and keep Sail-first verification focused.
Organization: Tasks are grouped by user story so each story can be implemented and validated independently.
Phase 1: Setup (Shared Regression Scaffolding)
Purpose: Create the focused regression entry points and residual guardrails for the hard-cut cleanup before changing runtime or schema behavior.
- T001 [P] Create the residual legacy-state Pest guard in
apps/platform/tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php - T002 [P] Add Spec 188 canonical-state regression entry points in
apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php,apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php,apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php, andapps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Add the narrow lifecycle truth and shared fixture support that every story depends on.
⚠️ CRITICAL: No user story work should begin until this phase is complete.
- T003 Implement the lifecycle add-and-backfill migration in
apps/platform/database/migrations/2026_04_09_000001_add_is_enabled_to_provider_connections.php - T004 [P] Add canonical lifecycle support to the core model and shared test fixtures in
apps/platform/app/Models/ProviderConnection.php,apps/platform/database/factories/ProviderConnectionFactory.php, andapps/platform/tests/Pest.php - T005 [P] Preserve provider and system authorization semantics during the cutover in
apps/platform/tests/Feature/ProviderConnections/ProviderConnectionListAuthorizationTest.php,apps/platform/tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php,apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php,apps/platform/tests/Feature/Rbac/ProviderConnectionsCreateUiEnforcementTest.php,apps/platform/tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php, andapps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php
Checkpoint: The schema, model, fixtures, and access invariants are ready; canonical surface and runtime work can now proceed.
Phase 3: User Story 1 - Read one canonical provider state language (Priority: P1)
Goal: Implement the operator-surface portion of the canonical reader cutover so admin, tenant, and system surfaces show only lifecycle, consent, and verification as the authoritative provider-state language.
Independent Test: Seed provider connections with canonical contradiction scenarios such as disabled with granted consent, enabled with missing consent, and enabled with blocked verification, then render provider, tenant, and system surfaces to verify that operators see lifecycle, consent, and verification only.
Tests for User Story 1
- T006 [P] [US1] Add admin provider list, detail, edit, and DB-only canonical-state assertions in
apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php,apps/platform/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php, andapps/platform/tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php - T007 [P] [US1] Add tenant and system canonical provider summary, provider-search exclusion, tenant-search safety, and DB-only assertions in
apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php,apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php,apps/platform/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php, andapps/platform/tests/Feature/Filament/TenantScopingTest.php
Implementation for User Story 1
- T008 [US1] Replace legacy provider list, detail, and edit presentation with lifecycle, consent, and verification in
apps/platform/app/Filament/Resources/ProviderConnectionResource.php - T009 [US1] Rework the tenant provider summary helper and shared infolist entry to emit canonical state only in
apps/platform/app/Filament/Resources/TenantResource.phpandapps/platform/resources/views/filament/infolists/entries/provider-connection-state.blade.php - T010 [US1] Rework system directory health rollups and provider rows to read canonical state in
apps/platform/app/Filament/System/Pages/Directory/Tenants.php,apps/platform/app/Filament/System/Pages/Directory/ViewTenant.php, andapps/platform/resources/views/filament/system/pages/directory/view-tenant.blade.php, counting only default Microsoft connections in list rollups while keeping detail rows canonical
Checkpoint: Provider, tenant, and system surfaces now speak one canonical provider-state language without visible legacy status or health semantics. The full reader-cutover milestone is complete only after T014 lands.
Phase 4: User Story 2 - Trust runtime decisions again (Priority: P1)
Goal: Move runtime readers, writers, and transport contracts to lifecycle, consent, and verification so action visibility, onboarding, verification, and health checks stop depending on removed legacy fields.
Independent Test: Execute create, onboarding, consent, verification, health-check, and mutation flows while asserting that all reads, writes, and queries depend only on lifecycle, consent, and verification truth.
Tests for User Story 2
- T011 [P] [US2] Add canonical reader-gate regressions for lifecycle, consent, and verification in
apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php,apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php, andapps/platform/tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php - T012 [P] [US2] Add canonical create and writer-flow regressions for resource create, onboarding, consent bootstrap, verification start, and health checks in
apps/platform/tests/Feature/ProviderConnections/MvpProviderScopeTest.php,apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php,apps/platform/tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php,apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionTest.php,apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php, andapps/platform/tests/Feature/ManagedTenantOnboardingWizardTest.php - T013 [P] [US2] Add audit and lifecycle-mutation regressions in
apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php,apps/platform/tests/Feature/Audit/ProviderConnectionConsentAuditTest.php,apps/platform/tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php, andapps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php
Implementation for User Story 2
- T014 [US2] Move resolver and background-job reads to
is_enabled,consent_status, andverification_statusinapps/platform/app/Services/Providers/ProviderConnectionResolver.phpandapps/platform/app/Jobs/ScanEntraAdminRolesJob.php - T015 [US2] Remove legacy transport and projection outputs from provider health-check contracts in
apps/platform/app/Services/Providers/Contracts/HealthResult.php,apps/platform/app/Services/Providers/MicrosoftProviderHealthCheck.php, andapps/platform/app/Services/Providers/ProviderConnectionStateProjector.php - T016 [US2] Update verification and health-check writers to persist canonical state only in
apps/platform/app/Jobs/ProviderConnectionHealthCheckJob.phpandapps/platform/app/Services/Verification/StartVerification.php - T017 [US2] Update onboarding, consent callback, and provider-mutation writers to persist lifecycle, consent, verification, and diagnostics only in
apps/platform/app/Http/Controllers/AdminConsentCallbackController.php,apps/platform/app/Http/Controllers/TenantOnboardingController.php,apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php, andapps/platform/app/Services/Providers/ProviderConnectionMutationService.php - T018 [US2] Keep enable or disable actions confirmation-gated and switch lifecycle audit metadata off legacy status in
apps/platform/app/Filament/Resources/ProviderConnectionResource.php
Checkpoint: Runtime decisions, verification flows, onboarding, and health checks all use canonical lifecycle, consent, and verification truth.
Phase 5: User Story 3 - Finish the hard cut without residual tail (Priority: P2)
Goal: Remove the remaining compatibility surface so schema, badges, helpers, factories, and tests cannot recreate legacy provider state.
Independent Test: Apply the final schema, run focused regression coverage, and prove that no active badge, contract, filter, helper, factory, query, or test depends on legacy provider status or health.
Tests for User Story 3
- T019 [P] [US3] Add contradiction scenarios for disabled plus granted consent and disabled plus
verification_status = healthyinapps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php,apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php, andapps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php - T020 [P] [US3] Add legacy-badge and residual-fallback regressions in
apps/platform/tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php,apps/platform/tests/Unit/Badges/BooleanEnabledBadgesTest.php,apps/platform/tests/Unit/Badges/ProviderConnectionBadgesTest.php,apps/platform/tests/Unit/Providers/ProviderConnectionBadgeMappingTest.php, andapps/platform/tests/Unit/Badges/BadgeCatalogTest.php
Implementation for User Story 3
- T021 [US3] Retire legacy provider badge domains and route lifecycle through shared badge mappings in
apps/platform/app/Support/Badges/BadgeDomain.php,apps/platform/app/Support/Badges/BadgeCatalog.php,apps/platform/app/Support/Badges/Domains/ProviderConnectionStatusBadge.php, andapps/platform/app/Support/Badges/Domains/ProviderConnectionHealthBadge.php - T022 [US3] Remove remaining legacy provider-state helper keys, labels, and comments from
apps/platform/app/Models/ProviderConnection.php,apps/platform/app/Filament/Resources/ProviderConnectionResource.php,apps/platform/app/Filament/Resources/TenantResource.php,apps/platform/resources/views/filament/infolists/entries/provider-connection-state.blade.php, andapps/platform/resources/views/filament/system/pages/directory/view-tenant.blade.php - T023 [US3] Remove any surviving legacy provider-state references from shared fixtures and targeted runtime paths in
apps/platform/database/factories/ProviderConnectionFactory.php,apps/platform/tests/Pest.php, and files matched byapps/platform/tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php - T024 [US3] Drop
status,health_status, and their indexes fromprovider_connectionsinapps/platform/database/migrations/2026_04_09_000002_drop_legacy_provider_state_columns_from_provider_connections.php
Checkpoint: The hard cut is complete; no active runtime, UI, badge, helper, factory, or schema path can recreate legacy provider state.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Format, verify, and confirm the hard cut with the focused Sail pack and manual smoke checks.
- T025 Run
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentfor touched files underapps/platform/app/,apps/platform/database/,apps/platform/resources/views/, andapps/platform/tests/ - T026 Run the focused Spec 188 Sail verification pack from
specs/188-provider-connection-state-cleanup/quickstart.md - T027 Execute the manual smoke checklist and residual legacy-state sweep from
specs/188-provider-connection-state-cleanup/quickstart.mdagainst/admin/provider-connections,/admin/tenants/{tenant},/system/directory/tenants, and/system/directory/tenants/{tenant} - T028 Validate that the final diff contains no dual-read or dual-write shim, no new provider-state abstraction, and no undeclared persistence beyond
is_enabledby reviewingapps/platform/app/Services/Providers/,apps/platform/app/Support/Badges/,apps/platform/database/migrations/, andspecs/188-provider-connection-state-cleanup/plan.md
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies; start immediately.
- Foundational (Phase 2): Depends on Setup completion; blocks all user story work.
- User Story 1 (Phase 3): Depends on Foundational completion.
- User Story 2 (Phase 4): Depends on Foundational completion.
- User Story 3 (Phase 5): Depends on User Story 1 and User Story 2 completion because it removes the remaining compatibility surface and drops the schema.
- Polish (Phase 6): Depends on all desired user stories being complete.
User Story Dependencies
- US1: Covers the operator-surface portion of the reader cutover after Phase 2 and is not a standalone implementation-complete slice until
T014lands. - US2: Independent as a review slice after Phase 2, but writer tasks
T015-T018must follow the canonical reader cutover before the feature is release-ready. - US3: Depends on the finished surface and runtime cutover from US1 and US2.
Cross-Story Implementation Sequencing
T008-T010andT014together form the canonical reader cutover across shared helpers, operator surfaces, and runtime gates.T015-T018complete the canonical writer and transport cutover and should land only after the reader cutover above is in place.T021-T024are final hard-cut cleanup tasks and depend on both P1 stories being functionally complete.
Within Each User Story
- Write or update the story tests first and confirm they fail for the intended reason.
- Move shared readers before story-specific writers when both are touched by the same cutover.
- Finish story-specific assertions after the implementation lands.
- Keep authorization, confirmation, and audit regressions green before advancing to the next story.
Parallel Opportunities
T001andT002can run in parallel.T004andT005can run in parallel afterT003lands.- Phase 3 and Phase 4 regression authoring can run in parallel after Phase 2 completes, but implementation sequencing still follows reader cutover before writer cutover.
T019andT020can run in parallel after both Phase 3 and Phase 4 are complete.
Parallel Example: User Story 1
# Lock the admin and read-only surface expectations before changing provider-state UI:
Task: T006 Add admin provider list, detail, edit, and DB-only canonical-state assertions in apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php, apps/platform/tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php, and apps/platform/tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php
Task: T007 Add tenant and system canonical provider summary, provider-search exclusion, tenant-search safety, and DB-only assertions in apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php, apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php, apps/platform/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php, and apps/platform/tests/Feature/Filament/TenantScopingTest.php
Parallel Example: User Story 2
# Lock reader, writer, and audit behavior before changing runtime provider-state logic:
Task: T011 Add canonical reader-gate regressions in apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php, apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php, and apps/platform/tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php
Task: T012 Add canonical writer-flow regressions in apps/platform/tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php, apps/platform/tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php, apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionTest.php, apps/platform/tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php, and apps/platform/tests/Feature/ManagedTenantOnboardingWizardTest.php
Task: T013 Add audit regressions in apps/platform/tests/Feature/Audit/ProviderConnectionConsentAuditTest.php, apps/platform/tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php, and apps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php
Parallel Example: User Story 3
# Lock contradiction coverage and final residual guards before dropping legacy provider columns:
Task: T019 Add contradiction scenarios in apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php, apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php, and apps/platform/tests/Feature/System/Spec114/DirectoryTenantsTest.php
Task: T020 Add legacy-badge and residual-fallback regressions in apps/platform/tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php, apps/platform/tests/Unit/Badges/BooleanEnabledBadgesTest.php, apps/platform/tests/Unit/Badges/ProviderConnectionBadgesTest.php, apps/platform/tests/Unit/Providers/ProviderConnectionBadgeMappingTest.php, and apps/platform/tests/Unit/Badges/BadgeCatalogTest.php
Implementation Strategy
First Demonstrable Milestone (Reader Cutover)
- Complete Phase 1: Setup.
- Complete Phase 2: Foundational.
- Complete Phase 3 plus
T014from Phase 4 to finish the canonical reader cutover. - Validate canonical provider surfaces and runtime reader gates across
/admin, tenant summaries, and/systembefore moving into runtime writer cutover.
Incremental Delivery
- Finish Setup and Foundational work.
- Deliver the full reader cutover across US1 plus
T014and validate the canonical provider-state language across surfaces and runtime gates. - Deliver the remaining US2 writer work and validate runtime writes and transport cleanup.
- Deliver US3 and validate the final hard cut and legacy removal.
- Finish Phase 6 verification and smoke checks.
Parallel Team Strategy
- One developer completes Phase 1 and Phase 2.
- After Phase 2, one developer takes US1 while another takes US2.
- Rejoin on US3 once surfaces and runtime behavior are both canonical.
- Finish with shared formatting, focused Sail tests, and the residual sweep.
Notes
- Every task follows the required checklist format: checkbox, task ID, optional parallel marker, required story label for story phases, and exact file paths.
- The task list preserves the plan’s hard-cut order: lifecycle foundation first, surface and runtime cutover next, then residual cleanup and schema removal last.
- The recommended MVP review slice is US1, but the feature is not shippable until US2 and US3 are complete because the spec forbids compatibility tails.