WAGERBABE DOCS
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