All Stories
2-2-3-stale-cache-servingDoneEpic 2.2
Story 2.2.3: Stale Cache Serving
Status: done
Tasks
- Task 1: Implement StaleCacheService class (AC: #1, #2, #3, #5)
- 1.1: Create `StaleCacheService` class in `server/app/core/stale_cache.py`
- 1.2: Implement `get_with_stale_fallback()` method with dual cache key pattern (`cache_key` + `cache_key:stale`)
- 1.3: Add stale TTL parameter (default 86400 seconds / 24 hours)
- 1.4: Integrate with existing CircuitBreaker to catch `CircuitOpenError` exceptions
- 1.5: Return `CacheMetadata` dataclass with `stale: bool` and `age: int` fields
- 1.6: Write stale cache to separate Redis key with extended TTL on every successful API fetch
- Task 2: Update Optic Odds service to use stale cache fallback (AC: #1, #2, #3)
- 2.1: Refactor Optic Odds client methods to use `StaleCacheService.get_with_stale_fallback()`
- 2.2: Add `X-Cache-Stale` and `X-Cache-Age` headers to FastAPI responses when metadata indicates stale data
- 2.3: Update response models to include optional cache metadata
- 2.4: Ensure all endpoints (fixtures, odds, data) support stale cache serving
- Task 3: Frontend stale data indicator (AC: #4)
- 3.1: Create `useStaleData` hook to parse `X-Cache-Stale` and `X-Cache-Age` headers
- 3.2: Create `<StaleDataBanner>` component with yellow warning icon and "Data may be outdated" message
- 3.3: Display banner at top of odds cards/lists when stale data detected
- 3.4: Include "Last updated X minutes ago" timestamp in banner
- 3.5: Auto-hide banner when fresh data is received (returns null when !isStale)
- Task 4: Testing and validation (AC: #1, #2, #3, #4, #5) - Backend tests complete
- 4.1: Unit tests for `StaleCacheService` - verify dual cache key writes and stale fallback logic
- 4.2: Integration test: simulate circuit breaker open state, verify stale cache served
- 4.3: Verify headers: `X-Cache-Stale: true` and `X-Cache-Age: {seconds}` present in response
- 4.4: Test stale cache expiration: verify 24-hour retention, then purge
- 4.5: Frontend tests: verify `<StaleDataBanner>` renders when headers present
- 4.6: E2E test: simulate API outage, verify stale data + banner display
Progress
Tasks4/4
Acceptance Criteria0
Total Tasks4