fix: explicit DM router and admin session exclusivity (#111, #112)#136
Merged
adrunkhuman merged 5 commits intomasterfrom Mar 21, 2026
Merged
fix: explicit DM router and admin session exclusivity (#111, #112)#136adrunkhuman merged 5 commits intomasterfrom
adrunkhuman merged 5 commits intomasterfrom
Conversation
**#112 – explicit DM routing precedence** - Add `DMRouter` in `typer_bot/services/dm_router.py` as the single source of truth for DM routing order: fixture session → results session → prediction handler. - Bot's `on_message` routes DMs through the router directly; cog-level `on_message` listeners removed from `AdminCommands` and `UserCommands` so routing no longer depends on listener registration order. - Remove the ad-hoc `has_results_session` guard buried in `DMPredictionHandler.handle_dm`; the router now owns that invariant. **#111 – admin DM workflow exclusivity** - `_start_fixture_dm` rejects the request if a results-entry session is already active, sending a clear DM to the admin. - `results_enter` rejects the request if a fixture-creation session is already active, responding with an ephemeral error. - Add `WorkflowStateStore.has_admin_session()` helper that covers both admin session types. Tests: - New `tests/test_dm_router.py` covers all routing precedence cases. - New `TestAdminSessionExclusivity` in `test_admin_commands.py` covers allowed and blocked session-start combinations. - Removed stale on_message listener tests that moved to the router. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Log and return when dm_router is None instead of silently dropping DMs - Catch all exceptions (not just HTTPException) when sending fixture-create DM so orphaned sessions are always cancelled on send failure - Remove dead has_admin_session() helper (never called) - Add TestOnMessageDMRouting tests covering DM→router, guild→skip, None-router warning, and thread-handler priority Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Catch all exceptions (not just discord.Forbidden) in results_enter DM send so orphaned results sessions are always cancelled on failure, matching the fix already applied to _start_fixture_dm - Patch discord.ext.commands.Bot.on_message in guild-message routing test instead of process_commands, so the test asserts the correct super() call path and stays robust against discord.py internals Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
🚅 Deployed to the matchday-typer-pr-136 environment in patient-quietude
|
- Add exclusivity check in fixture_create *before* the 'Check your DMs' response so conflicting-session errors are a single clear message, not a success ack followed by an error; the _start_fixture_dm fallback guard remains for the view-triggered path - Widen contextlib.suppress scope to Exception so any send failure in the conflict-rejection DM path still reaches return False - Split exclusivity test into command-path and _start_fixture_dm-path cases to cover both call sites Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move has_results_session guard before the open_fixtures check so the exclusivity error is shown for both the direct path (no open fixtures) and the warning-view path (open fixtures exist). Previously the guard was dead when fixtures were open — the view was shown instead, and clicking 'Yes' sent 'Check your DMs!' before _start_fixture_dm could block it. The _start_fixture_dm fallback guard remains for the narrow race window between the command check and the DM send. 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
DMRouterintyper_bot/services/dm_router.pyas the single source of truth for DM routing precedence (fixture session → results session → prediction handler). Bot'son_messageroutes DMs directly through the router; both cog-levelon_messagelisteners removed, eliminating the implicit listener-registration-order dependency._start_fixture_dmrejects (with a DM to the admin) if a results-entry session is active;results_enterrejects (with an ephemeral error) if a fixture-creation session is active. Both DM-send failure paths now cancel the session on any exception, not justdiscord.Forbidden.Test plan
tests/test_dm_router.py— 7 new tests covering routing precedence and guard conditionsTestAdminSessionExclusivityintest_admin_commands.py— 4 new tests for allowed/blocked session-start combinationsTestOnMessageDMRoutingintest_bot.py— 4 new tests verifying DM→router, guild→skip, None-router warning, thread-handler priorityCloses #111
Closes #112
🤖 Generated with Claude Code