# Implementation Plan: Inventory Dependencies Graph (042) **Branch**: `feat/042-inventory-dependencies-graph` | **Date**: 2026-01-10 | **Spec**: specs/042-inventory-dependencies-graph/spec.md ## Summary Provide a read-only dependency view for an Inventory Item (direct inbound/outbound edges) with filters for direction and relationship type. Dependencies are derived from inventory sync payloads and stored idempotently in `inventory_links`. ## MVP Constraints (Explicit) - Direct neighbors only (no depth > 1 traversal / transitive blast radius). - Limit-only queries (no pagination/cursors). - UI shows <= 50 edges per direction (<= 100 total when showing both directions). - Unknown/unsupported reference shapes are warning-only (no edge created). - Warnings persist on `InventorySyncRun.error_context.warnings[]`. - No new tables for warnings. ## Technical Context **Language/Version**: PHP 8.4.x **Primary Dependencies**: Laravel 12, Filament v4, Livewire v3 **Storage**: PostgreSQL (JSONB) **Testing**: Pest v4 **Target Platform**: Web (Filament admin) **Project Type**: Laravel monolith **Performance Goals**: dependency section renders in <2s with indexed + limited queries **Constraints**: tenant scoped only; no extra Graph lookups for enrichment **Scale/Scope**: edge rendering and extraction are hard-capped ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first: edges reflect last observed sync payloads; no backups/snapshots. - Read/write separation: UI is read-only; no Intune write paths. - Single contract path to Graph: no new Graph calls for this feature. - Tenant isolation: all edges stored/queried with `tenant_id`. - Automation: idempotent via unique key + upsert; observable via run record; warnings persisted. - Data minimization: only metadata stored; no secrets/tokens. Gate status: PASS. ## Project Structure ### Documentation (this feature) ```text specs/042-inventory-dependencies-graph/ ├── plan.md ├── spec.md ├── tasks.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ ├── README.md │ └── dependency-edge.schema.json └── checklists/ ├── pr-gate.md └── requirements.md ``` ### Source Code (repository root) ```text app/Filament/Resources/InventoryItemResource.php app/Models/InventoryItem.php app/Models/InventoryLink.php app/Models/InventorySyncRun.php app/Services/Inventory/DependencyExtractionService.php app/Services/Inventory/DependencyQueryService.php app/Support/Enums/RelationshipType.php resources/views/filament/components/dependency-edges.blade.php tests/Feature/InventoryItemDependenciesTest.php tests/Feature/DependencyExtractionFeatureTest.php tests/Unit/DependencyExtractionServiceTest.php ``` ## Phase 0: Research (Output: research.md) Document decisions + rationale + alternatives for MVP clarifications (limit-only, 50 per direction, warnings-on-run-record, warning-only unknown shapes, required foundation_type metadata, relationship-type filter). ## Phase 1: Design (Outputs: data-model.md, contracts/*, quickstart.md) - Data model: entities and fields, including `inventory_links` unique key and metadata shapes. - Contracts: JSON schema describing the dependency edge data passed to the UI. - Quickstart: how to view dependencies and run targeted tests. ## Phase 2: Implementation Plan (MVP) 1. UI filters: direction + relationship-type via querystring. 2. Query: use DB filtering via `DependencyQueryService` optional `relationship_type`. 3. Extraction: align unknown/unsupported shapes to warning-only and persist warnings on run record. 4. Tests: add/adjust unit/feature/UI smoke tests for relationship filtering and warning-only behavior. 5. Quality gates: Pint + targeted Pest tests. ## Complexity Tracking None for MVP (no constitution violations). | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |