# Feature: Initial Implementation (maraphon-app) **Branch:** `feature/initial-implementation` **Base branch:** `main` **Created:** 2026-05-05 **Status:** ๐ŸŸก In Progress **Strategy:** Big Bang **Mode:** Automated **Execution:** Orchestrator **Implementer models:** Sonnet 4.6 (backend) ยท Opus (frontend, with frontend-design skill) **Reviewer model:** Sonnet 4.6 ## Summary Build the maraphon-app end-to-end: a Blazor Hybrid (.NET 8 + WPF) sports-betting odds analyzer that scrapes marathonbet.by, persists snapshots in SQLite, exports to Excel matching the customer spec, and detects coefficient-flip anomalies. Architecture is Clean Architecture with all UI in a Razor Class Library so the host can later swap to ASP.NET Core Blazor Server with no UI rewrite. RU + EN localization, every variable parameter configurable. ## Build & Test Commands - **Build:** `dotnet build Marathon.sln` - **Test:** `dotnet test Marathon.sln` - **Lint:** `dotnet format Marathon.sln --verify-no-changes` - **Run:** `dotnet run --project src/Marathon.Hosts.WpfBlazor` > **Big Bang strategy:** Build/tests are NOT run for intermediate phases (Phases 0โ€“8). > The full build + test suite must pass at Phase 9 before final review. > An exception: a `dotnet build` *compile-only smoke check* is allowed after each > phase to catch syntax/type errors early โ€” this is faster than running tests and > consistent with Big Bang ("we don't run tests until the end"). ## Phases - [x] Phase 0: Scraping spike (research, throwaway) [domain: backend] โ†’ [subplan](./phase-0-scraping-spike.md) - [x] Phase 1: Solution skeleton + Domain model [domain: backend] โ†’ [subplan](./phase-1-solution-and-domain.md) - [x] Phase 2: Infrastructure โ€” Storage [domain: backend] โ†’ [subplan](./phase-2-storage.md) - [x] Phase 3: Infrastructure โ€” Scraping [domain: backend] โ†’ [subplan](./phase-3-scraping.md) - [x] Phase 4: Application layer + Background workers [domain: backend] โ†’ [subplan](./phase-4-application-and-workers.md) - [x] Phase 5: Blazor Hybrid host + Theme + i18n [domain: frontend] โ†’ [subplan](./phase-5-host-theme-i18n.md) - [x] Phase 6: Event browsing UI [domain: frontend] โ†’ [subplan](./phase-6-event-browsing-ui.md) - [ ] Phase 7: Anomaly detection [domain: fullstack] โ†’ [subplan](./phase-7-anomaly-detection.md) - [ ] Phase 8: Results loader [domain: fullstack] โ†’ [subplan](./phase-8-results-loader.md) - [ ] Phase 9: Packaging + polish (final phase โ€” full build + tests required) [domain: fullstack] โ†’ [subplan](./phase-9-packaging-polish.md) ## Parallelization Plan (Orchestrator mode) | Round | Phases | Notes | |---|---|---| | 1 | Phase 0 | Spike โ€” gating research, no parallelism | | 2 | Phase 1 | Domain โ€” must finish before Phases 2/3/5 | | 3 | **Phases 2, 3, 5 in parallel** | Storage, Scraping, UI Shell โ€” disjoint files | | 4 | Phase 4 | Application + Workers โ€” depends on 2 + 3 | | 5 | Phase 6 | Event UI โ€” depends on 4 + 5 | | 6 | Phase 7 | Anomaly detection โ€” depends on 6 | | 7 | Phase 8 | Results loader โ€” depends on 6 | | 8 | Phase 9 | Packaging โ€” final, runs full build + tests | ## Phase Progress Log | Phase | Domain | Status | Review | Build | Committed | |---|---|---|---|---|---| | Phase 0: Scraping spike | backend | โœ… Done | โš ๏ธ Pass with notes (Sonnet) | โญ๏ธ N/A (research) | โœ… 070e34b | | Phase 1: Solution + Domain | backend | โœ… Done | โš ๏ธ Pass with notes (Sonnet) | โœ… Build OK + 96/96 Domain tests | โœ… 61114ea | | Phase 2: Storage | backend | โœ… Done | โš ๏ธ Pass with notes (Sonnet, combined batch) | โœ… Build OK + 77/77 Infra tests | โœ… batch (e4d8476โ€ฆ686550dโ€ฆ+) | | Phase 3: Scraping | backend | โœ… Done | โš ๏ธ Pass with notes (Sonnet, combined batch) | โœ… Build OK + 77/77 Infra tests | โœ… batch (e4d8476โ€ฆ686550dโ€ฆ+) | | Phase 4: Application + Workers | backend | โœ… Done | โš ๏ธ Pass with notes (Sonnet) | โœ… Build OK + 202/202 tests | โœ… 2acbaa5 | | Phase 5: Host + Theme + i18n | frontend | โœ… Done | โš ๏ธ Pass with notes (Sonnet, combined batch) | โœ… Build OK + 11/11 UI tests | โœ… batch (e4d8476โ€ฆ686550dโ€ฆ+) | | Phase 6: Event browsing UI | frontend | โœ… Done | โš ๏ธ Pass with notes (Sonnet) | โœ… Build OK + 228/228 tests | โœ… 553db2b | | Phase 7: Anomaly detection | fullstack | โฌœ Not Started | โฌœ | โญ๏ธ Big Bang | โฌœ | | Phase 8: Results loader | fullstack | โฌœ Not Started | โฌœ | โญ๏ธ Big Bang | โฌœ | | Phase 9: Packaging + polish | fullstack | โฌœ Not Started | โฌœ | โฌœ | โฌœ | ## Final Review - [ ] Comprehensive code review (final-reviewer agent) - [ ] Security review (auth N/A, but covers scraping HttpClient, file I/O, user input) - [ ] Full build passes - [ ] Full test suite passes - [ ] User merge approval - [ ] Merged to `main` ## Resume Notes (2026-05-05 โ€” paused at end of parallel batch P2/P3/P5) **Where we left off:** The parallel batch (Phases 2, 3, 5) completed code-wise. Phase 5 was killed near the end of its "verify build" step. All files are committed as a single WIP snapshot on `feature/initial-implementation` so nothing is lost. No reviewer ran on this batch yet, and the solution does NOT build cleanly โ€” there are known cross-phase compile issues to resolve before review. **Tomorrow's action list (in order):** 1. `git pull` (or just verify branch) โ€” confirm we're on `feature/initial-implementation` at the WIP commit. 2. Run `dotnet build Marathon.sln` to capture the current error set as a baseline. 3. **Resolve known cross-phase compile issues:** - **Phase 2 โ†” Phase 3:** Phase 2's repository classes are `internal`; Phase 3's `Marathon.Infrastructure.Tests` references them directly. Fix: add `` to `src/Marathon.Infrastructure/Marathon.Infrastructure.csproj`. (Or make the repos public โ€” choose by reading the actual csproj first.) - **Phase 5:** `LocalizationOptions` namespace ambiguity (Microsoft.AspNetCore vs Microsoft.Extensions). Fix in WPF host or UI project โ€” qualify or alias. - **Phase 5:** Serilog API mismatch in WPF host (likely `UseSerilog` extension not found because Serilog.Extensions.Hosting wasn't pulled in transitively via the right namespace, OR the API call site uses an older Serilog API). 4. Once `dotnet build Marathon.sln` is green: - Run `dotnet test Marathon.sln` to see how many tests pass. - Spawn the phase-reviewer agent (Sonnet) to review the parallel batch as a single combined review (Phase 2 + 3 + 5 diff). Pass `git diff 144c936...HEAD`. - Address blocker findings; re-review until pass. 5. After review passes, finalize with one or more clean commits (the WIP commit can be `git reset --soft` to base and re-committed cleanly per phase, OR left as-is and the review passes apply). Update PLAN.md tracking rows for P2/P3/P5 to โœ… Done with commit hashes. 6. Move to **Phase 4** (Application + Workers โ€” backend, Sonnet 4.6). Phase 4 composes the per-module DI extensions (`PersistenceModule.AddMarathonPersistence` and `ScrapingModule.AddMarathonScraping`) into a top-level `Marathon.Infrastructure/DependencyInjection.cs` and adds `BackgroundService` pollers (`UpcomingEventsPoller`, `LiveOddsPoller`, plus a future `ResultsWatchListPoller` per the Phase 8 amendment). **Useful pointers:** - Phase 2 implementer report: see `tasks/a56ecc5e24bd7ea43.output` (don't read โ€” context-heavy; the summary is in the conversation transcript). - Phase 3 implementer report: agent ID `a8a537ba5721fba3d`. Same caveat. - Phase 5 implementer was killed; final state is the WIP commit. The agent had finished implementation and was about to verify build โ€” assume code is ~95% complete but unreviewed. - All 3 phase subplans have their `## Handoff to Next Phase` sections filled. - Cross-phase issues already documented in the conversation by the parallel agents โ€” see Phase 2 and Phase 3 reports for the specifics. **Do NOT:** - Reset/discard the WIP commit without first reading what's in it. - Skip the cross-phase fix step โ€” Phase 4 cannot proceed against a broken build. - Move to Phase 4 before reviewing the P2/P3/P5 batch. ## Amendment Log ### Amendment 1 โ€” 2026-05-05 โ€” Phase 8 strategy change (deferred โ€” formal approval will be requested when Phase 8 begins) **Type:** Modify upcoming phase (Phase 8 โ€” Results loader) **What changed:** Phase 8's original subplan assumed marathonbet.by exposes a public results / archive page that we can scrape to back-fill `EventResult`s. Phase 0 spike proved this endpoint does NOT exist (`/su/results` returns 404). **Why:** Spike findings โ€” see `spike/SCRAPE_FINDINGS.md` and the deviation note in `plans/initial-implementation/phase-0-scraping-spike.md` (Handoff section). **New approach (to be formalised when Phase 8 begins):** Maintain a "watch list" of events whose `ScheduledAt + EstimatedDuration` is in the past but whose status is not `Completed`. Poll those event-detail URLs every 5 min until either `eventJsonInfo.matchIsComplete=true` (capture `resultDescription`, mark complete) or the URL 404s (mark `ResultUnknown`). Optional fallback to flashscore/sofascore is a Phase 8 design decision. **Impact on existing phases:** Phase 4 (Application + Workers) may need a new `ResultsWatchListPoller : BackgroundService` in addition to the previously planned `UpcomingEventsPoller` and `LiveOddsPoller`. Phase 2 schema may need a `WatchStatus` field on `Event` (`Pending | InWatchList | Completed | ResultUnknown`). Both will be re-evaluated when Phase 8 starts. **Status:** Logged โ€” formal subplan revision and user approval will be requested at the start of Phase 8 (per skill rule: "All amendments require explicit user approval before taking effect"). Phases 1โ€“7 do not depend on Phase 8's tactical implementation.