feat: implement Phase 1 — solution skeleton and domain model
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.
This commit is contained in:
@@ -80,7 +80,7 @@ with scraping research, no implementation.
|
||||
| Phase | Agent | Model | Test Writer | Parallel | Notes |
|
||||
|---|---|---|---|---|---|
|
||||
| Phase 0 | phase-implementer | Opus | ⏭️ Skipped (research only) | — | ✅ Done 2026-05-05. Outputs: spike/SCRAPE_FINDINGS.md + spike/SCHEMA_DRAFT.md + 7 local fixtures. Anonymous scraping confirmed feasible; HttpClient+AngleSharp recommended; no Playwright needed; no public results page found (Phase 8 deviation noted). |
|
||||
| Phase 1 | phase-implementer | Sonnet 4.6 | ⏭️ Skipped (Big Bang) | — | — |
|
||||
| Phase 1 | phase-implementer | Sonnet 4.6 | ⏭️ Skipped (Big Bang) | — | ✅ Done 2026-05-05. 9 projects (5 src + 4 test). 96 domain tests passed. Key decisions: BetScope sealed hierarchy, ScheduledAt=UTC+3 (Moscow), OddsValue rejects zero. Deviations: slnx auto-created alongside sln, WPF App.xaml.cs needs FQ Application type. |
|
||||
| Phase 2 | phase-implementer | Sonnet 4.6 | ⏭️ Skipped (Big Bang) | ✅ With 3 + 5 | — |
|
||||
| Phase 3 | phase-implementer | Sonnet 4.6 | ⏭️ Skipped (Big Bang) | ✅ With 2 + 5 | — |
|
||||
| Phase 4 | phase-implementer | Sonnet 4.6 | ⏭️ Skipped (Big Bang) | — | — |
|
||||
@@ -101,6 +101,30 @@ with scraping research, no implementation.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Phase 1 (Solution skeleton + Domain model, 2026-05-05)
|
||||
|
||||
- **.NET 10 SDK creates `.slnx` by default.** `dotnet new sln` produces `Marathon.slnx`
|
||||
(new XML format), not `Marathon.sln`. A hand-crafted `Marathon.sln` was added alongside
|
||||
it so that `dotnet build Marathon.sln` works as specified in the plan. Both files are
|
||||
kept; prefer `Marathon.sln` for CLI commands.
|
||||
- **`BetScope` is a sealed record hierarchy:** `abstract record BetScope` with
|
||||
`sealed record MatchScope : BetScope` (singleton `Instance`) and
|
||||
`sealed record PeriodScope(int Number) : BetScope`. Use pattern matching, not
|
||||
an enum+nullable approach.
|
||||
- **`Event.ScheduledAt` must be UTC+3 (Moscow), not UTC.** The domain enforces
|
||||
`Offset == TimeSpan.FromHours(3)`. Phase 3 must construct `DateTimeOffset` with
|
||||
`+03:00` before passing to `Event`; do NOT convert to UTC first.
|
||||
- **`Directory.Build.props` must NOT set `TargetFramework`** — WpfBlazor needs
|
||||
`net8.0-windows` while all other projects use `net8.0`. Each csproj owns its TFM.
|
||||
- **`Marathon.Application` namespace conflicts with `System.Windows.Application`**
|
||||
in WPF `App.xaml.cs`. Fix: use `System.Windows.Application` fully qualified.
|
||||
Phase 5 must keep this qualification.
|
||||
- **Central package management:** all `PackageReference` elements in test csproj files
|
||||
must NOT include `Version=`. Versions live exclusively in `Directory.Packages.props`.
|
||||
- **96 domain tests, 0 failures.** All invariants covered: SportCode, EventId,
|
||||
OddsRate, OddsValue, BetScope, Bet (all 4 type combinations), OddsSnapshot,
|
||||
Event (ScheduledAt offset), Anomaly.
|
||||
|
||||
### Phase 0 (Scraping spike, 2026-05-05)
|
||||
|
||||
- **Anonymous scraping is feasible** from a non-Belarus IP. No Cloudflare, no JS
|
||||
|
||||
Reference in New Issue
Block a user