TenantAtlas/specs/047-inventory-foundations-nodes/tasks.md
ahmido 9c56a2349a feat/047-inventory-foundations-nodes (#51)
Adds Inventory Sync toggle include_foundations (default true) + persistence tests
Adds Coverage “Dependencies” column (/—) derived deterministically from graph_contracts (no Graph calls)
Spec/tasks/checklists updated + tasks ticked off

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #51
2026-01-10 20:47:29 +00:00

140 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
### Coverage Dependencies Support (UI-only)
- [x] T026 [US3] Add Coverage table column `Dependencies` (✅/—) in resources/views/filament/pages/inventory-coverage.blade.php
- [x] T027 [US3] Add deterministic resolver CoverageCapabilitiesResolver::supportsDependencies($type) (contracts/config derived) + unit test in tests/Unit/CoverageCapabilitiesResolverTest.php
- [x] T028 [P] [US3] Update Pest UI/feature test to assert Coverage renders `Dependencies` column and at least one ✅ 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 (DependencyQueryService + DependencyTargets\\DependencyTargetResolver + DependencyTargets\\FoundationTypeMap) 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
- [x] T025 [P] [US4] Verified resolver references: dependencies UI queries edges via DependencyQueryService and renders targets via DependencyTargets\DependencyTargetResolver + DependencyTargets\FoundationTypeMap (text-only task)
---
## 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 (T020T021)**.
---
## Parallel Execution Examples
### Within US1
- Run in parallel:
- T008 (include_foundations=true test) + T009 (include_foundations=false test)
- Then implement T006T007 and validate against T010
### Across Stories (after US1 complete)
- US2 UI tasks (T011T013) can proceed in parallel with US3 coverage tasks (T014T016).
---
## 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)