# Phase 9: Packaging + Polish (FINAL PHASE — full build + tests required) **Status:** ⬜ Not Started **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** fullstack **Implementer:** Sonnet 4.6 **Type:** **Final phase — Big Bang strategy mandates full build + full test suite pass.** ## Objective Make the application shippable: comprehensive logging, finalized configuration UX, deployment artifact (single-file exe and/or MSIX installer), README with end-user setup, screenshots, and a final pass for any cross-cutting polish (error UI, empty states, loading states, telemetry). ## Tasks ### Verification (FIRST — gate before any new work) - [ ] `dotnet restore Marathon.sln` — succeeds - [ ] `dotnet build Marathon.sln` — succeeds with NO warnings in Release mode - [ ] `dotnet test Marathon.sln` — ALL tests pass (this is the first time the full suite runs end-to-end since Big Bang strategy was used) - [ ] `dotnet format Marathon.sln --verify-no-changes` — passes - [ ] **If any of the above fails, fix before proceeding.** This is the only phase where build + tests are mandatory under Big Bang. ### Logging - [ ] Configure Serilog in `Marathon.Hosts.WpfBlazor/App.xaml.cs`: - Rolling file: `./logs/marathon-.log`, 7-day retention, 50 MB per file cap - Console sink (debug builds only) - Enrichers: `FromLogContext`, `WithThreadId`, `WithProcessId` - Minimum level via config: `Logging:MinimumLevel` (default `Information`) - [ ] Add structured logging at key points: - Scraping cycles start/end (sport, count, duration) - Snapshot persisted (event ID, snapshot ID) - Anomaly detected (event ID, score) - Excel export completed (path, row count) - All exceptions with stack + context ### Settings UX polish - [ ] Settings page validates input client-side (e.g., polling interval ≥ 5s) - [ ] Confirmation dialog before saving settings that require restart - [ ] "Reset to defaults" button per section - [ ] Live-edit of polling intervals takes effect within the next cycle ### Empty states & loading states - [ ] Every page that loads data shows a skeleton/spinner during fetch - [ ] Every list shows an empty-state illustration + helpful copy when no data - [ ] Network errors surface a clear toast with retry action ### Error UI - [ ] Global error boundary in `MainLayout.razor` catches Blazor exceptions - [ ] Display friendly message + "report issue" copy (with log path) - [ ] Errors logged to Serilog with full stack ### Packaging - [ ] Add `dotnet publish` profile for single-file self-contained exe: ``` dotnet publish src/Marathon.Hosts.WpfBlazor -c Release -r win-x64 --self-contained \ -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true ``` - [ ] (Optional) MSIX packaging via `Microsoft.Windows.SDK.BuildTools` — only if time permits and customer wants installer flow. - [ ] If Playwright is bundled, ensure browser binaries are included via `playwright.exe install` step in publish output. - [ ] Bundle `appsettings.json` in publish output; `appsettings.Local.json` is generated on first run. ### Documentation - [ ] Expand `README.md`: - System requirements (Windows 10+, .NET 8 runtime if not self-contained) - Installation instructions - First-run configuration walkthrough - Excel export sheet/column reference - Troubleshooting section (logs location, common errors) - Screenshots of main UI surfaces - [ ] Create `docs/USER_GUIDE.md` (RU) and `docs/USER_GUIDE_EN.md` for end users. - [ ] Update `CLAUDE.md` with final permanent learnings. - [ ] Capture screenshots: pre-match list, live list, event detail with chart, anomaly feed, settings page. Place in `docs/screenshots/`. ### Final commit hygiene - [ ] No commented-out code anywhere - [ ] No `TODO(phase-N)` markers remaining (Phase 9 IS the resolution phase) - [ ] `dotnet format` applied to entire solution - [ ] No NuGet vulnerabilities (`dotnet list package --vulnerable --include-transitive`) ## Files to Modify/Create - `src/Marathon.Hosts.WpfBlazor/App.xaml.cs` — Serilog config - `src/Marathon.Hosts.WpfBlazor/Properties/PublishProfiles/win-x64-self-contained.pubxml` - `src/Marathon.UI/Components/EmptyState.razor`, `LoadingSpinner.razor`, `ErrorBoundary.razor` - `README.md` — expanded - `docs/USER_GUIDE.md`, `USER_GUIDE_EN.md` - `docs/screenshots/*.png` - `CLAUDE.md` — final updates ## Acceptance Criteria - **Build passes**: `dotnet build` clean, zero warnings in Release. - **All tests pass**: `dotnet test` green. - **Lint passes**: `dotnet format --verify-no-changes` clean. - **Publish succeeds**: single-file exe produced and launches without errors. - **Documentation complete**: README + user guides + screenshots. - **No vulnerabilities**: `dotnet list package --vulnerable` returns nothing. ## Notes - This is the FINAL phase. The next step after this is the comprehensive review agent + security review + user merge approval. - If new bugs surface during full-suite testing, fix them here. Document each fix in CLAUDE.md if it reveals a permanent project lesson. ## Review Checklist - [ ] Build, tests, lint all green - [ ] Single-file publish works - [ ] Logs land in expected location with sensible content - [ ] No remaining `TODO(phase-N)` markers - [ ] Screenshots match current UI ## Handoff to Next Phase