TenantAtlas/specs/046-inventory-sync-button/spec.md
ahmido cf5b0027e3 046-inventory-sync-button (#47)
Zusammenfassung: Fügt im „Run Inventory Sync“-Modal einen include_dependencies-Toggle hinzu und persistiert die Auswahl in der InventorySyncRun.selection_payload. Tests, Quickstart und Tasks wurden entsprechend aktualisiert.

Files: InventoryLanding.php, InventorySyncButtonTest.php, quickstart.md, tasks.md
Motivation: Ermöglicht explizites Ein-/Ausschalten der Dependency-Extraktion pro Sync-Run (z. B. Assignments/Scope Tags/Foundations), statt starrer Defaults. Passt zur bestehenden selection_hash-Logik (InventorySelectionHasher) und zur deterministischen Selektionspersistenz.
Verhalten: include_dependencies ist im Modal standardmäßig true. Wird die Option gesetzt, landet der Wert als bool im selection_payload und beeinflusst selection_hash über die Normalisierung.
Tests: Neuer/angepasster Pest-Test stellt sicher, dass include_dependencies in selection_payload persistiert. Lokaler Testlauf:
./vendor/bin/sail artisan test tests/Feature/Inventory/InventorySyncButtonTest.php → alle Tests für diese Datei bestanden.
./vendor/bin/pint --dirty wurde ausgeführt (Formatting ok).
How to test (quick):
Start Sail + Queue:
Im Admin → Inventory: „Run Inventory Sync“ öffnen, Include dependencies umschalten, ausführen.
Prüfen: neu erstellter InventorySyncRun.selection_payload.include_dependencies ist der gesetzten Auswahl entsprechend. Oder laufen lassen:
Notes / Next steps:
Diese Änderung bereitet den Weg, später die Dependency-Extraction (042-inventory-dependencies-graph) optional tiefer zu integrieren.
Working tree ist sauber; es gibt ein nicht eingebundenes Verzeichnis 0800-future-features (unrelated).

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #47
2026-01-09 22:15:04 +00:00

8.1 KiB

Feature Specification: Inventory Sync Button

Feature Branch: 046-inventory-sync-button
Created: 2026-01-09
Status: Draft
Input: User description: "Add an Inventory Sync button"

User Scenarios & Testing (mandatory)

User Story 1 - Run Inventory Sync from UI (Priority: P1)

As an admin, I want a button in the admin UI to start an Inventory Sync for the currently selected tenant, so I can refresh inventory data without needing CLI.

Why this priority: Inventory is a core admin surface; the ability to refresh on-demand reduces troubleshooting time and improves trust in the data.

Independent Test: Can be fully tested by clicking a "Run Inventory Sync" button and verifying a new Sync Run record appears and progresses to a terminal state.

Acceptance Scenarios:

  1. Given I am viewing Inventory for a tenant, When I click "Run Inventory Sync", Then a new Inventory Sync Run is created for that tenant and work is started asynchronously.
  2. Given a sync run is started, When I view in-app notifications and the progress widget, Then I can see the sync progress and final outcome.
  3. Given a sync run finishes (success/partial/failed), When I open the Inventory Sync Runs list, Then the run is visible with its terminal status and error summary (if any).
  4. Given I am viewing Inventory for tenant A, When a request/payload/state attempts to start a sync for tenant B, Then the request is rejected (403/AccessDenied), I see “Not allowed”, and no run/job is created for tenant B.

User Story 2 - Safe feedback when sync cannot start (Priority: P2)

As an admin, I want clear feedback when an Inventory Sync cannot be started (for example due to locks or concurrency), so I understand what to do next.

Why this priority: Inventory sync runs are lock- and concurrency-gated; unclear failures lead to repeated clicks and confusion.

Independent Test: Can be tested by attempting to start a sync while another sync is already running and verifying the UI shows a clear message and does not create duplicate runs.

Acceptance Scenarios:

  1. Given a sync for the same tenant/selection is already running, When I click "Run Inventory Sync", Then the system does not start a second overlapping run and provides a clear explanation.

User Story 3 - Permissioned access (Priority: P3)

As a tenant-scoped admin, I want only authorized users to be able to start Inventory Sync runs, so tenant data and Graph access are not triggered by unauthorized users.

Why this priority: Starting a sync triggers tenant-scoped Graph reads and creates operational records.

Independent Test: Can be tested by using a user without the required permission and verifying the action is not available or is denied.

Acceptance Scenarios:

  1. Given I do not have permission to run inventory sync, When I view the Inventory area, Then I cannot trigger a sync and I receive an access denied message if I attempt it.

[Add more user stories as needed, each with an assigned priority]

Edge Cases

  • If a sync is already running for the same tenant + selection, the UI MUST not dispatch another run and MUST show an informational message.
  • If tenant credentials are missing/invalid, the run MUST end in a terminal failure state and the initiating user MUST be notified.
  • If the user clicks multiple times quickly, only one run MUST be dispatched; subsequent attempts MUST be blocked with a clear message.
  • If the UI is closed after dispatch, the run MUST still finish and remain observable later via runs list + notifications.
  • If queue workers are down, the run MUST remain observable as “queued/pending” and the UI MUST not pretend completion.
  • If a request/payload/state attempts cross-tenant initiation, the system MUST reject the attempt server-side (403/AccessDenied) and MUST NOT create any run/job for another tenant.

Requirements (mandatory)

Constitution alignment (required): If this feature introduces any Microsoft Graph calls or any write/change behavior, the spec MUST describe contract registry updates, safety gates (preview/confirmation/audit), tenant isolation, and tests.

Functional Requirements

  • FR-001: System MUST provide an admin UI action to start an Inventory Sync for the currently selected tenant.
  • FR-002: System MUST run Inventory Sync exclusively in the context of the current tenant (Tenant::current()). If any request/payload/state attempts to target a different tenant (e.g. provides tenant_id that does not match Tenant::current()->id), the system MUST reject the attempt server-side with 403/AccessDenied, MUST show a user-visible “Not allowed” message, and MUST NOT create any InventorySyncRun, BulkOperationRun, or queued job for the foreign tenant.
  • FR-003: System MUST create an observable Inventory Sync Run record when a sync is started.
  • FR-004: System MUST start the Inventory Sync asynchronously (queued/background execution), not inline in the request.
  • FR-005: System MUST enforce existing concurrency/lock rules and MUST NOT start overlapping runs for the same tenant/selection.
  • FR-006: System MUST show a clear success message when a run is started and a clear informational message when a run cannot be started due to locks/concurrency.
  • FR-007: System MUST enforce authorization for starting sync runs.
  • FR-008: System MUST record who initiated the sync run (user identity) on the run record AND in the audit trail for auditability.
  • FR-009: System MUST provide in-app visibility into sync progress and outcome via a DB-backed notifications panel.
  • FR-010: System MUST provide in-app visibility into sync progress and outcome via a bottom-right progress widget, consistent with the Policy Sync experience.

Assumptions

  • The Inventory Sync capability already exists and can be triggered by the application.
  • An Inventory Sync Runs list/detail view already exists (or will exist) where users can observe runs.

Dependencies

  • Tenant context switching is available so the action always targets the current tenant.
  • Existing concurrency/lock rules are enforced consistently for all sync starts (UI-triggered or otherwise).
  • The application has an existing mechanism for DB-backed in-app notifications and a progress widget (used by Policy Sync).

Example of marking unclear requirements:

Key Entities (include if feature involves data)

  • Inventory Sync Run: A record representing a single inventory sync execution for a specific tenant and selection; includes status, timestamps, and error summary.
  • Tenant: The tenant context the user is currently operating on; determines credentials/scope for inventory sync.
  • User (Initiator): The authenticated user who triggered the sync run; used for auditability and access control.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: An authorized admin can start an Inventory Sync from the UI in under 10 seconds (time to find + click action).
  • SC-002: In a normal tenant, 95% of sync start attempts either create a run or provide a clear lock/concurrency explanation within 2 seconds.
  • SC-003: In usability testing, at least 90% of admins can successfully start a sync and locate the resulting run and its progress without guidance.
  • SC-004: Support/debug time for "inventory looks stale" issues is reduced (measured as fewer repeated sync/troubleshooting requests), after rollout.