# 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`
