diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 4cce480..edc39cd 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -111,7 +111,7 @@ Plans: | 1-5 | v1.0 | 36/36 | Shipped | 2026-04-07 | | 6-9 | v1.1 | 25/25 | Shipped | 2026-04-08 | | 10. Branding Data Foundation | v2.2 | 3/3 | Complete | 2026-04-08 | -| 11. HTML Export Branding + ViewModel Integration | 2/4 | In Progress| | — | +| 11. HTML Export Branding + ViewModel Integration | 3/4 | In Progress| | — | | 12. Branding UI Views | v2.2 | 0/? | Not started | — | | 13. User Directory ViewModel | v2.2 | 0/? | Not started | — | | 14. User Directory View | v2.2 | 0/? | Not started | — | diff --git a/.planning/STATE.md b/.planning/STATE.md index 396405d..94d13d9 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v2.2 milestone_name: Report Branding & User Directory status: completed -stopped_at: Completed 11-01-PLAN.md — ReportBranding model and BrandingHtmlHelper -last_updated: "2026-04-08T12:35:43.420Z" +stopped_at: Completed 11-02-PLAN.md — HTML export branding injection +last_updated: "2026-04-08T12:46:42.149Z" last_activity: 2026-04-08 — Phase 11 planning completed progress: total_phases: 5 completed_phases: 1 total_plans: 7 - completed_plans: 4 + completed_plans: 6 --- # Project State @@ -60,6 +60,8 @@ Decisions are logged in PROJECT.md Key Decisions table. - [Phase 10-branding-data-foundation]: No new using statements required for Phase 10 DI registrations — SharepointToolbox.Infrastructure.Persistence and SharepointToolbox.Services were already imported - [Phase 11-html-export-branding]: BrandingHtmlHelper is internal — only used within Services.Export namespace, tests access via InternalsVisibleTo - [Phase 11-html-export-branding]: InternalsVisibleTo added via MSBuild AssemblyAttribute ItemGroup in csproj +- [Phase 11-html-export-branding]: branding parameter placed AFTER CancellationToken ct in WriteAsync — existing positional callers unaffected +- [Phase 11-html-export-branding]: MakeBranding helper added locally to each test class — test files stay self-contained ### Pending Todos @@ -74,7 +76,7 @@ None. ## Session Continuity -Last session: 2026-04-08T12:35:43.418Z -Stopped at: Completed 11-01-PLAN.md — ReportBranding model and BrandingHtmlHelper +Last session: 2026-04-08T12:46:37.894Z +Stopped at: Completed 11-02-PLAN.md — HTML export branding injection Resume file: None Next step: `/gsd:execute-phase 11` diff --git a/.planning/phases/11-html-export-branding/11-02-SUMMARY.md b/.planning/phases/11-html-export-branding/11-02-SUMMARY.md new file mode 100644 index 0000000..f94a378 --- /dev/null +++ b/.planning/phases/11-html-export-branding/11-02-SUMMARY.md @@ -0,0 +1,123 @@ +--- +phase: 11-html-export-branding +plan: 02 +subsystem: export +tags: [html-export, branding, csharp, tdd, dotnet] + +# Dependency graph +requires: + - phase: 11-01 + provides: ReportBranding record and BrandingHtmlHelper.BuildBrandingHeader static method +provides: + - HtmlExportService with optional ReportBranding? branding parameter on BuildHtml and WriteAsync + - SearchHtmlExportService with optional ReportBranding? branding parameter + - StorageHtmlExportService with optional ReportBranding? branding parameter (both overloads) + - DuplicatesHtmlExportService with optional ReportBranding? branding parameter + - UserAccessHtmlExportService with optional ReportBranding? branding parameter + - 7 new branding tests across all 5 export test files +affects: + - 11-03 (ViewModels assemble ReportBranding and pass to export services) + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Optional nullable parameter after CancellationToken ct in WriteAsync for backward compat" + - "Raw string literal split at body/h1 boundary to inject branding header between them" + - "sb.Append (not AppendLine) for branding header — BrandingHtmlHelper already appends newlines" + +key-files: + created: [] + modified: + - SharepointToolbox/Services/Export/HtmlExportService.cs + - SharepointToolbox/Services/Export/SearchHtmlExportService.cs + - SharepointToolbox/Services/Export/StorageHtmlExportService.cs + - SharepointToolbox/Services/Export/DuplicatesHtmlExportService.cs + - SharepointToolbox/Services/Export/UserAccessHtmlExportService.cs + - SharepointToolbox.Tests/Services/Export/HtmlExportServiceTests.cs + - SharepointToolbox.Tests/Services/Export/SearchExportServiceTests.cs + - SharepointToolbox.Tests/Services/Export/StorageHtmlExportServiceTests.cs + - SharepointToolbox.Tests/Services/Export/DuplicatesHtmlExportServiceTests.cs + - SharepointToolbox.Tests/Services/Export/UserAccessHtmlExportServiceTests.cs + +key-decisions: + - "branding parameter placed AFTER CancellationToken ct in WriteAsync signatures — existing positional callers unaffected" + - "Raw string literals in SearchHtmlExportService, StorageHtmlExportService, DuplicatesHtmlExportService split at body/h1 boundary for injection" + - "MakeBranding helper added locally to each test class rather than a shared base class — test files stay self-contained" + +# Metrics +duration: 4min +completed: 2026-04-08 +--- + +# Phase 11 Plan 02: HTML Export Branding Injection Summary + +**Optional ReportBranding parameter wired into all 5 HTML export services; branding header injected between body and h1 via BrandingHtmlHelper; 7 new tests confirm injection and null-safety** + +## Performance + +- **Duration:** ~4 min +- **Started:** 2026-04-08T12:41:44Z +- **Completed:** 2026-04-08T12:46:00Z +- **Tasks:** 2 (Task 1: implementation, Task 2: TDD tests) +- **Files modified:** 10 + +## Accomplishments + +- Added `ReportBranding? branding = null` as last parameter to `BuildHtml` on all 5 export services +- Added `ReportBranding? branding = null` after `CancellationToken ct` on all `WriteAsync` overloads (9 overloads total) +- Inserted `sb.Append(BrandingHtmlHelper.BuildBrandingHeader(branding));` between `` and `

