Creates the 9-project .NET 8 solution (5 src + 4 test) with Marathon.Domain fully implemented: value objects (SportCode, EventId, OddsRate, OddsValue, BetScope hierarchy), enums (Side, BetType, OddsSource, AnomalyKind), and entities (Sport, Country, League, Event, Bet, OddsSnapshot, EventResult, Anomaly) with all invariants enforced in constructors. 96 domain tests pass (FluentAssertions + xUnit). Directory.Build.props and Directory.Packages.props centralise build settings and NuGet versions. Both Marathon.sln and Marathon.slnx are committed; dotnet build Marathon.sln succeeds with 0 warnings/errors.
5.9 KiB
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 buildcompile-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
- Phase 0: Scraping spike (research, throwaway) [domain: backend] → subplan
- Phase 1: Solution skeleton + Domain model [domain: backend] → subplan
- Phase 2: Infrastructure — Storage [domain: backend] → subplan
- Phase 3: Infrastructure — Scraping [domain: backend] → subplan
- Phase 4: Application layer + Background workers [domain: backend] → subplan
- Phase 5: Blazor Hybrid host + Theme + i18n [domain: frontend] → subplan
- Phase 6: Event browsing UI [domain: frontend] → subplan
- Phase 7: Anomaly detection [domain: fullstack] → subplan
- Phase 8: Results loader [domain: fullstack] → subplan
- Phase 9: Packaging + polish (final phase — full build + tests required) [domain: fullstack] → subplan
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 | ⬜ | ✅ Build OK | ⬜ |
| Phase 2: Storage | backend | ⬜ Not Started | ⬜ | ⏭️ Big Bang | ⬜ |
| Phase 3: Scraping | backend | ⬜ Not Started | ⬜ | ⏭️ Big Bang | ⬜ |
| Phase 4: Application + Workers | backend | ⬜ Not Started | ⬜ | ⏭️ Big Bang | ⬜ |
| Phase 5: Host + Theme + i18n | frontend | ⬜ Not Started | ⬜ | ⏭️ Big Bang | ⬜ |
| Phase 6: Event browsing UI | frontend | ⬜ Not Started | ⬜ | ⏭️ Big Bang | ⬜ |
| 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
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 EventResults. 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.