WAGERBABE DOCS
All Stories
7-13-sgp-pricing-cacheDoneEpic 7.13

Story 7.13: SGP Pricing Cache

Status: done

Tasks

  • Task 1: Create SGPPricingCache class (AC: #1, #2, #5)
    • 1.1: Implement `SGPPricingCache` class in `server/app/services/betting/sgp_pricing_cache.py`
    • 1.2: Add Redis client dependency injection via module imports
    • 1.3: Implement `generate_cache_key(legs: List[ParlayLeg]) -> str` method
    • 1.4: Sort legs by fingerprint string for deterministic ordering
    • 1.5: Generate cache key using MD5 hash: `sgp:{sportsbook}:{hash}`
    • 1.6: Implement `async def get_or_fetch(legs, sportsbook_id, fetch_func)` method
    • 1.7: Check Redis cache with generated key - return cached value if exists
    • 1.8: If cache miss, fetch via provided fetch_func
    • 1.9: Store fetched odds in Redis with 30-second TTL
    • 1.10: Return odds to caller
  • Task 2: Integrate with parlay calculation endpoint (AC: #4)
    • 2.1: Import `SGPPricingCache` into `ParlayCalculatorService`
    • 2.2: Add SGPPricingCache singleton via `get_sgp_pricing_cache()`
    • 2.3: Modify `calculate()` method to use cache for SGPs
    • 2.4: Cache check before API call, cache set after API response
    • 2.5: Ensure cross-game parlays still use simple decimal multiplication (no caching)
    • 2.6: Response includes `cache_hit` field in `ParlayCalculationResponse`
  • Task 3: Add cache hit rate monitoring (AC: #3, #4)
    • 3.1: Add `SGPCacheMetrics` dataclass with tracking
    • 3.2: Track `hits` counter (increment on Redis cache hit)
    • 3.3: Track `misses` counter (increment on cache miss/API call)
    • 3.4: Track `sets` counter (successful cache writes)
    • 3.5: Calculate `hit_rate` property as percentage
    • 3.6: Expose metrics via `GET /api/v1/shared/cache/sgp/stats` endpoint
    • 3.7: Include `avg_lookup_ms` for latency tracking
    • 3.8: Include `api_calls_saved` and `estimated_cost_savings`
  • Task 4: Write unit tests (AC: #1, #2, #5)
    • 4.1: Test cache key generation with identical legs in different order produces same key
    • 4.2: Test cache key uniqueness for different leg combinations
    • 4.3: Test cache key generation for all market types (h2h, spreads, totals, props)
    • 4.4: Test Redis cache hit returns stored value without API call
    • 4.5: Test Redis cache miss triggers API call
    • 4.6: Test fetched value is stored in Redis with 30s TTL
    • 4.7: Test metrics tracking (hits, misses, sets)
    • 4.8: Test error handling when Redis is unavailable (fallback to direct API)
  • Task 5: Write integration tests (AC: #3, #4)
    • 5.1: Test identical SGP request within 30s uses cache (no API call)
    • 5.2: Test different SGP combinations create separate cache entries
    • 5.3: Test: 100 identical SGP requests → verify 99 cache hits (99% hit rate)
    • 5.4: Test cache hit rate tracking across requests
    • 5.5: Test metrics endpoint returns accurate cache hit rate
    • 5.6: Test cache hit rate >80% during simulated high traffic
    • 5.7: Test different sportsbooks use different cache keys

Progress

Tasks5/5
Acceptance Criteria0
Total Tasks5