TenantAtlas/specs/188-provider-connection-state-cleanup/tasks.md
ahmido 1655cc481e Spec 188: canonical provider connection state cleanup (#219)
## Summary
- migrate provider connections to the canonical three-dimension state model: lifecycle via `is_enabled`, consent via `consent_status`, and verification via `verification_status`
- remove legacy provider status and health badge paths, update admin and system directory surfaces, and align onboarding, consent callback, verification, resolver, and mutation flows with the new model
- add the Spec 188 artifact set, schema migrations, guard coverage, and expanded provider-state tests across admin, system, onboarding, verification, and rendering paths

## Verification
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Auth/SystemPanelAuthTest.php tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php`
- integrated browser smoke: validated admin provider list/detail/edit, tenant provider summary, system directory tenant detail, provider-connection search exclusion, and cleaned up the temporary smoke record afterward

## Filament / implementation notes
- Livewire v4.0+ compliance: preserved; this change targets Filament v5 on Livewire v4 and does not introduce older APIs
- Provider registration location: unchanged; Laravel 11+ panel providers remain registered in `bootstrap/providers.php`
- Globally searchable resources: `ProviderConnectionResource` remains intentionally excluded from global search; tenant global search remains enabled and continues to resolve to view pages
- Destructive actions: no new destructive action surface was introduced without confirmation or authorization; existing capability checks continue to gate provider mutations
- Asset strategy: unchanged; no new Filament assets were added, so deploy behavior for `php artisan filament:assets` remains unchanged
- Testing plan covered: system auth, tenant global search, provider lifecycle enable/disable behavior, and provider truth cleanup cutover behavior

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #219
2026-04-10 11:22:56 +00:00

19 KiB
Raw Permalink Blame History

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, and apps/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, and apps/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, and apps/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, and apps/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, and apps/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.php and apps/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, and apps/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, and apps/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, and apps/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, and apps/platform/tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php

Implementation for User Story 2

  • T014 [US2] Move resolver and background-job reads to is_enabled, consent_status, and verification_status in apps/platform/app/Services/Providers/ProviderConnectionResolver.php and apps/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, and apps/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.php and apps/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, and apps/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 = healthy in apps/platform/tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php, apps/platform/tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php, and apps/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, and apps/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, and apps/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, and apps/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 by apps/platform/tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php
  • T024 [US3] Drop status, health_status, and their indexes from provider_connections in apps/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 agent for touched files under apps/platform/app/, apps/platform/database/, apps/platform/resources/views/, and apps/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.md against /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_enabled by reviewing apps/platform/app/Services/Providers/, apps/platform/app/Support/Badges/, apps/platform/database/migrations/, and specs/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 T014 lands.
  • US2: Independent as a review slice after Phase 2, but writer tasks T015-T018 must 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-T010 and T014 together form the canonical reader cutover across shared helpers, operator surfaces, and runtime gates.
  • T015-T018 complete the canonical writer and transport cutover and should land only after the reader cutover above is in place.
  • T021-T024 are 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

  • T001 and T002 can run in parallel.
  • T004 and T005 can run in parallel after T003 lands.
  • 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.
  • T019 and T020 can 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)

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational.
  3. Complete Phase 3 plus T014 from Phase 4 to finish the canonical reader cutover.
  4. Validate canonical provider surfaces and runtime reader gates across /admin, tenant summaries, and /system before moving into runtime writer cutover.

Incremental Delivery

  1. Finish Setup and Foundational work.
  2. Deliver the full reader cutover across US1 plus T014 and validate the canonical provider-state language across surfaces and runtime gates.
  3. Deliver the remaining US2 writer work and validate runtime writes and transport cleanup.
  4. Deliver US3 and validate the final hard cut and legacy removal.
  5. Finish Phase 6 verification and smoke checks.

Parallel Team Strategy

  1. One developer completes Phase 1 and Phase 2.
  2. After Phase 2, one developer takes US1 while another takes US2.
  3. Rejoin on US3 once surfaces and runtime behavior are both canonical.
  4. 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 plans 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.