## Summary
- centralize all status-like badge semantics via `BadgeCatalog`/`BadgeRenderer` and new per-domain mappings plus coverage for every affected entity
- replace ad-hoc badge colors in Filament tables/views with the shared catalog and add a guard test that blocks new inline semantics
- stabilize restore views by avoiding `@php(...)` shorthand so Blade compiles cleanly, and document BADGE-001 in the constitution/templates
## Testing
- `vendor/bin/sail php vendor/bin/pint --dirty`
- `vendor/bin/sail artisan test tests/Unit/Badges tests/Feature/Guards/NoAdHocStatusBadgesTest.php`
- `vendor/bin/sail artisan test tests/Feature/Monitoring/OperationsDbOnlyTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php`
- `vendor/bin/sail artisan test tests/Feature/RestoreRunWizardMetadataTest.php tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php`
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #71
Kurzbeschreibung
Filament-native UI-Polish für das Tenant-Dashboard und zugehörige Inventory/Operations-Ansichten; entfernt alte custom Blade‑Panel-Wrapper (die die dicken Rahmen erzeugten) und ersetzt sie durch Filament‑Widgets (StatsOverview / TableWidget). Keine DB-Migrationen.
Änderungen (Kurz)
Dashboard: KPI‑Kacheln als StatsOverviewWidget (4 Tiles).
Needs‑Attention: sinnvolle Leerstaat‑UI (3 Health‑Checks + Links) und begrenzte, badge‑gestützte Issue‑Liste.
Recent Drift Findings & Recent Operations: Filament TableWidget (10 Zeilen), badge‑Spalten für Severity/Status/Outcome, kurze copyable IDs, freundliche Subject‑Labels statt roher UUIDs.
Entfernen der alten Blade-Wrapper, die ring- / shadow Klassen erzeugten.
Tests aktualisiert/ergänzt, um Tenant‑Scope und DB‑only Garantien zu prüfen.
Kleinigkeiten / UI‑Polish in Inventory/Operations-Listen und Panel‑Provider.
Wichtige Dateien (Auswahl)
DashboardKpis.php
NeedsAttention.php
RecentDriftFindings.php
RecentOperations.php
needs-attention.blade.php
Tests: TenantDashboardTenantScopeTest.php, inventory/operations test updates
Testing / Verifikation
Lokale Tests (empfohlen, vor Merge ausführen):
Formatter:
Filament assets (falls panel assets geändert wurden):
Review‑Hinweise (Was prüfen)
UI: Dashboard sieht visuell wie Filament‑Demo‑Widgets aus (keine dicken ring- Rahmen mehr).
Tables: Primary text zeigt freundliche Labels, nicht UUIDs; IDs sind copyable und kurz dargestellt.
Needs‑Attention: Leerstaat zeigt die 3 Health‑Checks + korrekte Links; bei Issues sind Badges und Farben korrekt.
Tenant‑Scope: Keine Daten von anderen Tenants leakieren (prüfe die aktualisierten TenantScope‑Tests).
Polling: Widgets poll nur wenn nötig (z.B. aktive Runs existieren).
Keine externen HTTP‑Calls oder ungeprüfte Jobs während Dashboard‑Rendering.
Deployment / Migrations
Keine Datenbankmigrationen.
Empfohlen: nach Merge ./vendor/bin/sail artisan filament:assets in Deployment‑Pipeline prüfen, falls neue panel assets registriert wurden.
Zusammenfassung für den Reviewer
Zweck: Entfernen der alten, handgebauten Panel‑Wrappers und Vereinheitlichung der Dashboard‑UX mit Filament‑nativen Komponenten; kleinere UI‑Polish in Inventory/Operations.
Tests: Unit/Feature tests für Tenant‑Scope und DB‑only Verhalten wurden aktualisiert; bitte laufen lassen.
Merge: Branch 058-tenant-ui-polish → dev (protected) via Pull Request in Gitea.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #70
Aligns Feature 057 spec wording and requirements checklist for the Filament v5 upgrade.
No runtime/code changes.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #69
Summary: Upgrade Filament to v5 (Livewire v4), replace Filament v4-only plugins, add first-party JSON renderer, and harden Monitoring/Ops UX guardrails.
What I changed:
Composer: upgraded filament/filament → v5, removed pepperfm/filament-json and lara-zeus/torch-filament, added torchlight/engine.
Views: replaced JSON viewer with json-viewer.blade.php and updated snapshot display.
Tests: added DB-only + tenant-isolation guard tests under Monitoring and OpsUx, plus Filament smoke tests.
Specs: added/updated specs/057-filament-v5-upgrade/* (spec, tasks, plan, quickstart, research).
Formatting: ran Pint; ran full test suite (641 passed, 5 skipped).
Validation:
Ran ./vendor/bin/sail artisan test (full suite) — all tests passed.
Ran ./vendor/bin/sail pint --dirty — formatting applied.
Ran npm run build locally (Vite) — assets generated.
Notes / Rollback:
Rollback: revert composer.json/composer.lock and build assets; documented in quickstart.md.
One pending app migration was noted during validation; ensure migrations are applied in staging before deploy.
Reviewers: @frontend, @backend (adjust as needed)
Spec links:
spec.md
tasks.md
quickstart.md
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #66
Kurzbeschreibung
Versteckt die Rerun-Row-Action für archivierte (soft-deleted) RestoreRuns und verhindert damit fehlerhafte Neu-Starts aus dem Archiv; ergänzt einen Regressionstest.
Änderungen
Code: RestoreRunResource.php — Sichtbarkeit der rerun-Action geprüft auf ! $record->trashed() und defensive Abbruchprüfung im Action-Handler.
Tests: RestoreRunRerunTest.php — neuer Test rerun action is hidden for archived restore runs.
Warum
Archivierte RestoreRuns durften nicht neu gestartet werden; UI zeigte trotzdem die Option. Das führte zu verwirrendem Verhalten und möglichen Fehlern beim Enqueueing.
Verifikation / QA
Unit/Feature:
./vendor/bin/sail artisan test tests/Feature/RestoreRunRerunTest.php
Stil/format:
./vendor/bin/pint --dirty
Manuell (UI):
Als Tenant-Admin Filament → Restore Runs öffnen.
Filter Archived aktivieren (oder Trashed filter auswählen).
Sicherstellen, dass für archivierte Einträge die Rerun-Action nicht sichtbar ist.
Auf einem aktiven (nicht-archivierten) Run prüfen, dass Rerun sichtbar bleibt und wie erwartet eine neue RestoreRun erzeugt.
Wichtige Hinweise
Kein DB-Migration required.
Diese PR enthält nur den UI-/Filament-Fix; die zuvor gemachten operative Fixes für Queue/adapter-Reconciliation bleiben ebenfalls auf dem Branch (z. B. frühere commits während der Debugging-Session).
T055 (Schema squash) wurde bewusst zurückgestellt und ist nicht Teil dieses PRs.
Merge-Checklist
Tests lokal laufen (RestoreRunRerunTest grünt)
Pint läuft ohne ungepatchte Fehler
Branch gepusht: 056-remove-legacy-bulkops (PR-URL: https://git.cloudarix.de/ahmido/TenantAtlas/compare/dev...056-remove-legacy-bulkops)
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #65
Kurzbeschreibung
Implementiert Feature 055 — Ops‑UX Constitution Rollout v1.3.0.
Behebt: globales BulkOperationProgress-Widget benötigt keinen manuellen Refresh mehr; ETA/Elapsed aktualisieren korrekt; Widget verschwindet automatisch.
Verbesserungen: zuverlässiges polling (Alpine factory + Livewire fallback), sofortiger Enqueue‑Signal-Dispatch, Failure‑Message‑Sanitization, neue Guard‑ und Regressionstests, Specs/Tasks aktualisiert.
Was geändert wurde (Auszug)
InventoryLanding.php
bulk-operation-progress.blade.php
OperationUxPresenter.php
SyncRestoreRunToOperationRun.php
PolicyResource.php
PolicyVersionResource.php
RestoreRunResource.php
tests/Feature/OpsUx/* (PollerRegistration, TerminalNotificationFailureMessageTest, CanonicalViewRunLinksTest, OperationCatalogCoverageTest, UnknownOperationTypeLabelTest)
InventorySyncButtonTest.php
tasks.md
Tests
Neue Tests hinzugefügt; php artisan test --group=ops-ux lokal grün (alle relevanten Tests laufen).
How to verify manually
Auf Branch wechseln: 055-ops-ux-rollout
In Filament: Inventory → Sync (oder relevante Bulk‑Aktion) auslösen.
Beobachten: Progress‑Widget erscheint sofort, ETA/Elapsed aktualisiert, Widget verschwindet nach Fertigstellung ohne Browser‑Refresh.
Optional: ./vendor/bin/sail exec app php artisan test --filter=OpsUx oder php artisan test --group=ops-ux
Besonderheiten / Hinweise
Einzelne, synchrone Policy‑Actions (ignore/restore/PolicyVersion single archive/restore/forceDelete) sind absichtlich inline und erzeugen kein OperationRun. Bulk‑Aktionen und restore.execute werden als Runs modelliert. Wenn gewünscht, kann ich die inline‑Actions auf OperationRunService umstellen, damit sie in Monitoring → Operations sichtbar werden.
Remote: Branch ist bereits gepusht (origin/055-ops-ux-rollout). PR kann in Gitea erstellt werden.
Links
Specs & tasks: tasks.md
Monitoring page: Operations.php
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #64
Summary
Kurz: Implementiert Feature 054 — canonical OperationRun-flow, Monitoring UI, dispatch-safety, notifications, dedupe, plus small UX safety clarifications (RBAC group search delegated; Restore group mapping DB-only).
What Changed
Core service: OperationRun lifecycle, dedupe and dispatch helpers — OperationRunService.php.
Model + migration: OperationRun model and migration — OperationRun.php, 2026_01_16_180642_create_operation_runs_table.php.
Notifications: queued + terminal DB notifications (initiator-only) — OperationRunQueued.php, OperationRunCompleted.php.
Monitoring UI: Filament list/detail + Livewire pieces (DB-only render) — OperationRunResource.php and related pages/views.
Start surfaces / Jobs: instrumented start surfaces, job middleware, and job updates to use canonical runs — multiple app/Jobs/* and app/Filament/* updates (see tests for full coverage).
RBAC + Restore UX clarifications: RBAC group search is delegated-Graph-based and disabled without delegated token; Restore group mapping remains DB-only (directory cache) and helper text always visible — TenantResource.php, RestoreRunResource.php.
Specs / Constitution: updated spec & quickstart and added one-line constitution guideline about Graph usage:
spec.md
quickstart.md
constitution.md
Tests & Verification
Unit / Feature tests added/updated for run lifecycle, notifications, idempotency, and UI guards: see tests/Feature/* (notably OperationRunServiceTest, MonitoringOperationsTest, OperationRunNotificationTest, and various Filament feature tests).
Full test run locally: ./vendor/bin/sail artisan test → 587 passed, 5 skipped.
Migrations
Adds create_operation_runs_table migration; run php artisan migrate in staging after review.
Notes / Rationale
Monitoring pages are explicitly DB-only at render time (no Graph calls). Start surfaces enqueue work only and return a “View run” link.
Delegated Graph access is used only for explicit user actions (RBAC group search); restore mapping intentionally uses cached DB data only to avoid render-time Graph calls.
Dispatch wrapper marks runs failed immediately if background dispatch throws synchronously to avoid misleading “queued” states.
Upgrade / Deploy Considerations
Run migrations: ./vendor/bin/sail artisan migrate.
Background workers should be running to process queued jobs (recommended to monitor queue health during rollout).
No secret or token persistence changes.
PR checklist
Tests updated/added for changed behavior
Specs updated: 054-unify-runs-suitewide docs + quickstart
Constitution note added (.specify)
Pint formatting applied
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #63
Summary
This PR introduces Unified Operations Runs + Monitoring Hub (053).
Goal: Standardize how long-running operations are tracked and monitored using the existing tenant-scoped run record (BulkOperationRun) as the canonical “operation run”, and surface it in a single Monitoring → Operations hub (view-only, tenant-scoped, role-aware).
Phase 1 adoption scope (per spec):
• Drift generation (drift.generate)
• Backup Set “Add Policies” (backup_set.add_policies)
Note: This PR does not convert every run type yet (e.g. GroupSyncRuns / InventorySyncRuns remain separate for now). This is intentionally incremental.
⸻
What changed
Monitoring / Operations hub
• Moved/organized run monitoring under Monitoring → Operations
• Added:
• status buckets (queued / running / succeeded / partially succeeded / failed)
• filters (run type, status bucket, time range)
• run detail “Related” links (e.g. Drift findings, Backup Set context)
• All hub pages are DB-only and view-only (no rerun/cancel/delete actions)
Canonical run semantics
• Added canonical helpers on BulkOperationRun:
• runType() (resource.action)
• statusBucket() derived from status + counts (testable semantics)
Drift integration (Phase 1)
• Drift generation start behavior now:
• creates/reuses a BulkOperationRun with drift context payload (scope_key + baseline/current run ids)
• dispatches generation job
• emits DB notifications including “View run” link
• On generation failure: stores sanitized failure entries + sends failure notification
Permissions / tenant isolation
• Monitoring run list/view is tenant-scoped and returns 403 for cross-tenant access
• Readonly can view runs but cannot start drift generation
⸻
Tests
Added/updated Pest coverage:
• BulkOperationRunStatusBucketTest.php
• DriftGenerationDispatchTest.php
• GenerateDriftFindingsJobNotificationTest.php
• RunAuthorizationTenantIsolationTest.php
Validation run locally:
• ./vendor/bin/pint --dirty
• targeted tests from feature quickstart / drift monitoring tests
⸻
Manual QA
1. Go to Monitoring → Operations
• verify filters (run type / status / time range)
• verify run detail shows counts + sanitized failures + “Related” links
2. Open Drift Landing
• with >=2 successful inventory runs for scope: should queue drift generation + show notification with “View run”
• as readonly: should not start generation
3. Run detail
• drift.generate runs show “Drift findings” related link
• failure entries are sanitized (no secrets/tokens/raw payload dumps)
⸻
Notes / Ops
• Queue workers must be restarted after deploy so they load the new code:
• php artisan queue:restart (or Sail equivalent)
• This PR standardizes monitoring for Phase 1 producers only; follow-ups will migrate additional run types into the unified pattern.
⸻
Spec / Docs
• SpecKit artifacts added under specs/053-unify-runs-monitoring/
• Checklists are complete:
• requirements checklist PASS
• writing checklist PASS
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #60
Status Update
Committed the async “Add selected” flow: job-only handler, deterministic run reuse, sanitized failure tracking, observation updates, and the new BulkOperationService/Progress test coverage.
All relevant tasks in tasks.md are marked done, and the checklist under requirements.md is fully satisfied (PASS).
Ran ./vendor/bin/pint --dirty plus BackupSetPolicyPickerTableTest.php—all green.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #59
Summary
Adds a tenant-scoped Entra Groups “Directory Cache” to enable DB-only group name resolution across the app (no render-time Graph calls), plus sync runs + observability.
What’s included
• Entra Groups cache
• New entra_groups storage (tenant-scoped) for group metadata (no memberships).
• Retention semantics: groups become stale / retained per spec (no hard delete on first miss).
• Group Sync Runs
• New “Group Sync Runs” UI (list + detail) with tenant isolation (403 on cross-tenant access).
• Manual “Sync Groups” action: creates/reuses a run, dispatches job, DB notification with “View run” link.
• Scheduled dispatcher command wired in console.php.
• DB-only label resolution (US3)
• Shared EntraGroupLabelResolver with safe fallback Unresolved (…last8) and UUID guarding.
• Refactors to prefer cached names (no typeahead / no live Graph) in:
• Tenant RBAC group selects
• Policy version assignments widget
• Restore results + restore wizard group mapping labels
Safety / Guardrails
• No render-time Graph calls: fail-hard guard test verifies UI paths don’t call GraphClientInterface during page render.
• Tenant isolation & authorization: policies + scoped queries enforced (cross-tenant access returns 403, not 404).
• Data minimization: only group metadata is cached (no membership/owners).
Tests / Verification
• Added/updated tests under tests/Feature/DirectoryGroups and tests/Unit/DirectoryGroups:
• Start sync → run record + job dispatch + upserts
• Retention purge semantics
• Scheduled dispatch wiring
• Render-time Graph guard
• UI/resource access isolation
• Ran:
• ./vendor/bin/pint --dirty
• ./vendor/bin/sail artisan test tests/Feature/DirectoryGroups
• ./vendor/bin/sail artisan test tests/Unit/DirectoryGroups
Notes / Follow-ups
• UI polish remains (picker/lookup UX, consistent progress widget/toasts across modules, navigation grouping).
• pr-gate checklist still has non-blocking open items (mostly UX/ops polish); requirements gate is green.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #57
Summary
This PR implements Spec 049 – Backup/Restore Job Orchestration: all critical Backup/Restore execution paths are job-only, idempotent, tenant-scoped, and observable via run records + DB notifications (Phase 1). The UI no longer performs heavy Graph work inside request/Filament actions for these flows.
Why
We want predictable UX and operations at MSP scale:
• no timeouts / long-running requests
• reproducible run state + per-item results
• safe error persistence (no secrets / no token leakage)
• strict tenant isolation + auditability for write paths
What changed
Foundational (Runs + Idempotency + Observability)
• Added a shared RunIdempotency helper (dedupe while queued/running).
• Added a read-only BulkOperationRuns surface (list + view) for status/progress.
• Added DB notifications for run status changes (with “View run” link).
US1 – Policy “Capture snapshot” is job-only
• Policy detail “Capture snapshot” now:
• creates/reuses a run (dedupe key: tenant + policy.capture_snapshot + policy DB id)
• dispatches a queued job
• returns immediately with notification + link to run detail
• Graph capture work moved fully into the job; request path stays Graph-free.
US3 – Restore runs orchestration is job-only + safe
• Live restore execution is queued and updates RestoreRun status/progress.
• Per-item outcomes are persisted deterministically (per internal DB record).
• Audit logging is written for live restore.
• Preview/dry-run is enforced as read-only (no writes).
Tenant isolation / authorization (non-negotiable)
• Run list/view/start are tenant-scoped and policy-guarded (cross-tenant access => 403, not 404).
• Explicit Pest tests cover cross-tenant denial and start authorization.
Tests / Verification
• ./vendor/bin/pint --dirty
• Targeted suite (examples):
• policy capture snapshot queued + idempotency tests
• restore orchestration + audit logging + preview read-only tests
• run authorization / tenant isolation tests
Notes / Scope boundaries
• Phase 1 UX = DB notifications + run detail page. A global “progress widget” is tracked as Phase 2 and not required for merge.
• Resilience/backoff is tracked in tasks but can be iterated further after merge.
Review focus
• Dedupe behavior for queued/running runs (reuse vs create-new)
• Tenant scoping & policy gates for all run surfaces
• Restore safety: audit event + preview no-writes
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #56
Feature 048: Backup/Restore UI Graph-Safety (Phase 1)
Dieses PR entfernt Microsoft Graph Calls aus UI-Renderpfaden (Filament/Livewire mount/render/options/typeahead/labels) in den kritischen Backup/Restore Screens und fügt Fail-Hard Guard Tests hinzu, die regressionssicher verhindern, dass UI-Rendering wieder Graph aufruft.
⸻
Motivation
Backup/Restore UI wurde teilweise “fragil”, weil UI-Komponenten (z.B. Group Typeahead/Option Labels) Graph/Entra direkt beim Rendern triggern konnten. Das führt zu:
• langsamen/unstabilen Seiten (429/Timeout/Permissions)
• schwer reproduzierbaren UI-Fehlern im MSP-Scale
• unnötiger Kopplung von “Page render” an Graph-Verfügbarkeit
Ziel: UI muss DB-only rendern; Graph darf nur in Jobs/Run-Execution stattfinden.
⸻
Scope / Changes
1) Restore Wizard: Entfernt Graph-Typeahead & Label-Resolution
• Group Mapping ist jetzt DB-only:
• manuelle GUID Eingabe / Skip
• GUID Validation
• Helper Text, wo die Object ID zu finden ist
• Keine Graph calls mehr in options() / getOptionLabelUsing() / typeahead beim Rendern.
2) Fail-Hard Guard Tests (Graph-Safety)
• Neue Test-Infrastruktur: FailHardGraphClient (GraphClientInterface darf nicht aufgerufen werden)
• Guard Tests als Pest Feature Tests (HTTP GET):
• Backup Sets Index rendert mit fail-hard Graph client
• Restore Wizard Route rendert mit fail-hard Graph client
• Assertions:
• 200 OK
• plus stable UI marker string
• Masking/Fallback Format ist deterministisch: Unresolved (…<last8>)
3) Spec/Plan/Tasks/Checklist
• Spec 048 aktualisiert, Tasks abgehakt
• requirements.md Checklist Gate: PASS
⸻
Out of Scope / Non-Goals
• Kein Umbau der “Execution”-Actions zu Jobs (Capture snapshot, Restore rerun, Dry-Run execution etc.) → eigener Folge-Spec (Phase 2).
• Keine Entra Group Name Resolution (separates Group-Inventory/Cache Feature).
• Keine neuen Tabellen/Migrations in Phase 1.
⸻
How to verify (manual)
Mit absichtlich kaputtem Tenant/Auth (Graph failt):
1. Öffne Backups & Restore → Backup Sets
✅ muss laden (UI render DB-only)
2. Öffne Restore Runs → Create Restore Run (Wizard)
✅ muss laden, kein Group-Typeahead mehr
3. Starte eine Restore Operation
❌ darf fehlschlagen (Graph kaputt) – wichtig ist: Render bleibt stabil, Run zeigt Fehler sauber pro Item.
⸻
Tests / Validation
Executed:
• ./vendor/bin/pint --dirty ✅
• ./vendor/bin/sail artisan test tests/Feature/Filament/BackupSetGraphSafetyTest.php tests/Feature/Filament/RestoreWizardGraphSafetyTest.php ✅
• (optional) Combined targeted suite ✅
⸻
Notes
• This PR intentionally focuses on UI Graph-Safety only.
• Any future reintroduction of Graph search/typeahead in UI must go through contracts first and be executed asynchronously, never in UI render paths.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #55
Ordering + limit-only Test für created_at DESC in DependencyExtractionFeatureTest.php
UI Test für masked Identifier (ID: 123456…) + Guest-Access blocked in InventoryItemDependenciesTest.php
Quickstart ergänzt um manuellen <2s Check in quickstart.md
pr-gate Checkbox-Format normalisiert (kein leading space) in pr-gate.md
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #49
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