17 KiB
| description |
|---|
| Task list for Provider Foundation v1 |
Tasks: Provider Foundation v1 (Microsoft-first, Security-first)
Input: Design documents from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/
Prerequisites: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/plan.md (required), /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/spec.md (required), /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/research.md, /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/data-model.md, /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/contracts/, /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/061-provider-foundation/quickstart.md
Tests: REQUIRED (Pest) for runtime behavior changes
Operations: Provider operations MUST create/reuse a canonical OperationRun, be enqueue-only, and keep Monitoring/ProviderConnections pages DB-only at render/poll time
Badges: If ProviderConnection status/health is rendered as a badge, use BadgeCatalog / BadgeRenderer (BADGE-001) and add mapping tests
Organization: Tasks are grouped by user story (US1, US2, US3) to enable independent delivery.
Phase 1: Setup (Shared Infrastructure)
Purpose: Prepare local environment + validate baseline
- T001 Start containers with
./vendor/bin/sail up -d(script:./vendor/bin/sail) - T002 Run baseline Ops-UX DB-only tests with
./vendor/bin/sail artisan test tests/Feature/Monitoring/OperationsDbOnlyTest.php(test:tests/Feature/Monitoring/OperationsDbOnlyTest.php) - T003 [P] Review existing idempotency + run tracking patterns in
app/Services/OperationRunService.phpandapp/Jobs/Middleware/TrackOperationRun.php
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Core provider foundation that all stories depend on (schema, models, policies, ops primitives)
Checkpoint: Migrations + models + policies exist; provider operation types are registered; shared run-gating utilities exist
- T004 Create provider connections migration in
database/migrations/2026_01_24_000001_create_provider_connections_table.php - T005 Create provider credentials migration in
database/migrations/2026_01_24_000002_create_provider_credentials_table.php - T005a Add DB-level invariant: partial unique index ensuring only one default per (tenant_id, provider) (example:
unique (tenant_id, provider) WHERE is_default = true; ensure default flipping is atomic/transactional) - T006 [P] Create
App\Models\ProviderConnectioninapp/Models/ProviderConnection.php(relations, casts, default-connection invariant) - T007 [P] Create
App\Models\ProviderCredentialinapp/Models/ProviderCredential.php(encrypted payload cast, hidden attributes, 1:1 relation) - T008 [P] Add tenant relationship for connections in
app/Models/Tenant.php(e.g.,providerConnections()/providerCredentials()as needed) - T009 [P] Add factories in
database/factories/ProviderConnectionFactory.phpanddatabase/factories/ProviderCredentialFactory.php - T010 Create authorization policy + gates for
provider.view,provider.manage,provider.run(capabilities-first; tenant-scoped). Map roles to capabilities: Owner/Manager=view+manage+run; Operator=view+run; Readonly=view only. Norole == Xchecks in feature code. - T010b [P] Add RBAC capability tests in
tests/Feature/ProviderConnections/ProviderRbacCapabilitiesTest.php(Operator can start operations but cannot manage; Readonly is view-only) - T011 Register the policy + gates in
app/Providers/AuthServiceProvider.php(create it and register inbootstrap/providers.phpif missing; otherwise use the project’s canonical policy registration provider) - T012 Add provider operation labels in
app/Support/OperationCatalog.phpusing canonical operation types:provider.connection.check,inventory.sync,compliance.snapshot(ensure UI/actions/jobs use these exact strings; updatetests/Feature/OpsUx/OperationCatalogCoverageTest.phpto detect multi-dot types) - T013 Add provider related links in
app/Support/OperationRunLinks.php(link provider runs to Provider Connections pages whencontext.provider_connection_idexists) - T014 Create provider operation registry in
app/Services/Providers/ProviderOperationRegistry.php(central allowlist + metadata for v1 operations) - T014a [P] Define provider capability interfaces + DTOs in
app/Services/Providers/Contracts/ProviderHealthCheck.php,app/Services/Providers/Contracts/HealthResult.php,app/Services/Providers/Contracts/ProviderInventoryCollector.php,app/Services/Providers/Contracts/ProviderComplianceCollector.php,app/Services/Providers/Contracts/ProviderDirectoryCollector.php,app/Services/Providers/Contracts/ProviderScriptExecutor.php - T014b [P] Implement credential retrieval/rotation service in
app/Services/Providers/CredentialManager.php(readsprovider_credentials, validates required keys, never logs decrypted payload) - T014c [P] Implement provider gateway in
app/Services/Providers/ProviderGateway.php(build Graph request context from ProviderConnection + CredentialManager, centralize correlation IDs + failure mapping, callGraphClientInterface) - T014d Enable Graph client binding for per-request credentials in
config/graph.phpandapp/Providers/AppServiceProvider.php(e.g.,GRAPH_ENABLEDoverride; do not require env client_secret for binding when ProviderGateway supplies request context) - T014e [P] Add unit tests for provider gateway + credential manager in
tests/Unit/Providers/CredentialManagerTest.phpandtests/Unit/Providers/ProviderGatewayTest.php - T015 Create run gating service in
app/Services/Providers/ProviderOperationStartGate.php(DB transaction +lockForUpdate()on ProviderConnection; dedupe same-operation; block different-operation as “scope busy”; returns active-run link) - T016 [P] Extend failure sanitization in
app/Support/OpsUx/RunFailureSanitizer.php(provider auth/throttling/outage reason codes + stronger secret redaction) - T017 [P] Add unit tests for failure sanitization in
tests/Unit/OpsUx/RunFailureSanitizerTest.php - T018 [P] Add unit tests for run gating in
tests/Unit/Providers/ProviderOperationStartGateTest.php - T019 Run foundational tests with
./vendor/bin/sail artisan test tests/Unit/OpsUx/RunFailureSanitizerTest.php(test:tests/Unit/OpsUx/RunFailureSanitizerTest.php)
Phase 3: User Story 1 — Set up a provider connection safely (Priority: P1) 🎯 MVP
Goal: Owner/Manager can create/manage Microsoft provider connections, attach credentials, set a default connection, and never expose secrets.
Independent Test: An Owner/Manager can create a connection + credentials, later view/edit it, and no secret values are displayed or leaked; pages remain DB-only at render/poll time.
Tests for User Story 1
- T020 [P] [US1] Add DB-only render test for Provider Connections in
tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php - T021 [P] [US1] Add role authorization test in
tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php - T022 [P] [US1] Add credential encryption/non-disclosure test in
tests/Feature/ProviderConnections/ProviderCredentialSecurityTest.php - T022b [P] [US1] Add credential leak guard test in
tests/Feature/ProviderConnections/CredentialLeakGuardTest.php(assert no secrets appear in OperationRun failure records or captured logs; forbidden substrings:client_secret,Bearer,access_token,refresh_token,Authorization)
Implementation for User Story 1
- T023 [US1] Create Filament resource skeleton in
app/Filament/Resources/ProviderConnectionResource.php - T024 [P] [US1] Create pages in
app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php,app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php,app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php - T025 [US1] Implement list/table + filters in
app/Filament/Resources/ProviderConnectionResource.php(tenant-scoped; DB-only) - T026 [US1] Implement create/edit forms in
app/Filament/Resources/ProviderConnectionResource.php(provider=microsoft,entra_tenant_id,display_name,is_default, status/health read-only fields) - T027 [US1] Implement credential upsert action (Owner/Manager only; secrets never shown) in
app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php - T028 [US1] Implement disable connection action with confirmation + audit log in
app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php - T029 [US1] Write audit log entries for connection + credential changes using
app/Services/Intune/AuditLogger.php(called fromapp/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.phpandapp/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php) - T030 [US1] Run story tests with
./vendor/bin/sail artisan test tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php(test:tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php)
Phase 4: User Story 2 — Verify connection health without blocking the UI (Priority: P2)
Goal: Owner/Manager/Operator can enqueue a health check that creates an OperationRun, updates health state, and shows stable reason codes/messages on failure.
Independent Test: Clicking “Check connection” enqueues exactly one run (dedupe), never calls Graph in the request cycle, and produces a visible run outcome + updates connection health.
Tests for User Story 2
- T031 [P] [US2] Add start-surface test (no Graph in request; job queued; run created) in
tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php - T032 [P] [US2] Add job behavior test (success + categorized failure) in
tests/Feature/ProviderConnections/ProviderConnectionHealthCheckJobTest.php - T032b [P] [US2] Assert OperationRun context contract for connection health checks in
tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php(context.provider,context.module,context.provider_connection_id,context.target_scope.entra_tenant_id)
Implementation for User Story 2
- T033 [US2] Add “Check connection” Filament action (enqueue-only) in
app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php(MUST callProviderOperationStartGatefirst: same-operation returns existing active run; different-operation for same scope blocks “scope busy” + link to active run) - T034 [US2] Create queued job in
app/Jobs/ProviderConnectionHealthCheckJob.php(usesapp/Jobs/Middleware/TrackOperationRun.php, updatesprovider_connectionshealth fields, updatesoperation_runs) - T035 [US2] Create health check module in
app/Services/Providers/MicrosoftProviderHealthCheck.php(implementsapp/Services/Providers/Contracts/ProviderHealthCheck.php, usesProviderGateway, maps failures to reason codes viaapp/Support/OpsUx/RunFailureSanitizer.php) - T035b [P] [US2] Ensure health check uses ProviderConnection context (
entra_tenant_id) and obtains tokens via ProviderGateway/CredentialManager (ProviderGateway is the only decryptor; no secrets in config/env beyond bootstrap) - T036 [US2] Run story tests with
./vendor/bin/sail artisan test tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php(test:tests/Feature/ProviderConnections/ProviderConnectionHealthCheckStartSurfaceTest.php)
Phase 5: User Story 3 — Run provider operations with safety and observability (Priority: P3)
Goal: Owner/Manager/Operator can run provider operations (inventory + compliance snapshot) as observable runs, with per-scope concurrency rules (dedupe vs scope-busy) and summary counts.
Independent Test: Starting inventory/compliance creates runs, obeys dedupe/scope-busy rules, never calls Graph in the request cycle, and writes summary counts + failures safely.
Tests for User Story 3
- T037 [P] [US3] Add scope-busy + dedupe behavior tests in
tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php - T038 [P] [US3] Add compliance snapshot summary_counts tests in
tests/Feature/ProviderConnections/ProviderComplianceSnapshotJobTest.php - T038b [P] [US3] Assert OperationRun context contract for inventory/compliance runs in
tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.phpandtests/Feature/ProviderConnections/ProviderComplianceSnapshotJobTest.php(context.provider,context.module,context.provider_connection_id,context.target_scope.entra_tenant_id)
Implementation for User Story 3
- T039 [US3] Add managed devices contract entry for compliance snapshot in
config/graph_contracts.php(resourcedeviceManagement/managedDevices, select includes compliance state) - T040 [US3] Add allowed summary keys for compliance counts in
app/Support/OpsUx/OperationSummaryKeys.php(addcompliant,noncompliant,unknown) - T041 [US3] Create compliance snapshot collector in
app/Services/Providers/MicrosoftComplianceSnapshotService.php(implementsapp/Services/Providers/Contracts/ProviderComplianceCollector.php, usesProviderGateway, Graph list + count compliance states) - T042 [US3] Create queued job in
app/Jobs/ProviderComplianceSnapshotJob.php(writesOperationRuncontext + summary_counts; updates failures with sanitized reason codes) - T043 [US3] Add “Compliance snapshot” Filament action (enqueue-only) in
app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php(MUST callProviderOperationStartGatefirst: same-operation returns existing active run; different-operation for same scope blocks “scope busy” + link to active run) - T044 [US3] Create minimal inventory collector in
app/Services/Providers/MicrosoftProviderInventoryCollector.php(implementsapp/Services/Providers/Contracts/ProviderInventoryCollector.php, usesProviderGateway, contract-backed listing + summary counts only) - T045 [US3] Create queued job in
app/Jobs/ProviderInventorySyncJob.php(writesOperationRuncontext + summary_counts; obeys scope-busy rules via start gate) - T046 [US3] Add “Inventory sync” Filament action (enqueue-only) in
app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php(MUST callProviderOperationStartGatefirst: same-operation returns existing active run; different-operation for same scope blocks “scope busy” + link to active run) - T047 [US3] Run story tests with
./vendor/bin/sail artisan test tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php(test:tests/Feature/ProviderConnections/ProviderOperationConcurrencyTest.php)
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Reduce regressions and improve consistency across stories
- T048 [P] Ensure provider operations set
context.target_scope.entra_tenant_idandcontext.target_scope.entra_tenant_nameinapp/Jobs/ProviderConnectionHealthCheckJob.php,app/Jobs/ProviderComplianceSnapshotJob.php, andapp/Jobs/ProviderInventorySyncJob.php - T049 [P] If ProviderConnection status/health is shown as badges, add a badge mapper + tests in
app/Support/Badges/Domains/andtests/Unit/Badges/ - T050 Run formatting with
./vendor/bin/sail php ./vendor/bin/pint --dirty(script:./vendor/bin/pint) - T051 Run focused feature tests with
./vendor/bin/sail artisan test tests/Feature/ProviderConnections(folder:tests/Feature/ProviderConnections)
Dependencies & Execution Order
User Story Dependency Graph
Phase 1 (Setup)
↓
Phase 2 (Foundation: schema/models/policy + ops primitives)
↓
US1 (Connections + credentials UI) ─┬─→ US2 (Health check run)
└─→ US3 (Inventory + compliance runs)
Parallel Opportunities
- Phase 2 tasks marked
[P]can be done in parallel (different files). - Within each user story phase,
[P]tests can be written in parallel. - Caution: US2 and US3 both extend
app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php(avoid parallel edits to that file unless coordinated).
Parallel Example: User Story 1
Task: "Add DB-only render test for Provider Connections in tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php"
Task: "Add role authorization test in tests/Feature/ProviderConnections/ProviderConnectionAuthorizationTest.php"
Task: "Add credential encryption/non-disclosure test in tests/Feature/ProviderConnections/ProviderCredentialSecurityTest.php"
Implementation Strategy
MVP First (User Story 1)
- Complete Phase 1 + Phase 2
- Complete US1 (Provider Connections + credentials management)
- Validate with
tests/Feature/ProviderConnections/*and DB-only render checks
Incremental Delivery
- US1 → demo/manage connections safely (no provider calls)
- US2 → add health check (first real provider call, but enqueue-only + observable)
- US3 → add inventory + compliance snapshot operations (summary counts + scope-busy rules)