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