Files
maraphon-app/plans/initial-implementation/phase-8-results-loader.md
T

83 lines
3.1 KiB
Markdown

# Phase 8: Results Loader
**Status:** ⬜ Not Started
**Parent plan:** [PLAN.md](./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)
- [ ] `PullResultsUseCase` was scaffolded in Phase 4 — extend it here:
- When `selection` is null/empty, fetch results for ALL completed events in range
that don't have a stored `EventResult` yet
- When `selection` provided, fetch results only for those events
- Idempotent — re-running for already-loaded results is a no-op
- [ ] Add `IResultsScraper`-related parser methods (or extend `IOddsScraper` with
`ScrapeResultsAsync`) — implementation may already exist from Phase 3.
- [ ] After persisting results, infer `WinnerSide` and update the `Event` accordingly
(or store derived `WinnerSide` on `EventResult` only — implementer's choice, document
in handoff).
- [ ] Tests in `Marathon.Application.Tests`:
- `PullResultsUseCase` with 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 `Results` entry 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` — extend
- `src/Marathon.UI/Pages/Results/ResultsLoader.razor`
- `src/Marathon.UI/Pages/Results/ResultsList.razor`
- `tests/Marathon.Application.Tests/UseCases/PullResultsUseCaseTests.cs`
- `tests/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 `EventResult` rows
- [ ] UI handles empty range gracefully (no events match)
- [ ] All strings localized
## Handoff to Next Phase
<!-- Filled by Phase 8 implementer. Phase 9 is packaging — note any runtime requirements
(e.g., Playwright browser binaries) that need to be bundled with the installer. -->