241 lines
8.8 KiB
Markdown
241 lines
8.8 KiB
Markdown
# Feature 185: Intune-like "Cleartext Settings" on Policy View
|
|
|
|
## Overview
|
|
Display Settings Catalog policies in Policy View with human-readable setting names, descriptions, and formatted values—similar to Intune Portal experience—instead of raw JSON and definition IDs.
|
|
|
|
## Problem Statement
|
|
Admins cannot effectively work with Settings Catalog policies when they only see:
|
|
- `settingDefinitionId` strings (e.g., `device_vendor_msft_passportforwork_biometrics_usebiometrics`)
|
|
- Raw JSON structures
|
|
- Choice values as GUIDs or internal strings
|
|
|
|
This makes policy review, audit, and troubleshooting extremely difficult.
|
|
|
|
## Goals
|
|
- **Primary**: Render Settings Catalog policies with display names, descriptions, grouped settings, and formatted values
|
|
- **Secondary**: Keep raw JSON available for audit/restore workflows
|
|
- **Tertiary**: Gracefully degrade when definition metadata is unavailable
|
|
|
|
## User Stories
|
|
|
|
### P1: US-UI-04 - Admin Views Readable Settings
|
|
**As an** Intune admin
|
|
**I want to** see policy settings with human-readable names and descriptions
|
|
**So that** I can understand what the policy configures without reading raw JSON
|
|
|
|
**Acceptance Criteria:**
|
|
- Display name shown for each setting (not definition ID)
|
|
- Description/help text visible on hover or expand
|
|
- Values formatted appropriately (True/False, numbers, choice labels)
|
|
- Settings grouped by category/section
|
|
|
|
### P2: US-UI-05 - Admin Searches/Filters Settings
|
|
**As an** Intune admin
|
|
**I want to** search and filter settings by name or value
|
|
**So that** I can quickly find specific configurations in large policies
|
|
|
|
**Acceptance Criteria:**
|
|
- Search box filters settings list
|
|
- Search works on display name and value
|
|
- Results update instantly
|
|
- Clear search resets view
|
|
|
|
### P3: US-UI-06 - Admin Accesses Raw JSON When Needed
|
|
**As an** Intune admin or auditor
|
|
**I want to** switch to raw JSON view
|
|
**So that** I can see the exact Graph API payload for audit/restore
|
|
|
|
**Acceptance Criteria:**
|
|
- Tab navigation between "Settings" and "JSON" views
|
|
- JSON view shows complete policy snapshot
|
|
- JSON view includes copy-to-clipboard
|
|
- Settings view is default
|
|
|
|
## Functional Requirements
|
|
|
|
### FR-185.1: Setting Definition Resolver Service
|
|
- **Input**: Array of `settingDefinitionId` (including children from group settings)
|
|
- **Output**: Map of `{definitionId => {displayName, description, helpText, categoryId, uxBehavior, ...}}`
|
|
- **Strategy**:
|
|
- Fetch from Graph API settingDefinitions endpoints
|
|
- Cache in database (`settings_catalog_definitions` table)
|
|
- Memory cache for request-level performance
|
|
- Fallback to prettified ID if definition not found
|
|
|
|
### FR-185.2: Database Schema for Definition Cache
|
|
**Table**: `settings_catalog_definitions`
|
|
- `id` (bigint, PK)
|
|
- `definition_id` (string, unique, indexed)
|
|
- `display_name` (string)
|
|
- `description` (text, nullable)
|
|
- `help_text` (text, nullable)
|
|
- `category_id` (string, nullable)
|
|
- `ux_behavior` (string, nullable)
|
|
- `raw` (jsonb) - full Graph response
|
|
- `timestamps`
|
|
|
|
### FR-185.3: Snapshot Enrichment (Non-Blocking)
|
|
- After hydrating `/configurationPolicies/{id}/settings`
|
|
- Extract all `settingDefinitionId` + children
|
|
- Call resolver to warm cache
|
|
- Store render hints in snapshot metadata: `definitions_cached: true/false`, `definition_count: N`
|
|
|
|
### FR-185.4: PolicyNormalizer Enhancement
|
|
- For `settingsCatalogPolicy` type:
|
|
- Output: `settings_groups[]` = `{title, description?, rows[]}`
|
|
- Each row: `{label, helpText?, value_display, value_raw, definition_id, instance_type}`
|
|
- Value formatting:
|
|
- `integer/bool`: show compact (True/False, numbers)
|
|
- `choice`: show friendly choice label (extract from `@odata.type` or value tail)
|
|
- `string`: truncate long values, add copy button
|
|
- Fallback: prettify `definitionId` if definition not found (e.g., `device_vendor_msft_policy_name` → "Device Vendor Msft Policy Name")
|
|
|
|
### FR-185.5: Policy View UI Update
|
|
- **Layout**: 2-column
|
|
- Left: "Configuration Settings" (grouped, searchable)
|
|
- Right: "Policy Details" (existing metadata: name, type, platform, last synced)
|
|
- **Tabs**:
|
|
- "Settings" (default) - cleartext UI with accordion groups
|
|
- "JSON" - raw snapshot viewer (pepperfm/filament-json)
|
|
- **Search/Filter**: Live search on setting display name and value
|
|
- **Accordion**: Settings grouped by category, collapsible
|
|
- **Fallback**: Generic table for non-Settings Catalog policies (existing behavior)
|
|
|
|
### FR-185.6: JSON Viewer Integration
|
|
- Use `pepperfm/filament-json` only on Policy View and Policy Version View
|
|
- Not rendered globally
|
|
|
|
## Non-Functional Requirements
|
|
|
|
### NFR-185.1: Performance
|
|
- Definition resolver: <500ms for batch of 50 definitions (cached)
|
|
- UI render: <2s for policy with 200 settings
|
|
- Search/filter: <200ms response time
|
|
|
|
### NFR-185.2: Caching Strategy
|
|
- DB cache: 30 days TTL for definitions
|
|
- Memory cache: Request-level only
|
|
- Cache warming: Background job after policy sync (optional)
|
|
|
|
### NFR-185.3: Graceful Degradation
|
|
- If definition not found: show prettified ID
|
|
- If Graph API fails: show cached data or fallback
|
|
- If no cache: show raw definition ID with info icon
|
|
|
|
### NFR-185.4: Maintainability
|
|
- Resolver service isolated, testable
|
|
- Normalizer logic separated from UI
|
|
- UI components reusable for Version view
|
|
|
|
## Technical Architecture
|
|
|
|
### Services
|
|
1. **SettingsCatalogDefinitionResolver** (`app/Services/Intune/`)
|
|
- `resolve(array $definitionIds): array`
|
|
- `resolveOne(string $definitionId): ?array`
|
|
- `warmCache(array $definitionIds): void`
|
|
- Uses GraphClientInterface
|
|
- Database: `SettingsCatalogDefinition` model
|
|
|
|
2. **PolicyNormalizer** (extend existing)
|
|
- `normalizeSettingsCatalog(array $snapshot, array $definitions): array`
|
|
- Returns structured groups + rows
|
|
|
|
### Database
|
|
**Migration**: `create_settings_catalog_definitions_table`
|
|
**Model**: `SettingsCatalogDefinition` (Eloquent)
|
|
|
|
### UI Components
|
|
**Resource**: `PolicyResource` (extend infolist)
|
|
- Tabs component
|
|
- Accordion for groups
|
|
- Search/filter component
|
|
- ViewEntry for settings table
|
|
|
|
## Implementation Plan
|
|
|
|
### Phase 1: Foundation (Resolver + DB)
|
|
1. Create migration `settings_catalog_definitions`
|
|
2. Create model `SettingsCatalogDefinition`
|
|
3. Create service `SettingsCatalogDefinitionResolver`
|
|
4. Add Graph client method for fetching definitions
|
|
5. Implement cache logic (DB + memory)
|
|
|
|
### Phase 2: Snapshot Enrichment
|
|
1. Extend `PolicySnapshotService` to extract definition IDs
|
|
2. Call resolver after settings hydration
|
|
3. Store metadata in snapshot
|
|
|
|
### Phase 3: Normalizer Enhancement
|
|
1. Extend `PolicyNormalizer` for Settings Catalog
|
|
2. Implement value formatting logic
|
|
3. Implement grouping logic
|
|
4. Add fallback for missing definitions
|
|
|
|
### Phase 4: UI Implementation
|
|
1. Update `PolicyResource` infolist with tabs
|
|
2. Create accordion view for settings groups
|
|
3. Add search/filter functionality
|
|
4. Integrate JSON viewer (pepperfm)
|
|
5. Add fallback for non-Settings Catalog policies
|
|
|
|
### Phase 5: Testing & Polish
|
|
1. Unit tests for resolver
|
|
2. Feature tests for UI
|
|
3. Manual QA on staging
|
|
4. Performance profiling
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
- `SettingsCatalogDefinitionResolverTest`
|
|
- Test definition mapping
|
|
- Test caching behavior
|
|
- Test fallback logic
|
|
- Test batch resolution
|
|
|
|
### Feature Tests
|
|
- `PolicyViewSettingsCatalogReadableTest`
|
|
- Mock Graph responses
|
|
- Assert UI shows display names
|
|
- Assert values formatted correctly
|
|
- Assert grouping works
|
|
- Assert search/filter works
|
|
- Assert JSON tab available
|
|
|
|
## Success Criteria
|
|
|
|
1. ✅ Admin sees human-readable setting names + descriptions
|
|
2. ✅ Values formatted appropriately (True/False, numbers, choice labels)
|
|
3. ✅ Settings grouped by category with accordion
|
|
4. ✅ Search/filter works on display name and value
|
|
5. ✅ Raw JSON available in separate tab
|
|
6. ✅ Unknown settings show prettified ID (no broken layout)
|
|
7. ✅ Performance: <2s render for 200 settings
|
|
8. ✅ Tests pass: Unit + Feature
|
|
|
|
## Dependencies
|
|
- Existing: `PolicyNormalizer`, `PolicySnapshotService`, `GraphClientInterface`
|
|
- New: `pepperfm/filament-json` (already installed in Feature 002)
|
|
- Database: PostgreSQL with JSONB support
|
|
|
|
## Risks & Mitigations
|
|
- **Risk**: Graph API rate limiting when fetching definitions
|
|
- **Mitigation**: Aggressive caching, batch requests, background warming
|
|
- **Risk**: Definition schema changes by Microsoft
|
|
- **Mitigation**: Raw JSONB storage allows flexible parsing, version metadata
|
|
- **Risk**: Large policies (1000+ settings) slow UI
|
|
- **Mitigation**: Pagination, lazy loading accordion groups, virtualized lists
|
|
|
|
## Out of Scope
|
|
- Editing settings (read-only view only)
|
|
- Definition schema versioning
|
|
- Multi-language support for definitions
|
|
- Real-time definition updates (cache refresh manual/scheduled)
|
|
|
|
## Future Enhancements
|
|
- Background job to pre-warm definition cache
|
|
- Definition schema versioning
|
|
- Comparison view between policy versions (diff)
|
|
- Export settings to CSV/Excel
|