3.1 KiB
3.1 KiB
Phase 8: Results Loader
Status: ⬜ Not Started Parent plan: PLAN.md Domain: fullstack Implementer: Sonnet (backend) + Opus (UI) Depends on: Phase 6 (UI patterns)
Objective
Per customer TZ §4: scrape and persist results of completed events, with a UI that allows the user to load all results in a date range OR pick specific events to load selectively.
Tasks
Backend (Sonnet)
PullResultsUseCasewas scaffolded in Phase 4 — extend it here:- When
selectionis null/empty, fetch results for ALL completed events in range that don't have a storedEventResultyet - When
selectionprovided, fetch results only for those events - Idempotent — re-running for already-loaded results is a no-op
- When
- Add
IResultsScraper-related parser methods (or extendIOddsScraperwithScrapeResultsAsync) — implementation may already exist from Phase 3. - After persisting results, infer
WinnerSideand update theEventaccordingly (or store derivedWinnerSideonEventResultonly — implementer's choice, document in handoff). - Tests in
Marathon.Application.Tests:PullResultsUseCasewith selection list pulls only those events- With null selection, pulls all completed events missing results in range
- Idempotency: running twice produces no duplicates
Frontend (Opus + frontend-design)
- Create
Marathon.UI/Pages/Results/ResultsLoader.razor:- Date range picker
- Two modes: "All in range" (default) | "Selected events"
- Selected events mode: searchable multi-select of completed events lacking results
- "Load Results" button → invokes
PullResultsUseCase - Progress indicator (number of events processed / total)
- Result table on completion showing what was loaded (event identity, score, winner side)
- Create
Marathon.UI/Pages/Results/ResultsList.razor:- Browse already-loaded results
- Filter by sport, date range, winner-side-1 / winner-side-2 / draw
- Link back to event detail page (Phase 6)
- Add
Resultsentry to navigation drawer. - Localize all strings RU + EN.
- Frontend tests:
- bUnit: loader page invokes use case with correct parameters in both modes
- bUnit: results list filter narrows correctly
Files to Modify/Create
src/Marathon.Application/UseCases/PullResultsUseCase.cs— extendsrc/Marathon.UI/Pages/Results/ResultsLoader.razorsrc/Marathon.UI/Pages/Results/ResultsList.razortests/Marathon.Application.Tests/UseCases/PullResultsUseCaseTests.cstests/Marathon.UI.Tests/Pages/Results/**
Acceptance Criteria
- Compiles (Big Bang).
- Selective loading respects user's selection.
- Bulk loading skips events that already have results.
- UI shows progress during a multi-event load.
Notes
- Big Bang: compile-only smoke check.
Review Checklist
- Idempotent — no duplicate
EventResultrows - UI handles empty range gracefully (no events match)
- All strings localized