feat: configurable community commands — enabled toggles for all features#106
feat: configurable community commands — enabled toggles for all features#106BillChirico merged 1 commit intomainfrom
Conversation
|
Claude finished @BillChirico's task in 2m 12s —— View job Code Review: PR #106 — Configurable community commands
4 issues found (0 critical, 3 warnings, 1 nitpick)
AI fix prompt (copy-paste into Claude Code) |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (7)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds feature flags for community features (help, announce, snippet, poll, tldr): new config sections with enabled flags, updates config allowlist, adds runtime guards in commands, updates tests, and exposes toggles in the dashboard editor. Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
|
| Filename | Overview |
|---|---|
| src/commands/announce.js | adds config.announce?.enabled gate check with proper error message |
| src/commands/help.js | adds config.help?.enabled gate check with proper error message |
| web/src/components/dashboard/config-editor.tsx | adds Community Features card with toggles for all 5 commands and updates knownSections array |
| src/commands/snippet.js | missing enabled gate check — command will work even when disabled in config/UI |
| src/commands/poll.js | missing enabled gate check — command will work even when disabled in config/UI |
Last reviewed commit: 69ef675
There was a problem hiding this comment.
Review Summary
4 issues found (0 critical, 2 warnings, 2 nitpicks)
🟡 Warnings
- Missing test for disabled help gate (
tests/commands/help.test.js) — Mock updated toenabled: truebut no test verifies the early-return whenhelp.enabledisfalse. - Missing test for disabled announce gate (
tests/commands/announce.test.js) — Same gap: no test for theannounce.enabled: falsepath.
🔵 Nitpicks
- Autocomplete not gated (
src/commands/help.js:371) —autocomplete()still returns suggestions whenhelp.enabledisfalse, leading to confusing UX (suggestions appear, but command rejects). - Missing trailing newline (
config.json:168) — File no longer ends with a newline.
🤖 AI fix prompt (copy-paste into Claude Code)
On branch feat/command-config-gates, fix these 4 issues:
1. tests/commands/help.test.js — Add a test case "should reject when help is disabled":
- Mock getConfig to return { help: { enabled: false } }
- Call execute() and assert interaction.reply was called with content containing "not enabled" and ephemeral: true
- Assert interaction.deferReply was NOT called
2. tests/commands/announce.test.js — Add a test case "should reject when announce is disabled":
- Mock getConfig to return { announce: { enabled: false }, permissions: { enabled: true, adminRoleId: null, usePermissions: true } }
- Call execute() and assert interaction.reply was called with content containing "not enabled" and ephemeral: true
- Assert interaction.deferReply was NOT called
3. src/commands/help.js — In the autocomplete() function (line 371), add an early return when config.help.enabled is false:
const config = getConfig(interaction.guildId);
if (!config.help?.enabled) { return await interaction.respond([]); }
4. config.json — Add a trailing newline at the end of the file (after the closing }).
There was a problem hiding this comment.
Pull request overview
This PR implements configurable toggles for community feature commands (help, announce, snippet, poll, tldr) allowing guild admins to selectively enable features via the web dashboard. The changes introduce an enabled flag gate pattern for community commands while keeping moderation commands always available.
Changes:
- Added enabled gates to
/helpand/announcecommands with consistent error messaging - Created Community Features card in web dashboard with toggles for all 5 community commands
- Added all 5 feature sections to backend config allowlist and default config.json
- Updated test mocks to reflect enabled state requirement
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/commands/help.js | Added config.help.enabled gate check at execute start, minor formatting fix |
| src/commands/announce.js | Added config.announce.enabled gate check before permission validation |
| tests/commands/help.test.js | Updated mock config to include help: { enabled: true } |
| tests/commands/announce.test.js | Updated mock config to include announce: { enabled: true } |
| src/api/utils/configAllowlist.js | Added help, announce, snippet, poll, tldr to SAFE_CONFIG_KEYS |
| config.json | Added config sections for 5 community features, removed duplicate starboard entry |
| web/src/components/dashboard/config-editor.tsx | Added Community Features card with 5 toggles, updated type guard knownSections |
Comments suppressed due to low confidence (2)
tests/commands/help.test.js:13
- The new enabled gate functionality lacks test coverage. Add a test case that verifies the command returns the expected error message when config.help.enabled is false. This would require temporarily mocking getConfig to return { help: { enabled: false } } for that specific test.
getConfig: vi.fn().mockReturnValue({ help: { enabled: true } }),
tests/commands/announce.test.js:16
- The new enabled gate functionality lacks test coverage. Add a test case that verifies the command returns the expected error message when config.announce.enabled is false. This would require temporarily mocking getConfig to return { announce: { enabled: false }, permissions: { ... } } for that specific test.
announce: { enabled: true },
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@config.json`:
- Around line 150-167: Add documentation entries for the new config sections
added to config.json: "help", "announce", "snippet", "poll", and "tldr" into the
README.md configuration reference table; for each of help/announce/snippet/poll
document the "enabled" boolean and its purpose, and for "tldr" document
"enabled" plus "defaultMessages" (default number of messages to consider),
"maxMessages" (upper limit of messages allowed), and "cooldownSeconds" (cooldown
period between TLDR operations) with concise descriptions and expected
types/defaults so the README's config table matches the new keys in config.json.
In `@tests/commands/announce.test.js`:
- Around line 14-19: The test suite currently forces announce.enabled true via
the getConfig mock; add a new test in tests/commands/announce.test.js that sets
vi.mock('../../src/modules/config.js').getConfig to return announce: { enabled:
false } and then invokes the announce command handler (the same execute/handler
used by existing tests) asserting that the interaction receives an immediate
ephemeral reply (interaction.reply called with ephemeral: true) and that
interaction.deferReply and any DB methods (mocked DB client methods used in
other announce tests) are not called. Ensure the test resets mocks between cases
(restore/mocking getConfig) and mirrors existing test patterns for invoking the
command so it fails fast when announce.enabled is false.
In `@tests/commands/help.test.js`:
- Around line 12-14: Add a test in tests/commands/help.test.js that mocks
../../src/modules/config.js.getConfig to return { help: { enabled: false } },
then invoke the same help command/handler used by the existing tests and assert
the disabled early-return path is taken: e.g., the handler returns early
(undefined/false) or responds with the expected disabled result, and verify any
help-rendering function (the module's showHelp/sendHelp/handler) is not called
(use a spy/mock) so the help.enabled === false branch is covered.
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
config.jsonsrc/api/utils/configAllowlist.jssrc/commands/announce.jssrc/commands/help.jstests/commands/announce.test.jstests/commands/help.test.jsweb/src/components/dashboard/config-editor.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Greptile Review
- GitHub Check: Agent
- GitHub Check: claude-review
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use ESM modules withimport/exportsyntax; never userequire()
Always usenode:protocol for Node.js builtins (e.g.,import { readFileSync } from 'node:fs')
Always use semicolons in code
Use single quotes for strings (enforced by Biome)
Use 2-space indentation (enforced by Biome)
Files:
tests/commands/announce.test.jssrc/api/utils/configAllowlist.jssrc/commands/announce.jstests/commands/help.test.jsweb/src/components/dashboard/config-editor.tsxsrc/commands/help.js
tests/**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
tests/**/*.{js,ts,jsx,tsx}: All new code must include tests; test coverage must maintain 80% threshold on statements, branches, functions, and lines
Use Vitest for testing; runpnpm testbefore every commit andpnpm test:coverageto verify 80% coverage threshold
Files:
tests/commands/announce.test.jstests/commands/help.test.js
src/**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{js,ts,jsx,tsx}: Always use Winston for logging viaimport { info, warn, error } from '../logger.js'; never useconsole.log,console.warn,console.error, or anyconsole.*method in src/ files
Pass structured metadata to Winston logging calls (e.g.,info('Message processed', { userId, channelId }))
Use custom error classes fromsrc/utils/errors.jsfor error handling
Always log errors with context before re-throwing
UsegetConfig(guildId?)fromsrc/modules/config.jsto read configuration values
UsesetConfigValue(path, value, guildId?)fromsrc/modules/config.jsto update configuration at runtime
UsesafeSend()utility for all outgoing Discord messages to enforce allowedMentions and prevent mention spam
UsesanitizeMentions()to strip@everyone/@here from outgoing text via zero-width space insertion before sending
UsesplitMessage()utility to handle Discord's 2000-character message limit
onConfigChangecallbacks receive(newValue, oldValue, fullPath, guildId)as parameters
Files:
src/api/utils/configAllowlist.jssrc/commands/announce.jssrc/commands/help.js
src/commands/**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/commands/**/*.{js,ts,jsx,tsx}: Slash commands must export adataproperty with a SlashCommandBuilder and an asyncexecute(interaction)function
ExportadminOnly = truefor moderator-only slash commands
Duration-based commands (timeout, tempban, slowmode) must useparseDuration()fromsrc/utils/duration.jsfor parsing duration arguments
Always callcheckHierarchy(moderator, target)before executing moderation actions to prevent moderating users with equal or higher roles
Files:
src/commands/announce.jssrc/commands/help.js
config.json
📄 CodeRabbit inference engine (AGENTS.md)
Document new config sections and keys in
README.md's config reference when updatingconfig.json
Files:
config.json
🧠 Learnings (13)
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to config.json : Document new config sections and keys in `README.md`'s config reference when updating `config.json`
Applied to files:
src/api/utils/configAllowlist.jsweb/src/components/dashboard/config-editor.tsxconfig.json
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/commands/**/*{ban,kick}*.{js,ts,jsx,tsx} : Moderation commands must DM the target user before executing kicks/bans (as users cannot receive DMs after being kicked/banned)
Applied to files:
src/commands/announce.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/commands/**/*{ban,kick,warn,timeout,mute}*.{js,ts,jsx,tsx} : Moderation commands must follow the pattern: deferReply() → validate → sendDmNotification() → execute Discord action → createCase() → sendModLogEmbed() → checkEscalation()
Applied to files:
src/commands/announce.jssrc/commands/help.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/commands/**/*.{js,ts,jsx,tsx} : Export `adminOnly = true` for moderator-only slash commands
Applied to files:
src/commands/announce.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/commands/**/*.{js,ts,jsx,tsx} : Always call `checkHierarchy(moderator, target)` before executing moderation actions to prevent moderating users with equal or higher roles
Applied to files:
src/commands/announce.jssrc/commands/help.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/commands/**/*.{js,ts,jsx,tsx} : Slash commands must export a `data` property with a SlashCommandBuilder and an async `execute(interaction)` function
Applied to files:
src/commands/announce.jssrc/commands/help.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to tests/**/*.{js,ts,jsx,tsx} : Use Vitest for testing; run `pnpm test` before every commit and `pnpm test:coverage` to verify 80% coverage threshold
Applied to files:
tests/commands/help.test.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/**/*.{js,ts,jsx,tsx} : `onConfigChange` callbacks receive `(newValue, oldValue, fullPath, guildId)` as parameters
Applied to files:
web/src/components/dashboard/config-editor.tsx
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/**/*.{js,ts,jsx,tsx} : Use `setConfigValue(path, value, guildId?)` from `src/modules/config.js` to update configuration at runtime
Applied to files:
web/src/components/dashboard/config-editor.tsx
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/**/*.{js,ts,jsx,tsx} : Use `getConfig(guildId?)` from `src/modules/config.js` to read configuration values
Applied to files:
web/src/components/dashboard/config-editor.tsx
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/**/*.{js,ts,jsx,tsx} : Use `safeSend()` utility for all outgoing Discord messages to enforce allowedMentions and prevent mention spam
Applied to files:
src/commands/help.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/**/*.{js,ts,jsx,tsx} : Always use Winston for logging via `import { info, warn, error } from '../logger.js'`; never use `console.log`, `console.warn`, `console.error`, or any `console.*` method in src/ files
Applied to files:
src/commands/help.js
📚 Learning: 2026-02-26T22:59:10.394Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-26T22:59:10.394Z
Learning: Applies to src/modules/{ai,spam,moderation}.js : Per-request modules (AI, spam, moderation) call `getConfig(interaction.guildId)` on every invocation for automatic config hot-reload; `onConfigChange` listeners provide observability only
Applied to files:
src/commands/help.js
🧬 Code graph analysis (3)
src/commands/announce.js (1)
src/utils/safeSend.js (1)
safeReply(138-145)
web/src/components/dashboard/config-editor.tsx (1)
web/src/components/ui/card.tsx (3)
Card(76-76)CardContent(81-81)CardTitle(79-79)
src/commands/help.js (3)
src/commands/announce.js (2)
config(141-141)config(350-350)src/modules/config.js (1)
getConfig(282-313)src/utils/safeSend.js (1)
safeReply(138-145)
🔇 Additional comments (5)
src/api/utils/configAllowlist.js (1)
16-20: Allowlist expansion looks correct.These keys are correctly added to
SAFE_CONFIG_KEYS, enabling API read/write for the new community feature toggles.src/commands/help.js (1)
328-335: Feature gate placement is correct.Nice early guard before
deferReply, withsafeReplyand ephemeral feedback for disabled/help.src/commands/announce.js (1)
143-149:/announcegate is implemented cleanly.Early return avoids unnecessary permission checks and DB access when the feature is disabled.
web/src/components/dashboard/config-editor.tsx (2)
51-51: Type guard update is aligned with new config schema.Including
help/announce/snippet/poll/tldrin known sections is the right compatibility update for partial API responses.
1191-1224: Community feature toggle card is a solid addition.The UI wiring to
draftConfig[feature].enabledmatches the new per-guild feature-flag model.
…gles - /help and /announce now check config.help.enabled / config.announce.enabled - /snippet, /poll, /tldr already have enabled checks from their PRs - Added help, announce, snippet, poll, tldr to SAFE_CONFIG_KEYS (API writable) - Added Community Features card to web config editor with toggle for each - config.json includes all 5 new sections (disabled by default = opt-in)
c7ad31b to
69ef675
Compare
| })); | ||
| vi.mock('../../src/modules/config.js', () => ({ | ||
| getConfig: vi.fn().mockReturnValue({}), | ||
| getConfig: vi.fn().mockReturnValue({ help: { enabled: true } }), |
There was a problem hiding this comment.
🟡 Warning: No test for the help.enabled === false path
The mock was updated to return enabled: true so existing tests pass, but there's no test verifying that the command returns early with the "not enabled" message when help.enabled is false. This is the main feature of this PR — it should be tested.
Add a test like:
it('should reject when help is disabled', async () => {
const { getConfig } = await import('../../src/modules/config.js');
getConfig.mockReturnValueOnce({ help: { enabled: false } });
const interaction = createInteraction('view');
await execute(interaction);
expect(interaction.reply).toHaveBeenCalledWith(
expect.objectContaining({
content: expect.stringContaining('not enabled'),
ephemeral: true,
}),
);
expect(interaction.deferReply).not.toHaveBeenCalled();
});|
|
||
| vi.mock('../../src/modules/config.js', () => ({ | ||
| getConfig: vi.fn().mockReturnValue({ | ||
| announce: { enabled: true }, |
There was a problem hiding this comment.
🟡 Warning: No test for the announce.enabled === false path
Same as help.test.js — the mock now returns enabled: true but there's no test verifying the gate rejects when announce.enabled is false.
Add a test like:
it('should reject when announce is disabled', async () => {
const { getConfig } = await import('../../src/modules/config.js');
getConfig.mockReturnValueOnce({
announce: { enabled: false },
permissions: { enabled: true, adminRoleId: null, usePermissions: true },
});
const interaction = createMockInteraction('list');
await execute(interaction);
expect(interaction.reply).toHaveBeenCalledWith(
expect.objectContaining({
content: expect.stringContaining('not enabled'),
ephemeral: true,
}),
);
expect(interaction.deferReply).not.toHaveBeenCalled();
});| */ | ||
| export async function execute(interaction) { | ||
| const config = getConfig(interaction.guildId); | ||
| if (!config.help?.enabled) { |
There was a problem hiding this comment.
🟡 Warning: autocomplete() (line 371) not gated behind config.help.enabled
When help.enabled is false, autocomplete() still queries the DB and returns topic suggestions. Users see autocomplete results, submit the command, and then get "not enabled" — confusing UX and a wasted DB query.
Add the same gate at the top of autocomplete():
export async function autocomplete(interaction) {
const config = getConfig(interaction.guildId);
if (!config.help?.enabled) {
return await interaction.respond([]);
}
// ... existing logic
}| "poll": { | ||
| "enabled": false | ||
| }, | ||
| "tldr": { |
There was a problem hiding this comment.
🟡 Warning: New config sections not documented in README.md
Per AGENTS.md: "Document new config sections and keys in README.md's config reference when updating config.json."
The help, announce, snippet, poll, and tldr sections need entries in the README config reference. Each needs at minimum the enabled boolean documented, and tldr also needs defaultMessages, maxMessages, and cooldownSeconds.
🔵 Nitpick: Missing trailing newline — File doesn't end with a newline character.
There was a problem hiding this comment.
4 issues found (0 critical, 3 warnings, 1 nitpick). See inline comments for details.
Warnings:
- Missing test for
help.enabled === falsepath (tests/commands/help.test.js) - Missing test for
announce.enabled === falsepath (tests/commands/announce.test.js) autocomplete()not gated behindconfig.help.enabled(src/commands/help.js:371)- New config sections not documented in README.md config reference (
config.json)
Nitpick:
5. Missing trailing newline in config.json
| })); | ||
| vi.mock('../../src/modules/config.js', () => ({ | ||
| getConfig: vi.fn().mockReturnValue({}), | ||
| getConfig: vi.fn().mockReturnValue({ help: { enabled: true } }), |
There was a problem hiding this comment.
consider adding test case for when help.enabled is false to verify the gate check works
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/commands/help.test.js
Line: 13
Comment:
consider adding test case for when `help.enabled` is false to verify the gate check works
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.|
|
||
| vi.mock('../../src/modules/config.js', () => ({ | ||
| getConfig: vi.fn().mockReturnValue({ | ||
| announce: { enabled: true }, |
There was a problem hiding this comment.
consider adding test case for when announce.enabled is false to verify the gate check works
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/commands/announce.test.js
Line: 16
Comment:
consider adding test case for when `announce.enabled` is false to verify the gate check works
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (4)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/commands/snippet.js
Line: 349-351
Comment:
missing `config.snippet?.enabled` gate check — config and UI claim this command is toggleable but it will work regardless of the setting
```suggestion
export async function execute(interaction) {
const config = getConfig(interaction.guildId);
if (!config.snippet?.enabled) {
await safeReply(interaction, {
content: '❌ The /snippet command is not enabled on this server.',
ephemeral: true,
});
return;
}
const subcommand = interaction.options.getSubcommand();
await interaction.deferReply({ ephemeral: subcommand !== 'get' });
```
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/commands/poll.js
Line: 61-69
Comment:
missing `config.poll?.enabled` gate check — config and UI claim this command is toggleable but it will work regardless of the setting
```suggestion
export async function execute(interaction) {
const config = getConfig(interaction.guildId);
if (!config.poll?.enabled) {
await safeReply(interaction, {
content: '❌ The /poll command is not enabled on this server.',
ephemeral: true,
});
return;
}
await interaction.deferReply({ ephemeral: true });
const pool = getPool();
```
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/commands/snippet.js
Line: 13
Comment:
add `safeReply` to import for the enabled gate check
```suggestion
import { safeEditReply, safeReply } from '../utils/safeSend.js';
```
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/commands/poll.js
Line: 14
Comment:
add `safeReply` to import for the enabled gate check
```suggestion
import { safeEditReply, safeReply } from '../utils/safeSend.js';
```
How can I resolve this? If you propose a fix, please make it concise. |
Summary
All community feature commands are now configurable per guild with an
enabledtoggle.Changes
/help— gated behindconfig.help.enabled/announce— gated behindconfig.announce.enabled/snippet— already has gate (PR feat: /snippet code sharing command (#41) #103)/poll— already has gate (PR feat: /poll voting system with buttons (#47) #104)/tldr— already has gate (PR feat: /tldr conversation summarizer (#25) #105)Web Dashboard
SAFE_CONFIG_KEYSso the API allows savingConfig
All features disabled by default (opt-in). Admins enable what they want:
{ "help": { "enabled": true }, "poll": { "enabled": true } }Mod commands
/ban,/kick,/warn, etc. remain always-on — they're already permission-gated.1643 tests passing, 0 lint errors.