Skip to content

Suggestion Command Draft PR #869

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

Suggestion Command Draft PR #869

wants to merge 8 commits into from

Conversation

Atmois
Copy link
Contributor

@Atmois Atmois commented May 18, 2025

Description

When the command is run makes a post in a defined channel which has two buttons, approve and deny, those buttons can only be interacted with by admins. It also will add thumps up and down reaction for user votes and create a thread attached to it.

Guidelines

  • My code follows the style guidelines of this project (formatted with Ruff)

  • I have performed a self-review of my own code

  • I have commented my code, particularly in hard-to-understand areas

  • I have made corresponding changes to the documentation if needed

  • My changes generate no new warnings

  • I have tested this change

  • Any dependent changes have been merged and published in downstream modules

  • I have added all appropriate labels to this PR

  • I have followed all of these guidelines.

Additional Information

Most of it has been completed, the major missing component is button persistence on restart.

Summary by Sourcery

Implement a suggestion submission feature allowing users to submit suggestions via a slash command, log them to a configurable channel, and enable admin-only approve/deny interactions with vote tracking and threaded discussions.

New Features:

  • Add /suggest slash command that opens a SuggestionModal for users to submit suggestions
  • Introduce SuggestionModal and ButtonView to post suggestions as embeds with Approve/Deny buttons for admins
  • Enable users to vote on suggestions via 👍/👎 reactions and automatically create a discussion thread for each suggestion

Enhancements:

  • Add suggestion_log_id field to guild configuration with corresponding getters and setters
  • Implement SuggestionController for ensuring guild records and creating suggestion entries in the database
  • Register persistent ButtonView in bot startup to handle suggestion approval/denial interactions

@Atmois Atmois requested a review from electron271 May 18, 2025 08:43
@Atmois Atmois linked an issue May 18, 2025 that may be closed by this pull request
Copy link
Contributor

sourcery-ai bot commented May 18, 2025

Reviewer's Guide

Introduces a new suggestion command flow: a modal for user submissions, configuration UI for setting the suggestion channel, database support for persisting suggestions and channel settings, and interactive approve/deny buttons with reactions and thread creation.

Sequence Diagram: Admin Reviewing a Suggestion

sequenceDiagram
    actor Admin
    participant DiscordClient as Discord Client
    participant SuggestionMessage as Suggestion Message (in Channel)
    participant ButtonView as ButtonView (Tux Bot Component)
    participant DiscordAPI as Discord API

    Admin->>DiscordClient: Clicks "Approve" or "Deny" button on SuggestionMessage
    DiscordClient->>ButtonView: Button interaction received
    ButtonView->>ButtonView: Perform permission check (e.g., checks.has_pl(5))
    alt Admin has required permissions
        ButtonView->>ButtonView: Update internal embed state (e.g., status to "Accepted"/"Rejected", add reviewer)
        ButtonView->>DiscordAPI: Edit original SuggestionMessage with updated embed and buttons
    else Admin lacks permissions
        ButtonView->>Admin: (Interaction fails or ephemeral error - not explicitly shown in diff)
    end
Loading

Class Diagram: New UI Components - SuggestionModal and ButtonView

classDiagram
    class SuggestionModal {
        <<UI Modal>>
        +bot: commands.Bot
        +config: GuildConfigController
        +suggestion_title: discord.ui.TextInput
        +suggestion_description: discord.ui.TextInput
        +__init__(title: str, bot: commands.Bot)
        +on_submit(interaction: discord.Interaction) void
    }
    note for SuggestionModal "New modal for users to submit suggestions."

    class ButtonView {
        <<UI View>>
        +embed: discord.Embed
        +__init__(embed: discord.Embed)
        +green_button(interaction: discord.Interaction, button: discord.ui.Button) void
        note for green_button "Handles 'Accept' button. Requires @checks.has_pl(5)."
        +red_button(interaction: discord.Interaction, button: discord.ui.Button) void
        note for red_button "Handles 'Deny' button. Requires @checks.has_pl(5)."
    }
    note for ButtonView "New view with 'Accept' and 'Deny' buttons for suggestion messages."

    SuggestionModal --|> discord.ui.Modal
    ButtonView --|> discord.ui.View
    SuggestionModal ..> GuildConfigController : uses
    SuggestionModal ..> discord.Embed : creates
    ButtonView ..> discord.Embed : manipulates
Loading

Class Diagram: New Backend Components - Suggestion Cog and SuggestionController

classDiagram
    class Suggestion {
        <<Cog>>
        +bot: commands.Bot
        +__init__(bot: commands.Bot)
        +suggestion(interaction: discord.Interaction) void
        note for suggestion "App command '/suggest'. Sends SuggestionModal to the user."
    }
    note for Suggestion "New Cog to handle the '/suggest' application command."

    class SuggestionController {
        <<Database Controller>>
        +table: PrismaTable_Suggestion "prisma.suggestion table accessor"
        +guild_table: PrismaTable_Guild "prisma.guild table accessor"
        +__init__()
        +ensure_guild_exists(guild_id: int) Guild
        +create_suggestion(suggestion_title: str, suggestion_description: str, suggestion_status: SuggestionStatus, suggestion_user_id: int, guild_id: int) Suggestion
    }
    note for SuggestionController "New controller for creating and managing suggestion records in the database."

    Suggestion --|> discord.ext.commands.Cog
    Suggestion ..> SuggestionModal : creates and sends
    SuggestionController ..> prisma.models.Guild : uses
    SuggestionController ..> prisma.models.Suggestion : uses
    SuggestionController ..> prisma.enums.SuggestionStatus : uses
Loading

Class Diagram: Updates to GuildConfigController for Suggestions

classDiagram
    class GuildConfigController {
        <<Existing Controller>>
        #get_guild_config_field_value(guild_id, field_name)
        #ensure_guild_exists(guild_id)
        #table
        +get_log_channel(guild_id: int, log_type: str) int | None
        note for get_log_channel "Internal 'log_channel_ids' map updated to include 'suggestion'."
        +get_suggestion_log_channel(guild_id: int) int | None
        note for get_suggestion_log_channel "New method to retrieve the suggestion log channel ID."
        +update_suggestion_log_id(guild_id: int, suggestion_log_id: int) GuildConfig | None
        note for update_suggestion_log_id "New method to set or update the suggestion log channel ID."
    }
    note for GuildConfigController "Modified to manage configuration for suggestion log channels."
Loading

Class Diagram: Updates to ConfigSetLogChannel View for Suggestions

classDiagram
    class ConfigSetLogChannel {
        <<Existing UI View>>
        +db: GuildConfigController
        +__init__(timeout: float)
        %% Other select handlers like _set_join_log(...)
        +_set_suggestion_log(interaction: discord.Interaction, select: discord.ui.ChannelSelect) void
        note for _set_suggestion_log "New discord.ui.ChannelSelect element and handler added to set the suggestion channel."
    }
    note for ConfigSetLogChannel "Modified to include a UI ChannelSelect dropdown for configuring the suggestion log channel."

    ConfigSetLogChannel --|> discord.ui.View
    ConfigSetLogChannel ..> GuildConfigController : uses (via self.db)
Loading

Class Diagram: Updates to DatabaseController and Tux Bot for Suggestions

classDiagram
    class DatabaseController {
        <<Existing Controller Aggregator>>
        +note: NoteController
        +reminder: ReminderController
        +snippet: SnippetController
        +guild: GuildController
        +guild_config: GuildConfigController
        +suggestion: SuggestionController
        note for suggestion "New SuggestionController instance added for suggestion data management."
        +__init__()
    }
    note for DatabaseController "Modified to integrate the new SuggestionController."

    class Tux {
        <<Bot Class>>
        %% Other attributes and methods
        +on_ready() void
        note for on_ready "Modified to add ButtonView persistently using self.add_view(). This is a step towards button persistence on restart."
    }
    note for Tux "Bot class updated to register the new ButtonView for suggestions."

    Tux --|> discord.ext.commands.Bot
    DatabaseController ..> SuggestionController : aggregates
    Tux ..> ButtonView : registers globally
Loading

File-Level Changes

Change Details Files
Add suggestion channel configuration support
  • Extend guild_config mapping with suggestion_log_id
  • Implement get_suggestion_log_channel and update_suggestion_log_id methods
  • Add ChannelSelect UI to set suggestion log channel
tux/database/controllers/guild_config.py
tux/ui/views/config.py
Register persistent suggestion button view on bot startup
  • Import ButtonView in the bot entrypoint
  • Call add_view for ButtonView in on_ready
tux/bot.py
Implement suggestion modal and interactive button view
  • Create SuggestionModal to collect title and description
  • Query configured channel, send embed with Under Review status
  • Attach reactions and start a thread on the message
  • Define ButtonView with Accept/Deny buttons and PL-level permission checks
tux/ui/modals/suggestion.py
Add SuggestionController for database operations
  • Implement ensure_guild_exists to upsert guild records
  • Implement create_suggestion to record suggestions
tux/database/controllers/suggestion.py
Add slash command Cog for suggestions
  • Create Suggestion Cog with /suggest command
  • Send SuggestionModal on command invocation
tux/cogs/misc/suggestions.py

Possibly linked issues

  • #1: Implements the /suggest command, adding channel posting, reactions, admin buttons, and discussion threads as requested.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@anemoijereja-eden
Copy link
Collaborator

will need rewrites following completion of #853

Copy link
Collaborator

Choose a reason for hiding this comment

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

does this need to be in bot.py?

@@ -116,7 +117,10 @@ async def get_private_log_id(self, guild_id: int) -> int | None:
async def get_report_log_id(self, guild_id: int) -> int | None:
return await self.get_guild_config_field_value(guild_id, "report_log_id")

async def get_dev_log_id(self, guild_id: int) -> int | None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this rename necessary?

from tux.database.client import db


class SuggestionController:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This controller should probably have a method for retrieving suggestions and maybe even searching them.
create_suggestion should be an upsert method, rather than a pure insert.

auto_archive_duration=1440,
)

reactions = ["👍", "👎"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Move this to constants file, or ideally make configurable.

@anemoijereja-eden anemoijereja-eden added the status: waiting for db migration changes require extensive use of the database system label Jun 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for db migration changes require extensive use of the database system
Projects
None yet
Development

Successfully merging this pull request may close these issues.

/suggest command
3 participants