All Stories
2-1-2-game-detail-endpointReviewEpic 2.1
Story 2.1.2: Game Detail Endpoint (On-Demand Full Data)
Status: review
Tasks
- Task 1: Create DetailService (AC: #2)
- 1.1: Create `server/app/services/odds/detail_service.py` with DetailService class
- 1.2: Implement `fetch_game_detail(fixture_id, sportsbooks)` method
- 1.3: Implement Optic Odds API call to fetch full fixture data with all markets
- 1.4: Implement `aggregate_markets()` to group markets by type (spread, ML, total, player_props, alt_spreads, alt_totals)
- 1.5: Unit test: verify all market types extracted and grouped correctly
- Task 2: Create Pydantic Schemas (AC: #2, #3)
- 2.1: Create `server/app/schemas/odds/detail.py` with FixtureInfo, MarketOdds, GameDetail, GameDetailResponse models
- 2.2: Define market grouping structure supporting nested player_props by category
- 2.3: Add sportsbooks list to response
- 2.4: Add meta field with market_count, cached, response_time_ms
- 2.5: Unit test: schema serialization/deserialization
- Task 3: Create API Endpoint (AC: #1, #2, #3)
- 3.1: Create `server/app/api/v1/endpoints/odds/detail.py` router
- 3.2: Implement `GET /api/v1/fixtures/{fixture_id}/detail` endpoint
- 3.3: Add query parameter: `sportsbooks` (comma-separated, default: "fanduel,draftkings")
- 3.4: Add input validation with Pydantic (fixture_id format, valid sportsbook names)
- 3.5: Register router in main app
- 3.6: Integration test: endpoint returns valid GameDetailResponse
- Task 4: Implement Redis Caching with SWR (AC: #4)
- 4.1: Create cache key pattern: `odds:detail:{fixture_id}:{sportsbooks_hash}`
- 4.2: Implement soft TTL (15 sec) / hard TTL (30 sec) SWR pattern
- 4.3: On cache hit within soft TTL: return cached, no refresh
- 4.4: On cache hit within hard TTL but past soft TTL: return cached, trigger background refresh
- 4.5: On cache miss: fetch from Optic Odds API, cache, return
- 4.6: Add cache hit/miss logging for monitoring
- 4.7: Integration test: verify SWR behavior with 30s TTL
- Task 5: Performance Validation (AC: #1)
- 5.1: Add response timing decorator/middleware
- 5.2: Measure and log response time per request
- 5.3: Add response_time_ms to meta field in response
- 5.4: Create load test scenario for detail endpoint (extend Locust framework)
- 5.5: Validate p95 < 2s with 50 concurrent requests
- Task 6: Error Handling & Fallback (AC: #4)
- 6.1: On Optic Odds API failure + cache available: return stale cache with `stale: true` in meta
- 6.2: On Optic Odds API failure + no cache: return 503 with retry guidance
- 6.3: On fixture not found: return 404 with clear error message
- 6.4: Unit test: verify fallback behavior for each error case
Progress
Tasks6/6
Acceptance Criteria0
Total Tasks6