13 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-user-access-audit | 07 | execute | 4 |
|
|
true |
|
|
Purpose: Integration glue that makes all Phase 7 pieces discoverable and functional at runtime. Output: Modified MainWindow.xaml, MainWindow.xaml.cs, App.xaml.cs, Strings.resx, Strings.fr.resx
<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>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/07-user-access-audit/07-CONTEXT.md @.planning/phases/07-user-access-audit/07-04-SUMMARY.md @.planning/phases/07-user-access-audit/07-05-SUMMARY.md @.planning/phases/07-user-access-audit/07-06-SUMMARY.md From SharepointToolbox/MainWindow.xaml (existing tabs): ```xml ```From SharepointToolbox/MainWindow.xaml.cs:
PermissionsTabItem.Content = serviceProvider.GetRequiredService<PermissionsView>();
StorageTabItem.Content = serviceProvider.GetRequiredService<StorageView>();
// ... etc
SettingsTabItem.Content = serviceProvider.GetRequiredService<SettingsView>();
From SharepointToolbox/App.xaml.cs:
// Phase 2: Permissions
services.AddTransient<IPermissionsService, PermissionsService>();
services.AddTransient<CsvExportService>();
services.AddTransient<HtmlExportService>();
services.AddTransient<PermissionsViewModel>();
services.AddTransient<PermissionsView>();
Services: IUserAccessAuditService -> UserAccessAuditService, IGraphUserSearchService -> GraphUserSearchService Export: UserAccessCsvExportService, UserAccessHtmlExportService ViewModel: UserAccessAuditViewModel View: UserAccessAuditView
Task 1: Add DI registrations in App.xaml.cs SharepointToolbox/App.xaml.cs In `App.xaml.cs`, add a new section in `RegisterServices` after the existing Phase 4 registrations and before `services.AddSingleton()`:```csharp
// Phase 7: User Access Audit
services.AddTransient<IUserAccessAuditService, UserAccessAuditService>();
services.AddTransient<IGraphUserSearchService, GraphUserSearchService>();
services.AddTransient<UserAccessCsvExportService>();
services.AddTransient<UserAccessHtmlExportService>();
services.AddTransient<UserAccessAuditViewModel>();
services.AddTransient<UserAccessAuditView>();
```
Add the necessary using statement at the top if not already present (Services.Export namespace is already imported via existing export services).
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
App.xaml.cs registers all Phase 7 services, ViewModel, and View in the DI container.
Task 2: Add TabItem to MainWindow.xaml and wire in MainWindow.xaml.cs
SharepointToolbox/MainWindow.xaml, SharepointToolbox/MainWindow.xaml.cs
**MainWindow.xaml**: Add a new TabItem before SettingsTabItem (after TemplatesTabItem):
```xml
<TabItem x:Name="UserAccessAuditTabItem"
Header="{Binding Source={x:Static loc:TranslationSource.Instance}, Path=[tab.userAccessAudit]}">
</TabItem>
```
**MainWindow.xaml.cs**: Add tab content wiring after the existing tab assignments, before SettingsTabItem:
```csharp
// Phase 7: User Access Audit
var auditView = serviceProvider.GetRequiredService<UserAccessAuditView>();
UserAccessAuditTabItem.Content = auditView;
// Wire site picker dialog factory for audit tab (same pattern as Permissions)
if (auditView.DataContext is UserAccessAuditViewModel auditVm)
{
auditVm.OpenSitePickerDialog = () =>
{
var factory = serviceProvider.GetRequiredService<Func<TenantProfile, SitePickerDialog>>();
return factory(auditVm.CurrentProfile ?? new TenantProfile());
};
}
```
Add `using SharepointToolbox.ViewModels.Tabs;` to MainWindow.xaml.cs if not already present (it should be via existing tab wiring, but the UserAccessAuditViewModel type needs to be resolved).
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
MainWindow.xaml has UserAccessAuditTabItem. MainWindow.xaml.cs wires UserAccessAuditView content and site picker dialog factory.
Task 3: Add localization keys to Strings.resx and Strings.fr.resx
SharepointToolbox/Localization/Strings.resx, SharepointToolbox/Localization/Strings.fr.resx
Add the following keys to both resx files. Add them at the end of the existing data entries, before the closing `` tag.
**Strings.resx (English):**
```xml
<data name="tab.userAccessAudit" xml:space="preserve">
<value>User Access Audit</value>
</data>
<data name="audit.grp.users" xml:space="preserve">
<value>Select Users</value>
</data>
<data name="audit.grp.sites" xml:space="preserve">
<value>Target Sites</value>
</data>
<data name="audit.grp.options" xml:space="preserve">
<value>Scan Options</value>
</data>
<data name="audit.search.placeholder" xml:space="preserve">
<value>Search users by name or email...</value>
</data>
<data name="audit.users.selected" xml:space="preserve">
<value>{0} user(s) selected</value>
</data>
<data name="audit.btn.run" xml:space="preserve">
<value>Run Audit</value>
</data>
<data name="audit.btn.exportCsv" xml:space="preserve">
<value>Export CSV</value>
</data>
<data name="audit.btn.exportHtml" xml:space="preserve">
<value>Export HTML</value>
</data>
<data name="audit.summary.total" xml:space="preserve">
<value>Total Accesses</value>
</data>
<data name="audit.summary.sites" xml:space="preserve">
<value>Sites</value>
</data>
<data name="audit.summary.highPriv" xml:space="preserve">
<value>High Privilege</value>
</data>
<data name="audit.toggle.byUser" xml:space="preserve">
<value>By User</value>
</data>
<data name="audit.toggle.bySite" xml:space="preserve">
<value>By Site</value>
</data>
<data name="audit.filter.placeholder" xml:space="preserve">
<value>Filter results...</value>
</data>
<data name="audit.noUsers" xml:space="preserve">
<value>Select at least one user to audit.</value>
</data>
<data name="audit.noSites" xml:space="preserve">
<value>Select at least one site to scan.</value>
</data>
```
**Strings.fr.resx (French):**
```xml
<data name="tab.userAccessAudit" xml:space="preserve">
<value>Audit des acces utilisateur</value>
</data>
<data name="audit.grp.users" xml:space="preserve">
<value>Selectionner les utilisateurs</value>
</data>
<data name="audit.grp.sites" xml:space="preserve">
<value>Sites cibles</value>
</data>
<data name="audit.grp.options" xml:space="preserve">
<value>Options d'analyse</value>
</data>
<data name="audit.search.placeholder" xml:space="preserve">
<value>Rechercher par nom ou email...</value>
</data>
<data name="audit.users.selected" xml:space="preserve">
<value>{0} utilisateur(s) selectionne(s)</value>
</data>
<data name="audit.btn.run" xml:space="preserve">
<value>Lancer l'audit</value>
</data>
<data name="audit.btn.exportCsv" xml:space="preserve">
<value>Exporter CSV</value>
</data>
<data name="audit.btn.exportHtml" xml:space="preserve">
<value>Exporter HTML</value>
</data>
<data name="audit.summary.total" xml:space="preserve">
<value>Total des acces</value>
</data>
<data name="audit.summary.sites" xml:space="preserve">
<value>Sites</value>
</data>
<data name="audit.summary.highPriv" xml:space="preserve">
<value>Privileges eleves</value>
</data>
<data name="audit.toggle.byUser" xml:space="preserve">
<value>Par utilisateur</value>
</data>
<data name="audit.toggle.bySite" xml:space="preserve">
<value>Par site</value>
</data>
<data name="audit.filter.placeholder" xml:space="preserve">
<value>Filtrer les resultats...</value>
</data>
<data name="audit.noUsers" xml:space="preserve">
<value>Selectionnez au moins un utilisateur.</value>
</data>
<data name="audit.noSites" xml:space="preserve">
<value>Selectionnez au moins un site.</value>
</data>
```
Note: French accented characters (e with accent) should use proper Unicode characters in the actual file. Use the existing file's encoding pattern.
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5
Both Strings.resx and Strings.fr.resx contain all audit-related localization keys. Keys match those referenced in UserAccessAuditView.xaml.
- `dotnet build SharepointToolbox/SharepointToolbox.csproj` succeeds with 0 errors
- MainWindow shows User Access Audit tab in the TabControl
- App.xaml.cs has DI registrations for all Phase 7 types
- All localization keys used in XAML exist in both resx files
- Site picker dialog factory is wired for the audit ViewModel
<success_criteria> The User Access Audit feature is fully integrated into the application. The tab appears in MainWindow, all services resolve from DI, dialog factories work, and UI text is localized in both English and French. </success_criteria>
After completion, create `.planning/phases/07-user-access-audit/07-07-SUMMARY.md`