spec: app protection policy coverage (009)
This commit is contained in:
parent
47db966a19
commit
c46a5df243
30
specs/009-app-protection-policy/plan.md
Normal file
30
specs/009-app-protection-policy/plan.md
Normal file
@ -0,0 +1,30 @@
|
||||
# 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`
|
||||
57
specs/009-app-protection-policy/spec.md
Normal file
57
specs/009-app-protection-policy/spec.md
Normal file
@ -0,0 +1,57 @@
|
||||
# Feature Specification: App Protection (MAM) Policy Type Coverage
|
||||
|
||||
**Feature Branch**: `feat/009-app-protection-policy`
|
||||
**Created**: 2025-12-29
|
||||
**Status**: Draft
|
||||
|
||||
## Overview
|
||||
Make **App Protection (MAM)** policies (`appProtectionPolicy`) reliable in TenantAtlas’ existing Policy/Backup/Restore flows by:
|
||||
|
||||
- Preventing **non-policy objects** (Managed App Configurations) from being imported as policies during sync.
|
||||
- Capturing and restoring **assignments** for `managedAppPolicies`.
|
||||
- Expanding the accepted `@odata.type` family so restore/create flows don’t fail with false `odata_mismatch`.
|
||||
- Improving **admin readability** by normalizing key settings (booleans/durations) into Intune-like sections.
|
||||
|
||||
## In Scope
|
||||
- Policy type: `appProtectionPolicy` (`deviceAppManagement/managedAppPolicies`)
|
||||
- Policy sync: skip objects with `@odata.type == #microsoft.graph.targetedManagedAppConfiguration`
|
||||
- Backup/version capture: capture assignments when enabled
|
||||
- Restore: reapply assignments using `/assign` with group + assignment filter mapping (existing mapping UI)
|
||||
- UI: normalize App Protection snapshots for readability (bool/duration formatting + grouped sections)
|
||||
|
||||
## Out of Scope (v1)
|
||||
- “Target apps” (`/targetApps`) workflows for App Protection objects (showing the actual app list like Intune).
|
||||
- Full “create from scratch” for missing App Protection policies (beyond generic create fallback).
|
||||
- Separately modeling App Configurations (`targetedManagedAppConfigurations`) as their own policy type.
|
||||
|
||||
## User Scenarios & Testing *(mandatory)*
|
||||
|
||||
### User Story 1 — Clean Inventory (P1)
|
||||
As an admin, I want the App Protection policy list to only include actual protection policies (not app configurations), so inventory stays accurate.
|
||||
|
||||
**Independent Test**: Run policy sync; confirm `targetedManagedAppConfiguration` objects do not appear as `appProtectionPolicy` records.
|
||||
|
||||
**Acceptance Scenarios**
|
||||
1. Given Graph returns mixed objects from `managedAppPolicies`, when sync runs, then items with `@odata.type == #microsoft.graph.targetedManagedAppConfiguration` are skipped.
|
||||
|
||||
### User Story 2 — Backup assignments (P1)
|
||||
As an admin, I can capture App Protection assignments during backup/version capture, so restore can reproduce targeting.
|
||||
|
||||
**Independent Test**: Capture a backup set with assignments enabled; verify assignments are saved for App Protection policies.
|
||||
|
||||
**Acceptance Scenarios**
|
||||
1. Given assignments are enabled, when capturing an App Protection snapshot, then assignments are fetched via the configured assignments endpoint and stored on the version/item.
|
||||
|
||||
### User Story 3 — Restore assignments (P1)
|
||||
As an admin, I can restore App Protection assignments using group mapping with clear skip/failure reasons.
|
||||
|
||||
**Independent Test**: Restore an App Protection backup into a tenant with different group IDs; verify assignments are created/skipped with expected outcomes.
|
||||
|
||||
**Acceptance Scenarios**
|
||||
1. Given group mapping is present, when restore executes, then assignments are applied via `/assign`.
|
||||
2. Given group mapping is missing for a group, when restore executes, then that assignment is skipped with a clear reason.
|
||||
|
||||
## Notes
|
||||
- Filtering is implemented in code because Graph filtering does not reliably exclude `targetedManagedAppConfiguration` objects from the `managedAppPolicies` list response.
|
||||
- `@odata.type` matching uses `config/graph_contracts.php` as the safety gate for create flows.
|
||||
- Assignments restore uses derived endpoints (e.g. `/deviceAppManagement/androidManagedAppProtections/{id}/assign`) based on `@odata.type` for compatibility.
|
||||
23
specs/009-app-protection-policy/tasks.md
Normal file
23
specs/009-app-protection-policy/tasks.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Tasks: App Protection Policy Type Coverage (009)
|
||||
|
||||
**Branch**: `feat/009-app-protection-policy` | **Date**: 2025-12-29
|
||||
**Input**: [spec.md](./spec.md), [plan.md](./plan.md)
|
||||
|
||||
## Phase 1: Contracts
|
||||
- [ ] T001 Add App Protection assignments endpoints + type family to `config/graph_contracts.php`.
|
||||
|
||||
## Phase 2: Sync filtering
|
||||
- [ ] T002 Filter out `#microsoft.graph.targetedManagedAppConfiguration` during `appProtectionPolicy` sync.
|
||||
|
||||
## Phase 3: Restore endpoint compatibility
|
||||
- [ ] T003 Resolve derived update/assign endpoints for App Protection based on `@odata.type`.
|
||||
|
||||
## Phase 4: UI normalization
|
||||
- [ ] T004 Add `AppProtectionPolicyNormalizer` (booleans/durations + grouped sections).
|
||||
|
||||
## Phase 5: Tests + Verification
|
||||
- [ ] T005 Add contract coverage tests in `tests/Unit/GraphContractRegistryActualDataTest.php`.
|
||||
- [ ] T006 Add sync filtering test in `tests/Feature/Jobs/*`.
|
||||
- [ ] T007 Add unit tests for derived endpoint resolution + normalizer output.
|
||||
- [ ] T008 Run tests (targeted): `./vendor/bin/sail artisan test --filter=appProtectionPolicy`
|
||||
- [ ] T009 Run Pint: `./vendor/bin/pint --dirty`
|
||||
Loading…
Reference in New Issue
Block a user