` in every exporter +- Split raw string literals in 3 services (SearchHtml, StorageHtml, Duplicates) at the body/h1 boundary to enable injection +- StorageHtmlExportService `_togIdx` reset logic left untouched (per plan pitfall guidance) +- HtmlExportService both overloads updated (PermissionEntry and SimplifiedPermissionEntry) +- StorageHtmlExportService both overloads updated (nodes-only and nodes+fileTypeMetrics) +- Added `MakeBranding` helper to all 5 test classes; wrote 7 new tests (3 in HtmlExportServiceTests, 1 each in the other 4) +- All 45 export tests pass; full suite: 247 passed / 0 failed / 26 skipped (skips are pre-existing integration tests) + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Add branding parameter to all 5 HTML export services** - `2233fb8` (feat) +2. **Task 2: Extend export tests to verify branding injection** - `d8b6616` (feat) + +## Files Created/Modified + +- `SharepointToolbox/Services/Export/HtmlExportService.cs` - branding param + injection (2 BuildHtml, 2 WriteAsync) +- `SharepointToolbox/Services/Export/SearchHtmlExportService.cs` - branding param + injection via raw string split +- `SharepointToolbox/Services/Export/StorageHtmlExportService.cs` - branding param + injection (2 BuildHtml, 2 WriteAsync) +- `SharepointToolbox/Services/Export/DuplicatesHtmlExportService.cs` - branding param + injection via raw string split +- `SharepointToolbox/Services/Export/UserAccessHtmlExportService.cs` - branding param + injection +- `SharepointToolbox.Tests/Services/Export/HtmlExportServiceTests.cs` - 3 new branding tests +- `SharepointToolbox.Tests/Services/Export/SearchExportServiceTests.cs` - 1 new branding test +- `SharepointToolbox.Tests/Services/Export/StorageHtmlExportServiceTests.cs` - 1 new branding test +- `SharepointToolbox.Tests/Services/Export/DuplicatesHtmlExportServiceTests.cs` - 1 new branding test +- `SharepointToolbox.Tests/Services/Export/UserAccessHtmlExportServiceTests.cs` - 1 new branding test + +## Decisions Made + +- Placed `branding` AFTER `CancellationToken ct` in WriteAsync — avoids breaking any existing positional callers that pass ct by position +- Used `sb.Append` (not `sb.AppendLine`) when inserting branding header — BrandingHtmlHelper already ends its output with a newline, so no double blank line +- Raw string literals split at body/h1 boundary by closing the first literal after `` then re-opening for `

` — avoids string concatenation or interpolation awkwardness inside raw string blocks + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None. + +## Next Phase Readiness + +- All 5 HTML export services now accept `ReportBranding? branding = null` — Plan 11-03 ViewModels can assemble `ReportBranding` from `IBrandingService` and `TenantProfile` and pass it to any of these services +- All existing callers compile unchanged (zero-regression confirmed by full test suite) +- Build passes with 0 warnings + +--- +*Phase: 11-html-export-branding* +*Completed: 2026-04-08*