TenantAtlas/specs/188-provider-connection-state-cleanup/quickstart.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

13 KiB

Quickstart: Canonical Provider Connection State Cleanup

Goal

Validate that provider connections use exactly three canonical business dimensions after the cutover:

  • Lifecycle from is_enabled
  • Consent from consent_status
  • Verification from verification_status

The release is not complete until runtime readers, runtime writers, shared helpers, system-directory summaries, badges, factories, and tests stop depending on status and health_status.

Prerequisites

  1. Start Sail.
  2. Work from the feature branch with the new lifecycle migration available.
  3. Prepare seeded scenarios for at least:
    • disabled connection with granted consent and verification_status = healthy
    • enabled connection with required consent and unknown verification
    • enabled connection with granted consent and blocked verification caused by missing credentials
    • tenant with no default Microsoft provider connection
  4. Ensure one workspace member with provider manage access and one out-of-scope actor are available for authorization checks.

Validation Order

1. Run the reader-cutover regression pack

cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionListAuthorizationTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/ProviderConnectionsCreateUiEnforcementTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php

Expected outcome:

  • Resolver gates, action visibility, enable or disable behavior, and the Entra admin-roles scan all evaluate lifecycle from is_enabled rather than status.

2. Run the operator-surface and shared-helper regression pack

cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantScopingTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/DirectoryTenantsTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionViewsDbOnlyRenderingSpec081Test.php

Expected outcome:

  • Provider list, provider detail, provider edit, tenant provider summaries, system directory summaries, tenant global search, provider-connection search exclusion, and DB-only rendering paths show lifecycle, consent, and verification without legacy status or health language.
  • System-directory list rollups count only each tenant's default Microsoft provider connection, while detail rows stay canonical for every rendered connection.

3. Run the writer-cutover regression pack

cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/MvpProviderScopeTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingProviderConnectionTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php

Expected outcome:

  • Direct resource create, health checks, onboarding, consent bootstrap, and verification start flows persist only is_enabled, consent_status, verification_status, and diagnostics.
  • No writer recreates status or health_status.

4. Run the audit and badge regression pack

cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/ProviderConnectionConsentAuditTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/BooleanEnabledBadgesTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/BadgeCatalogTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/ProviderConnectionBadgesTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Providers/ProviderConnectionBadgeMappingTest.php

Expected outcome:

  • Audit metadata and lifecycle-mutation regressions record lifecycle changes without reintroducing legacy from_status or to_status fields.
  • Provider surfaces reuse centralized badge mappings for lifecycle, consent, and verification only.

5. Update helpers and run contradiction coverage

Implementation requirement:

  • Update database/factories/ProviderConnectionFactory.php and tests/Pest.php so default provider fixtures use is_enabled, consent_status, and verification_status only.
  • Add contradiction coverage proving that disabled plus consent granted and disabled plus verification_status = healthy remain separate truths.
  • Add tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php so targeted provider-state runtime files cannot reference removed provider columns again.

Expected outcome:

  • Shared test scaffolding stops recreating removed fields.
  • Canonical-state separation is enforced by tests instead of by convention.

6. Format touched files

cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent

Expected outcome:

  • All touched implementation files match project formatting.

7. Apply the final schema state

cd apps/platform && ./vendor/bin/sail artisan migrate

Expected outcome:

  • The final drop migration has been applied and the verification pack runs against the post-drop schema state.

8. Run the focused final verification pack

cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionEnableDisableTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionListAuthorizationTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/MvpProviderScopeTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Verification/ProviderConnectionHealthCheckWritesReportTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingProviderConnectionTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingProviderConnectionPlatformDefaultTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/EntraAdminRoles/ScanEntraAdminRolesJobTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/ProviderConnectionsCreateUiEnforcementTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/EditProviderConnectionUiEnforcementTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections/ProviderConnectionTruthCleanupSpec179Test.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantScopingTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/DirectoryTenantsTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/ProviderConnectionConsentAuditTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/ProviderConnectionConsentRevocationAuditTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Audit/ProviderConnectionVerificationAuditTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/BooleanEnabledBadgesTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/BadgeCatalogTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/ProviderConnectionBadgesTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Providers/ProviderConnectionBadgeMappingTest.php

Expected outcome:

  • The cutover works across runtime gates, writes, shared operator surfaces, audits, and badges without any dependency on removed legacy provider columns.

9. Perform the residual legacy-state sweep

Implementation requirement:

  • Run the new residual guard test.
  • Search targeted provider-state runtime paths for the removed column names to confirm there is no surviving dependency in resolvers, jobs, resources, controllers, helpers, factories, or shared Blade views.
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyProviderConnectionStateFallbackTest.php

Expected outcome:

  • No targeted provider-state file still reads, writes, filters, or renders status or health_status for ProviderConnection.

Manual Smoke Check

  1. Open /admin/provider-connections and confirm the default-visible state columns are Lifecycle, Consent, and Verification.
  2. Open a disabled connection that still has granted consent and confirm the page shows Lifecycle: Disabled without losing the positive consent state.
  3. Open a connection with granted consent and blocked verification and confirm the page shows the blocker as verification truth rather than as a synthetic legacy error state.
  4. Open /admin/tenants/{tenant} and confirm the shared provider summary no longer renders legacy status or health diagnostics as peer truths.
  5. Open /system/directory/tenants and /system/directory/tenants/{tenant} and confirm read-only summaries align with the same lifecycle, consent, and verification story shown in /admin.
  6. Trigger enable, disable, consent, and verification flows and confirm audit history and notifications remain intact.
  7. Trigger admin global search in workspace context and confirm tenants remain searchable while provider connections remain excluded.
  8. Repeat one admin-plane URL as an out-of-scope actor and confirm deny-as-not-found behavior remains unchanged.

Release Completion Criteria

  • Schema no longer contains status or health_status on provider_connections.
  • Runtime readers and writers no longer mention removed fields.
  • Legacy badge domains for provider connection status and health are deleted.
  • Shared helpers and views no longer expose removed legacy keys.
  • Focused regression coverage and the residual guard prove the hard cut is complete.