Skip to content

feat(sports): make the schedule fetch window configurable - #286

Open
ChuckBuilds wants to merge 2 commits into
mainfrom
feat/configurable-schedule-window
Open

feat(sports): make the schedule fetch window configurable#286
ChuckBuilds wants to merge 2 commits into
mainfrom
feat/configurable-schedule-window

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Stacked on #285 — merge that first.

What this adds

schedule_lookback_days and schedule_lookahead_days, advanced settings on all nine scoreboards. Previously hard-coded at 14 back / 7 forward.

Bounded 1–60 days. A non-numeric or out-of-range value falls back to the default rather than raising, so a bad config can't take the plugin down or turn one refresh into a season-wide request.

Defaults keep today's behaviour, so no board changes on upgrade. The one exception is soccer, whose lookahead moves 7 → 14 to match the fetch its partial substitutes for — that's the bug from #285.

Why days is the wrong primitive

Worth stating plainly, because this is an escape hatch rather than the answer.

"Show me the next 5 games" is a count. The days it spans depends entirely on the league's cadence — about 5 days for MLB, about 5 weeks for the Premier League. So any fixed number of days is wrong for one of them, and this setting makes the user do that arithmetic themselves.

The better version sets the horizon from a game count and expands until it's satisfied, gated on whether favourite teams are configured:

  • no favourites — keep the short window; someone browsing a whole league shouldn't pull a season of fixtures to show five
  • favourites set — step 7 → 30 → 60 days, stopping as soon as N games for those teams are found

Cost: unchanged for no-favourites and for daily leagues (satisfied at the first step); 2–3 requests on a cold cache for a weekly league, which is the case that's currently broken. Future fixtures are static, so a long cache TTL means that's paid once.

The plugin already resolves self.favorite_teams in SportsCore.__init__, before the first fetch, so the gate is available where it's needed.

Verification

  • All nine schemas carry both keys, x-advanced: true, bounds 1–60.
  • Clamping covered: a configured value is used, absent falls back, non-numeric falls back, 3650 clamps to 60, 0 and negatives clamp to 1.
  • The soccer horizon test now reads the full fetch's span from soccer_managers.py and requires the configured default to be at least as wide, so the two can't drift apart again.
  • Safety harness clean on a four-plugin spot check (soccer, baseball, hockey, ufc).
  • Across the nine plugins' suites, the only failures are the two pre-existing missing-src ones that also fail on main.

Separate finding, not fixed here

Measuring API load on a live rig turned up idle-season polling: NHLLiveManager fetched 0 games 22 times in 2 hours — every ~5.5 minutes, year-round, mid-August. Roughly 264 requests/day for one out-of-season league, all returning nothing. That's a defaults problem rather than a configurability one and deserves its own change.

claude added 2 commits August 14, 2026 21:17
Reported by a user: Manchester United never appeared even though their
next fixture was 22 August, and with favourites turned off the board
showed exactly one Premier League game, Arsenal v Coventry.

_get_weeks_data() is the partial that serves the display until the
background fetch lands. It looked ahead seven days; _fetch_soccer_api_data(),
the fetch it substitutes for, looks ahead fourteen. So a fixture inside
the real window was simply missing from the board.

That gap is invisible in a league that plays daily and severe in one that
plays weekly, where a whole matchweek can fall inside it. Reproduced
against ESPN on 2026-08-14:

  -2w..+1w  20260731-20260821 ->  1 event   (COV @ ARS, the 21st)
  -2w..+4w  20260731-20260911 -> 30 events  (MAN @ HUL on the 22nd, ...)

The Premier League's opening matchweek was 21-24 August, so a +7d horizon
caught the Friday opener and hid the other nine fixtures -- exactly the
single game the user described.

Both horizons now come from one pair of module constants, so the partial
cannot silently end up narrower than the fetch it stands in for again.
The test reads the full fetch's span out of soccer_managers.py and
requires the partial to be at least as wide, rather than hard-coding
either number.

Mutation-checked: reverting the horizon, re-hardcoding the window in
_get_weeks_data, and narrowing the back-window are all caught.

Harness clean; soccer's other tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
How far back and forward games are fetched was hard-coded at 14 days back
and 7 forward, in all nine scoreboards.

Days is the wrong unit for a league that plays weekly: a whole matchweek
can fall just past a short horizon and never reach the board, which is
how a user's favourite team went missing while other clubs in the same
league appeared. Both sides are now advanced settings --
schedule_lookback_days and schedule_lookahead_days -- bounded 1 to 60,
with a non-numeric or out-of-range value falling back to the default
rather than raising.

Defaults keep today's behaviour, so nobody's board changes on upgrade.
The exception is soccer, whose lookahead moves 7 -> 14 to match the fetch
its partial stands in for; that is the reported bug.

This is an escape hatch, not the final answer. The right primitive is a
game count rather than a day count -- "the next five fixtures" spans five
days for a daily league and five weeks for a weekly one, so any fixed
number of days is wrong for one of them. That change wants gating on
whether favourite teams are configured, so a user browsing a whole league
does not pull a season of fixtures to show five.

Harness clean on a four-plugin spot check; the two failures across the
nine plugins' test suites are the pre-existing missing-src ones also
present on main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 99eb7827-94de-4366-b538-61f975edf7e3


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 38 complexity

Metric Results
Complexity 38

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants