docs(13-01): complete user directory model and service extension plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ Requirements for v2.2 Report Branding & User Directory. Each maps to roadmap pha
|
|||||||
|
|
||||||
- [ ] **UDIR-01**: User can toggle between search mode and directory browse mode in user access audit tab
|
- [ ] **UDIR-01**: User can toggle between search mode and directory browse mode in user access audit tab
|
||||||
- [ ] **UDIR-02**: User can browse full tenant user directory with pagination (handles 999+ users)
|
- [ ] **UDIR-02**: User can browse full tenant user directory with pagination (handles 999+ users)
|
||||||
- [ ] **UDIR-03**: User can filter directory by user type (member vs guest)
|
- [x] **UDIR-03**: User can filter directory by user type (member vs guest)
|
||||||
- [ ] **UDIR-04**: User can see department and job title columns in directory list
|
- [ ] **UDIR-04**: User can see department and job title columns in directory list
|
||||||
- [ ] **UDIR-05**: User can select one or more users from directory to run the access audit
|
- [ ] **UDIR-05**: User can select one or more users from directory to run the access audit
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| BRAND-02 | Phase 12 | Complete |
|
| BRAND-02 | Phase 12 | Complete |
|
||||||
| UDIR-01 | Phase 13 | Pending |
|
| UDIR-01 | Phase 13 | Pending |
|
||||||
| UDIR-02 | Phase 13 | Pending |
|
| UDIR-02 | Phase 13 | Pending |
|
||||||
| UDIR-03 | Phase 13 | Pending |
|
| UDIR-03 | Phase 13 | Complete |
|
||||||
| UDIR-04 | Phase 13 | Pending |
|
| UDIR-04 | Phase 13 | Pending |
|
||||||
| UDIR-05 | Phase 14 | Pending |
|
| UDIR-05 | Phase 14 | Pending |
|
||||||
|
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ Plans:
|
|||||||
4. Clicking "Pull from Entra" in the profile dialog fetches and displays the tenant's banner logo if one exists, and shows a clear user-facing message if none is configured
|
4. Clicking "Pull from Entra" in the profile dialog fetches and displays the tenant's banner logo if one exists, and shows a clear user-facing message if none is configured
|
||||||
**Plans**: 3 plans
|
**Plans**: 3 plans
|
||||||
Plans:
|
Plans:
|
||||||
- [ ] 12-01-PLAN.md — Base64ToImageSourceConverter, localization keys, App.xaml registration, ClientLogoPreview property
|
- [x] 12-01-PLAN.md — Base64ToImageSourceConverter, localization keys, App.xaml registration, ClientLogoPreview property
|
||||||
- [ ] 12-02-PLAN.md — SettingsView MSP logo section (preview, import, clear)
|
- [x] 12-02-PLAN.md — SettingsView MSP logo section (preview, import, clear)
|
||||||
- [ ] 12-03-PLAN.md — ProfileManagementDialog client logo section (preview, import, clear, Entra pull)
|
- [x] 12-03-PLAN.md — ProfileManagementDialog client logo section (preview, import, clear, Entra pull)
|
||||||
|
|
||||||
### Phase 13: User Directory ViewModel
|
### Phase 13: User Directory ViewModel
|
||||||
**Goal**: The UserAccessAuditViewModel supports a full directory browse mode with paginated load, member/guest filtering, and department/job title display, fully testable without the View.
|
**Goal**: The UserAccessAuditViewModel supports a full directory browse mode with paginated load, member/guest filtering, and department/job title display, fully testable without the View.
|
||||||
@@ -95,7 +95,10 @@ Plans:
|
|||||||
2. Invoking the load-directory command fetches all enabled member users via `PageIterator`, updates a progress observable with the running user count, and supports cancellation mid-load
|
2. Invoking the load-directory command fetches all enabled member users via `PageIterator`, updates a progress observable with the running user count, and supports cancellation mid-load
|
||||||
3. A "Members only / Include guests" toggle filters the displayed list in-memory without issuing a new Graph request
|
3. A "Members only / Include guests" toggle filters the displayed list in-memory without issuing a new Graph request
|
||||||
4. Each user row in the observable collection exposes DisplayName, UPN, Department, and JobTitle; Department and JobTitle columns are visible and sortable in the ViewModel's `ICollectionView`
|
4. Each user row in the observable collection exposes DisplayName, UPN, Department, and JobTitle; Department and JobTitle columns are visible and sortable in the ViewModel's `ICollectionView`
|
||||||
**Plans**: TBD
|
**Plans**: 2 plans
|
||||||
|
Plans:
|
||||||
|
- [ ] 13-01-PLAN.md — Extend GraphDirectoryUser with UserType + service includeGuests parameter
|
||||||
|
- [ ] 13-02-PLAN.md — UserAccessAuditViewModel directory browse mode (toggle, load, filter, sort, tests)
|
||||||
|
|
||||||
### Phase 14: User Directory View
|
### Phase 14: User Directory View
|
||||||
**Goal**: Administrators can toggle into directory browse mode from the user access audit tab, see the paginated user list with filters, and launch an access audit for a selected user.
|
**Goal**: Administrators can toggle into directory browse mode from the user access audit tab, see the paginated user list with filters, and launch an access audit for a selected user.
|
||||||
@@ -117,5 +120,5 @@ Plans:
|
|||||||
| 10. Branding Data Foundation | v2.2 | 3/3 | Complete | 2026-04-08 |
|
| 10. Branding Data Foundation | v2.2 | 3/3 | Complete | 2026-04-08 |
|
||||||
| 11. HTML Export Branding + ViewModel Integration | 4/4 | Complete | 2026-04-08 | — |
|
| 11. HTML Export Branding + ViewModel Integration | 4/4 | Complete | 2026-04-08 | — |
|
||||||
| 12. Branding UI Views | 3/3 | Complete | 2026-04-08 | — |
|
| 12. Branding UI Views | 3/3 | Complete | 2026-04-08 | — |
|
||||||
| 13. User Directory ViewModel | v2.2 | 0/? | Not started | — |
|
| 13. User Directory ViewModel | 1/2 | In Progress| | — |
|
||||||
| 14. User Directory View | v2.2 | 0/? | Not started | — |
|
| 14. User Directory View | v2.2 | 0/? | Not started | — |
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ gsd_state_version: 1.0
|
|||||||
milestone: v2.2
|
milestone: v2.2
|
||||||
milestone_name: Report Branding & User Directory
|
milestone_name: Report Branding & User Directory
|
||||||
status: completed
|
status: completed
|
||||||
stopped_at: Completed 12-03-PLAN.md
|
stopped_at: Completed 13-01-PLAN.md
|
||||||
last_updated: "2026-04-08T13:21:44.626Z"
|
last_updated: "2026-04-08T14:02:35.700Z"
|
||||||
last_activity: 2026-04-08 — Phase 11 planning completed
|
last_activity: 2026-04-08 — Phase 11 planning completed
|
||||||
progress:
|
progress:
|
||||||
total_phases: 5
|
total_phases: 5
|
||||||
completed_phases: 3
|
completed_phases: 3
|
||||||
total_plans: 10
|
total_plans: 12
|
||||||
completed_plans: 10
|
completed_plans: 11
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -68,6 +68,7 @@ Decisions are logged in PROJECT.md Key Decisions table.
|
|||||||
- [Phase 12]: Skipped BitmapImage creation test due to missing Xunit.StaFact; STA thread required for WPF BitmapImage
|
- [Phase 12]: Skipped BitmapImage creation test due to missing Xunit.StaFact; STA thread required for WPF BitmapImage
|
||||||
- [Phase 12]: Used Grid overlay with DataTrigger for logo/placeholder visibility toggle in SettingsView
|
- [Phase 12]: Used Grid overlay with DataTrigger for logo/placeholder visibility toggle in SettingsView
|
||||||
- [Phase 12]: Label+StackPanel layout for logo section in ProfileManagementDialog, consistent with SettingsView pattern
|
- [Phase 12]: Label+StackPanel layout for logo section in ProfileManagementDialog, consistent with SettingsView pattern
|
||||||
|
- [Phase 13]: UserType added as last positional param for backward compat; includeGuests defaults false; userType always in Select
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -82,7 +83,7 @@ None.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-08T13:21:44.623Z
|
Last session: 2026-04-08T14:02:35.697Z
|
||||||
Stopped at: Completed 12-03-PLAN.md
|
Stopped at: Completed 13-01-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
Next step: `/gsd:execute-phase 11`
|
Next step: `/gsd:execute-phase 11`
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
phase: 13-user-directory-viewmodel
|
||||||
|
plan: 01
|
||||||
|
subsystem: api
|
||||||
|
tags: [microsoft-graph, user-directory, wpf, csharp]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 10-branding-data-foundation
|
||||||
|
provides: GraphDirectoryUser model, GraphUserDirectoryService, IGraphUserDirectoryService
|
||||||
|
provides:
|
||||||
|
- GraphDirectoryUser with UserType property for client-side member/guest filtering
|
||||||
|
- IGraphUserDirectoryService.GetUsersAsync with includeGuests parameter
|
||||||
|
- Graph filter branching (members-only vs all users)
|
||||||
|
affects: [13-02-PLAN, user-directory-viewmodel]
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns: [default-parameter backward compat, Graph filter branching]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- SharepointToolbox/Core/Models/GraphDirectoryUser.cs
|
||||||
|
- SharepointToolbox/Services/IGraphUserDirectoryService.cs
|
||||||
|
- SharepointToolbox/Services/GraphUserDirectoryService.cs
|
||||||
|
- SharepointToolbox.Tests/Services/GraphUserDirectoryServiceTests.cs
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "UserType added as last positional parameter to preserve backward compat for existing callers"
|
||||||
|
- "includeGuests defaults to false so all existing call sites compile unchanged"
|
||||||
|
- "userType always in Graph Select array regardless of includeGuests value"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Default parameter backward compat: new optional params added with defaults matching prior behavior"
|
||||||
|
|
||||||
|
requirements-completed: [UDIR-03]
|
||||||
|
|
||||||
|
duration: 2min
|
||||||
|
completed: 2026-04-08
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 13 Plan 01: User Directory Model & Service Extension Summary
|
||||||
|
|
||||||
|
**Extended GraphDirectoryUser with UserType property and added includeGuests filter parameter to GraphUserDirectoryService for client-side member/guest filtering**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 2 min
|
||||||
|
- **Started:** 2026-04-08T14:00:08Z
|
||||||
|
- **Completed:** 2026-04-08T14:01:51Z
|
||||||
|
- **Tasks:** 3
|
||||||
|
- **Files modified:** 4
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
- Added string? UserType as last positional parameter to GraphDirectoryUser record
|
||||||
|
- Added bool includeGuests = false parameter to IGraphUserDirectoryService.GetUsersAsync with Graph filter branching
|
||||||
|
- Updated MapUser to populate UserType from Graph User object with userType always in Select array
|
||||||
|
- Added 2 new tests (MapUser_PopulatesUserType, MapUser_NullUserType) and updated 2 existing tests with UserType assertions
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
All three tasks committed atomically (single plan scope):
|
||||||
|
|
||||||
|
1. **Tasks 1-3: Model + Service + Tests** - `9a98371` (feat)
|
||||||
|
|
||||||
|
**Plan metadata:** [pending]
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
- `SharepointToolbox/Core/Models/GraphDirectoryUser.cs` - Added UserType as 6th positional parameter
|
||||||
|
- `SharepointToolbox/Services/IGraphUserDirectoryService.cs` - Added includeGuests parameter with XML docs
|
||||||
|
- `SharepointToolbox/Services/GraphUserDirectoryService.cs` - Filter branching, userType in Select, MapUser UserType mapping
|
||||||
|
- `SharepointToolbox.Tests/Services/GraphUserDirectoryServiceTests.cs` - Updated 2 existing tests, added 2 new UserType tests
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
- UserType added as last positional parameter (string?) so existing construction sites only need one additional argument
|
||||||
|
- includeGuests defaults to false preserving all existing call sites unchanged (backward compatible)
|
||||||
|
- userType always included in Graph Select array regardless of includeGuests flag, so MapUser always has data
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
None.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
- GraphDirectoryUser now carries UserType for Phase 13-02 in-memory member/guest filtering
|
||||||
|
- IGraphUserDirectoryService.GetUsersAsync ready for ViewModel to call with includeGuests=true
|
||||||
|
- All 7 unit tests pass, 4 integration tests skipped (expected - require live tenant)
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 13-user-directory-viewmodel*
|
||||||
|
*Completed: 2026-04-08*
|
||||||
Reference in New Issue
Block a user