150 lines
6.8 KiB
Markdown
150 lines
6.8 KiB
Markdown
---
|
||
|
||
description: "Task list for Graph Contracts — LIST $expand Parity Fix"
|
||
---
|
||
|
||
# Tasks: Graph Contracts — LIST `$expand` Parity Fix
|
||
|
||
**Input**: Design documents from `specs/112-list-expand-parity/`
|
||
|
||
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
|
||
|
||
**Tests**: REQUIRED (Pest) — this feature changes runtime Graph request shapes.
|
||
|
||
## Phase 1: Setup (Shared)
|
||
|
||
**Purpose**: Confirm inputs and establish a baseline before changing runtime behavior.
|
||
|
||
- [X] T001 [Shared] Read implementation plan in specs/112-list-expand-parity/plan.md
|
||
- [X] T002 [P] [Shared] Verify $expand allowlist exists for Entra role assignments in config/graph_contracts.php
|
||
- [X] T003 [P] [Shared] Identify existing Graph tests to extend in tests/Unit/GraphContractRegistryTest.php and tests/Unit/MicrosoftGraphClientListPoliciesSelectTest.php
|
||
|
||
---
|
||
|
||
## Phase 2: Foundational (Blocking Prerequisites)
|
||
|
||
**Purpose**: Establish pre-change confidence and shared test baseline.
|
||
|
||
- [X] T004 [Shared] Run baseline focused tests listed in specs/112-list-expand-parity/quickstart.md
|
||
|
||
**Checkpoint**: Baseline established; safe to implement.
|
||
|
||
---
|
||
|
||
## Phase 3: User Story 1 — Admin roles report shows real principal names (Priority: P1) 🎯 MVP
|
||
|
||
**Goal**: Admin Roles report requests `principal` expansion and renders real principal display names when Graph provides them.
|
||
|
||
**Independent Test**: Simulate role assignment list retrieval and assert report output uses `principal.displayName` when present, else falls back to `Unknown`.
|
||
|
||
### Tests for User Story 1
|
||
|
||
- [X] T005 [P] [US1] Create report service test scaffolding in tests/Unit/EntraAdminRolesReportServiceTest.php (RefreshDatabase + mock GraphClientInterface)
|
||
- [X] T006 [US1] Implement tests asserting `entraRoleAssignments` call includes `expand => 'principal'` and payload uses principal display name in tests/Unit/EntraAdminRolesReportServiceTest.php
|
||
|
||
### Implementation for User Story 1
|
||
|
||
- [X] T007 [US1] Pass `expand => 'principal'` when fetching assignments in app/Services/EntraAdminRoles/EntraAdminRolesReportService.php
|
||
- [X] T008 [US1] Forward caller-provided `expand` into LIST query input in app/Services/Graph/MicrosoftGraphClient.php
|
||
- [X] T009 [US1] Normalize + cap `$expand` in app/Services/Graph/GraphContractRegistry.php (split string on top-level commas only; preserve commas inside balanced parentheses; trim, drop empty, dedupe, maxTokenLen=200, maxItems=10 after allowlist)
|
||
|
||
### Regression tests for User Story 1
|
||
|
||
- [X] T010 [US1] Add LIST `$expand` request-shape test coverage in tests/Unit/MicrosoftGraphClientListPoliciesSelectTest.php
|
||
- [X] T011 [US1] Add `$expand` normalization/cap test coverage in tests/Unit/GraphContractRegistryTest.php
|
||
- [X] T012 [US1] Run story tests in tests/Unit/EntraAdminRolesReportServiceTest.php plus Graph tests in tests/Unit/MicrosoftGraphClientListPoliciesSelectTest.php
|
||
|
||
**Checkpoint**: Entra Admin Roles report can render real principal names when upstream provides them.
|
||
|
||
---
|
||
|
||
## Phase 4: User Story 2 — Engineers can request explicit LIST expansions safely (Priority: P2)
|
||
|
||
**Goal**: LIST supports explicit expansions safely and discoverably (document option shape, allowlist enforcement).
|
||
|
||
**Independent Test**: Inspect outgoing LIST request and confirm `$expand` is included only when explicitly provided and allowlisted.
|
||
|
||
### Tests for User Story 2
|
||
|
||
- [X] T013 [P] [US2] Add test asserting LIST omits `$expand` when `expand` is not provided in tests/Unit/MicrosoftGraphClientListPoliciesSelectTest.php
|
||
- [X] T014 [P] [US2] Add tests asserting (a) disallowed expand tokens are removed (exact-match allowlist, no partial matches) and (b) allowlisted subquery/select-style expand tokens that contain commas inside parentheses are preserved as a single token (no naive comma-splitting) in tests/Unit/GraphContractRegistryTest.php
|
||
|
||
### Implementation for User Story 2
|
||
|
||
- [X] T015 [US2] Document supported `listPolicies()` options (select/expand/filter/top/platform + input shapes) in app/Services/Graph/GraphClientInterface.php
|
||
- [X] T016 [US2] Ensure `GraphContractCheck` query shape remains compatible (select + expand) in app/Console/Commands/GraphContractCheck.php
|
||
|
||
**Checkpoint**: Engineers can safely request allowlisted expansions on LIST without silent capability mismatch.
|
||
|
||
---
|
||
|
||
## Phase 5: User Story 3 — Misuse is detectable in non-production (Priority: P3)
|
||
|
||
**Goal**: When `$expand` is sanitized (removed or truncated), maintainers get a diagnostic signal in non-production with low noise in production.
|
||
|
||
**Independent Test**: Trigger mixed allowed/disallowed expand and assert a non-production warning is emitted with policy type + removed values.
|
||
|
||
### Tests for User Story 3
|
||
|
||
- [X] T017 [US3] Add Log::spy-based test for non-production diagnostics when `$expand` is sanitized in tests/Unit/GraphContractRegistryTest.php
|
||
- [X] T018 [US3] Add production-noise guard test (debug-level or suppressed warn) for `$expand` sanitization in tests/Unit/GraphContractRegistryTest.php
|
||
|
||
### Implementation for User Story 3
|
||
|
||
- [X] T019 [US3] Emit structured diagnostic logs when `$expand` is removed/truncated in app/Services/Graph/GraphContractRegistry.php
|
||
|
||
**Checkpoint**: Sanitization is visible during dev/staging without spamming production logs.
|
||
|
||
---
|
||
|
||
## Phase 6: Polish & Cross-Cutting Concerns
|
||
|
||
**Purpose**: Keep the change safe, consistent, and shippable.
|
||
|
||
- [X] T020 [Shared] Run formatting on touched files (Pint) after changes in app/Services/Graph/GraphContractRegistry.php
|
||
- [X] T021 [Shared] Run focused suite listed in specs/112-list-expand-parity/quickstart.md
|
||
|
||
---
|
||
|
||
## Dependencies & Execution Order
|
||
|
||
### Phase Dependencies
|
||
|
||
- Setup (Phase 1) → Foundational (Phase 2) → US1 (Phase 3) → US2 (Phase 4) → US3 (Phase 5) → Polish (Phase 6)
|
||
|
||
### User Story Dependencies
|
||
|
||
- US1 depends on LIST `$expand` parity (implemented as part of US1 via app/Services/Graph/MicrosoftGraphClient.php + app/Services/Graph/GraphContractRegistry.php).
|
||
- US2 extends US1 with discoverability + additional safety regression coverage.
|
||
- US3 depends on the sanitization logic (adds diagnostics + tests).
|
||
|
||
### Parallel Opportunities
|
||
|
||
- Phase 1: T002 and T003 can run in parallel.
|
||
- US1: T005 can be done in parallel with T008/T009 (different files).
|
||
- US2: T013 and T014 can run in parallel.
|
||
|
||
---
|
||
|
||
## Parallel Example: User Story 1
|
||
|
||
- In parallel:
|
||
- T005 (test scaffolding) in tests/Unit/EntraAdminRolesReportServiceTest.php
|
||
- T008 (LIST forwards expand) in app/Services/Graph/MicrosoftGraphClient.php
|
||
- T009 (sanitize/normalize/cap expand) in app/Services/Graph/GraphContractRegistry.php
|
||
|
||
---
|
||
|
||
## Implementation Strategy
|
||
|
||
### MVP First (User Story 1 Only)
|
||
|
||
1. Complete Phase 1–2
|
||
2. Complete US1 (Phase 3)
|
||
3. Stop and ship if acceptance + regression tests pass
|
||
|
||
### Then harden (US2 + US3)
|
||
|
||
- Add discoverability + extra regression guards (US2)
|
||
- Add diagnostics behavior + tests (US3)
|