## Summary <!-- Kurz: Was ändert sich und warum? --> ## Spec-Driven Development (SDD) - [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/` - [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md` - [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation) - [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert ## Implementation - [ ] Implementierung entspricht der Spec - [ ] Edge cases / Fehlerfälle berücksichtigt - [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes ## Tests - [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit) - [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`) ## Migration / Config / Ops (falls relevant) - [ ] Migration(en) enthalten und getestet - [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration) - [ ] Neue Env Vars dokumentiert (`.env.example` / Doku) - [ ] Queue/cron/storage Auswirkungen geprüft ## UI (Filament/Livewire) (falls relevant) - [ ] UI-Flows geprüft - [ ] Screenshots/Notizen hinzugefügt ## Notes <!-- Links, Screenshots, Follow-ups, offene Punkte --> Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local> Reviewed-on: #4
7.6 KiB
Feature 005: Policy Lifecycle Management
Overview
Implement proper lifecycle management for policies that are deleted in Intune, including soft delete, UI indicators, and orphaned policy handling.
Problem Statement
Currently, when a policy is deleted in Intune:
- ❌ Policy remains in TenantAtlas database indefinitely
- ❌ No indication that policy no longer exists in Intune
- ❌ Backup Items reference "ghost" policies
- ❌ Users cannot distinguish between active and deleted policies
Discovered during: Feature 004 manual testing (user deleted policy in Intune)
Goals
- Primary: Implement soft delete for policies removed from Intune
- Secondary: Show clear UI indicators for deleted policies
- Tertiary: Maintain referential integrity for Backup Items and Policy Versions
Scope
- Policy Sync: Detect missing policies during
SyncPoliciesJob - Data Model: Add
deleted_at,deleted_bycolumns (Laravel Soft Delete pattern) - UI: Badge indicators, filters, restore capability
- Audit: Log when policies are soft-deleted and restored
User Stories
User Story 1 - Automatic Soft Delete on Sync
As a system administrator, I want policies deleted in Intune to be automatically marked as deleted in TenantAtlas, so that the inventory reflects the current Intune state.
Acceptance Criteria:
-
Given a policy exists in TenantAtlas with
external_id"abc-123", When the next policy sync runs and "abc-123" is NOT returned by Graph API, Then the policy is soft-deleted (setsdeleted_at = now()) -
Given a soft-deleted policy, When it re-appears in Intune (same
external_id), Then the policy is automatically restored (deleted_at = null) -
Given multiple policies are deleted in Intune, When sync runs, Then all missing policies are soft-deleted in a single transaction
User Story 2 - UI Indicators for Deleted Policies
As an admin, I want to see clear indicators when viewing deleted policies, so I understand their status.
Acceptance Criteria:
-
Given I view a Backup Item referencing a deleted policy, When I see the policy name, Then it shows a red "Deleted" badge next to the name
-
Given I view the Policies list, When I enable the "Show Deleted" filter, Then deleted policies appear with:
- Red "Deleted" badge
- Deleted date in "Last Synced" column
- Grayed-out appearance
-
Given a policy was deleted, When I view the Policy detail page, Then I see:
- Warning banner: "This policy was deleted from Intune on {date}"
- All data remains readable (versions, snapshots, metadata)
User Story 3 - Restore Workflow
As an admin, I want to restore a deleted policy from backup, so I can recover accidentally deleted configurations.
Acceptance Criteria:
-
Given I view a deleted policy's detail page, When I click the "Restore to Intune" action, Then the restore wizard opens pre-filled with the latest policy snapshot
-
Given a policy is successfully restored to Intune, When the next sync runs, Then the policy is automatically undeleted in TenantAtlas (
deleted_at = null)
Functional Requirements
Data Model
FR-005.1: Policies table MUST use Laravel Soft Delete pattern:
Schema::table('policies', function (Blueprint $table) {
$table->softDeletes(); // deleted_at
$table->string('deleted_by')->nullable(); // admin email who triggered deletion
});
FR-005.2: Policy model MUST use SoftDeletes trait:
use Illuminate\Database\Eloquent\SoftDeletes;
class Policy extends Model {
use SoftDeletes;
}
Policy Sync Behavior
FR-005.3: PolicySyncService::syncPolicies() MUST detect missing policies:
- Collect all
external_idvalues returned by Graph API - Query existing policies for this tenant:
whereNotIn('external_id', $currentExternalIds) - Soft delete missing policies:
each(fn($p) => $p->delete())
FR-005.4: System MUST restore policies that re-appear:
- Check if policy exists with
Policy::withTrashed()->where('external_id', $id)->first() - If soft-deleted: call
$policy->restore() - Update
last_synced_attimestamp
FR-005.5: System MUST log audit entries:
policy.deleted(when soft-deleted during sync)policy.restored(when re-appears in Intune)
UI Display
FR-005.6: PolicyResource table MUST:
- Default query: exclude soft-deleted policies
- Add filter "Show Deleted" (includes
withTrashed()in query) - Show "Deleted" badge for soft-deleted policies
FR-005.7: BackupItemsRelationManager MUST:
- Show "Deleted" badge when
policy->trashed()returns true - Allow viewing deleted policy details (read-only)
FR-005.8: Policy detail view MUST:
- Show warning banner when policy is soft-deleted
- Display deletion date and reason (if available)
- Disable edit actions (policy no longer exists in Intune)
Non-Functional Requirements
NFR-005.1: Soft delete MUST NOT break existing features:
- Backup Items keep valid foreign keys
- Policy Versions remain accessible
- Restore functionality works for deleted policies
NFR-005.2: Performance: Sync detection MUST NOT cause N+1 queries:
- Use single
whereNotIn()query to find missing policies - Batch soft-delete operation
NFR-005.3: Data retention: Soft-deleted policies MUST be retained for audit purposes (no automatic purging)
Implementation Plan
Phase 1: Data Model (30 min)
- Create migration for
policiessoft delete columns - Add
SoftDeletestrait to Policy model - Run migration on dev environment
Phase 2: Sync Logic (1 hour)
- Update
PolicySyncService::syncPolicies()- Track current external IDs from Graph
- Soft delete missing policies
- Restore re-appeared policies
- Add audit logging
- Test with manual deletion in Intune
Phase 3: UI Indicators (1.5 hours)
- Update
PolicyResource:- Add "Show Deleted" filter
- Add "Deleted" badge column
- Modify query to exclude deleted by default
- Update
BackupItemsRelationManager:- Show "Deleted" badge for
policy->trashed()
- Show "Deleted" badge for
- Update Policy detail view:
- Warning banner for deleted policies
- Disable edit actions
Phase 4: Testing (1 hour)
- Unit tests:
- Test soft delete on sync
- Test restore on re-appearance
- Feature tests:
- E2E sync with deleted policies
- UI filter behavior
- Manual QA:
- Delete policy in Intune → sync → verify soft delete
- Re-create policy → sync → verify restore
Total Estimated Duration: ~4-5 hours
Risks & Mitigations
| Risk | Mitigation |
|---|---|
| Foreign key constraints block soft delete | Laravel soft delete only sets timestamp, constraints remain valid |
| Bulk delete impacts performance | Use chunked queries if tenant has 1000+ policies |
| Deleted policies clutter UI | Default filter hides them, "Show Deleted" is opt-in |
Success Criteria
- ✅ Policies deleted in Intune are soft-deleted in TenantAtlas within 1 sync cycle
- ✅ Re-appearing policies are automatically restored
- ✅ UI clearly indicates deleted status
- ✅ Backup Items and Versions remain accessible for deleted policies
- ✅ No breaking changes to existing features
Related Features
- Feature 004: Assignments & Scope Tags (discovered this issue during testing)
- Feature 001: Backup/Restore (must work with deleted policies)
Status: Planned (Post-Feature 004)
Priority: P2 (Quality of Life improvement)
Created: 2025-12-22
Author: AI + Ahmed
Next Steps: Implement after Feature 004 Phase 3 testing complete