Instruction file imported from RandomStatsGuy/ScoreSense (
.cursor/rules/draft-hub-performance.mdc). Copyright stays with the author.
Fantasy performance
- Prefer materialized caches over live
predict_*on hub routes:artifacts/draft_pool/,artifacts/weekly_predictions/. - Pool vs overlay:
build_draft_pool_payload()thenbuild_value_overlay()invalue_sheet.py. Do not recompute the pool per request. - Roster/cap reads are DB-only. Sleeper runs on link/sync, or
GET /api/hub/roster?live_sleeper=1for a one-off pull. GET /api/hub/homeandGET /league/{id}/freshnessserve the last-known snapshot (stale_as_of) and never parse commissioner workbooks or block on Sleeper. Cap-sheet stale uses file mtimes vs storedfile_fingerprint. Workbook parse stays on explicit sheet sync.- Hub
GET /media/{id}serves the original unless?w=is set. Snap to 48 / 96 / 256, cache the WebP variant next to the file, and never resize on a cache hit. Clients request the painted size — do not ship the studio original for a 22px mark. - Scoring history lives in SQLite
sleeper_scoring_cache. Refresh on league sync orGET /api/hub/league/{id}/insights?refresh=1. - CPU-heavy work uses
app/process_pool.py. Do not start a per-route process pool. - Secrets and paths go through
src/config.py, not rawos.environin routes. HUB_TIMING=truelogs slow hub routes (>500ms) and may setX-Hub-Timing-MS.- After mlready or model changes, refresh the draft-pool fingerprint (
preseason_refreshorscripts/ops/fix_artifact_fingerprints.py). Do not leave first-visit Fantasy pages on cold live inference.
Measurement and perceived speed
Perceived speed follows the same architecture: paint roster/cap snapshots first, retain known content during refresh, reserve image/skeleton geometry, and make selection/previews immediate. Trades loads Ideas/Inbox on demand and reuses the existing account/league/team-scoped weekly snapshot. Measure cold/warm navigation and a representative interaction before claiming an improvement; record device/viewport, cache state, and data source.
Future field-measurement targets are LCP ≤2.5s, INP ≤200ms, and CLS ≤0.1 at the 75th percentile, segmented by phone/desktop (Core Web Vitals thresholds). These are targets, not current results; one local lab render cannot establish a field percentile. Do not add a telemetry dependency or more polling just to populate the rollout log.
