fix: stale results guard, calculation post results, default UTC#132
Merged
adrunkhuman merged 4 commits intomasterfrom Mar 21, 2026
Merged
fix: stale results guard, calculation post results, default UTC#132adrunkhuman merged 4 commits intomasterfrom
adrunkhuman merged 4 commits intomasterfrom
Conversation
…TC (#121, #102, #77) #121: ResultsEntryHandler.save_results() now re-validates the fixture before writing. Raises ValueError if the fixture is closed or scores already exist, preventing a stale confirmation button from silently overwriting scored results. ResultsConfirmView.confirm() surfaces the error to the admin; session is preserved so they can cancel explicitly. Uses the existing fixture_has_scores() DB method — no new queries. #102: _post_calculation_to_channel() now prepends the entered match results to the announcement via new format_fixture_results() in prediction_parser.py. Data was already present in FixtureScoreResult — just not passed through to the post. #77: Default timezone changed from Europe/Warsaw to UTC. Existing stored deadlines are unaffected — they carry an embedded UTC offset in the ISO string so parse_iso() ignores APP_TZ for them. Deadline inputs via the admin DM workflow are now expected in UTC. .env.example updated accordingly. Closes #121, #102, #77. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Clear results session immediately in ResultsConfirmView.confirm() error path rather than relying on the 120s view timeout; buttons are already removed via view=None so the session had no reachable cleanup path within the window. - Make db.save_results() atomic: wraps check+write in BEGIN IMMEDIATE so the fixture-status and scores-exist guards are not a TOCTOU against concurrent admin sessions or panel corrections. - Use strict=True in format_fixture_results() zip so a games/results length mismatch surfaces as an explicit error rather than a silently truncated post. - Wrap ZoneInfo() construction in timezone.py with a try/except and re-raise as RuntimeError with the invalid key in the message, so a bad TZ env var fails at startup with a clear diagnostic instead of a raw ZoneInfoNotFoundError. - Update test_timezone.py to reflect UTC default (two tests hardcoded the old Europe/Warsaw expectation). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uard test
Wrap the INSERT and commit in db.save_results() in a try/except that calls
db.rollback() on failure, matching the pattern used by every other BEGIN
IMMEDIATE block in the file. Previously a write-time error would leave the
IMMEDIATE lock held until the connection closed rather than releasing it
promptly.
Standardise early-exit rollbacks to db.rollback() (aiosqlite connection method)
instead of db.execute("ROLLBACK") raw SQL to stay consistent with the rest of
the file.
Add test_save_results_db_rejects_scores_exist_open_fixture: exercises the
scores-exist guard at the real SQLite layer by inserting scores directly without
closing the fixture, covering the path that the existing mock-based test only
approximated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
🚅 Deployed to the matchday-typer-pr-132 environment in patient-quietude
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ResultsEntryHandler.save_results()now validates the fixture before writing: re-checks status and scores existence atomically insidedb.save_results()withBEGIN IMMEDIATE, preventing a stale confirmation button from silently overwriting already-scored results. Session is cleared immediately on rejection (buttons are gone viaview=None).format_fixture_results()prepended to the/admin results calculateannouncement so users can see the actual entered match results alongside standings.Europe/WarsawtoUTC. Existing stored fixtures are unaffected (UTC offsets are embedded in stored ISO strings). Deadline inputs in the admin DM workflow are now expected in UTC.Test plan
uv run pytest— 295 passed, 1 skippedTZ=Europe/Warsawoverride still works for deployments that need itCloses #121
Closes #102
Closes #77
🤖 Generated with Claude Code