docs(08-simplified-permissions): create phase plan (6 plans, 5 waves)
Plans cover plain-language permission labels, risk-level color coding, summary counts, detail-level toggle, export integration, and unit tests. PermissionEntry record is NOT modified — uses wrapper pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
222
.planning/phases/08-simplified-permissions/08-05-PLAN.md
Normal file
222
.planning/phases/08-simplified-permissions/08-05-PLAN.md
Normal file
@@ -0,0 +1,222 @@
|
||||
---
|
||||
phase: 08-simplified-permissions
|
||||
plan: 05
|
||||
type: execute
|
||||
wave: 4
|
||||
depends_on: ["08-02", "08-03", "08-04"]
|
||||
files_modified:
|
||||
- SharepointToolbox/Localization/Strings.resx
|
||||
- SharepointToolbox/Localization/Strings.fr.resx
|
||||
- SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs
|
||||
autonomous: true
|
||||
requirements:
|
||||
- SIMP-01
|
||||
- SIMP-02
|
||||
- SIMP-03
|
||||
must_haves:
|
||||
truths:
|
||||
- "All new UI strings have EN and FR localization keys"
|
||||
- "Export commands pass SimplifiedResults when IsSimplifiedMode is true"
|
||||
- "PermissionsView.xaml display options GroupBox uses localization keys not hardcoded strings"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/Localization/Strings.resx"
|
||||
provides: "EN localization keys for simplified permissions UI"
|
||||
contains: "grp.display.opts"
|
||||
- path: "SharepointToolbox/Localization/Strings.fr.resx"
|
||||
provides: "FR localization keys for simplified permissions UI"
|
||||
contains: "grp.display.opts"
|
||||
key_links:
|
||||
- from: "SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs"
|
||||
to: "SharepointToolbox/Services/Export/CsvExportService.cs"
|
||||
via: "ExportCsvAsync calls simplified overload when IsSimplifiedMode"
|
||||
pattern: "SimplifiedResults"
|
||||
- from: "SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs"
|
||||
to: "SharepointToolbox/Services/Export/HtmlExportService.cs"
|
||||
via: "ExportHtmlAsync calls simplified overload when IsSimplifiedMode"
|
||||
pattern: "SimplifiedResults"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Wire the simplified export paths, add all EN/FR localization keys, and finalize the integration between ViewModel export commands and the simplified export service overloads.
|
||||
|
||||
Purpose: Completes the integration: export commands use simplified data when mode is active, and all UI strings are properly localized in both languages.
|
||||
Output: Updated Strings.resx, Strings.fr.resx, updated PermissionsViewModel export methods
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@C:/Users/dev/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@C:/Users/dev/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/phases/08-simplified-permissions/08-01-SUMMARY.md
|
||||
@.planning/phases/08-simplified-permissions/08-02-SUMMARY.md
|
||||
@.planning/phases/08-simplified-permissions/08-03-SUMMARY.md
|
||||
@.planning/phases/08-simplified-permissions/08-04-SUMMARY.md
|
||||
|
||||
<interfaces>
|
||||
<!-- PermissionsViewModel export methods to be updated -->
|
||||
From PermissionsViewModel (current ExportCsvAsync):
|
||||
```csharp
|
||||
private async Task ExportCsvAsync()
|
||||
{
|
||||
if (_csvExportService == null || Results.Count == 0) return;
|
||||
// ... SaveFileDialog ...
|
||||
await _csvExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None);
|
||||
}
|
||||
```
|
||||
|
||||
From PermissionsViewModel (current ExportHtmlAsync):
|
||||
```csharp
|
||||
private async Task ExportHtmlAsync()
|
||||
{
|
||||
if (_htmlExportService == null || Results.Count == 0) return;
|
||||
// ... SaveFileDialog ...
|
||||
await _htmlExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None);
|
||||
}
|
||||
```
|
||||
|
||||
<!-- Export service overloads (from 08-04) -->
|
||||
From CsvExportService:
|
||||
```csharp
|
||||
public async Task WriteAsync(IReadOnlyList<SimplifiedPermissionEntry> entries, string filePath, CancellationToken ct);
|
||||
```
|
||||
|
||||
From HtmlExportService:
|
||||
```csharp
|
||||
public async Task WriteAsync(IReadOnlyList<SimplifiedPermissionEntry> entries, string filePath, CancellationToken ct);
|
||||
```
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Add EN and FR localization keys for simplified permissions</name>
|
||||
<files>SharepointToolbox/Localization/Strings.resx, SharepointToolbox/Localization/Strings.fr.resx</files>
|
||||
<action>
|
||||
Add the following keys to `SharepointToolbox/Localization/Strings.resx` (EN). Insert them in alphabetical order among existing keys, following the existing `<data>` element format:
|
||||
|
||||
```xml
|
||||
<data name="chk.simplified.mode" xml:space="preserve"><value>Simplified mode</value></data>
|
||||
<data name="grp.display.opts" xml:space="preserve"><value>Display Options</value></data>
|
||||
<data name="lbl.detail.level" xml:space="preserve"><value>Detail level:</value></data>
|
||||
<data name="rad.detail.detailed" xml:space="preserve"><value>Detailed (all rows)</value></data>
|
||||
<data name="rad.detail.simple" xml:space="preserve"><value>Simple (summary only)</value></data>
|
||||
<data name="lbl.summary.users" xml:space="preserve"><value>user(s)</value></data>
|
||||
```
|
||||
|
||||
Add the corresponding French translations to `SharepointToolbox/Localization/Strings.fr.resx`:
|
||||
|
||||
```xml
|
||||
<data name="chk.simplified.mode" xml:space="preserve"><value>Mode simplifie</value></data>
|
||||
<data name="grp.display.opts" xml:space="preserve"><value>Options d'affichage</value></data>
|
||||
<data name="lbl.detail.level" xml:space="preserve"><value>Niveau de detail :</value></data>
|
||||
<data name="rad.detail.detailed" xml:space="preserve"><value>Detaille (toutes les lignes)</value></data>
|
||||
<data name="rad.detail.simple" xml:space="preserve"><value>Simple (resume uniquement)</value></data>
|
||||
<data name="lbl.summary.users" xml:space="preserve"><value>utilisateur(s)</value></data>
|
||||
```
|
||||
|
||||
Note: French accented characters (e, a with accents) should be used if the resx file supports it. Check existing FR entries for the pattern — if they use plain ASCII, match that convention.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5</automated>
|
||||
</verify>
|
||||
<done>6 new localization keys added to both Strings.resx and Strings.fr.resx. Keys match the binding paths used in PermissionsView.xaml (grp.display.opts, chk.simplified.mode, lbl.detail.level, rad.detail.simple, rad.detail.detailed, lbl.summary.users).</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Wire export commands to use simplified overloads and update summary card text</name>
|
||||
<files>SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs</files>
|
||||
<action>
|
||||
Modify `SharepointToolbox/ViewModels/Tabs/PermissionsViewModel.cs` to update the export commands to pass simplified data when IsSimplifiedMode is active.
|
||||
|
||||
Update `ExportCsvAsync`:
|
||||
```csharp
|
||||
private async Task ExportCsvAsync()
|
||||
{
|
||||
if (_csvExportService == null || Results.Count == 0) return;
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Title = "Export permissions to CSV",
|
||||
Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*",
|
||||
DefaultExt = "csv",
|
||||
FileName = "permissions"
|
||||
};
|
||||
if (dialog.ShowDialog() != true) return;
|
||||
try
|
||||
{
|
||||
if (IsSimplifiedMode && SimplifiedResults.Count > 0)
|
||||
await _csvExportService.WriteAsync(SimplifiedResults.ToList(), dialog.FileName, CancellationToken.None);
|
||||
else
|
||||
await _csvExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None);
|
||||
OpenFile(dialog.FileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"Export failed: {ex.Message}";
|
||||
_logger.LogError(ex, "CSV export failed.");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Update `ExportHtmlAsync`:
|
||||
```csharp
|
||||
private async Task ExportHtmlAsync()
|
||||
{
|
||||
if (_htmlExportService == null || Results.Count == 0) return;
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Title = "Export permissions to HTML",
|
||||
Filter = "HTML files (*.html)|*.html|All files (*.*)|*.*",
|
||||
DefaultExt = "html",
|
||||
FileName = "permissions"
|
||||
};
|
||||
if (dialog.ShowDialog() != true) return;
|
||||
try
|
||||
{
|
||||
if (IsSimplifiedMode && SimplifiedResults.Count > 0)
|
||||
await _htmlExportService.WriteAsync(SimplifiedResults.ToList(), dialog.FileName, CancellationToken.None);
|
||||
else
|
||||
await _htmlExportService.WriteAsync(Results, dialog.FileName, CancellationToken.None);
|
||||
OpenFile(dialog.FileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"Export failed: {ex.Message}";
|
||||
_logger.LogError(ex, "HTML export failed.");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: `SimplifiedResults.ToList()` converts `IReadOnlyList<SimplifiedPermissionEntry>` to `List<SimplifiedPermissionEntry>` which satisfies the `IReadOnlyList<SimplifiedPermissionEntry>` parameter. This is needed because the field type is `IReadOnlyList` but the service expects `IReadOnlyList`.
|
||||
|
||||
Also add `using System.Linq;` if not already present (it likely is via global using or existing code).
|
||||
|
||||
Do NOT change constructor signatures, RunOperationAsync, or any other method besides ExportCsvAsync and ExportHtmlAsync.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5</automated>
|
||||
</verify>
|
||||
<done>ExportCsvAsync and ExportHtmlAsync check IsSimplifiedMode and pass SimplifiedResults to the overloaded WriteAsync when active. Standard PermissionEntry path unchanged when simplified mode is off.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors
|
||||
- Strings.resx contains keys: grp.display.opts, chk.simplified.mode, lbl.detail.level, rad.detail.simple, rad.detail.detailed, lbl.summary.users
|
||||
- Strings.fr.resx contains the same keys with French values
|
||||
- ExportCsvAsync branches on IsSimplifiedMode to call the simplified overload
|
||||
- ExportHtmlAsync branches on IsSimplifiedMode to call the simplified overload
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
The full pipeline is wired: UI toggles -> ViewModel mode -> simplified data -> export services. All new UI text has EN/FR localization. Exports produce simplified output when the user has simplified mode active.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/08-simplified-permissions/08-05-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user