--- description: "Task list for Inventory Sync Button (046)" --- # Tasks: Inventory Sync Button (046) **Input**: Design documents from `/specs/046-inventory-sync-button/` **Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md, contracts/ **Tests**: REQUIRED (Pest) — this feature changes runtime behavior. **Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story. ## Format: `- [ ] T### [P?] [Story] Description with file path` - **[P]**: Can run in parallel (different files, no dependencies) - **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3) - Include exact file paths in descriptions --- ## Phase 1: Setup (Shared Infrastructure) **Purpose**: Ensure feature docs and baseline scaffolding are in place. - [ ] T001 Verify feature docs exist and are current in specs/046-inventory-sync-button/{spec.md,plan.md,research.md,data-model.md,quickstart.md,contracts/internal-actions.md} - [X] T001 Verify feature docs exist and are current in specs/046-inventory-sync-button/{spec.md,plan.md,research.md,data-model.md,quickstart.md,contracts/internal-actions.md} - [X] T002 [P] Locate existing Inventory landing UI and runs list pages in app/Filament/Pages/InventoryLanding.php and app/Filament/Resources/InventorySyncRunResource/** --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Core infrastructure that MUST be complete before ANY user story work can be finished end-to-end. - [X] T003 Add nullable initiator FK to inventory sync runs in database/migrations/xxxx_xx_xx_xxxxxx_add_user_id_to_inventory_sync_runs_table.php - [X] T004 [P] Add `user()` relationship + casts/guarding as needed in app/Models/InventorySyncRun.php - [X] T005 [P] Add `use Illuminate\Database\Eloquent\Relations\BelongsTo;` + `user(): BelongsTo` in app/Models/InventorySyncRun.php - [X] T006 Add queued job skeleton for inventory sync in app/Jobs/RunInventorySyncJob.php - [X] T007 [P] Add default inventory selection builder (full inventory) and deterministic selection_hash helper as methods on app/Services/Inventory/InventorySyncService.php (no new factory/hasher classes) - [X] T008 Add service entrypoint that attributes initiator on run record in app/Services/Inventory/InventorySyncService.php **Checkpoint**: DB schema + job/service primitives exist. --- ## Phase 3: User Story 1 — Run Inventory Sync from UI (Priority: P1) 🎯 MVP **Goal**: Provide a “Run Inventory Sync” action for the current tenant that dispatches work asynchronously and is observable. **Independent Test**: Clicking the action creates a `BulkOperationRun` and an `InventorySyncRun`, then job completes and updates both + DB notifications. ### Tests for User Story 1 (REQUIRED) - [X] T010 [P] [US1] Add feature test covering action dispatch + run creation AND cross-tenant rejection (403 + “Not allowed” + no run/job created) in tests/Feature/Inventory/InventorySyncButtonTest.php - [X] T011 [P] [US1] Add feature test covering queued job success updates bulk run + inventory run in tests/Feature/Inventory/RunInventorySyncJobTest.php ### Implementation for User Story 1 - [X] T012 [US1] Add “Run Inventory Sync” header action to app/Filament/Pages/InventoryLanding.php - [X] T013 [US1] If needed, surface the action in resources/views/filament/pages/inventory-landing.blade.php (only if header actions aren’t visible) - [X] T014 [US1] On click, build default selection via app/Services/Inventory/InventorySyncService.php - [X] T015 [US1] On click, create BulkOperationRun (resource `inventory`, action `sync`, total_items=1) via app/Services/BulkOperationService.php (inline from the action handler) - [X] T016 [US1] On click, send “started” Filament DB notification in app/Filament/Pages/InventoryLanding.php - [X] T017 [US1] On click, dispatch app/Jobs/RunInventorySyncJob.php with tenant_id, user_id, bulk_run_id, selection_payload - [X] T018 [US1] Implement app/Jobs/RunInventorySyncJob.php to start bulk run + call InventorySyncService entrypoint - [X] T019 [US1] In job, map InventorySyncRun terminal outcome → BulkOperationService counters/status in app/Jobs/RunInventorySyncJob.php - [X] T020 [US1] In job, send completion/failure DB notification to the initiating user in app/Jobs/RunInventorySyncJob.php - [X] T021 [US1] Emit audit events for dispatched + completed/failed/skipped using app/Services/Intune/AuditLogger.php from app/Jobs/RunInventorySyncJob.php **Checkpoint**: US1 works end-to-end with queue worker running. --- ## Phase 4: User Story 2 — Safe feedback when sync cannot start (Priority: P2) **Goal**: Prevent duplicate/overlapping runs and provide clear feedback when sync can’t start. **Independent Test**: With a `running` InventorySyncRun for the same tenant+selection, the action does not dispatch a new job and shows an informational message. ### Tests for User Story 2 (REQUIRED) - [X] T022 [P] [US2] Add feature test for “already running” preflight blocking in tests/Feature/Inventory/InventorySyncButtonTest.php - [X] T023 [P] [US2] Add feature test for lock/concurrency skip outcome mapping in tests/Feature/Inventory/RunInventorySyncJobTest.php ### Implementation for User Story 2 - [X] T024 [US2] Add preflight check for existing running selection_hash in app/Filament/Pages/InventoryLanding.php - [X] T025 [US2] Compute selection_hash using app/Services/Inventory/InventorySyncService.php (same logic used for run creation) and use it for the preflight check in app/Filament/Pages/InventoryLanding.php - [X] T026 [US2] Add clear Filament notification message when blocked due to running/locks in app/Filament/Pages/InventoryLanding.php - [X] T027 [US2] Ensure RunInventorySyncJob handles `skipped` InventorySyncRun (concurrency/lock) and marks BulkOperationRun as completed_with_errors or completed (skipped) with reason in app/Jobs/RunInventorySyncJob.php **Checkpoint**: User gets clear feedback; duplicates are prevented. --- ## Phase 5: User Story 3 — Permissioned access (Priority: P3) **Goal**: Only authorized users can start Inventory Sync. **Independent Test**: Unauthorized users do not see the action (or cannot execute it) and no runs are created. ### Tests for User Story 3 (REQUIRED) - [X] T028 [P] [US3] Add feature test that unauthorized user cannot see/execute the action in tests/Feature/Inventory/InventorySyncButtonTest.php ### Implementation for User Story 3 - [X] T029 [US3] Gate action visibility/authorization via User::canSyncTenant(Tenant::current()) in app/Filament/Pages/InventoryLanding.php - [X] T030 [US3] Ensure server-side authorization check is enforced in action handler (not only visibility) in app/Filament/Pages/InventoryLanding.php **Checkpoint**: Authorization is enforced and tested. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Make delivery safe, consistent, and easy to validate. - [X] T031 [P] Add/adjust translation-safe, consistent notification copy (start/complete/fail) in app/Filament/Pages/InventoryLanding.php and app/Jobs/RunInventorySyncJob.php - [X] T032 Ensure `InventorySyncRunResource` shows initiator when present (user_id) in app/Filament/Resources/InventorySyncRunResource.php - [X] T033 [P] Run formatter on changed files: `./vendor/bin/pint --dirty` - [X] T034 Run targeted tests: `./vendor/bin/sail artisan test --filter=InventorySync` (or specific test files) - [X] T035 Validate quickstart steps remain accurate in specs/046-inventory-sync-button/quickstart.md - [X] T036 Make BulkOperation progress reflect selected policy types (total_items = #types; per-type success/failure) in app/Filament/Pages/InventoryLanding.php and app/Jobs/RunInventorySyncJob.php - [X] T037 Add `include_dependencies` toggle to the “Run Inventory Sync” modal in app/Filament/Pages/InventoryLanding.php and cover via tests/Feature/Inventory/InventorySyncButtonTest.php --- ## Dependencies & Execution Order ### User Story dependency graph - Setup → Foundational → US1 → (US2, US3) → Polish Rationale: - US1 establishes the action + job + progress/notifications baseline. - US2 and US3 are incremental safety/guardrails on top of the same action. ### Parallel opportunities - Phase 2: T004, T005, T007 can run in parallel (separate files). - US1: T010 and T011 can be written in parallel. - US2: T022 and T023 can be written in parallel. --- ## Parallel Example: User Story 1 Parallelizable work for US1 (after Phase 2 is complete): ```text Run in parallel: - T010 + T011 (tests) - T012 + T018 (UI action + job implementation) Then: - T015–T017 (wire dispatch + notifications) - T019–T021 (status mapping + DB notif + audit) ``` --- ## Implementation Strategy ### MVP scope (recommended) - Deliver US1 only (Phases 1–3) and validate via quickstart. - Then add US2 and US3 as hardening increments.