Archive 5 phases (36 plans) to milestones/v1.0-phases/. Archive roadmap, requirements, and audit to milestones/. Evolve PROJECT.md with shipped state and validated requirements. Collapse ROADMAP.md to one-line milestone summary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
138 lines
5.6 KiB
Markdown
138 lines
5.6 KiB
Markdown
---
|
|
phase: 02-permissions
|
|
plan: 03
|
|
subsystem: api
|
|
tags: [sharepoint, pnp-framework, tenant-admin, site-listing, csharp]
|
|
|
|
# Dependency graph
|
|
requires:
|
|
- phase: 01-foundation
|
|
provides: SessionManager.GetOrCreateContextAsync, TenantProfile, OperationProgress
|
|
provides:
|
|
- ISiteListService interface for ViewModel mocking
|
|
- SiteListService tenant admin API wrapper enumerating all sites
|
|
- SiteInfo record model (Url, Title)
|
|
affects: [02-06-site-picker-dialog, 02-permissions-viewmodel]
|
|
|
|
# Tech tracking
|
|
tech-stack:
|
|
added: []
|
|
patterns:
|
|
- "Admin URL derivation: Regex transform contoso.sharepoint.com → contoso-admin.sharepoint.com"
|
|
- "ServerException wrapping: Access denied → InvalidOperationException with actionable message"
|
|
- "InternalsVisibleTo pattern for testing internal static helpers without making them public"
|
|
|
|
key-files:
|
|
created:
|
|
- SharepointToolbox/Core/Models/SiteInfo.cs
|
|
- SharepointToolbox/Services/ISiteListService.cs
|
|
- SharepointToolbox/Services/SiteListService.cs
|
|
modified:
|
|
- SharepointToolbox/AssemblyInfo.cs
|
|
- SharepointToolbox.Tests/Services/SiteListServiceTests.cs
|
|
|
|
key-decisions:
|
|
- "DeriveAdminUrl is internal static (not private) so tests can call it directly without a live tenant"
|
|
- "InternalsVisibleTo added to AssemblyInfo.cs — plan specified internal visibility but omitted the assembly attribute needed to test it"
|
|
- "OneDrive personal sites filtered by -my.sharepoint.com URL pattern in addition to Active status check"
|
|
|
|
patterns-established:
|
|
- "Admin URL derivation: use Regex.Replace with (https://[^.]+)(\\.sharepoint\\.com) pattern"
|
|
- "Tenant admin access: pass synthetic TenantProfile with admin URL to SessionManager.GetOrCreateContextAsync"
|
|
|
|
requirements-completed: [PERM-02]
|
|
|
|
# Metrics
|
|
duration: 1min
|
|
completed: 2026-04-02
|
|
---
|
|
|
|
# Phase 2 Plan 3: SiteListService Summary
|
|
|
|
**ISiteListService + SiteListService wrapper for SharePoint tenant admin API using PnP.Framework Tenant.GetSitePropertiesFromSharePoint, with admin URL regex derivation and ServerException-to-InvalidOperationException wrapping**
|
|
|
|
## Performance
|
|
|
|
- **Duration:** 1 min
|
|
- **Started:** 2026-04-02T11:48:57Z
|
|
- **Completed:** 2026-04-02T11:50:40Z
|
|
- **Tasks:** 1 (TDD: RED + GREEN)
|
|
- **Files modified:** 5
|
|
|
|
## Accomplishments
|
|
|
|
- SiteInfo record model created in Core/Models
|
|
- ISiteListService interface defined — enables ViewModel mocking in Plan 06 (SitePickerDialog)
|
|
- SiteListService derives admin URL via Regex, connects via SessionManager to tenant admin endpoint
|
|
- Active-only filtering with OneDrive personal site exclusion (-my.sharepoint.com)
|
|
- DeriveAdminUrl tested with 2 unit tests (standard URL, trailing-slash URL)
|
|
|
|
## Task Commits
|
|
|
|
Each task was committed atomically:
|
|
|
|
1. **Task 1 RED: SiteListServiceTests (failing)** - `5c10840` (test)
|
|
2. **Task 1 GREEN: ISiteListService, SiteListService, SiteInfo** - `78b3d4f` (feat)
|
|
|
|
**Plan metadata:** _(pending)_
|
|
|
|
_Note: TDD task has two commits (test RED → feat GREEN); no REFACTOR step needed — code is clean as written_
|
|
|
|
## Files Created/Modified
|
|
|
|
- `SharepointToolbox/Core/Models/SiteInfo.cs` - Simple record with Url and Title properties
|
|
- `SharepointToolbox/Services/ISiteListService.cs` - Interface contract for GetSitesAsync
|
|
- `SharepointToolbox/Services/SiteListService.cs` - Implementation: admin URL derivation, tenant query, filtering, error wrapping
|
|
- `SharepointToolbox/AssemblyInfo.cs` - Added InternalsVisibleTo("SharepointToolbox.Tests")
|
|
- `SharepointToolbox.Tests/Services/SiteListServiceTests.cs` - Two unit tests for DeriveAdminUrl
|
|
|
|
## Decisions Made
|
|
|
|
- DeriveAdminUrl marked `internal static` rather than `private static` to allow direct unit testing without mocking a full SessionManager
|
|
- `InternalsVisibleTo("SharepointToolbox.Tests")` added to AssemblyInfo.cs — this is the standard .NET approach for testing internal members (Rule 3 deviation, see below)
|
|
- OneDrive sites excluded by URL pattern (`-my.sharepoint.com`) in addition to `Status == "Active"` to avoid returning personal storage sites in the picker
|
|
|
|
## Deviations from Plan
|
|
|
|
### Auto-fixed Issues
|
|
|
|
**1. [Rule 3 - Blocking] Added InternalsVisibleTo to expose internal DeriveAdminUrl to test project**
|
|
- **Found during:** Task 1 GREEN (test compilation failed with CS0117)
|
|
- **Issue:** Plan specified `internal static` for DeriveAdminUrl for testability, but did not include the `InternalsVisibleTo` assembly attribute required for the test project to access it
|
|
- **Fix:** Added `[assembly: InternalsVisibleTo("SharepointToolbox.Tests")]` to AssemblyInfo.cs
|
|
- **Files modified:** SharepointToolbox/AssemblyInfo.cs
|
|
- **Verification:** Tests compile and both DeriveAdminUrl tests pass (2/2)
|
|
- **Committed in:** 78b3d4f (GREEN commit)
|
|
|
|
---
|
|
|
|
**Total deviations:** 1 auto-fixed (1 blocking)
|
|
**Impact on plan:** Necessary for test infrastructure — plan's intent was clearly to test internal method; InternalsVisibleTo is the standard mechanism. No scope creep.
|
|
|
|
## Issues Encountered
|
|
|
|
None
|
|
|
|
## User Setup Required
|
|
|
|
None - no external service configuration required.
|
|
|
|
## Next Phase Readiness
|
|
|
|
- ISiteListService ready for injection into SitePickerDialog (Plan 06)
|
|
- SiteListService compiles and DeriveAdminUrl verified; live tenant testing requires admin credentials (handled at runtime via SessionManager interactive login)
|
|
- Full test suite: 53 pass, 4 skip, 0 fail
|
|
|
|
## Self-Check: PASSED
|
|
|
|
- FOUND: SharepointToolbox/Core/Models/SiteInfo.cs
|
|
- FOUND: SharepointToolbox/Services/ISiteListService.cs
|
|
- FOUND: SharepointToolbox/Services/SiteListService.cs
|
|
- FOUND: .planning/phases/02-permissions/02-03-SUMMARY.md
|
|
- FOUND: commit 5c10840 (test RED)
|
|
- FOUND: commit 78b3d4f (feat GREEN)
|
|
|
|
---
|
|
*Phase: 02-permissions*
|
|
*Completed: 2026-04-02*
|