216 lines
15 KiB
Markdown
216 lines
15 KiB
Markdown
# Tasks: Inventory Dependencies Graph (042)
|
|
|
|
**Input**: Design documents in `specs/042-inventory-dependencies-graph/` (plan.md, spec.md, research.md, data-model.md, contracts/, quickstart.md)
|
|
|
|
**Notes**
|
|
- Tasks are grouped by user story so each story is independently testable.
|
|
- Tests are included because this feature affects runtime behavior.
|
|
- MVP constraints (direct only, limit-only, 50 per direction, warnings-on-run-record, no warnings tables) must remain enforced.
|
|
|
|
## Phase 1: Setup (Shared)
|
|
|
|
**Purpose**: Ensure feature docs and scope constraints are locked before code changes.
|
|
|
|
- [x] T001 Validate MVP constraints in `specs/042-inventory-dependencies-graph/plan.md` remain aligned with `specs/042-inventory-dependencies-graph/spec.md`
|
|
- [x] T002 Validate scope + NFR checkboxes in `specs/042-inventory-dependencies-graph/checklists/requirements.md` cover all accepted MVP constraints
|
|
|
|
---
|
|
|
|
## Phase 2: Foundational (Blocking Prerequisites)
|
|
|
|
**Purpose**: Storage + extraction + query services that all UI stories rely on.
|
|
|
|
**Checkpoint**: After Phase 2, edges can be extracted and queried tenant-safely with limits.
|
|
|
|
- [ ] T003 [P] Ensure relationship types and labels are centralized in `app/Support/Enums/RelationshipType.php`
|
|
- [ ] T004 Ensure `inventory_links` schema (unique key + indexes) matches spec in `database/migrations/2026_01_07_150000_create_inventory_links_table.php`
|
|
- [ ] T005 [P] Ensure `InventoryLink` casts and tenant-safe query patterns in `app/Models/InventoryLink.php`
|
|
- [ ] T006 [P] Ensure factory coverage for dependency edges in `database/factories/InventoryLinkFactory.php`
|
|
- [ ] T007 Align idempotent upsert semantics for edges in `app/Services/Inventory/DependencyExtractionService.php`
|
|
- [ ] T008 Implement warning-only handling for unknown/unsupported reference shapes in `app/Services/Inventory/DependencyExtractionService.php`
|
|
- [ ] T009 Persist warnings on the sync run record at `InventorySyncRun.error_context.warnings[]` via `app/Services/Inventory/InventorySyncService.php`
|
|
- [ ] T010 Implement limit-only inbound/outbound queries with optional relationship filter in `app/Services/Inventory/DependencyQueryService.php` (ordered by `created_at DESC`)
|
|
- [ ] T011 [P] Add determinism + idempotency tests in `tests/Unit/DependencyExtractionServiceTest.php`
|
|
- [ ] T012 [P] Add tenant isolation tests for queries in `tests/Feature/DependencyExtractionFeatureTest.php`
|
|
- [x] T003 [P] Ensure relationship types and labels are centralized in `app/Support/Enums/RelationshipType.php`
|
|
- [x] T004 Ensure `inventory_links` schema (unique key + indexes) matches spec in `database/migrations/2026_01_07_150000_create_inventory_links_table.php`
|
|
- [x] T005 [P] Ensure `InventoryLink` casts and tenant-safe query patterns in `app/Models/InventoryLink.php`
|
|
- [x] T006 [P] Ensure factory coverage for dependency edges in `database/factories/InventoryLinkFactory.php`
|
|
- [x] T007 Align idempotent upsert semantics for edges in `app/Services/Inventory/DependencyExtractionService.php` (including hydrated assignments when not present in list payloads)
|
|
- [x] T008 Implement warning-only handling for unknown/unsupported reference shapes in `app/Services/Inventory/DependencyExtractionService.php`
|
|
- [x] T009 Persist warnings on the sync run record at `InventorySyncRun.error_context.warnings[]` via `app/Services/Inventory/InventorySyncService.php`
|
|
- [x] T010 Implement limit-only inbound/outbound queries with optional relationship filter in `app/Services/Inventory/DependencyQueryService.php` (ordered by `created_at DESC`)
|
|
- [x] T011 [P] Add determinism + idempotency tests in `tests/Unit/DependencyExtractionServiceTest.php`
|
|
- [x] T012 [P] Add tenant isolation tests for queries in `tests/Feature/DependencyExtractionFeatureTest.php`
|
|
|
|
---
|
|
|
|
## Phase 3: User Story 1 — View Dependencies (Priority: P1) 🎯 MVP
|
|
|
|
**Goal**: As an admin, I can view direct inbound/outbound dependencies for an inventory item.
|
|
|
|
**Independent Test**: Opening an Inventory Item shows a Dependencies section that renders within limits and supports direction filtering.
|
|
|
|
- [ ] T013 [P] [US1] Wire dependencies section into Filament item view in `app/Filament/Resources/InventoryItemResource.php`
|
|
- [ ] T014 [P] [US1] Render edges grouped by relationship type in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [ ] T015 [US1] Add direction filter (querystring-backed) in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [ ] T016 [US1] Parse/validate `direction` and pass to query service in `app/Filament/Resources/InventoryItemResource.php`
|
|
- [ ] T017 [US1] Add UI smoke test for dependencies rendering + direction filter in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [x] T013 [P] [US1] Wire dependencies section into Filament item view in `app/Filament/Resources/InventoryItemResource.php`
|
|
- [x] T014 [P] [US1] Render edges grouped by relationship type in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [x] T015 [US1] Add direction filter (querystring-backed) in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [x] T016 [US1] Parse/validate `direction` and pass to query service in `app/Filament/Resources/InventoryItemResource.php`
|
|
- [x] T017 [US1] Add UI smoke test for dependencies rendering + direction filter in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
|
|
---
|
|
|
|
## Phase 4: User Story 2 — Identify Missing Prerequisites (Priority: P2)
|
|
|
|
**Goal**: As an admin, I can clearly see when a referenced prerequisite object is missing.
|
|
|
|
**Independent Test**: A missing target renders a red “Missing” badge and safe tooltip using `metadata.last_known_name`/`metadata.raw_ref`.
|
|
|
|
- [ ] T018 [US2] Ensure unresolved targets create `target_type='missing'` edges with safe metadata in `app/Services/Inventory/DependencyExtractionService.php`
|
|
- [ ] T019 [US2] Display “Missing” badge + tooltip for missing edges in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [ ] T020 [US2] Add feature test for missing edge creation + metadata in `tests/Feature/DependencyExtractionFeatureTest.php`
|
|
- [ ] T021 [US2] Add UI test asserting missing badge/tooltip is visible in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [x] T018 [US2] Ensure unresolved targets create `target_type='missing'` edges with safe metadata in `app/Services/Inventory/DependencyExtractionService.php`
|
|
- [x] T019 [US2] Display “Missing” badge + tooltip for missing edges in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [x] T020 [US2] Add feature test for missing edge creation + metadata in `tests/Feature/DependencyExtractionFeatureTest.php`
|
|
- [x] T021 [US2] Add UI test asserting missing badge/tooltip is visible in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
|
|
---
|
|
|
|
## Phase 5: User Story 3 — Filter By Relationship Type (Priority: P2)
|
|
|
|
**Goal**: As an admin, I can filter dependencies by relationship type to reduce noise.
|
|
|
|
**Independent Test**: Selecting a relationship type shows only matching edges; default “All” shows everything.
|
|
|
|
- [ ] T022 [US3] Add relationship-type dropdown filter (querystring-backed) in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [ ] T023 [US3] Parse/validate `relationship_type` and pass to query service in `app/Filament/Resources/InventoryItemResource.php`
|
|
- [ ] T024 [US3] Add UI smoke test verifying relationship filter limits edges in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [x] T022 [US3] Add relationship-type dropdown filter (querystring-backed) in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [x] T023 [US3] Parse/validate `relationship_type` and pass to query service in `app/Filament/Resources/InventoryItemResource.php`
|
|
- [x] T024 [US3] Add UI smoke test verifying relationship filter limits edges in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
|
|
---
|
|
|
|
## Phase 6: User Story 4 — Zero Dependencies (Priority: P3)
|
|
|
|
**Goal**: As an admin, I get a clear empty state when no dependencies exist.
|
|
|
|
**Independent Test**: When queries return zero edges, the UI shows “No dependencies found” and does not error.
|
|
|
|
- [ ] T025 [US4] Render zero-state message in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [ ] T026 [US4] Add UI test for zero-state rendering in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [x] T025 [US4] Render zero-state message in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [x] T026 [US4] Add UI test for zero-state rendering in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
|
|
---
|
|
|
|
## Phase 7: Polish & Cross-Cutting Concerns
|
|
|
|
**Purpose**: Tighten docs/contracts and run quality gates.
|
|
|
|
- [ ] T027 [P] Align filter docs + URLs in `specs/042-inventory-dependencies-graph/quickstart.md`
|
|
- [ ] T028 [P] Ensure schema reflects metadata requirements in `specs/042-inventory-dependencies-graph/contracts/dependency-edge.schema.json`
|
|
- [ ] T029 Update requirement-gate checkboxes in `specs/042-inventory-dependencies-graph/checklists/pr-gate.md`
|
|
- [ ] T030 Run Pint and fix formatting in `app/`, `resources/views/filament/components/`, and `tests/` (touching `app/Support/Enums/RelationshipType.php`, `resources/views/filament/components/dependency-edges.blade.php`, `tests/Feature/InventoryItemDependenciesTest.php`)
|
|
- [ ] T031 Run targeted tests: `tests/Feature/InventoryItemDependenciesTest.php`, `tests/Feature/DependencyExtractionFeatureTest.php`, `tests/Unit/DependencyExtractionServiceTest.php`
|
|
- [x] T027 [P] Align filter docs + URLs in `specs/042-inventory-dependencies-graph/quickstart.md`
|
|
- [x] T028 [P] Ensure schema reflects metadata requirements in `specs/042-inventory-dependencies-graph/contracts/dependency-edge.schema.json`
|
|
- [x] T029 Update requirement-gate checkboxes in `specs/042-inventory-dependencies-graph/checklists/pr-gate.md`
|
|
- [x] T030 Run Pint and fix formatting in `app/`, `resources/views/filament/components/`, and `tests/` (touching `app/Support/Enums/RelationshipType.php`, `resources/views/filament/components/dependency-edges.blade.php`, `tests/Feature/InventoryItemDependenciesTest.php`)
|
|
- [x] T031 Run targeted tests: `tests/Feature/InventoryItemDependenciesTest.php`, `tests/Feature/DependencyExtractionFeatureTest.php`, `tests/Unit/DependencyExtractionServiceTest.php`
|
|
|
|
---
|
|
|
|
## Phase 8: Consistency & Security Coverage (Cross-Cutting)
|
|
|
|
**Purpose**: Close remaining spec→tasks gaps (ordering, masking, auth expectations, logging severity).
|
|
|
|
- [ ] T032 [P] Add test asserting inbound/outbound query ordering by `created_at DESC` + limit-only behavior in `tests/Feature/DependencyExtractionFeatureTest.php` (or `tests/Unit/DependencyExtractionServiceTest.php` if more appropriate)
|
|
- [ ] T033 [US2] Implement masked/abbreviated identifier rendering when `metadata.last_known_name` is null in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [ ] T034 [US2] Add UI test for masked identifier behavior in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [ ] T035 [P] Add auth behavior test for the inventory item dependencies view (guest blocked; authenticated tenant user allowed) in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [ ] T036 [P] Ensure unknown/unsupported reference warnings are logged at `info` severity in `app/Services/Inventory/DependencyExtractionService.php` and add a unit test using `Log::fake()` in `tests/Unit/DependencyExtractionServiceTest.php`
|
|
- [ ] T037 Document how to verify the <2s dependency section goal (manual acceptance check) in `specs/042-inventory-dependencies-graph/quickstart.md`
|
|
- [x] T032 [P] Add test asserting inbound/outbound query ordering by `created_at DESC` + limit-only behavior in `tests/Feature/DependencyExtractionFeatureTest.php` (or `tests/Unit/DependencyExtractionServiceTest.php` if more appropriate)
|
|
- [x] T033 [US2] Implement masked/abbreviated identifier rendering when `metadata.last_known_name` is null in `resources/views/filament/components/dependency-edges.blade.php`
|
|
- [x] T034 [US2] Add UI test for masked identifier behavior in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [x] T035 [P] Add auth behavior test for the inventory item dependencies view (guest blocked; authenticated tenant user allowed) in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
- [x] T036 [P] Ensure unknown/unsupported reference warnings are logged at `info` severity in `app/Services/Inventory/DependencyExtractionService.php` and add a unit test using `Log::fake()` in `tests/Unit/DependencyExtractionServiceTest.php`
|
|
- [x] T037 Document how to verify the <2s dependency section goal (manual acceptance check) in `specs/042-inventory-dependencies-graph/quickstart.md`
|
|
|
|
---
|
|
|
|
## Phase 9: 042.2 — Dependency Target Name Resolution (Resolver + Batch) 🎯
|
|
|
|
**Goal**: Remove UI-level "Unknown" logic by rendering a stable DTO per edge target, and resolve names from the local DB when possible.
|
|
|
|
**Constraints**:
|
|
- No Entra/Graph lookups in the Dependencies UI (DB-only).
|
|
- No new tables.
|
|
- Deterministic, tenant-scoped, batch queries (no N+1).
|
|
|
|
- [x] T038 Introduce DTO + resolver registry (batch) for dependency targets (e.g., `DependencyTargetDto`, `DependencyTargetResolver`)
|
|
- [x] T039 Implement DB-based resolvers for scope tags and assignment filters; keep AAD groups as external refs (no resolution)
|
|
- [x] T040 Wire resolver into the Dependencies view (attach DTO to each edge) and simplify Blade rendering to DTO-only
|
|
- [x] T041 Add linking for resolved targets (tenant-scoped Inventory Item view URL)
|
|
- [x] T042 Add tests: unit (batch + determinism + tenant isolation) and feature/UI (resolved names + external group label)
|
|
|
|
---
|
|
|
|
## Dependencies & Execution Order
|
|
|
|
### Phase Dependencies
|
|
|
|
- Phase 1 (Setup) → Phase 2 (Foundational) → US1 (MVP) → US2/US3 → US4 → Polish
|
|
|
|
### User Story Dependencies
|
|
|
|
- US1 depends on Phase 2.
|
|
- US2 depends on Phase 2 and US1 (needs the Dependencies view).
|
|
- US3 depends on Phase 2 and US1 (needs the Dependencies view).
|
|
- US4 depends on US1 (zero-state is part of the Dependencies view).
|
|
|
|
## Parallel Execution Examples
|
|
|
|
### Phase 2 (Foundational)
|
|
|
|
- [P] `app/Support/Enums/RelationshipType.php` and `database/migrations/2026_01_07_150000_create_inventory_links_table.php`
|
|
- [P] `database/factories/InventoryLinkFactory.php` and `tests/Unit/DependencyExtractionServiceTest.php`
|
|
|
|
### User Story 1 (US1)
|
|
|
|
- [P] Update `app/Filament/Resources/InventoryItemResource.php` while implementing rendering in `resources/views/filament/components/dependency-edges.blade.php`
|
|
|
|
### User Story 2 (US2)
|
|
|
|
- [P] Implement missing-edge extraction in `app/Services/Inventory/DependencyExtractionService.php` while updating UI rendering in `resources/views/filament/components/dependency-edges.blade.php`
|
|
|
|
### User Story 3 (US3)
|
|
|
|
- [P] Implement relationship dropdown in `resources/views/filament/components/dependency-edges.blade.php` while wiring query parsing in `app/Filament/Resources/InventoryItemResource.php`
|
|
|
|
### User Story 4 (US4)
|
|
|
|
- [P] Implement zero-state UI in `resources/views/filament/components/dependency-edges.blade.php` while writing the UI assertion in `tests/Feature/InventoryItemDependenciesTest.php`
|
|
|
|
## Implementation Strategy
|
|
|
|
### MVP First (US1 Only)
|
|
|
|
1. Complete Phase 1 and Phase 2.
|
|
2. Implement US1 and validate with `tests/Feature/InventoryItemDependenciesTest.php`.
|
|
3. Stop and demo MVP UI before proceeding to US2/US3.
|
|
|
|
### Incremental Delivery
|
|
|
|
1. Phase 1 + Phase 2 → foundation ready.
|
|
2. US1 → demo dependency view.
|
|
3. US2 → add missing-prerequisite trust signals.
|
|
4. US3 → add relationship filtering for readability.
|
|
5. US4 → refine empty-state UX.
|