fix(01-foundation): revise plans based on checker feedback
- 01-03: wave 2 → wave 3 (depends on 01-02 which is also wave 2; must be wave 3) - 01-06: add ProgressUpdatedMessage.cs to files_modified; add third StatusBarItem (progress %) to XAML per locked CONTEXT.md decision; add ProgressUpdatedMessage subscription in MainWindowViewModel.OnActivated() - 01-08: add comment to empty <files> element (auto task with no file output) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
phase: 01-foundation
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 2
|
||||
wave: 3
|
||||
depends_on:
|
||||
- 01-01
|
||||
- 01-02
|
||||
|
||||
@@ -8,6 +8,7 @@ depends_on:
|
||||
- 01-04
|
||||
- 01-05
|
||||
files_modified:
|
||||
- SharepointToolbox/Core/Messages/ProgressUpdatedMessage.cs
|
||||
- SharepointToolbox/ViewModels/FeatureViewModelBase.cs
|
||||
- SharepointToolbox/ViewModels/MainWindowViewModel.cs
|
||||
- SharepointToolbox/ViewModels/ProfileManagementViewModel.cs
|
||||
@@ -53,6 +54,10 @@ must_haves:
|
||||
to: "SharepointToolbox/Core/Messages/TenantSwitchedMessage.cs"
|
||||
via: "WeakReferenceMessenger.Default.Send on ComboBox selection change"
|
||||
pattern: "TenantSwitchedMessage"
|
||||
- from: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
||||
to: "SharepointToolbox/Core/Messages/ProgressUpdatedMessage.cs"
|
||||
via: "Messenger.Register<ProgressUpdatedMessage> in OnActivated — updates StatusBar observable properties"
|
||||
pattern: "ProgressUpdatedMessage"
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -113,6 +118,7 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: FeatureViewModelBase + unit tests</name>
|
||||
<files>
|
||||
SharepointToolbox/Core/Messages/ProgressUpdatedMessage.cs,
|
||||
SharepointToolbox/ViewModels/FeatureViewModelBase.cs,
|
||||
SharepointToolbox.Tests/ViewModels/FeatureViewModelBaseTests.cs
|
||||
</files>
|
||||
@@ -248,6 +254,8 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
```csharp
|
||||
[ObservableProperty] private TenantProfile? _selectedProfile;
|
||||
[ObservableProperty] private string _connectionStatus = "Not connected";
|
||||
[ObservableProperty] private string _progressStatus = string.Empty;
|
||||
[ObservableProperty] private int _progressPercentage;
|
||||
public ObservableCollection<TenantProfile> TenantProfiles { get; } = new();
|
||||
|
||||
// ConnectCommand: calls SessionManager.GetOrCreateContextAsync(SelectedProfile)
|
||||
@@ -257,6 +265,22 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
// LoadProfilesAsync: called on startup, loads from ProfileService
|
||||
```
|
||||
|
||||
Override `OnActivated()` to register for `ProgressUpdatedMessage` from any active feature ViewModel:
|
||||
```csharp
|
||||
protected override void OnActivated()
|
||||
{
|
||||
base.OnActivated();
|
||||
Messenger.Register<ProgressUpdatedMessage>(this, (r, m) =>
|
||||
{
|
||||
r.ProgressStatus = m.Value.Message;
|
||||
r.ProgressPercentage = m.Value.Total > 0
|
||||
? (int)(100.0 * m.Value.Current / m.Value.Total)
|
||||
: 0;
|
||||
});
|
||||
}
|
||||
```
|
||||
This wires the StatusBar operation text and progress % to live updates from any running feature operation.
|
||||
|
||||
**ProfileManagementViewModel.cs**: Wraps ProfileService for dialog binding.
|
||||
- `ObservableCollection<TenantProfile> Profiles`
|
||||
- `AddCommand`, `RenameCommand`, `DeleteCommand`
|
||||
@@ -269,7 +293,8 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
- On language change: updates `TranslationSource.Instance.CurrentCulture` + calls `SettingsService.SetLanguageAsync`
|
||||
- `RunOperationAsync`: not applicable — stub throws `NotSupportedException` (Settings tab has no long-running operation)
|
||||
|
||||
**MainWindow.xaml** — Full shell layout as locked in CONTEXT.md:
|
||||
**MainWindow.xaml** — Full shell layout as locked in CONTEXT.md.
|
||||
StatusBar MUST have three fields per the locked decision (tenant name | operation status text | progress percentage):
|
||||
```xml
|
||||
<Window Title="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[app.title]}"
|
||||
MinWidth="900" MinHeight="600">
|
||||
@@ -288,11 +313,13 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
Command="{Binding ClearSessionCommand}" />
|
||||
</ToolBar>
|
||||
|
||||
<!-- StatusBar -->
|
||||
<!-- StatusBar: three fields per locked layout decision -->
|
||||
<StatusBar DockPanel.Dock="Bottom" Height="24">
|
||||
<StatusBarItem Content="{Binding SelectedProfile.Name}" />
|
||||
<Separator />
|
||||
<StatusBarItem Content="{Binding ConnectionStatus}" />
|
||||
<Separator />
|
||||
<StatusBarItem Content="{Binding ProgressPercentage, StringFormat={}{0}%}" />
|
||||
</StatusBar>
|
||||
|
||||
<!-- Log Panel -->
|
||||
@@ -370,7 +397,7 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
<verify>
|
||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj 2>&1 | tail -5</automated>
|
||||
</verify>
|
||||
<done>Build succeeds with 0 errors. MainWindow.xaml contains RichTextBox x:Name="LogPanel". All 8 tab headers use TranslationSource bindings. Global exception handlers registered in App.xaml.cs.</done>
|
||||
<done>Build succeeds with 0 errors. MainWindow.xaml contains RichTextBox x:Name="LogPanel". StatusBar has three StatusBarItems (tenant name, connection status, progress %). All 8 tab headers use TranslationSource bindings. Global exception handlers registered in App.xaml.cs.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
@@ -379,13 +406,15 @@ public sealed class LanguageChangedMessage : ValueChangedMessage<string>
|
||||
- `dotnet build SharepointToolbox.sln` passes with 0 errors
|
||||
- `dotnet test --filter "Category=Unit"` all pass
|
||||
- MainWindow.xaml contains `x:Name="LogPanel"` RichTextBox
|
||||
- MainWindow.xaml StatusBar has three StatusBarItems: SelectedProfile.Name | ConnectionStatus | ProgressPercentage%
|
||||
- App.xaml.cs registers `DispatcherUnhandledException` and `TaskScheduler.UnobservedTaskException`
|
||||
- FeatureViewModelBase contains no `async void` methods (anti-pattern violation)
|
||||
- ObservableCollection is never modified from Task.Run (pattern 7 compliance)
|
||||
- MainWindowViewModel.OnActivated() subscribes to ProgressUpdatedMessage and updates ProgressStatus + ProgressPercentage
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
Application compiles and launches to a visible WPF shell. FeatureViewModelBase tests green. All ViewModels registered in DI. Log panel wired to Serilog.
|
||||
Application compiles and launches to a visible WPF shell. FeatureViewModelBase tests green. All ViewModels registered in DI. Log panel wired to Serilog. StatusBar shows all three fields including live progress percentage.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
|
||||
@@ -62,7 +62,7 @@ Output: Confirmed working foundation. Green light for Phase 2.
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Run full test suite and verify zero failures</name>
|
||||
<files></files>
|
||||
<files><!-- no files created or modified — test-execution-only task --></files>
|
||||
<action>
|
||||
Run the complete test suite:
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user