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
8.0 KiB
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-scopedInventoryItemrows; 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
InventoryItemrows 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,notificationMessageTemplatein 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=trueand see foundationInventoryItemrows for the tenant. -
Run sync with
include_foundations=falseand see no foundationInventoryItemrows (even if a foundation type appears inpolicy_types). -
T006 [US1] Implement foundation-type inclusion/exclusion based on
include_foundationsin 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)
- T026 [US3] Add Coverage table column
Dependencies(✅/—) in resources/views/filament/pages/inventory-coverage.blade.php - T027 [US3] Add deterministic resolver CoverageCapabilitiesResolver::supportsDependencies($type) (contracts/config derived) + unit test in tests/Unit/CoverageCapabilitiesResolverTest.php
- T028 [P] [US3] Update Pest UI/feature test to assert Coverage renders
Dependenciescolumn 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
InventoryItemexists. -
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
- T020 [P] Run formatting on changed files with ./vendor/bin/pint --dirty
- 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
- 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 - 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] 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 (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)