Kontext / Ziel
Diese PR standardisiert Tenant‑RBAC Enforcement in der Filament‑UI: statt ad-hoc Gate::*, abort_if/abort_unless und kopierten ->visible()/->disabled()‑Closures gibt es jetzt eine zentrale, wiederverwendbare Implementierung für Actions (Header/Table/Bulk).
Links zur Spec:
spec.md
plan.md
quickstart.md
Was ist drin
Neue zentrale Helper-API: UiEnforcement (Tenant-plane RBAC‑UX “source of truth” für Filament Actions)
Standardisierte Tooltip-Texte und Context-DTO (UiTooltips, TenantAccessContext)
Migration vieler tenant‑scoped Filament Action-Surfaces auf das Standardpattern (ohne ad-hoc Auth-Patterns)
CI‑Guard (Test) gegen neue ad-hoc Patterns in app/Filament/**:
verbietet Gate::allows/denies/check/authorize, use Illuminate\Support\Facades\Gate, abort_if/abort_unless
Legacy-Allowlist ist aktuell leer (neue Verstöße failen sofort)
RBAC-UX Semantik (konsequent & testbar)
Non-member: UI Actions hidden (kein Tenant‑Leak); Execution wird blockiert (Filament hidden→disabled chain), Defense‑in‑depth enthält zusätzlich serverseitige Guards.
Member ohne Capability: Action visible aber disabled + Standard-Tooltip; Execution wird blockiert (keine Side Effects).
Member mit Capability: Action enabled und ausführbar.
Destructive actions: über ->destructive() immer mit ->requiresConfirmation() + klare Warntexte (Execution bleibt über ->action(...)).
Wichtig: In Filament v5 sind hidden/disabled Actions typischerweise “silently blocked” (200, keine Ausführung). Die Tests prüfen daher UI‑State + “no side effects”, nicht nur HTTP‑Statuscodes.
Sicherheit / Scope
Keine neuen DB-Tabellen, keine Migrations, keine Microsoft Graph Calls (DB‑only bei Render; kein outbound HTTP).
Tenant Isolation bleibt Isolation‑Boundary (deny-as-not-found auf Tenant‑Ebene, Capability erst nach Membership).
Kein Asset-Setup erforderlich; keine neuen Filament Assets.
Compliance Notes (Repo-Regeln)
Filament v5 / Livewire v4.0+ kompatibel.
Keine Änderungen an Provider‑Registrierung (Laravel 11+/12: providers.php bleibt der Ort; hier unverändert).
Global Search: keine gezielte Änderung am Global‑Search-Verhalten in dieser PR.
Tests / Qualität
Pest Feature/Unit Tests für Member/Non-member/Tooltip/Destructive/Regression‑Guard.
Guard-Test: “No ad-hoc Filament auth patterns”.
Full suite laut Tasks: vendor/bin/sail artisan test --compact → 837 passed, 5 skipped.
Checklist: requirements.md vollständig (16/16).
Review-Fokus
API‑Usage in neuen/angepassten Filament Actions: UiEnforcement::forAction/forTableAction/forBulkAction(...)->requireCapability(...)->apply()
Guard-Test soll “red” werden, sobald jemand neue ad-hoc Auth‑Patterns einführt (by design).
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #81
## Summary
- introduce the Provider Connection Filament resource (list/create/edit) with DB-only controls, grouped action dropdowns, and badge-driven status/health rendering
- wire up the provider foundation stack (migrations, models, policies, providers, operations, badges, and audits) plus the required spec docs/checklists
- standardize Inventory Sync notifications so the job no longer writes its own DB rows; terminal notifications now flow exclusively through OperationRunCompleted while the start surface still shows the queued toast
## Testing
- ./vendor/bin/sail php ./vendor/bin/pint --dirty
- ./vendor/bin/sail artisan test tests/Unit/Badges/ProviderConnectionBadgesTest.php
- ./vendor/bin/sail artisan test tests/Feature/ProviderConnections tests/Feature/Filament/ProviderConnectionsDbOnlyTest.php
- ./vendor/bin/sail artisan test tests/Feature/Inventory/RunInventorySyncJobTest.php tests/Feature/Inventory/InventorySyncStartSurfaceTest.php
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #73
Summary:
completes Feature 060 by adding the suite-wide TagBadge catalog (spec/domain/renderer) plus migration notes/tests/docs/specs/plan/checklist.
standardizes all inert “tag-like” badges (policy type/category/platform, tenant environment, backup schedule frequency, etc.) to use the new catalog so only neutral colors are emitted.
fixes remaining Feature 059 regressions (inventory run/restore badges, Inventory Coverage tables, Boolean-enabled streak) and adds the BooleanEnabled badge mappings/guards/tests plus new QA tasks/checklist.
Testing:
BooleanEnabledBadgesTest.php
PolicyGeneralViewTest.php
PolicySettingsStandardViewTest.php
SettingsCatalogPolicyNormalizedDisplayTest.php
PolicyViewSettingsCatalogReadableTest.php (partial/visual checks skipped)
TagBadgeCatalogTest.php
TagBadgePaletteInvariantTest.php
NoForbiddenTagBadgeColorsTest.php
NoAdHocStatusBadgesTest.php
Manual QA per quickstart.md confirmed.
Next steps:
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #72
## 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
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 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
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
expose enrollment config subtypes as their own policy types (limit/platform restrictions/notifications) with preview-only restore risk and proper Graph contracts
classify enrollment configs by their @odata.type + deviceEnrollmentConfigurationType so sync only keeps ESP in windowsEnrollmentStatusPage and the rest stay in their own types, including new restore-normalizer UI blocks + warnings
hydrate enrollment notifications: snapshot fetch now downloads each notification template + localized messages, normalized view surfaces template names/subjects/messages, and restore previews keep preview-only behavior
tenant UI tweaks: Tenant list and detail actions moved into an action group; “Open in Entra” re-added in index, and detail now has “Deactivate” + tests covering the new menu layout and actions
tests added/updated for sync, snapshots, restores, normalized settings, tenant UI, plus Pint/test suite run
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #31
Added termsAndConditions to the supported policy list and Graph contract so Intune sync/backup/restore paths (and scope tag handling) treat Terms & Conditions like other enrollment policies, ensuring listings, snapshots, assignments CRUD, and restore modes flow naturally (tenantpilot.php (lines 168-225), graph_contracts.php (lines 520-560), InteractsWithODataTypes.php (lines 10-30)).
Exposed a dedicated TermsAndConditionsNormalizer and tagged it in AppServiceProvider so the Filament UI shows readable rows (display name, title, acceptance statement, body, scope tags) and the diff engine flattens them consistently (TermsAndConditionsNormalizer.php (lines 1-94), AppServiceProvider.php (lines 43-58)).
Added Pest coverage for the new type that checks config/contract entries, assignment restore behavior, normalized output, and PolicySync ingestion (TermsAndConditionsPolicyTypeTest.php (lines 70-200)).
Tests:
TermsAndConditionsPolicyTypeTest.php
./vendor/bin/pint --dirty
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #30
tenantpilot.php/graph_contracts.php include the new policy type, Graph contract, and /assign assignment flow (deviceHealthScriptAssignments payload key).
ScriptsPolicyNormalizer now supports deviceComplianceScript (more metadata + script display), and InteractsWithODataTypes knows the new type.
UI diff view highlights detection-script changes (same logic as other script policies) once tenantpilot.display.show_script_content is enabled.
Added regression coverage in tests/Feature/Filament/ScriptPoliciesNormalizedDisplayTest plus new feature test DeviceComplianceScriptPolicyTypeTest.
Runs: ScriptPoliciesNormalizedDisplayTest.php, ./vendor/bin/pint --dirty.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #29
Created a safe session branch, committed everything, fast-forward merged back into feat/012-windows-update-rings, then pushed.
Commit: 074a656 feat(rings): update rings + update profiles
Push is done; upstream tracking is se
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #18
Wichtige Änderungen:
- Eine neue "Restore via Wizard"-Aktion wurde der PolicyVersion-Tabelle hinzugefügt.
- Diese Aktion ermöglicht die Erstellung eines Einzelposten-BackupSets aus dem ausgewählten
Policy-Version-Snapshot.
- Der CreateRestoreRun Wizard unterstützt nun das Vorbefüllen seiner Formularfelder basierend auf
Abfrageparametern, was eine nahtlose Übergabe von der PolicyVersion-Aktion ermöglicht.
- Umfassende Feature-Tests wurden hinzugefügt, um die korrekte Funktionalität und Integration dieses
neuen Workflows sicherzustellen.
- Die specs/011-restore-run-wizard/tasks.md wurde aktualisiert, um den Abschluss von Aufgabe T023
widerzuspiegeln.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #17
Resolves assignment filter names when Graph stores filter IDs at assignment root.
Tracks assignment fetch success/failure and shows clearer UI states for versions.
Adds scope tag fallback display in backup set items.
Restored versions now capture applied assignments consistently.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #8