Skip to content

Refactor Discord package for long-term maintainability - #1

Merged
owens1127 merged 8 commits into
mainfrom
refactor/discord-maintainability-split
Apr 24, 2026
Merged

Refactor Discord package for long-term maintainability#1
owens1127 merged 8 commits into
mainfrom
refactor/discord-maintainability-split

Conversation

@owens1127

Copy link
Copy Markdown
Contributor

Summary

  • decompose oversized Discord bot modules into folder-first domains (manifest, pagination, command helpers)
  • centralize deferred command error reporting and Sentry capture through shared/logger paths
  • simplify startup and routing by moving app composition into create_app() and keeping main.py thin

Test plan

  • python3 - <<'PY' ... py_compile ... PY across src/
  • run command sync dry-run in CI (sync-discord-commands with dry-run env)
  • smoke test /subscription status, /subscribe, /player-search in a Discord test guild

Made with Cursor

Split commands, pagination, and manifest/client concerns into focused modules, centralize error handling with Sentry-aware logging, and clean up startup/sync flow to reduce coupling and improve readability.

Made-with: Cursor
Cover clan-id resolution, Discord relative time formatting fallbacks, and pagination token/custom-id parsing to lock in behavior during refactors.

Made-with: Cursor
@owens1127
owens1127 marked this pull request as ready for review April 23, 2026 04:12
Copilot AI review requested due to automatic review settings April 23, 2026 04:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Discord ingress/bot codebase into smaller domain-focused modules (manifest, pagination, command helpers) while centralizing deferred-error reporting and introducing optional Sentry initialization during app startup.

Changes:

  • Split large monolithic handlers into src/commands/*, src/pagination/*, and src/manifest/* modules with focused helpers and shared utilities.
  • Introduced create_app() in src/app_factory.py and simplified src/main.py to only expose the FastAPI app.
  • Added optional Sentry initialization + logger capture support, and added a set of unittest-based tests for key helpers.

Reviewed changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_subscription_helpers.py Adds unit tests for subscription helper functions and route constants.
tests/test_subscribe_resolution.py Adds unit tests for clan group id parsing.
tests/test_shared_time_format.py Adds unit tests for ISO-to-Discord relative timestamp formatting.
tests/test_raidhub_client_envelope.py Adds unit tests for envelope normalization behavior.
tests/test_pagination_tokens_and_ids.py Adds unit tests for pagination custom IDs and nav token parsing.
tests/test_manifest_commands.py Adds unit tests to enforce stable command manifest shape/names.
src/sync_commands.py Updates command manifest import to new src/manifest package.
src/subscribe_handlers.py Deletes legacy subscribe/unsubscribe handler module (moved into src/commands).
src/structured_logger.py Adds Sentry exception capture to error() logging.
src/sentry_init.py New helper to initialize Sentry from settings.
src/raidhub_client_types.py Extracts RaidHubEnvelopeCode into its own module.
src/raidhub_client_envelope.py New module for normalizing RaidHub envelope responses.
src/raidhub_client.py Refactors headers creation and delegates envelope normalization to shared helper.
src/pagination/tokens.py Extracts token parsing/clamping helpers.
src/pagination/session_pager.py Deletes legacy monolithic pagination implementation (split into new modules).
src/pagination/runtime.py New runtime/session store + pager dispatch logic.
src/pagination/ids.py New helpers for parsing/building pager custom_ids.
src/pagination/components.py New helpers for building pager action rows (Prev/Next/Start).
src/pagination/init.py Re-exports the refactored pagination API surface.
src/manifest/schema.py New DTO schema for command/option JSON generation.
src/manifest/builders.py Refactors command building into build_commands() and shared option builders.
src/manifest/init.py New wrapper for building the JSON command manifest from DTOs.
src/main.py Simplifies app entrypoint to app = create_app().
src/interaction_handlers.py Deletes legacy monolithic interaction handlers module (moved into app_factory + src/commands).
src/config.py Adds Sentry-related settings and env parsing.
src/commands/unsubscribe.py Routes + error reporting refactor; uses shared subscription helpers and centralized exception reporting.
src/commands/subscription_routes.py New constants for subscription route IDs.
src/commands/subscription_helpers.py New module for subscription payload building + status formatting + error messaging.
src/commands/subscription.py Refactors subscription command to use extracted helpers and centralized exception reporting.
src/commands/subscribe_resolution.py Extracts clan/player resolution logic from subscribe handler.
src/commands/subscribe.py Refactors subscribe command to use extracted resolution + centralized exception reporting.
src/commands/shared.py Adds iso_to_discord_relative() + report_deferred_exception() utilities.
src/commands/player_search_helpers.py Extracts player search pager rendering + formatting helpers.
src/commands/player_search.py Refactors player-search command to use extracted helpers and centralized exception reporting.
src/commands/instance.py Refactors instance command to use centralized exception reporting.
src/cli_sync_commands.py Changes CLI entrypoint wrapper to call into src.sync_commands.cli().
src/app_factory.py New create_app() composing settings, clients, routing, signature validation, and metrics.
pyproject.toml Adds build system metadata and Sentry dependency; updates console script mapping.
README.md Updates documentation to match new structure and adds observability section.
.github/workflows/start.yml Adds package build step and updates Python version.
.github/workflows/pr-ci.yml Updates Python version and switches to compileall for syntax check.
.github/workflows/deploy.yml Adds package build step and updates Python version.
.env.example Adds Sentry env vars (currently with a concrete DSN value).
Comments suppressed due to low confidence (1)

pyproject.toml:24

  • sync-discord-commands is configured to load cli_sync_commands:cli, but there is no top-level cli_sync_commands.py module in the repo (the file lives at src/cli_sync_commands.py). As-is, the console script will raise ModuleNotFoundError when installed/built. Update the entry point to src.cli_sync_commands:cli (or add proper setuptools package-dir config / move the module so the import path matches).
[project.scripts]
sync-discord-commands = "cli_sync_commands:cli"


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .env.example Outdated
Comment on lines +17 to +21
SENTRY_DSN="https://11a145d0ec878f0306afca7a63062d6d@o4510296341217280.ingest.us.sentry.io/4511267202072576"
SENTRY_ENVIRONMENT=development
SENTRY_RELEASE=
SENTRY_SEND_DEFAULT_PII=true
SENTRY_TRACES_SAMPLE_RATE=0.1

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.env.example includes a concrete Sentry DSN value. This can unintentionally send local/dev error data to a real Sentry project (and effectively publishes the DSN). Replace it with an empty value or an obvious placeholder DSN, and document that users should supply their own DSN via SENTRY_DSN.

Copilot uses AI. Check for mistakes.
Comment thread src/cli_sync_commands.py Outdated
Comment on lines +6 to +15
def cli() -> int:
from src.sync_commands import cli as sync_cli

return sync_cli()

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/cli_sync_commands.py mutates sys.path to make imports resolve. This is brittle in an installed package and likely indicates the packaging/module layout should be fixed instead (e.g., ensure the console entry point imports src.cli_sync_commands, and then import src.sync_commands via normal package imports without path surgery).

Copilot uses AI. Check for mistakes.
Switch subscription command surface to focused status/delete plus unsubscribe-player and unsubscribe-clan, update option names to player/clan, and preserve existing rules when subscribing new targets. Enrich subscribe confirmations and subscription status with resolved player/clan names while keeping status embeds text-only.

Made-with: Cursor
@owens1127
owens1127 marked this pull request as draft April 24, 2026 02:03
@owens1127
owens1127 marked this pull request as ready for review April 24, 2026 02:10
@owens1127
owens1127 marked this pull request as draft April 24, 2026 02:10
@owens1127
owens1127 marked this pull request as ready for review April 24, 2026 02:22
@owens1127
owens1127 merged commit ada415c into main Apr 24, 2026
2 checks passed
@owens1127
owens1127 deleted the refactor/discord-maintainability-split branch April 24, 2026 02:28
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