# Implementation Plan: App Protection Policy Type (009) **Branch**: `feat/009-app-protection-policy` **Date**: 2025-12-29 **Spec Source**: [spec.md](./spec.md) ## Summary Make `appProtectionPolicy` reliable by: - Filtering non-policy objects during sync (`targetedManagedAppConfiguration`). - Adding Graph contract coverage for assignments + `@odata.type` family. - Adding targeted Pest tests to lock in behavior. ## Execution Steps 1. Update `config/graph_contracts.php` for `appProtectionPolicy`: - Add assignments list + assign action endpoints (and payload key if needed). - Expand `type_family` to the common App Protection `@odata.type` values. 2. Update `app/Services/Intune/PolicySyncService.php`: - Skip `#microsoft.graph.targetedManagedAppConfiguration` entries when syncing `appProtectionPolicy`. 3. Fix restore endpoints for assignments + policy updates: - Use derived endpoints (e.g. `/androidManagedAppProtections/{id}` and `/androidManagedAppProtections/{id}/assign`) based on `@odata.type`. 4. Add admin-friendly normalization: - Add `AppProtectionPolicyNormalizer` for boolean/duration formatting and Intune-like sections. 5. Add/extend tests: - `tests/Unit/GraphContractRegistryActualDataTest.php` for `appProtectionPolicy` contract coverage. - `tests/Feature/Jobs/*` to assert sync filtering behavior. - `tests/Unit/*` to assert normalizer output and endpoint resolution. 6. Run formatting + tests: - `./vendor/bin/pint --dirty` - `./vendor/bin/sail artisan test --filter=appProtectionPolicy`