docs(phase-06): complete phase verification and update state
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ milestone: v1.0
|
||||
milestone_name: milestone
|
||||
status: completed
|
||||
stopped_at: Completed 06-05-PLAN.md — 10 GlobalSiteSelectionTests covering full global site selection contract
|
||||
last_updated: "2026-04-07T08:14:30.489Z"
|
||||
last_updated: "2026-04-07T08:18:02.949Z"
|
||||
last_activity: 2026-04-07 — Roadmap created (Phases 6-9), 10/10 requirements mapped
|
||||
progress:
|
||||
total_phases: 4
|
||||
|
||||
137
.planning/phases/06-global-site-selection/06-VERIFICATION.md
Normal file
137
.planning/phases/06-global-site-selection/06-VERIFICATION.md
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
phase: 06-global-site-selection
|
||||
verified: 2026-04-07T00:00:00Z
|
||||
status: passed
|
||||
score: 7/7 truths verified
|
||||
re_verification: false
|
||||
---
|
||||
|
||||
# Phase 06: Global Site Selection Verification Report
|
||||
|
||||
**Phase Goal:** Administrators can select one or more target sites once from the toolbar and have every feature tab use that selection by default
|
||||
**Verified:** 2026-04-07
|
||||
**Status:** PASSED
|
||||
**Re-verification:** No — initial verification
|
||||
|
||||
---
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 1 | GlobalSitesChangedMessage exists following the ValueChangedMessage pattern | VERIFIED | `GlobalSitesChangedMessage.cs` — `sealed class ... : ValueChangedMessage<IReadOnlyList<SiteInfo>>` |
|
||||
| 2 | FeatureViewModelBase receives message, stores GlobalSites, exposes virtual hook | VERIFIED | `FeatureViewModelBase.cs` lines 30, 82–83, 90–103 — property, registration, private receiver, virtual override |
|
||||
| 3 | MainWindowViewModel owns GlobalSelectedSites, broadcasts message, clears on tenant/session | VERIFIED | `MainWindowViewModel.cs` lines 43–75, 102–103, 146 — collection, CollectionChanged broadcast, clear paths |
|
||||
| 4 | Toolbar shows "Select Sites" button bound to OpenGlobalSitePickerCommand and a live count label | VERIFIED | `MainWindow.xaml` lines 26–31; `MainWindow.xaml.cs` lines 25–29 — button, TextBlock, dialog factory wired |
|
||||
| 5 | Localization keys present in EN and FR for all 5 toolbar strings | VERIFIED | `Strings.resx` lines 308–320; `Strings.fr.resx` lines 308–320 — 5 keys each |
|
||||
| 6 | All 6 consuming tab VMs override OnGlobalSitesChanged with local-override protection | VERIFIED | Grep confirms override in: PermissionsViewModel, StorageViewModel, SearchViewModel, DuplicatesViewModel, FolderStructureViewModel, TransferViewModel; BulkMembersViewModel confirmed excluded (no match) |
|
||||
| 7 | 10 unit tests pass covering the full contract; no regressions in existing suite | VERIFIED | `dotnet test --filter GlobalSiteSelection` → 10 Passed; full suite → 144 Passed, 22 Skipped, 0 Failed |
|
||||
|
||||
**Score:** 7/7 truths verified
|
||||
|
||||
---
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
| Artifact | Provides | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `SharepointToolbox/Core/Messages/GlobalSitesChangedMessage.cs` | Messenger message for global site selection | VERIFIED | Exists, substantive (9 lines, ValueChangedMessage<IReadOnlyList<SiteInfo>>), registered in FeatureViewModelBase |
|
||||
| `SharepointToolbox/ViewModels/FeatureViewModelBase.cs` | Base class with GlobalSites property and virtual hook | VERIFIED | Contains `GlobalSites`, `OnGlobalSitesChanged`, registration in `OnActivated` |
|
||||
| `SharepointToolbox/ViewModels/MainWindowViewModel.cs` | Global site selection state, command, broadcast | VERIFIED | Contains `GlobalSelectedSites`, `OpenGlobalSitePickerCommand`, `GlobalSitesSelectedLabel`, `BroadcastGlobalSites` |
|
||||
| `SharepointToolbox/MainWindow.xaml` | Toolbar with Select Sites button and count label | VERIFIED | Contains `OpenGlobalSitePickerCommand` binding and `GlobalSitesSelectedLabel` TextBlock |
|
||||
| `SharepointToolbox/MainWindow.xaml.cs` | SitePickerDialog factory wiring | VERIFIED | Contains `OpenGlobalSitePickerDialog` factory lambda |
|
||||
| `SharepointToolbox/Localization/Strings.resx` | EN localization keys | VERIFIED | 5 keys: toolbar.selectSites, toolbar.selectSites.tooltip, toolbar.selectSites.tooltipDisabled, toolbar.globalSites.count, toolbar.globalSites.none |
|
||||
| `SharepointToolbox/Localization/Strings.fr.resx` | FR localization keys | VERIFIED | Same 5 keys with French translations |
|
||||
| `SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs` | Multi-site global consumption | VERIFIED | `OnGlobalSitesChanged` override, `_hasLocalSiteOverride`, reset in `OnTenantSwitched` |
|
||||
| `SharepointToolbox/ViewModels/Tabs/StorageViewModel.cs` | Single-site global consumption | VERIFIED | `OnGlobalSitesChanged`, `OnSiteUrlChanged` partial, `_hasLocalSiteOverride`, reset in `OnTenantSwitched` |
|
||||
| `SharepointToolbox/ViewModels/Tabs/SearchViewModel.cs` | Single-site global consumption | VERIFIED | `OnGlobalSitesChanged` confirmed present |
|
||||
| `SharepointToolbox/ViewModels/Tabs/DuplicatesViewModel.cs` | Single-site global consumption | VERIFIED | `OnGlobalSitesChanged` confirmed present |
|
||||
| `SharepointToolbox/ViewModels/Tabs/FolderStructureViewModel.cs` | Single-site global consumption | VERIFIED | `OnGlobalSitesChanged` confirmed present |
|
||||
| `SharepointToolbox/ViewModels/Tabs/TransferViewModel.cs` | Single-site (SourceSiteUrl) global consumption | VERIFIED | `OnGlobalSitesChanged`, `_hasLocalSourceSiteOverride`, `OnSourceSiteUrlChanged` confirmed present |
|
||||
| `SharepointToolbox.Tests/ViewModels/GlobalSiteSelectionTests.cs` | 10 unit tests for full contract | VERIFIED | All 10 tests pass |
|
||||
|
||||
---
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
| From | To | Via | Status | Details |
|
||||
|------|----|-----|--------|---------|
|
||||
| `FeatureViewModelBase.cs` | `GlobalSitesChangedMessage.cs` | `Messenger.Register<GlobalSitesChangedMessage>` in OnActivated | WIRED | Line 82: `Messenger.Register<GlobalSitesChangedMessage>(this, (r, m) => ...)` |
|
||||
| `MainWindowViewModel.cs` | `GlobalSitesChangedMessage.cs` | `WeakReferenceMessenger.Default.Send` in BroadcastGlobalSites | WIRED | Lines 180–182: `WeakReferenceMessenger.Default.Send(new GlobalSitesChangedMessage(...))` |
|
||||
| `MainWindow.xaml` | `MainWindowViewModel.cs` | Command binding for OpenGlobalSitePickerCommand | WIRED | Line 27: `Command="{Binding OpenGlobalSitePickerCommand}"` |
|
||||
| `MainWindow.xaml.cs` | `SitePickerDialog.xaml.cs` | Dialog factory lambda using DI | WIRED | Lines 25–29: `viewModel.OpenGlobalSitePickerDialog = () => { var factory = serviceProvider.GetRequiredService<Func<TenantProfile, SitePickerDialog>>(); ... }` |
|
||||
| `PermissionsViewModel.cs` | `FeatureViewModelBase.cs` | Override of OnGlobalSitesChanged virtual method | WIRED | Line 161: `protected override void OnGlobalSitesChanged(IReadOnlyList<SiteInfo> sites)` |
|
||||
| `StorageViewModel.cs` | `FeatureViewModelBase.cs` | Override of OnGlobalSitesChanged virtual method | WIRED | Line 100: `protected override void OnGlobalSitesChanged(IReadOnlyList<SiteInfo> sites)` |
|
||||
| `GlobalSiteSelectionTests.cs` | `MainWindowViewModel.cs` | Tests broadcast and clear behavior | WIRED | Test 10 uses `GlobalSelectedSites`; Tests 1–9 send via WeakReferenceMessenger |
|
||||
| `GlobalSiteSelectionTests.cs` | `StorageViewModel.cs` | Tests single-site consumption and local override | WIRED | Tests 3–5, 8 exercise `OnGlobalSitesChanged` via messenger send |
|
||||
|
||||
---
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
| Requirement | Source Plans | Description | Status | Evidence |
|
||||
|-------------|-------------|-------------|--------|----------|
|
||||
| SITE-01 | 06-01, 06-02, 06-03, 06-04, 06-05 | User can select one or multiple target sites from toolbar and all feature tabs use that selection as default | SATISFIED | Message contract (06-01), MainWindowViewModel broadcast (06-02), toolbar UI (06-03), tab VM consumption (06-04), unit tests (06-05) — full end-to-end chain verified |
|
||||
| SITE-02 | 06-04, 06-05 | User can override global site selection per-tab for single-site operations | SATISFIED | `_hasLocalSiteOverride` field in all 6 consuming VMs; `OnSiteUrlChanged` / `OnSourceSiteUrlChanged` partial methods detect user typing; tests 4, 7 verify local override prevents global overwrite |
|
||||
|
||||
No orphaned requirements — REQUIREMENTS.md maps only SITE-01 and SITE-02 to Phase 6, and both are claimed and satisfied by the plans.
|
||||
|
||||
---
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
None. Files scanned for TODO/FIXME/HACK/PLACEHOLDER, empty implementations, and stub returns:
|
||||
|
||||
- "placeholder" occurrences in `MainWindow.xaml.cs` are code comments (`// Replace ... placeholder with the DI-resolved ...`) describing the construction pattern — they are not stub implementations.
|
||||
- "placeholder" in export service HTML strings is an HTML `<input placeholder=...>` attribute — unrelated to implementation stubs.
|
||||
- No empty handlers, `return null`, `return {}`, or `console.log`-only implementations found.
|
||||
- Build: 0 errors, 0 warnings.
|
||||
|
||||
---
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
The following items cannot be verified programmatically and require a running instance of the application:
|
||||
|
||||
#### 1. Select Sites button visual presence and position
|
||||
|
||||
**Test:** Launch the application, connect to a tenant profile. Observe the main toolbar.
|
||||
**Expected:** A "Select Sites" button is visible after the Clear Session button separator, followed by a gray label showing "No sites selected" (or the FR equivalent if app is in French).
|
||||
**Why human:** XAML rendering and visual layout cannot be verified from static file analysis.
|
||||
|
||||
#### 2. SitePickerDialog opens on button click
|
||||
|
||||
**Test:** Click the "Select Sites" toolbar button while connected to a tenant.
|
||||
**Expected:** The SitePickerDialog opens, displaying the sites for the connected tenant. Selecting sites and clicking OK updates the count label (e.g., "2 site(s) selected").
|
||||
**Why human:** Dialog opening requires a live DI container, real window handle, and SharePoint connectivity.
|
||||
|
||||
#### 3. Button disabled state when no profile is connected
|
||||
|
||||
**Test:** Launch the application without selecting a tenant profile (or deselect the current one).
|
||||
**Expected:** The "Select Sites" button appears visually disabled and cannot be clicked.
|
||||
**Why human:** WPF CanExecute rendering requires a live UI; IsEnabled binding cannot be observed statically.
|
||||
|
||||
#### 4. Tab pre-fill behavior end-to-end
|
||||
|
||||
**Test:** Select 2 sites globally. Navigate to the Storage tab, Search tab, Permissions tab, and Transfer tab.
|
||||
**Expected:** Storage/Search SiteUrl fields show the first selected site URL; Permissions SelectedSites shows both sites; Transfer SourceSiteUrl shows the first site URL.
|
||||
**Why human:** UI binding rendering from pre-filled ViewModel state requires a running application.
|
||||
|
||||
#### 5. Local override does not disrupt global selection
|
||||
|
||||
**Test:** With 2 global sites selected, go to the Storage tab and type a custom URL in the site URL field. Switch to the Permissions tab.
|
||||
**Expected:** Permissions tab still shows the 2 globally selected sites. The Storage tab keeps the manually typed URL. The toolbar still shows "2 site(s) selected."
|
||||
**Why human:** Cross-tab state isolation requires observing live UI across multiple tab switches.
|
||||
|
||||
---
|
||||
|
||||
### Gaps Summary
|
||||
|
||||
No gaps. All 7 observable truths are verified. All 14 required artifacts exist, are substantive, and are wired. All 8 key links are confirmed. Both requirements (SITE-01, SITE-02) are satisfied with full traceability. The test suite confirms correctness with 10 new passing tests and 0 regressions.
|
||||
|
||||
---
|
||||
|
||||
_Verified: 2026-04-07_
|
||||
_Verifier: Claude (gsd-verifier)_
|
||||
Reference in New Issue
Block a user