feat/047-inventory-foundations-nodes #52

Closed
ahmido wants to merge 6 commits from feat/047-inventory-foundations-nodes into dev
Owner

Summary

Dieses PR erweitert den Inventory-Sync um Foundation Nodes (Intune “Foundations”), damit Abhängigkeiten (Dependencies) lokal und deterministisch aufgelöst werden können – ohne UI-Graph-Lookups.

Kernidee: Foundations werden (optional) als InventoryItem-Rows gespeichert, damit Dependencies UI z.B. Scope Tags und Assignment Filters mit Namen anzeigen kann.

Scope / What’s included

Inventory Sync: Foundations als Inventory Items
• Foundations werden nur synchronisiert, wenn include_foundations=true.
• Foundations werden nicht gelöscht, wenn sie später nicht mehr gesehen werden → sie werden über last_seen_* implizit stale.
• Run-Counts sind deterministisch:
• include_foundations=true ⇒ items_observed_count/items_upserted_count beinhalten Foundations
• include_foundations=false ⇒ Counts enthalten nur Policies

Data minimization / Safety
• Foundation meta_jsonb bleibt sanitized:
• Invariant: meta_jsonb == InventoryMetaSanitizer::sanitize(meta_jsonb)
• Guard: json_encode(meta_jsonb) enthält kein Bearer / Token-Artefakte

UI: Inventory Sync Button / Toggles
• Inventory Sync UI enthält jetzt include_foundations Toggle (Default: true)
• (include_dependencies bleibt optional wie bisher)

Dependencies UI: DB-only Name Resolution (keine UI-Graph Calls)
• Dependencies UI löst Foundation-Targets nur via DB auf (z.B. Scope Tag / Assignment Filter)
• Entra Group Name Resolution bleibt out of scope (external groups bleiben maskiert, z.B. Group (external): abcd12…)
• Guardrail: Es existiert ein Test, der hart fehlschlägt, wenn beim UI-Rendering ein Graph Call erfolgt

Out of scope / Non-Goals
• Keine Entra /groups Lookups für Gruppennamen (separates “Group Inventory” Feature)
• Kein Purge/Hard-Delete von Foundation Inventory Items
• Kein UI-Polish/Redesign (Landingpage etc.) – bewusst getrennt

Tests & Verification

Ran locally
• ./vendor/bin/pint --dirty
• ./vendor/bin/sail test tests/Feature/Inventory/InventorySyncServiceTest.php
• ./vendor/bin/sail test tests/Feature/InventoryItemDependenciesTest.php
• (falls vorhanden) ./vendor/bin/sail test tests/Feature/Filament/InventoryPagesTest.php

Key test coverage
• include_foundations true/false (Upserts + Counts)
• meta_jsonb sanitizer equality + “Bearer ” guard
• FR-006 guard: UI rendering does not call GraphClientInterface

Manual UI testing (quick)
1. Inventory → Run Inventory Sync
• Run mit include_foundations=true
• Erwartung: Foundations erscheinen (Category “Foundations”), Dependencies zeigen Namen wo möglich
2. Run erneut mit include_foundations=false
• Erwartung: Foundations bleiben sichtbar (stale via last_seen), aber Run-Counts enthalten sie nicht
3. Open Inventory Item → Dependencies
• Erwartung: Scope Tags / Assignment Filters werden als Name oder “Unresolved (…)” angezeigt, externe Gruppen bleiben maskiert.

Notes
• Dieses PR ist “Spec-first” (Specs/Plan/Tasks/Checklist vorhanden und abgehakt).
• Keine neuen DB-Tabellen nötig; nutzt bestehende Inventory-Struktur und Sanitizer-Regeln.

Summary Dieses PR erweitert den Inventory-Sync um Foundation Nodes (Intune “Foundations”), damit Abhängigkeiten (Dependencies) lokal und deterministisch aufgelöst werden können – ohne UI-Graph-Lookups. Kernidee: Foundations werden (optional) als InventoryItem-Rows gespeichert, damit Dependencies UI z.B. Scope Tags und Assignment Filters mit Namen anzeigen kann. ⸻ Scope / What’s included Inventory Sync: Foundations als Inventory Items • Foundations werden nur synchronisiert, wenn include_foundations=true. • Foundations werden nicht gelöscht, wenn sie später nicht mehr gesehen werden → sie werden über last_seen_* implizit stale. • Run-Counts sind deterministisch: • include_foundations=true ⇒ items_observed_count/items_upserted_count beinhalten Foundations • include_foundations=false ⇒ Counts enthalten nur Policies Data minimization / Safety • Foundation meta_jsonb bleibt sanitized: • Invariant: meta_jsonb == InventoryMetaSanitizer::sanitize(meta_jsonb) • Guard: json_encode(meta_jsonb) enthält kein Bearer / Token-Artefakte UI: Inventory Sync Button / Toggles • Inventory Sync UI enthält jetzt include_foundations Toggle (Default: true) • (include_dependencies bleibt optional wie bisher) Dependencies UI: DB-only Name Resolution (keine UI-Graph Calls) • Dependencies UI löst Foundation-Targets nur via DB auf (z.B. Scope Tag / Assignment Filter) • Entra Group Name Resolution bleibt out of scope (external groups bleiben maskiert, z.B. Group (external): abcd12…) • Guardrail: Es existiert ein Test, der hart fehlschlägt, wenn beim UI-Rendering ein Graph Call erfolgt ⸻ Out of scope / Non-Goals • Keine Entra /groups Lookups für Gruppennamen (separates “Group Inventory” Feature) • Kein Purge/Hard-Delete von Foundation Inventory Items • Kein UI-Polish/Redesign (Landingpage etc.) – bewusst getrennt ⸻ Tests & Verification Ran locally • ./vendor/bin/pint --dirty ✅ • ./vendor/bin/sail test tests/Feature/Inventory/InventorySyncServiceTest.php ✅ • ./vendor/bin/sail test tests/Feature/InventoryItemDependenciesTest.php ✅ • (falls vorhanden) ./vendor/bin/sail test tests/Feature/Filament/InventoryPagesTest.php ✅ Key test coverage • include_foundations true/false (Upserts + Counts) • meta_jsonb sanitizer equality + “Bearer ” guard • FR-006 guard: UI rendering does not call GraphClientInterface ⸻ Manual UI testing (quick) 1. Inventory → Run Inventory Sync • Run mit include_foundations=true • Erwartung: Foundations erscheinen (Category “Foundations”), Dependencies zeigen Namen wo möglich 2. Run erneut mit include_foundations=false • Erwartung: Foundations bleiben sichtbar (stale via last_seen), aber Run-Counts enthalten sie nicht 3. Open Inventory Item → Dependencies • Erwartung: Scope Tags / Assignment Filters werden als Name oder “Unresolved (…)” angezeigt, externe Gruppen bleiben maskiert. ⸻ Notes • Dieses PR ist “Spec-first” (Specs/Plan/Tasks/Checklist vorhanden und abgehakt). • Keine neuen DB-Tabellen nötig; nutzt bestehende Inventory-Struktur und Sanitizer-Regeln.
ahmido added 5 commits 2026-01-10 20:50:50 +00:00
ahmido added 1 commit 2026-01-10 20:51:32 +00:00
Author
Owner

“Already merged via #51 / already in dev”.

“Already merged via #51 / already in dev”.
ahmido closed this pull request 2026-01-10 20:52:56 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ahmido/TenantAtlas#52
No description provided.