3.9 KiB
3.9 KiB
phase, title, status, created
| phase | title | status | created |
|---|---|---|---|
| 15 | Consolidation Data Model | ready-for-planning | 2026-04-09 |
Phase 15 Context: Consolidation Data Model
Decided Areas (from prior research + STATE.md)
These are locked — do not re-litigate during planning or execution.
| Decision | Value |
|---|---|
| Consolidation scope | User access audit report only — site-centric permission report is unchanged |
| Source model | UserAccessEntry (already normalized, one user per row) |
| Consolidation is opt-in | Defaults to OFF; toggle wired in Phase 16 |
| No API calls | Pure data transformation — no Graph or CSOM calls |
| Existing exports unchanged | When consolidation is not applied, output is identical to pre-v2.3 |
Discussed Areas
1. Consolidation Key (What Defines "Same Access")
Decision: Merge rows only when all four fields match: UserLogin + PermissionLevel + AccessType + GrantedThrough.
- Strictest matching — preserves the audit trail of how access was granted
- A user with "Contribute (Direct)" on 3 sites and "Contribute (Group: Members)" on 2 sites produces 2 consolidated rows, not 1
UserLoginis the identity key (notUserDisplayName, which could vary)AccessTypeenum values: Direct, Group, Inherited — all treated as distinctGrantedThroughstring comparison is exact (e.g., "SharePoint Group: Members" vs "SharePoint Group: Owners" are separate)
2. Merged Locations Model
Decision: List<LocationInfo> with a LocationCount convenience property.
ConsolidatedPermissionEntryholds all fields from the consolidation key plus aList<LocationInfo>containing each merged site's URL and titleLocationInfois a lightweight record:{ string SiteUrl, string SiteTitle, string ObjectTitle, string ObjectUrl, string ObjectType }LocationCountis a computed property (Locations.Count) — convenience for display and sorting- No information loss — all original location data is preserved in the list
- Presentation decisions (how to render the list) are deferred to Phase 16
3. Report Scope
Decision: Consolidation applies to user access audit (UserAccessEntry) only.
- The user access audit report is already user-centric and normalized (one user per row) — natural fit for "merge same user across locations"
- The site-centric permission report (
PermissionEntry) flows the opposite direction (site → users); consolidating it would mean "same permission set across sites" — a different feature entirely HtmlExportService(site-centric) is untouched by this phaseUserAccessHtmlExportServicewill receive consolidated data in Phase 16; this phase only builds the model and service
Deferred Ideas (out of scope for Phase 15)
- Consolidation toggle UI (Phase 16)
- Consolidated view rendering in HTML exports (Phase 16)
- Group expansion within consolidated rows (Phase 17)
- Consolidation in CSV exports (out of scope per REQUIREMENTS.md)
- "Same permission set across sites" consolidation for site-centric report (not planned)
code_context
| Asset | Path | Reuse |
|---|---|---|
| UserAccessEntry model | SharepointToolbox/Core/Models/UserAccessEntry.cs |
Source model — consolidated entry mirrors its fields + locations list |
| UserAccessAuditService | SharepointToolbox/Services/UserAccessAuditService.cs |
Produces the UserAccessEntry list that feeds the consolidator |
| UserAccessHtmlExportService | SharepointToolbox/Services/Export/UserAccessHtmlExportService.cs |
Downstream consumer in Phase 16 — must accept both flat and consolidated lists |
| DuplicatesService grouping pattern | SharepointToolbox/Services/DuplicatesService.cs |
Reference for composite-key grouping via MakeKey() pattern |
| PermissionSummaryBuilder | SharepointToolbox/Core/Helpers/PermissionSummaryBuilder.cs |
Reference for aggregation pattern over permission data |
| Test project | SharepointToolbox.Tests/ |
New tests for PermissionConsolidator with known input/output pairs |