# Tasks: Foundations in Inventory (047) **Input**: Design documents from `specs/047-inventory-foundations-nodes/` **Tests**: REQUIRED (Pest) because this feature changes runtime behavior. ## User Stories (Prioritized) - **User Story 1 (P1) — Sync policies + foundations**: When `include_foundations=true`, foundations are synced as tenant-scoped `InventoryItem` rows; when false, they are not synced. - **User Story 2 (P2) — Inventory browsing**: Inventory Items list can be filtered to “Foundations” and searched by name. - **User Story 3 (P2) — Coverage communication**: Coverage page presents separate “Policies” and “Foundations” matrices. - **User Story 4 (P3) — Resolve dependency names**: Dependencies UI resolves foundation names via local `InventoryItem` rows only (no UI Graph calls). --- ## Phase 1: Setup (Shared Infrastructure) - [ ] T001 Confirm foundation types are configured in config/tenantpilot.php (`foundation_types`) and foundations are categorized as "Foundations" in Inventory - [ ] T002 Confirm Graph contract registry includes resources for `assignmentFilter`, `roleScopeTag`, `notificationMessageTemplate` in config/graph_contracts.php - [ ] T003 [P] Confirm Inventory selection payload schema includes `include_foundations` (specs/047-inventory-foundations-nodes/contracts/inventory-selection.schema.json) --- ## Phase 2: Foundational (Blocking Prerequisites) - [ ] T004 Ensure inventory sync selection normalization retains include_foundations semantics in app/Services/Inventory/InventorySelectionHasher.php - [ ] T005 Ensure inventory sync run observability/count fields remain accurate when adding foundations in app/Services/Inventory/InventorySyncService.php --- ## Phase 3: User Story 1 — Sync policies + foundations (Priority: P1) 🎯 MVP **Goal**: Foundation objects exist as `InventoryItem` rows when foundations are included. **Independent Test Criteria**: - Run sync with `include_foundations=true` and see foundation `InventoryItem` rows for the tenant. - Run sync with `include_foundations=false` and see no foundation `InventoryItem` rows (even if a foundation type appears in `policy_types`). - [ ] T006 [US1] Implement foundation-type inclusion/exclusion based on `include_foundations` in app/Services/Inventory/InventorySyncService.php - [ ] T007 [US1] Ensure type metadata lookup merges supported policy types + foundation types for sync category/platform assignment in app/Services/Inventory/InventorySyncService.php - [ ] T008 [P] [US1] Add Pest test for include_foundations=true foundation upserts in tests/Feature/Inventory/InventorySyncServiceTest.php - [ ] T009 [P] [US1] Add Pest test for include_foundations=false excludes foundations even when selected in tests/Feature/Inventory/InventorySyncServiceTest.php - [ ] T010 [US1] Verify idempotency: repeated sync updates last_seen_* without duplicate rows for foundation types in tests/Feature/Inventory/InventorySyncServiceTest.php --- ## Phase 4: User Story 2 — Inventory browsing (Priority: P2) **Goal**: Inventory list can filter to foundations and show correct labels. **Independent Test Criteria**: - Inventory Items table offers Category filter values including `Foundations`. - Filtering Category=Foundations returns only foundation items. - [ ] T011 [US2] Update type label/category metadata resolution to include foundations in app/Filament/Resources/InventoryItemResource.php - [ ] T012 [US2] Update table filter option lists to include foundation categories/types in app/Filament/Resources/InventoryItemResource.php - [ ] T013 [P] [US2] Add Pest test asserting Inventory Items list page loads and includes Foundations category filter option (or equivalent rendered text) in tests/Feature/Filament/InventoryPagesTest.php --- ## Phase 5: User Story 3 — Coverage communication (Priority: P2) **Goal**: Coverage clearly separates Policies vs Foundations. **Independent Test Criteria**: - Coverage page renders headings “Policies” and “Foundations”. - Foundations table rows are derived from `config('tenantpilot.foundation_types')`. - [ ] T014 [US3] Update Coverage page view-model to expose supported policy types + foundation types in app/Filament/Pages/InventoryCoverage.php - [ ] T015 [US3] Update Coverage Blade view to render two tables in resources/views/filament/pages/inventory-coverage.blade.php - [ ] T016 [P] [US3] Add/adjust Pest test assertions for both headings in tests/Feature/Filament/InventoryPagesTest.php --- ## Phase 6: User Story 4 — Resolve dependency names (Priority: P3) **Goal**: Dependencies UI shows resolved names for foundations using local DB inventory items. **Independent Test Criteria**: - Given an edge referencing a scope tag or assignment filter, the dependencies UI shows the resolved display name when a matching foundation `InventoryItem` exists. - UI performs no Graph calls for resolution (DB-only resolver path). - [ ] T017 [US4] Ensure dependency name resolution uses DB-only resolver (DependencyTargetResolver + foundation mapping) and does not call Graph client during rendering - [ ] T018 [P] [US4] Add/adjust resolver unit test for foundation resolution via InventoryItem rows in tests/Unit/DependencyTargetResolverTest.php - [ ] T019 [P] [US4] Add/adjust feature test validating dependencies view renders resolved foundation names (tenant-scoped) in tests/Feature/InventoryItemDependenciesTest.php --- ## Phase 7: Polish & Cross-Cutting Concerns - [x] T020 [P] Run formatting on changed files with ./vendor/bin/pint --dirty - [x] T021 Run targeted tests for this feature with ./vendor/bin/sail test tests/Feature/Inventory/InventorySyncServiceTest.php tests/Feature/Filament/InventoryPagesTest.php - [ ] T022 [P] Validate manual quickstart steps in specs/047-inventory-foundations-nodes/quickstart.md - [x] T023 [P] [US1] Add feature test: foundation InventoryItem meta_jsonb is sanitized (`stored == sanitizer->sanitize(stored)`) after sync (no payload dump) in tests/Feature/Inventory/InventorySyncServiceTest.php - [x] T024 [P] [US1] Add feature test: InventorySyncRun observed/upserted counts include foundations when enabled (tenant A) and exclude them when disabled (tenant B) (deterministic) in tests/Feature/Inventory/InventorySyncServiceTest.php - [ ] T025 [P] [US4] Verify task references match actual resolver classes used (DependencyTargetResolver + mapping); adjust task text only (no behavior change) --- ## Dependencies & Execution Order ### Story Dependencies - **US1 (P1)** blocks all other stories (foundations must exist before they can be browsed/resolved). - **US2 (P2)** depends on US1 (needs foundation data to browse meaningfully). - **US3 (P2)** is config-driven but depends on US1 for end-to-end verification. - **US4 (P3)** depends on US1 (needs foundation inventory items to resolve names). ### Suggested MVP Scope - MVP = **Phase 3 (US1)** + **Phase 7 (T020–T021)**. --- ## Parallel Execution Examples ### Within US1 - Run in parallel: - T008 (include_foundations=true test) + T009 (include_foundations=false test) - Then implement T006–T007 and validate against T010 ### Across Stories (after US1 complete) - US2 UI tasks (T011–T013) can proceed in parallel with US3 coverage tasks (T014–T016). --- ## Format Validation - Every task line starts with `- [ ]` and includes a sequential TaskID (T001…) - Story phases use `[US1]`…`[US4]` labels; Setup/Foundational/Polish have no story label - Tasks marked `[P]` are parallelizable (different files / no blocking dependency)