chore: archive v1.1 Enhanced Reports milestone
Some checks failed
Release SharePoint Toolbox v2 / release (push) Failing after 14s
Some checks failed
Release SharePoint Toolbox v2 / release (push) Failing after 14s
v1.1 shipped with 4 phases (25 plans), 10/10 requirements complete: - Global site selection (toolbar picker, all tabs consume) - User access audit (Graph people-picker, direct/group/inherited) - Simplified permissions (plain-language labels, risk levels, detail toggle) - Storage visualization (LiveCharts2 pie/donut + bar charts) Post-phase polish: centralized site selection (removed per-tab pickers), claims prefix stripping, StorageMetrics backfill, chart tooltip fix, summary stats in app + HTML exports. 205 tests passing, 10,484 LOC. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,23 +8,19 @@ A C#/WPF desktop application for IT administrators and MSPs to audit and manage
|
||||
|
||||
Administrators can audit and manage SharePoint/Teams permissions and storage across multiple client tenants from a single, reliable desktop application.
|
||||
|
||||
## Current Milestone: v1.1 Enhanced Reports
|
||||
|
||||
**Goal:** Add user access audit, simplified permissions, storage visualization, and global multi-site selection
|
||||
|
||||
**Target features:**
|
||||
- Export all SharePoint/Teams accesses a specific user has across selected sites
|
||||
- Simplified permissions reports with plain-language labels and summary views
|
||||
- Storage metrics graph by file type (pie/donut and bar chart, toggleable)
|
||||
- Global multi-site selection in toolbar (pick sites once, all tabs use them)
|
||||
|
||||
## Current State
|
||||
|
||||
**Shipped:** v1.0 MVP (2026-04-07)
|
||||
**Status:** Feature-complete for v1 parity; v1.1 in progress
|
||||
**Shipped:** v1.1 Enhanced Reports (2026-04-08)
|
||||
**Status:** Feature-complete for v1.1; no active milestone
|
||||
|
||||
Tech stack: C# / WPF / .NET 10 / PnP Framework / Microsoft Graph SDK / MSAL / Serilog / CommunityToolkit.Mvvm
|
||||
Tests: 134 automated (xUnit), 22 skipped (require live SharePoint tenant)
|
||||
**v1.1 shipped features:**
|
||||
- Global multi-site selection in toolbar (pick sites once, all tabs use them)
|
||||
- User access audit tab with Graph API people-picker, direct/group/inherited access distinction
|
||||
- Simplified permissions with plain-language labels, color-coded risk levels, detail-level toggle
|
||||
- Storage visualization with LiveCharts2 pie/donut and bar charts by file type
|
||||
|
||||
Tech stack: C# / WPF / .NET 10 / PnP Framework / Microsoft Graph SDK / MSAL / Serilog / CommunityToolkit.Mvvm / LiveCharts2
|
||||
Tests: 205 automated (xUnit), 22 skipped (require live SharePoint tenant)
|
||||
Distribution: 200 MB self-contained EXE (win-x64)
|
||||
|
||||
## Requirements
|
||||
@@ -37,11 +33,12 @@ Distribution: 200 MB self-contained EXE (win-x64)
|
||||
- Modular architecture (separate files per feature area, DI, MVVM) — v1.0
|
||||
- Self-contained single EXE distribution — v1.0
|
||||
|
||||
### Active
|
||||
### Shipped in v1.1
|
||||
|
||||
- [ ] Export all SharePoint/Teams accesses a specific user has across selected sites (UACC-01/02)
|
||||
- [ ] Simplified permissions reports (plain language, summary views) (SIMP-01/02/03)
|
||||
- [ ] Storage metrics graph by file type (pie/donut and bar chart, toggleable) (VIZZ-01/02/03)
|
||||
- [x] Global multi-site selection in toolbar (SITE-01/02) — v1.1
|
||||
- [x] Export all SharePoint/Teams accesses a specific user has across selected sites (UACC-01/02) — v1.1
|
||||
- [x] Simplified permissions reports (plain language, summary views) (SIMP-01/02/03) — v1.1
|
||||
- [x] Storage metrics graph by file type (pie/donut and bar chart, toggleable) (VIZZ-01/02/03) — v1.1
|
||||
|
||||
### Out of Scope
|
||||
|
||||
@@ -57,9 +54,9 @@ Distribution: 200 MB self-contained EXE (win-x64)
|
||||
## Context
|
||||
|
||||
- **v1.0 shipped** with full feature parity: permissions, storage, search, duplicates, bulk operations, templates, folder provisioning
|
||||
- **Known tech debt:** FeatureTabBase dead code removed post-v1.0; bulk DataGrid row highlighting added post-v1.0; cancel test locale fix applied post-v1.0
|
||||
- **Localization:** 199 EN/FR keys, full parity verified
|
||||
- **Architecture:** 106 C# files + 16 XAML files across Core/Infrastructure/Services/ViewModels/Views layers
|
||||
- **v1.1 shipped** with enhanced reports: user access audit, simplified permissions, storage charts, global site selection
|
||||
- **Localization:** 220+ EN/FR keys, full parity verified
|
||||
- **Architecture:** 120+ C# files + 17 XAML files across Core/Infrastructure/Services/ViewModels/Views layers
|
||||
|
||||
## Constraints
|
||||
|
||||
@@ -83,4 +80,4 @@ Distribution: 200 MB self-contained EXE (win-x64)
|
||||
| Wave 0 scaffold pattern | Models + interfaces + test stubs before implementation | ✓ Good — all phases had test targets from day 1 |
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-07 after v1.1 milestone start*
|
||||
*Last updated: 2026-04-08 after v1.1 milestone shipped*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## Milestones
|
||||
|
||||
- ✅ **v1.0 MVP** — Phases 1-5 (shipped 2026-04-07) — [archive](milestones/v1.0-ROADMAP.md)
|
||||
- 🔄 **v1.1 Enhanced Reports** — Phases 6-9 (in progress)
|
||||
- ✅ **v1.1 Enhanced Reports** — Phases 6-9 (shipped 2026-04-08) — [archive](milestones/v1.1-ROADMAP.md)
|
||||
|
||||
## Phases
|
||||
|
||||
@@ -18,98 +18,19 @@
|
||||
|
||||
</details>
|
||||
|
||||
**v1.1 Enhanced Reports**
|
||||
<details>
|
||||
<summary>✅ v1.1 Enhanced Reports (Phases 6-9) — SHIPPED 2026-04-08</summary>
|
||||
|
||||
- [x] **Phase 6: Global Site Selection** — Toolbar-level multi-site picker that all feature tabs consume as their default target (completed 2026-04-07)
|
||||
- [x] **Phase 7: User Access Audit** — New feature tab: export every SharePoint/Teams access a specific user holds across selected sites (completed 2026-04-07)
|
||||
- [x] **Phase 8: Simplified Permissions** — Plain-language labels, summary counts, color coding, and detail-level toggle on the permissions report (completed 2026-04-07)
|
||||
- [x] **Phase 9: Storage Visualization** — Charting dependency + pie/donut and bar chart views of storage by file type in the Storage Metrics tab (completed 2026-04-07)
|
||||
- [x] Phase 6: Global Site Selection (5/5 plans) — completed 2026-04-07
|
||||
- [x] Phase 7: User Access Audit (10/10 plans) — completed 2026-04-07
|
||||
- [x] Phase 8: Simplified Permissions (6/6 plans) — completed 2026-04-07
|
||||
- [x] Phase 9: Storage Visualization (4/4 plans) — completed 2026-04-07
|
||||
|
||||
## Phase Details
|
||||
|
||||
### Phase 6: Global Site Selection
|
||||
**Goal**: Administrators can select one or more target sites once from the toolbar and have every feature tab use that selection by default
|
||||
**Depends on**: Phase 5 (v1.0 foundation — toolbar and tab architecture in place)
|
||||
**Requirements**: SITE-01, SITE-02
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. A multi-site picker control is visible in the main toolbar at all times, regardless of which tab is active
|
||||
2. Selecting sites in the toolbar causes all feature tabs to default to those sites when an operation is run
|
||||
3. A user can override the global selection on any individual tab without clearing the global state
|
||||
4. The global site selection persists across tab switches within the same session
|
||||
**Plans:** 5/5 plans complete
|
||||
Plans:
|
||||
- [ ] 06-01-PLAN.md — GlobalSitesChangedMessage + FeatureViewModelBase extension
|
||||
- [ ] 06-02-PLAN.md — MainWindowViewModel global selection state + command
|
||||
- [ ] 06-03-PLAN.md — Toolbar UI, dialog wiring, and localization keys
|
||||
- [ ] 06-04-PLAN.md — Tab VM updates for global site consumption
|
||||
- [ ] 06-05-PLAN.md — Unit tests for global site selection flow
|
||||
|
||||
### Phase 7: User Access Audit
|
||||
**Goal**: Administrators can audit every permission a specific user holds across selected sites, distinguish access types (direct/group/inherited), and export results to CSV or HTML
|
||||
**Depends on**: Phase 6
|
||||
**Requirements**: UACC-01, UACC-02
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. A User Access Audit tab (or panel) is accessible and accepts a user identifier and site selection as inputs
|
||||
2. Running the audit returns a list of all access entries the user holds across the selected sites
|
||||
3. Results distinguish between direct role assignments, SharePoint group memberships, and inherited access
|
||||
4. Results can be exported to CSV or HTML in the same format established by v1.0 export patterns
|
||||
**Plans:** 10/10 plans complete
|
||||
Plans:
|
||||
- [ ] 07-01-PLAN.md — UserAccessEntry model + service interfaces (Wave 1)
|
||||
- [ ] 07-02-PLAN.md — UserAccessAuditService implementation (Wave 2)
|
||||
- [ ] 07-03-PLAN.md — GraphUserSearchService implementation (Wave 2)
|
||||
- [ ] 07-04-PLAN.md — UserAccessAuditViewModel (Wave 3)
|
||||
- [ ] 07-05-PLAN.md — UserAccessAuditView XAML layout (Wave 4)
|
||||
- [ ] 07-06-PLAN.md — CSV + HTML export services (Wave 2)
|
||||
- [ ] 07-07-PLAN.md — Tab wiring, DI, localization (Wave 4)
|
||||
- [ ] 07-08-PLAN.md — Unit tests (Wave 5)
|
||||
- [ ] 07-09-PLAN.md — Gap closure: DataGrid visual indicators + ObjectType column (Wave 6)
|
||||
- [ ] 07-10-PLAN.md — Gap closure: Debounced search unit test (Wave 6)
|
||||
|
||||
### Phase 8: Simplified Permissions
|
||||
**Goal**: Permissions reports are readable by non-technical users through plain-language labels, color coding, and a configurable detail level
|
||||
**Depends on**: Phase 6
|
||||
**Requirements**: SIMP-01, SIMP-02, SIMP-03
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. The permissions report displays human-readable labels (e.g., "Can edit files") alongside or instead of raw SharePoint role names (e.g., "Contribute") when the simplified mode toggle is on
|
||||
2. The report shows summary counts per permission level with color indicators distinguishing high, medium, and low access levels
|
||||
3. A detail-level selector (simple / detailed) controls whether individual item-level rows are shown or collapsed into summary rows
|
||||
4. Toggling modes and detail level does not require re-running the scan — it re-renders from the already-fetched data
|
||||
**Plans:** 6/6 plans complete
|
||||
Plans:
|
||||
- [ ] 08-01-PLAN.md — RiskLevel enum, PermissionLevelMapping, SimplifiedPermissionEntry, PermissionSummary (Wave 1)
|
||||
- [ ] 08-02-PLAN.md — PermissionsViewModel simplified mode, detail toggle, summary computation (Wave 2)
|
||||
- [ ] 08-03-PLAN.md — PermissionsView XAML: toggles, summary panel, color-coded DataGrid (Wave 3)
|
||||
- [ ] 08-04-PLAN.md — HTML + CSV export simplified overloads (Wave 3)
|
||||
- [ ] 08-05-PLAN.md — Localization keys (EN/FR) + export command wiring (Wave 4)
|
||||
- [ ] 08-06-PLAN.md — Unit tests: mapping, summary, ViewModel toggle behavior (Wave 5)
|
||||
|
||||
### Phase 9: Storage Visualization
|
||||
**Goal**: The Storage Metrics tab displays an interactive chart of space consumption by file type, togglable between pie/donut and bar chart views
|
||||
**Depends on**: Phase 6
|
||||
**Requirements**: VIZZ-01, VIZZ-02, VIZZ-03
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. A WPF charting library (LiveCharts2 or OxyPlot) is integrated as a NuGet dependency and renders correctly in the self-contained EXE build
|
||||
2. After a storage scan completes, a chart appears in the Storage Metrics tab showing space broken down by file type
|
||||
3. A toggle control switches the chart between pie/donut and bar chart representations without re-running the scan
|
||||
4. The chart updates automatically whenever a new storage scan finishes, without requiring manual refresh
|
||||
**Plans:** 4/4 plans complete
|
||||
Plans:
|
||||
- [ ] 09-01-PLAN.md — LiveCharts2 NuGet + FileTypeMetric model + IStorageService extension (Wave 1)
|
||||
- [ ] 09-02-PLAN.md — StorageService file-type enumeration implementation (Wave 2)
|
||||
- [ ] 09-03-PLAN.md — ViewModel chart properties + View XAML + localization (Wave 3)
|
||||
- [ ] 09-04-PLAN.md — Unit tests for chart ViewModel behavior (Wave 4)
|
||||
</details>
|
||||
|
||||
## Progress
|
||||
|
||||
| Phase | Milestone | Plans Complete | Status | Completed |
|
||||
|-------|-----------|----------------|--------|-----------|
|
||||
| 1. Foundation | v1.0 | 8/8 | Complete | 2026-04-02 |
|
||||
| 2. Permissions | v1.0 | 7/7 | Complete | 2026-04-02 |
|
||||
| 3. Storage and File Operations | v1.0 | 8/8 | Complete | 2026-04-02 |
|
||||
| 4. Bulk Operations and Provisioning | v1.0 | 10/10 | Complete | 2026-04-03 |
|
||||
| 5. Distribution and Hardening | v1.0 | 3/3 | Complete | 2026-04-03 |
|
||||
| 6. Global Site Selection | v1.1 | 5/5 | Complete | 2026-04-07 |
|
||||
| 7. User Access Audit | v1.1 | 10/10 | Complete | 2026-04-07 |
|
||||
| 8. Simplified Permissions | v1.1 | 6/6 | Complete | 2026-04-07 |
|
||||
| 9. Storage Visualization | v1.1 | 4/4 | Complete | 2026-04-07 |
|
||||
| Phase | Milestone | Plans | Status | Completed |
|
||||
|-------|-----------|-------|--------|-----------|
|
||||
| 1-5 | v1.0 | 36/36 | Shipped | 2026-04-07 |
|
||||
| 6-9 | v1.1 | 25/25 | Shipped | 2026-04-08 |
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
gsd_state_version: 1.0
|
||||
milestone: v1.0
|
||||
milestone_name: milestone
|
||||
status: completed
|
||||
stopped_at: Completed 09-04-PLAN.md
|
||||
last_updated: "2026-04-07T13:40:30Z"
|
||||
last_activity: 2026-04-07 — Completed 09-04 (StorageViewModel chart unit tests)
|
||||
milestone: v1.1
|
||||
milestone_name: v1.1 Enhanced Reports
|
||||
status: shipped
|
||||
stopped_at: Milestone archived
|
||||
last_updated: "2026-04-08T00:00:00Z"
|
||||
last_activity: 2026-04-08 — v1.1 milestone archived and tagged
|
||||
progress:
|
||||
total_phases: 4
|
||||
completed_phases: 4
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
# Requirements: SharePoint Toolbox v1.1 Enhanced Reports
|
||||
# Requirements Archive: SharePoint Toolbox v1.1 Enhanced Reports
|
||||
|
||||
**Defined:** 2026-04-07
|
||||
**Core Value:** Administrators can audit and manage SharePoint/Teams permissions and storage across multiple client tenants from a single, reliable desktop application.
|
||||
**Completed:** 2026-04-08
|
||||
**Coverage:** 10/10 requirements complete
|
||||
|
||||
## v1.1 Requirements
|
||||
## Requirements
|
||||
|
||||
### Global Site Selection
|
||||
|
||||
- [x] **SITE-01**: User can select one or multiple target sites from the toolbar and all feature tabs use that selection as default
|
||||
- [x] **SITE-02**: User can override global site selection per-tab for single-site operations
|
||||
- *Outcome: Initially implemented, later removed — per-tab selectors replaced by centralized global-only selection*
|
||||
|
||||
### User Access Audit
|
||||
|
||||
@@ -27,39 +29,29 @@
|
||||
- [x] **VIZZ-02**: User can toggle between pie/donut chart and bar chart views
|
||||
- [x] **VIZZ-03**: Graph updates automatically when storage scan completes
|
||||
|
||||
## Future Requirements
|
||||
## Traceability
|
||||
|
||||
None deferred — all active requirements scoped to v1.1.
|
||||
| Requirement | Phase | Status | Notes |
|
||||
|-------------|-------|--------|-------|
|
||||
| SITE-01 | Phase 6 | Complete | |
|
||||
| SITE-02 | Phase 6 | Complete | Per-tab override later removed in favor of global-only |
|
||||
| UACC-01 | Phase 7 | Complete | |
|
||||
| UACC-02 | Phase 7 | Complete | |
|
||||
| SIMP-01 | Phase 8 | Complete | 11 standard SharePoint roles mapped |
|
||||
| SIMP-02 | Phase 8 | Complete | 4 risk levels: High/Medium/Low/ReadOnly |
|
||||
| SIMP-03 | Phase 8 | Complete | |
|
||||
| VIZZ-01 | Phase 9 | Complete | LiveCharts2 SkiaSharp backend |
|
||||
| VIZZ-02 | Phase 9 | Complete | |
|
||||
| VIZZ-03 | Phase 9 | Complete | |
|
||||
|
||||
## Out of Scope
|
||||
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| Cross-platform (Mac/Linux) | WPF is Windows-only; not justified for current user base |
|
||||
| Real-time monitoring / alerts | Requires background service, beyond scope |
|
||||
| Cross-platform (Mac/Linux) | WPF is Windows-only |
|
||||
| Real-time monitoring / alerts | Requires background service |
|
||||
| Automated remediation (auto-revoke) | Liability risk |
|
||||
| Content migration between tenants | Separate product category |
|
||||
| Version history management | Surface totals in storage metrics only |
|
||||
|
||||
## Traceability
|
||||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| SITE-01 | Phase 6 | Complete |
|
||||
| SITE-02 | Phase 6 | Complete |
|
||||
| UACC-01 | Phase 7 | Complete |
|
||||
| UACC-02 | Phase 7 | Complete |
|
||||
| SIMP-01 | Phase 8 | Complete |
|
||||
| SIMP-02 | Phase 8 | Complete |
|
||||
| SIMP-03 | Phase 8 | Complete |
|
||||
| VIZZ-01 | Phase 9 | Complete |
|
||||
| VIZZ-02 | Phase 9 | Complete |
|
||||
| VIZZ-03 | Phase 9 | Complete |
|
||||
|
||||
**Coverage:**
|
||||
- v1.1 requirements: 10 total
|
||||
- Mapped to phases: 10
|
||||
- Unmapped: 0
|
||||
|
||||
---
|
||||
*Requirements defined: 2026-04-07 | Traceability updated: 2026-04-07*
|
||||
*Archived: 2026-04-08*
|
||||
81
.planning/milestones/v1.1-ROADMAP.md
Normal file
81
.planning/milestones/v1.1-ROADMAP.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# v1.1 Enhanced Reports — Milestone Archive
|
||||
|
||||
**Goal:** Add user access audit, simplified permissions, storage visualization, and global multi-site selection
|
||||
**Status:** Shipped 2026-04-08
|
||||
**Timeline:** 2026-04-07 to 2026-04-08
|
||||
|
||||
## Stats
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Phases | 4 (Phases 6-9) |
|
||||
| Plans | 25 |
|
||||
| Commits | 29 |
|
||||
| C# LOC (total) | 10,484 |
|
||||
| Tests | 205 pass / 22 skip |
|
||||
| Requirements | 10/10 complete |
|
||||
|
||||
## Key Accomplishments
|
||||
|
||||
1. **Global Site Selection (Phase 6)** — Toolbar-level multi-site picker consumed by all feature tabs. Per-tab site selectors removed in favor of centralized selection. WeakReferenceMessenger broadcast pattern.
|
||||
|
||||
2. **User Access Audit (Phase 7)** — New feature tab: people-picker with Graph API autocomplete, audit every permission a specific user holds across selected sites, distinguish direct/group/inherited access, export to CSV/HTML. Claims prefix stripping for clean display.
|
||||
|
||||
3. **Simplified Permissions (Phase 8)** — Plain-language labels mapped from 11 standard SharePoint roles, color-coded risk levels (High/Medium/Low/ReadOnly), summary cards with counts, detail-level toggle (simple/detailed), simplified export overloads for both CSV and HTML.
|
||||
|
||||
4. **Storage Visualization (Phase 9)** — LiveCharts2 (SkiaSharp) integration for pie/donut and bar chart views of storage by file type. CamlQuery-based file enumeration to work around StorageMetrics API zeros. Custom single-slice tooltip. Per-library backfill for accurate folder-level metrics. Chart data included in HTML/CSV exports with summary stat cards.
|
||||
|
||||
5. **Post-phase Polish** — Removed per-tab site selectors from 8 tabs (centralized to global toolbar), fixed UserAccessAudit DataGrid binding (CollectionViewSource disconnect), added site-level summary totals to Storage tab and HTML reports, suppressed NU1701 NuGet warnings.
|
||||
|
||||
## Phases
|
||||
|
||||
### Phase 6: Global Site Selection (5 plans)
|
||||
- GlobalSitesChangedMessage + FeatureViewModelBase extension
|
||||
- MainWindowViewModel global selection state + command
|
||||
- Toolbar UI, dialog wiring, and localization keys
|
||||
- Tab VM updates for global site consumption
|
||||
- Unit tests for global site selection flow
|
||||
|
||||
### Phase 7: User Access Audit (10 plans)
|
||||
- UserAccessEntry model + service interfaces
|
||||
- UserAccessAuditService implementation
|
||||
- GraphUserSearchService implementation
|
||||
- UserAccessAuditViewModel
|
||||
- UserAccessAuditView XAML layout
|
||||
- CSV + HTML export services
|
||||
- Tab wiring, DI, localization
|
||||
- Unit tests
|
||||
- Gap closure: DataGrid visual indicators + ObjectType column
|
||||
- Gap closure: Debounced search unit test
|
||||
|
||||
### Phase 8: Simplified Permissions (6 plans)
|
||||
- RiskLevel enum, PermissionLevelMapping, SimplifiedPermissionEntry, PermissionSummary
|
||||
- PermissionsViewModel simplified mode, detail toggle, summary computation
|
||||
- PermissionsView XAML: toggles, summary panel, color-coded DataGrid
|
||||
- HTML + CSV export simplified overloads
|
||||
- Localization keys (EN/FR) + export command wiring
|
||||
- Unit tests: mapping, summary, ViewModel toggle behavior
|
||||
|
||||
### Phase 9: Storage Visualization (4 plans)
|
||||
- LiveCharts2 NuGet + FileTypeMetric model + IStorageService extension
|
||||
- StorageService file-type enumeration implementation
|
||||
- ViewModel chart properties + View XAML + localization
|
||||
- Unit tests for chart ViewModel behavior
|
||||
|
||||
## Requirements Covered
|
||||
|
||||
| Requirement | Description | Status |
|
||||
|-------------|-------------|--------|
|
||||
| SITE-01 | Global multi-site selection from toolbar | Complete |
|
||||
| SITE-02 | Per-tab override capability | Complete (later removed — centralized) |
|
||||
| UACC-01 | Export all user accesses across sites | Complete |
|
||||
| UACC-02 | Distinguish direct/group/inherited access | Complete |
|
||||
| SIMP-01 | Plain-language permission labels | Complete |
|
||||
| SIMP-02 | Summary counts with color coding | Complete |
|
||||
| SIMP-03 | Detail-level selector | Complete |
|
||||
| VIZZ-01 | Charting library integration | Complete |
|
||||
| VIZZ-02 | Toggle pie/donut vs bar chart | Complete |
|
||||
| VIZZ-03 | Auto-update chart on scan complete | Complete |
|
||||
|
||||
---
|
||||
*Archived: 2026-04-08*
|
||||
110
.planning/phases/08-simplified-permissions/VERIFICATION.md
Normal file
110
.planning/phases/08-simplified-permissions/VERIFICATION.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
phase: 08-simplified-permissions
|
||||
verified: 2026-04-07T14:30:00Z
|
||||
status: passed
|
||||
score: 4/4 must-haves verified
|
||||
re_verification: false
|
||||
---
|
||||
|
||||
# Phase 8: Simplified Permissions Verification Report
|
||||
|
||||
**Phase Goal:** Permissions reports are readable by non-technical users through plain-language labels, color coding, and a configurable detail level
|
||||
**Verified:** 2026-04-07T14:30:00Z
|
||||
**Status:** PASSED
|
||||
**Re-verification:** No -- initial verification
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths (Success Criteria)
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 1 | The permissions report displays human-readable labels (e.g., "Can edit files") alongside or instead of raw SharePoint role names when the simplified mode toggle is on | VERIFIED | `PermissionLevelMapping.cs` maps 11 standard SP roles to plain-language labels (e.g., "Contribute" -> "Can edit files and list items"). `SimplifiedPermissionEntry` wraps `PermissionEntry` with computed `SimplifiedLabels`. `PermissionsView.xaml` has a "Simplified" DataGrid column (line 254) bound to `SimplifiedLabels`, visible only when `IsSimplifiedMode=True`. ViewModel `OnIsSimplifiedModeChanged` calls `RebuildSimplifiedData()` which populates `SimplifiedResults`. Test `IsSimplifiedMode_WhenToggled_RebuildsSimplifiedResults` confirms. |
|
||||
| 2 | The report shows summary counts per permission level with color indicators distinguishing high, medium, and low access levels | VERIFIED | `PermissionSummaryBuilder.Build()` groups entries by `RiskLevel` and returns 4 `PermissionSummary` records with `Count` and `DistinctUsers`. `PermissionsView.xaml` lines 143-201 render an `ItemsControl` bound to `Summaries` with `DataTrigger`s that apply distinct background colors per risk level: High=#FEE2E2 (red), Medium=#FEF3C7 (amber), Low=#D1FAE5 (green), ReadOnly=#DBEAFE (blue). DataGrid rows are also color-coded via `RowStyle` DataTriggers (lines 226-243). Tests `Build_ReturnsAllFourRiskLevels` and `Summaries_ContainsCorrectRiskBreakdown` confirm. |
|
||||
| 3 | A detail-level selector (simple / detailed) controls whether individual item-level rows are shown or collapsed into summary rows | VERIFIED | `PermissionsView.xaml` lines 89-96 have two RadioButtons ("Simple (summary only)" / "Detailed (all rows)") bound to `IsDetailView` via `InvertBoolConverter`. DataGrid has a `MultiDataTrigger` (lines 214-220) that collapses the grid when `IsSimplifiedMode=True AND IsDetailView=False`, showing only summary cards. Test `IsDetailView_Toggle_DoesNotChangeCounts` confirms toggle does not re-compute data. |
|
||||
| 4 | Toggling modes and detail level does not require re-running the scan -- it re-renders from the already-fetched data | VERIFIED | `OnIsSimplifiedModeChanged` calls `RebuildSimplifiedData()` which wraps the existing `Results` collection -- no service call. `OnIsDetailViewChanged` only fires `OnPropertyChanged(nameof(ActiveItemsSource))`. `ActiveItemsSource` is a computed property that returns `Results` or `SimplifiedResults` based on mode. Export services also branch on `IsSimplifiedMode` without re-scanning. Test `IsDetailView_Toggle_DoesNotChangeCounts` confirms counts remain stable across toggles. |
|
||||
|
||||
**Score:** 4/4 truths verified
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
| Artifact | Expected | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `SharepointToolbox/Core/Models/RiskLevel.cs` | Risk level enum (High, Medium, Low, ReadOnly) | VERIFIED | 4-value enum, 17 lines, well-documented |
|
||||
| `SharepointToolbox/Core/Helpers/PermissionLevelMapping.cs` | Static mapping from SP role names to labels + risk | VERIFIED | 11 mappings, GetMapping/GetMappings/GetHighestRisk/GetSimplifiedLabels, case-insensitive, unknown->Medium fallback |
|
||||
| `SharepointToolbox/Core/Models/SimplifiedPermissionEntry.cs` | Wrapper model with SimplifiedLabels + RiskLevel | VERIFIED | Wraps PermissionEntry via Inner, 9 passthrough properties, WrapAll factory |
|
||||
| `SharepointToolbox/Core/Models/PermissionSummary.cs` | Summary record + builder | VERIFIED | PermissionSummary record + PermissionSummaryBuilder.Build returns all 4 risk levels |
|
||||
| `SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs` | IsSimplifiedMode, IsDetailView, SimplifiedResults, Summaries, ActiveItemsSource, RebuildSimplifiedData | VERIFIED | All properties present. Toggle handlers wired. Export branches for simplified mode. |
|
||||
| `SharepointToolbox/Views/Tabs/PermissionsView.xaml` | Toggle controls, summary panel, color-coded DataGrid | VERIFIED | Display Options GroupBox with checkbox + radio buttons, ItemsControl summary panel with color DataTriggers, DataGrid RowStyle with risk-level coloring, Simplified column visible in simplified mode |
|
||||
| `SharepointToolbox/Services/Export/CsvExportService.cs` | Simplified overload with SimplifiedLabels + RiskLevel columns | VERIFIED | BuildCsv(IReadOnlyList<SimplifiedPermissionEntry>) adds SimplifiedLabels and RiskLevel columns |
|
||||
| `SharepointToolbox/Services/Export/HtmlExportService.cs` | Simplified overload with risk cards and color-coded rows | VERIFIED | BuildHtml(IReadOnlyList<SimplifiedPermissionEntry>) adds risk-card summary section, risk-badge per row, Simplified column |
|
||||
| `SharepointToolbox/Core/Converters/InvertBoolConverter.cs` | Bool inverter for radio button binding | VERIFIED | IValueConverter, Convert and ConvertBack both invert |
|
||||
| `SharepointToolbox/Localization/Strings.resx` | New keys: chk.simplified.mode, grp.display.opts, lbl.detail.level, rad.detail.simple, rad.detail.detailed, lbl.summary.users | VERIFIED | All 6 keys present in EN |
|
||||
| `SharepointToolbox/Localization/Strings.fr.resx` | French translations for new keys | VERIFIED | All 6 keys present in FR |
|
||||
| `SharepointToolbox.Tests/Helpers/PermissionLevelMappingTests.cs` | Tests for mapping correctness | VERIFIED | 8 test methods covering known roles (11 InlineData), unknown fallback, case insensitivity, semicolon split, risk ranking, labels |
|
||||
| `SharepointToolbox.Tests/Models/PermissionSummaryBuilderTests.cs` | Tests for summary builder | VERIFIED | 4 test methods: all 4 risk levels, empty collection, distinct users, WrapAll preserves Inner |
|
||||
| `SharepointToolbox.Tests/ViewModels/PermissionsViewModelTests.cs` | Simplified mode tests | VERIFIED | 4 new tests: default false, toggle rebuilds, detail toggle no-op, risk breakdown |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
| From | To | Via | Status | Details |
|
||||
|------|----|-----|--------|---------|
|
||||
| SimplifiedPermissionEntry | PermissionLevelMapping | `PermissionLevelMapping.GetMappings/GetSimplifiedLabels/GetHighestRisk` | WIRED | Constructor calls all three mapping methods (lines 48-50) |
|
||||
| SimplifiedPermissionEntry | PermissionEntry | `Inner` property | WIRED | Constructor stores entry as `Inner`, 9 passthrough properties delegate to `Inner` |
|
||||
| PermissionsViewModel | SimplifiedPermissionEntry | `SimplifiedPermissionEntry.WrapAll(Results)` in `RebuildSimplifiedData` | WIRED | Line 234 |
|
||||
| PermissionsViewModel | PermissionSummaryBuilder | `PermissionSummaryBuilder.Build(SimplifiedResults)` in `RebuildSimplifiedData` | WIRED | Line 235 |
|
||||
| PermissionsView.xaml | PermissionsViewModel | DataGrid binds `ActiveItemsSource`, summary binds `Summaries`, toggles bind `IsSimplifiedMode`/`IsDetailView` | WIRED | XAML bindings at lines 72-96 (toggles), 143 (Summaries), 205 (ActiveItemsSource) |
|
||||
| CsvExportService | SimplifiedPermissionEntry | Overloaded `BuildCsv`/`WriteAsync` | WIRED | ViewModel calls simplified overload when `IsSimplifiedMode && SimplifiedResults.Count > 0` (line 346) |
|
||||
| HtmlExportService | SimplifiedPermissionEntry | Overloaded `BuildHtml`/`WriteAsync` | WIRED | ViewModel calls simplified overload when `IsSimplifiedMode && SimplifiedResults.Count > 0` (line 372) |
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
| Requirement | Description | Status | Evidence |
|
||||
|-------------|-------------|--------|----------|
|
||||
| SIMP-01 | User can toggle plain-language permission labels | SATISFIED | PermissionLevelMapping + SimplifiedPermissionEntry + IsSimplifiedMode toggle + Simplified column in DataGrid |
|
||||
| SIMP-02 | Permissions report includes summary counts and color coding | SATISFIED | PermissionSummaryBuilder + summary ItemsControl with color DataTriggers + DataGrid RowStyle coloring + HTML risk cards |
|
||||
| SIMP-03 | User can choose detail level (simple/detailed) for reports | SATISFIED | IsDetailView radio buttons + MultiDataTrigger hides DataGrid in simple mode + summary-only display |
|
||||
|
||||
No orphaned requirements found for Phase 8.
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
| File | Line | Pattern | Severity | Impact |
|
||||
|------|------|---------|----------|--------|
|
||||
| (none) | - | - | - | No TODO, FIXME, placeholder, or stub patterns found in any Phase 8 file |
|
||||
|
||||
### Build and Test Results
|
||||
|
||||
- **Main project build:** 0 errors, 9 warnings (all pre-existing NuGet compatibility warnings)
|
||||
- **Test project build:** 0 errors, 12 warnings (same NuGet warnings)
|
||||
- **Targeted tests:** 27 passed, 0 failed (PermissionLevelMappingTests + PermissionSummaryBuilderTests + PermissionsViewModelTests)
|
||||
- **PermissionEntry.cs:** Confirmed unmodified (git diff empty)
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
### 1. Simplified Mode Visual Toggle
|
||||
|
||||
**Test:** Run the app, scan a site's permissions, then check the "Simplified mode" checkbox.
|
||||
**Expected:** The "Simplified" column appears in the DataGrid showing labels like "Can edit files and list items" next to raw "Contribute". Summary cards appear above the grid with colored backgrounds (red for High, amber for Medium, green for Low, blue for ReadOnly) and correct counts.
|
||||
**Why human:** Visual layout, color rendering, and DataGrid column sizing cannot be verified programmatically.
|
||||
|
||||
### 2. Detail Level Switching
|
||||
|
||||
**Test:** With simplified mode on, click "Simple (summary only)" radio button, then "Detailed (all rows)".
|
||||
**Expected:** In simple mode, the DataGrid hides and only summary cards are visible. In detailed mode, the DataGrid reappears with all rows. No loading indicator or delay -- instant re-render.
|
||||
**Why human:** Visual collapse/expand behavior and perceived latency require human observation.
|
||||
|
||||
### 3. Export in Simplified Mode
|
||||
|
||||
**Test:** With simplified mode on, export to CSV and HTML. Open both files.
|
||||
**Expected:** CSV includes "SimplifiedLabels" and "RiskLevel" columns. HTML includes risk-level colored summary cards at the top and a "Simplified" + "Risk" column in the table with colored badges.
|
||||
**Why human:** File content rendering and visual appearance of HTML export need manual inspection.
|
||||
|
||||
### Gaps Summary
|
||||
|
||||
No gaps found. All 4 success criteria are verified through code inspection, build confirmation, and passing unit tests. The implementation is complete: data models, mapping layer, ViewModel logic, XAML UI with color-coded summary panel and detail toggle, export service overloads, localization in EN and FR, and comprehensive unit test coverage.
|
||||
|
||||
---
|
||||
|
||||
_Verified: 2026-04-07T14:30:00Z_
|
||||
_Verifier: Claude (gsd-verifier)_
|
||||
103
.planning/phases/09-storage-visualization/VERIFICATION.md
Normal file
103
.planning/phases/09-storage-visualization/VERIFICATION.md
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
phase: 09-storage-visualization
|
||||
verified: 2026-04-07T15:00:00Z
|
||||
status: passed
|
||||
score: 4/4 success criteria verified
|
||||
re_verification: false
|
||||
---
|
||||
|
||||
# Phase 9: Storage Visualization Verification Report
|
||||
|
||||
**Phase Goal:** The Storage Metrics tab displays an interactive chart of space consumption by file type, togglable between pie/donut and bar chart views
|
||||
**Verified:** 2026-04-07
|
||||
**Status:** PASSED
|
||||
**Re-verification:** No -- initial verification
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths (Success Criteria)
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 1 | A WPF charting library (LiveCharts2) is integrated as a NuGet dependency and renders correctly in the self-contained EXE build | VERIFIED | `LiveChartsCore.SkiaSharpView.WPF 2.0.0-rc5.4` in csproj line 43; `IncludeNativeLibrariesForSelfExtract=true` in csproj line 16; `dotnet build` succeeds with 0 errors |
|
||||
| 2 | After a storage scan completes, a chart appears in the Storage Metrics tab showing space broken down by file type | VERIFIED | `StorageService.CollectFileTypeMetricsAsync` (lines 68-159) enumerates files via CamlQuery with `FileLeafRef`/`File_x0020_Size`, groups by extension; `StorageViewModel.RunOperationAsync` calls it (line 218) and sets `FileTypeMetrics` (line 224); `StorageView.xaml` binds `lvc:PieChart Series="{Binding PieChartSeries}"` (line 170) and `lvc:CartesianChart Series="{Binding BarChartSeries}"` (line 190) |
|
||||
| 3 | A toggle control switches the chart between pie/donut and bar chart representations without re-running the scan | VERIFIED | `IsDonutChart` property (line 41) with `OnIsDonutChartChanged` (line 298) calls `UpdateChartSeries`; RadioButtons in StorageView.xaml (lines 67-71) bind to `IsDonutChart`; PieChart visibility bound via `MultiDataTrigger` on `IsDonutChart=True` (lines 160-161); CartesianChart visibility on `IsDonutChart=False` (lines 180-181); toggle only regenerates series from in-memory `FileTypeMetrics`, no re-scan |
|
||||
| 4 | The chart updates automatically whenever a new storage scan finishes, without requiring manual refresh | VERIFIED | `RunOperationAsync` (line 169) calls `CollectStorageAsync` then `CollectFileTypeMetricsAsync` (line 218), sets `FileTypeMetrics` (line 224) whose private setter calls `UpdateChartSeries()` (line 51); every scan execution path updates chart data automatically |
|
||||
|
||||
**Score:** 4/4 success criteria verified
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
| Artifact | Expected | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `SharepointToolbox/SharepointToolbox.csproj` | LiveChartsCore.SkiaSharpView.WPF PackageReference + IncludeNativeLibrariesForSelfExtract | VERIFIED | Line 43: PackageReference version 2.0.0-rc5.4; Line 16: IncludeNativeLibrariesForSelfExtract=true |
|
||||
| `SharepointToolbox/Core/Models/FileTypeMetric.cs` | Record with Extension, TotalSizeBytes, FileCount, DisplayLabel | VERIFIED | 21-line record with computed DisplayLabel property |
|
||||
| `SharepointToolbox/Services/IStorageService.cs` | CollectFileTypeMetricsAsync method signature | VERIFIED | Returns `Task<IReadOnlyList<FileTypeMetric>>` with ClientContext, IProgress, CancellationToken parameters |
|
||||
| `SharepointToolbox/Services/StorageService.cs` | CollectFileTypeMetricsAsync implementation with CSOM CamlQuery | VERIFIED | Lines 68-159: paged CamlQuery with FileLeafRef/File_x0020_Size, extension grouping, sorted result |
|
||||
| `SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs` | Chart properties, toggle, UpdateChartSeries, auto-update from RunOperationAsync | VERIFIED | 393 lines: FileTypeMetrics, PieChartSeries, BarChartSeries, BarXAxes, BarYAxes, IsDonutChart, UpdateChartSeries with top-10+Other logic |
|
||||
| `SharepointToolbox/Views/Tabs/StorageView.xaml` | PieChart, CartesianChart controls, RadioButton toggle, data bindings | VERIFIED | 199 lines: lvc:PieChart and lvc:CartesianChart with MultiDataTrigger visibility, RadioButtons for toggle |
|
||||
| `SharepointToolbox.Tests/ViewModels/StorageViewModelChartTests.cs` | Unit tests for chart series, toggle, aggregation | VERIFIED | 7 tests covering series creation, bar structure, donut toggle, top-10+Other, tenant switch, empty data |
|
||||
| `SharepointToolbox/Localization/Strings.resx` | Chart localization keys (stor.chart.*) | VERIFIED | 5 keys: stor.chart.title, stor.chart.donut, stor.chart.bar, stor.chart.toggle, stor.chart.nodata |
|
||||
| `SharepointToolbox/Localization/Strings.fr.resx` | French chart localization keys | VERIFIED | All 5 keys present with French translations |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
| From | To | Via | Status | Details |
|
||||
|------|----|-----|--------|---------|
|
||||
| StorageViewModel.RunOperationAsync | StorageService.CollectFileTypeMetricsAsync | `_storageService.CollectFileTypeMetricsAsync(ctx, progress, ct)` | WIRED | Line 218 of ViewModel calls service; result assigned to FileTypeMetrics at line 224 |
|
||||
| FileTypeMetrics setter | UpdateChartSeries | Private setter calls `UpdateChartSeries()` | WIRED | Line 51: setter triggers chart rebuild |
|
||||
| IsDonutChart toggle | UpdateChartSeries | OnIsDonutChartChanged partial method | WIRED | Line 298-301: property change handler calls UpdateChartSeries |
|
||||
| StorageView.xaml PieChart | PieChartSeries | `Series="{Binding PieChartSeries}"` | WIRED | Line 170 in XAML |
|
||||
| StorageView.xaml CartesianChart | BarChartSeries | `Series="{Binding BarChartSeries}"` | WIRED | Line 190 in XAML |
|
||||
| StorageView.xaml RadioButtons | IsDonutChart | `IsChecked="{Binding IsDonutChart}"` | WIRED | Lines 68-71 in XAML |
|
||||
| IStorageService.CollectFileTypeMetricsAsync | FileTypeMetric | Return type `IReadOnlyList<FileTypeMetric>` | WIRED | Interface line 25 returns FileTypeMetric list |
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
| Requirement | Source Plan | Description | Status | Evidence |
|
||||
|-------------|------------|-------------|--------|----------|
|
||||
| VIZZ-01 | 09-01, 09-04 | Storage Metrics tab includes a graph showing space by file type | SATISFIED | LiveCharts2 integrated; PieChart and CartesianChart in StorageView.xaml; CollectFileTypeMetricsAsync provides data grouped by extension |
|
||||
| VIZZ-02 | 09-02, 09-03, 09-04 | User can toggle between pie/donut chart and bar chart views | SATISFIED | IsDonutChart property with RadioButton toggle; MultiDataTrigger visibility switching between PieChart and CartesianChart |
|
||||
| VIZZ-03 | 09-03, 09-04 | Graph updates when storage scan completes | SATISFIED | RunOperationAsync calls CollectFileTypeMetricsAsync then sets FileTypeMetrics, whose setter triggers UpdateChartSeries automatically |
|
||||
|
||||
No orphaned requirements found. All 3 VIZZ requirements are covered by plans and satisfied by implementation.
|
||||
|
||||
### Build and Test Verification
|
||||
|
||||
| Check | Status | Details |
|
||||
|-------|--------|---------|
|
||||
| `dotnet build SharepointToolbox.csproj` | PASSED | 0 errors, 6 NuGet compatibility warnings (SkiaSharp/OpenTK on net10.0 -- informational only) |
|
||||
| `dotnet test --filter StorageViewModelChart` | PASSED | 7 passed, 0 failed, 0 skipped |
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
| File | Line | Pattern | Severity | Impact |
|
||||
|------|------|---------|----------|--------|
|
||||
| (none) | - | - | - | No anti-patterns detected |
|
||||
|
||||
No TODO/FIXME/HACK markers, no empty implementations, no stub returns, no console.log-only handlers found in any phase 9 artifacts.
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
### 1. Chart renders visually after a real storage scan
|
||||
|
||||
**Test:** Connect to a SharePoint tenant, run a storage scan, observe the chart area below the DataGrid.
|
||||
**Expected:** A donut chart appears showing file types (e.g., DOCX, PDF, XLSX) with legend on the right. Each slice is labeled and has a tooltip showing size and file count.
|
||||
**Why human:** Chart rendering depends on SkiaSharp GPU/software rendering pipeline; cannot verify visual output programmatically.
|
||||
|
||||
### 2. Toggle between donut and bar chart
|
||||
|
||||
**Test:** After a scan completes and chart is visible, click the "Bar Chart" radio button in the Chart View group.
|
||||
**Expected:** The donut chart disappears and a bar chart appears with file types on the X axis (rotated -45 degrees) and formatted byte sizes on the Y axis. Toggling back to "Donut Chart" restores the donut view.
|
||||
**Why human:** Visual transition and layout correctness require human eye.
|
||||
|
||||
### 3. Self-contained EXE publish includes SkiaSharp native libraries
|
||||
|
||||
**Test:** Run `dotnet publish -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true` and verify the resulting EXE launches and renders charts.
|
||||
**Expected:** Single EXE runs without missing DLL errors; charts render in the published build.
|
||||
**Why human:** Native library extraction and SkiaSharp initialization behavior varies by machine and can only be confirmed at runtime.
|
||||
|
||||
---
|
||||
|
||||
_Verified: 2026-04-07_
|
||||
_Verifier: Claude (gsd-verifier)_
|
||||
Reference in New Issue
Block a user