feat: starboard — showcase popular messages (#48)#99
Conversation
|
Claude finished @BillChirico's task in 2m 58s —— View job Review: PR #99 — feat: starboard
Result: 1 issue found (documentation only)🟡 Warning: Missing AGENTS.md and README.md documentation — Per AGENTS.md §Documentation, new modules must update:
All previously flagged code issues (intent, partials, dead variables, safeSend, test assertions, warn logs, redundant index, feedback loop guard) have been resolved. CI is green. The implementation is solid — just needs the docs update to comply with project conventions. See inline comment and review verdict for details + copy-paste AI fix prompt. |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughImplements a Discord starboard feature that automatically reposts messages to a dedicated channel when they receive a configurable number of star reactions. Includes configuration schema, database migration, event listeners, embed generation, and comprehensive test coverage. Changes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
|---|---|
| migrations/002_starboard-posts.cjs | Added starboard_posts table with UNIQUE constraint on source_message_id, uses parameterized queries, proper up/down migrations |
| src/modules/starboard.js | Comprehensive starboard implementation with proper error handling, uses safeSend, handles partials, implements wildcard emoji support; minor edge case with custom emoji configuration format |
| src/modules/events.js | Reaction handlers properly check bot reactions, fetch partials, verify guild context, and include error handling; events wiring is correct |
| src/index.js | Added required GuildMessageReactions intent and Message/Reaction partials for uncached reaction events |
Sequence Diagram
sequenceDiagram
participant User
participant Discord
participant EventHandler
participant Starboard
participant DB
participant StarboardChannel
User->>Discord: Reacts to message with ⭐
Discord->>EventHandler: MessageReactionAdd event
EventHandler->>EventHandler: Check bot reaction, fetch partials
EventHandler->>EventHandler: Verify guild context & config
EventHandler->>Starboard: handleReactionAdd()
Starboard->>Starboard: Check feedback loop, ignored channels
Starboard->>Starboard: getStarCount() (with self-star exclusion)
alt Star count >= threshold
Starboard->>DB: findStarboardPost()
alt Existing post
Starboard->>StarboardChannel: Fetch & edit message
Starboard->>DB: updateStarboardPostCount()
else New post
Starboard->>StarboardChannel: safeSend() embed
Starboard->>DB: insertStarboardPost()
end
end
User->>Discord: Removes reaction
Discord->>EventHandler: MessageReactionRemove event
EventHandler->>Starboard: handleReactionRemove()
Starboard->>DB: findStarboardPost()
alt Post exists
Starboard->>Starboard: getStarCount()
alt Below threshold
Starboard->>StarboardChannel: Delete message
Starboard->>DB: deleteStarboardPost()
else Above threshold
Starboard->>StarboardChannel: Update message
Starboard->>DB: updateStarboardPostCount()
end
end
Last reviewed commit: 980114f
There was a problem hiding this comment.
Review Summary — 5 issues found
🔴 Critical (1)
- Missing
GuildMessageReactionsintent + Partials config (src/index.js): The client doesn't declareGatewayIntentBits.GuildMessageReactions, so reaction events will never fire — the entire starboard feature is silently non-functional. Additionally,Partials.Message,Partials.Channel, andPartials.Reactionare needed for the partial-handling code to work on uncached messages.
🟡 Warning (3)
- Starboard channel feedback loop (
src/modules/starboard.js:243): No guard prevents starring starboard embeds themselves. Starring an embed creates a new starboard post for it, potentially cascading. - Dead variable with confusing precedence (
src/modules/events.js:232-242): Theguildvariable is alwaysnulldue to??/ternary precedence. Works by accident but is misleading. Same issue duplicated in the remove handler. - Unbounded
reaction.users.fetch()(src/modules/starboard.js:191): No limit parameter — could page through all users on popular messages.
🔵 Nitpick (1)
- Redundant index (
migrations/002_starboard-posts.cjs:21):source_message_idUNIQUE constraint already creates an index. Consider indexingguild_idinstead.
📝 Documentation
- Missing AGENTS.md / README.md updates: Per project conventions, new modules must be added to the Key Files table in AGENTS.md and documented in README.md.
There was a problem hiding this comment.
Review Summary — 3 issues found
🔴 Critical (1)
- Missing
GuildMessageReactionsintent + Partials config (src/index.js:100-108): The client doesn't declareGatewayIntentBits.GuildMessageReactions, so reaction events will never fire — the entire starboard feature is silently non-functional. Additionally,Partials.Message,Partials.Channel, andPartials.Reactionare needed for the partial-handling code to work on uncached messages.
🟡 Warning (1)
- Unbounded
reaction.users.fetch()consideration (src/modules/starboard.js:191): The{ limit: 100 }is already present, but a comment documenting the intentional trade-off (self-star check misses authors beyond 100 reactions) would help future maintainers.
🔵 Nitpick (1)
- Missing startup log for starboard (
src/modules/events.js): Other features (welcome, AI, moderation) log at startup inregisterReadyHandler; starboard should too for consistency.
✅ What's solid
- Core starboard logic is well-structured with proper error handling, partial message support, and feedback loop prevention
- Comprehensive test coverage (35 new tests)
- DB queries are parameterized (no SQL injection)
- Winston logger used throughout (no
console.*) - JSDoc on all exported functions
- Config follows existing
getConfig()per-request pattern
📝 Note on previous review comments
- The Greptile review flagged a guild resolution logic error in events.js lines 232-234 / 260-262. Looking at the current code (commit
e43cbc1), this has already been fixed — the logic is now correct (const guild = reaction.message.guild; if (!guild && reaction.message.partial) ...). - The redundant index issue in the migration has also been fixed (line 21 now has a comment explaining why no explicit index is needed).
Blocking issue
The intent/partials fix in src/index.js is the only blocking issue. Everything else is optional.
There was a problem hiding this comment.
2 issues found. 🔴 Critical: Missing Partials configuration in src/index.js — without Partials.Message/Channel/Reaction, Discord.js won't emit reaction events for uncached messages, making starboard dead code for older messages. 🟡 Warning: Missing AGENTS.md and README.md documentation updates per project conventions. See inline comments for details and fix instructions.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/starboard.js`:
- Around line 175-204: The self-star detection in getStarCount currently fetches
only the first 100 users via reaction.users.fetch({ limit: 100 }) which can miss
the author for reactions >100; update getStarCount to paginate through
reaction.users.fetch using the `after` cursor (or fetch in chunks) until either
the author ID is found or no more users remain, then subtract one if found;
alternatively, document the limitation if you intentionally keep the 100-limit
(add a clear comment near the reaction.users.fetch call explaining it may miss
authors beyond the first 100 users).
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
config.jsonmigrations/002_starboard-posts.cjssrc/index.jssrc/modules/events.jssrc/modules/starboard.jstests/modules/events.test.jstests/modules/starboard.test.js
📜 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). (2)
- GitHub Check: Greptile Review
- GitHub Check: claude-review
🧰 Additional context used
📓 Path-based instructions (4)
**/*.js
📄 CodeRabbit inference engine (AGENTS.md)
**/*.js: Use ESM modules only — useimport/export, neverrequire()
Usenode:protocol for Node.js builtins (e.g.import { readFileSync } from 'node:fs')
Always use semicolons
Use single quotes for strings
Use 2-space indentation
No TypeScript — use plain JavaScript with JSDoc comments for documentation
Files:
src/modules/events.jstests/modules/starboard.test.jstests/modules/events.test.jssrc/index.jssrc/modules/starboard.js
src/**/*.js
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.js: Always use Winston for logging — import{ 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 config
UsesetConfigValue(path, value, guildId?)fromsrc/modules/config.jsto update config at runtime
UsesplitMessage()utility for messages exceeding Discord's 2000-character limit
UsesafeSend()wrapper for outgoing Discord messages to sanitize mentions and enforce allowedMentions
Files:
src/modules/events.jssrc/index.jssrc/modules/starboard.js
src/modules/events.js
📄 CodeRabbit inference engine (AGENTS.md)
Register event handlers in
src/modules/events.jsby callingclient.on()with the event name and handler function
Files:
src/modules/events.js
tests/**/*.js
📄 CodeRabbit inference engine (AGENTS.md)
Test files must achieve at least 80% code coverage on statements, branches, functions, and lines
Files:
tests/modules/starboard.test.jstests/modules/events.test.js
🧠 Learnings (6)
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/modules/events.js : Register event handlers in `src/modules/events.js` by calling `client.on()` with the event name and handler function
Applied to files:
src/modules/events.jstests/modules/events.test.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/modules/{ai,spam,moderation}.js : Per-request modules (AI, spam, moderation) should call `getConfig(interaction.guildId)` on every invocation for automatic hot-reload support
Applied to files:
src/modules/events.jstests/modules/events.test.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/**/*.js : Use `safeSend()` wrapper for outgoing Discord messages to sanitize mentions and enforce allowedMentions
Applied to files:
src/modules/events.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Applies to src/**/*.js : Use `getConfig(guildId?)` from `src/modules/config.js` to read config
Applied to files:
tests/modules/events.test.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Update `AGENTS.md` whenever finding new pitfalls or adding features that affect AI agent context
Applied to files:
src/modules/starboard.js
📚 Learning: 2026-02-25T02:39:33.506Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-25T02:39:33.506Z
Learning: Update `config.json` documentation in README.md when adding new config sections or keys
Applied to files:
src/modules/starboard.js
🧬 Code graph analysis (4)
src/modules/events.js (2)
src/modules/config.js (6)
client(161-161)client(522-522)client(526-529)client(711-711)getConfig(282-313)err(94-94)src/modules/starboard.js (3)
reaction(176-176)handleReactionAdd(215-309)handleReactionRemove(320-389)
tests/modules/starboard.test.js (2)
src/db.js (1)
getPool(142-147)src/modules/starboard.js (10)
resolveStarboardConfig(162-164)buildStarboardEmbed(33-81)findStarboardPost(89-101)insertStarboardPost(114-128)updateStarboardPostCount(137-143)deleteStarboardPost(151-154)getStarCount(175-204)reaction(176-176)handleReactionAdd(215-309)handleReactionRemove(320-389)
tests/modules/events.test.js (2)
src/modules/events.js (1)
registerReactionHandlers(232-286)src/modules/starboard.js (3)
reaction(176-176)handleReactionAdd(215-309)handleReactionRemove(320-389)
src/modules/starboard.js (4)
src/db.js (1)
getPool(142-147)src/modules/config.js (1)
err(94-94)src/utils/debugFooter.js (1)
r(305-305)src/logger.js (3)
debug(223-225)warn(237-239)info(230-232)
🔇 Additional comments (21)
src/index.js (1)
107-107: LGTM!Adding
GatewayIntentBits.GuildMessageReactionsis required to receiveMessageReactionAddandMessageReactionRemoveevents for the starboard feature. Correctly placed with the other intents.migrations/002_starboard-posts.cjs (1)
1-27: LGTM!The migration correctly creates the
starboard_poststable with appropriate schema:
UNIQUEconstraint onsource_message_idprovides the implicit index needed for efficient lookupsON CONFLICThandling in the module'sinsertStarboardPostaligns with this constraint- Defensive
IF NOT EXISTS/IF EXISTSclauses for idempotencyconfig.json (1)
98-105: LGTM!Sensible default configuration:
enabled: falseensures the feature is opt-inthreshold: 3is a reasonable minimum for community engagementselfStarAllowed: falseprevents gaming the system- All fields align with
STARBOARD_DEFAULTSin the moduletests/modules/events.test.js (3)
31-34: LGTM!Proper mock setup for the starboard module with both reaction handlers returning resolved promises.
413-493: Good test coverage forregisterReactionHandlers.The tests properly cover:
- Event registration verification
- Bot reaction filtering
- Starboard disabled state handling
- Delegation to
handleReactionAdd/handleReactionRemove- Error handling (graceful failure without throwing)
543-544: LGTM!Correctly verifies that
registerEventHandlerswires both reaction events.src/modules/events.js (4)
17-17: LGTM!Import aligns with the module's public API.
60-65: LGTM!Startup logging for starboard follows the established pattern for other features (welcome, AI, moderation), providing useful context with
channelIdandthreshold.
224-286: Well-structured reaction handlers.Good implementation:
- Bot reactions correctly filtered early (line 235, 262)
- Partial message fetching handles uncached messages (lines 238-244, 264-270)
- Per-guild config resolution via
getConfig(guildId)enables hot-reload support (lines 248, 274) — aligns with learned pattern- Error handling with structured metadata (lines 253-258, 279-284)
- Early returns for disabled starboard prevent unnecessary processing
315-315: LGTM!Correctly wires reaction handlers into the event registration flow.
tests/modules/starboard.test.js (5)
1-29: LGTM!Clean test setup with proper mocks for logger and database modules, followed by imports of the starboard module's public API.
30-88: Well-designed test helpers.The factory functions (
mockPool,makeMockMessage,makeStarboardConfig,makeMockReaction) provide clean abstractions that make tests readable and maintainable.
92-328: Comprehensive unit tests for core functions.Good coverage of:
resolveStarboardConfigdefault mergingbuildStarboardEmbedwith various message states (content, no content, attachments, embeds, missing author)- DB operations with correct SQL verification
getStarCountwith self-star handling and edge cases
330-553: ThoroughhandleReactionAddtest coverage.Tests cover the critical flows:
- Disabled starboard
- Non-matching emoji
- Ignored channels
- Self-star prevention
- Below-threshold handling
- New post creation
- Existing post updates
- Partial reaction fetching
555-677: GoodhandleReactionRemovetest coverage.Tests verify:
- Disabled starboard handling
- No-op when no existing post
- Deletion when falling below threshold
- Count updates when still above threshold
src/modules/starboard.js (6)
1-22: LGTM!Clean module header with appropriate imports and well-documented defaults that align with
config.json.
33-81: Robust embed builder implementation.Good defensive coding:
- Null-safe author name fallback chain (
displayName ?? username ?? 'Unknown')- Handles both Discord.js Collection
.find()and plain Map iteration for attachments- Falls back to embed images when no image attachment exists
89-154: LGTM on database helpers.
findStarboardPost: Properly catches errors and returnsnullto avoid breaking the flowinsertStarboardPost: UsesON CONFLICT ... DO UPDATEfor safe upsert behaviorupdateStarboardPostCount/deleteStarboardPost: Straightforward operations
162-164: LGTM!Simple spread merge provides expected override behavior.
215-309: Well-structured reaction add handler.Good implementation details:
- Early returns for disabled/misconfigured starboard
- Partial fetch handling with graceful failure
- Feedback loop prevention (ignoring starboard channel reactions)
- Self-star check before counting
- Threshold check before any Discord API calls
- Fallback repost logic when existing starboard message was deleted (lines 279-290)
320-389: LGTM on reaction remove handler.Properly handles both cases:
- Below threshold → delete starboard post and DB record
- Above threshold → update embed count
The
debuglevel log for "already deleted" (line 364) is appropriate since this is an expected race condition.
566faa0 to
0efab50
Compare
There was a problem hiding this comment.
3 issues found (2 warnings, 1 nitpick). See inline comments for details.
🟡 Warning (2):
- Missing documentation updates (
AGENTS.md+README.md): Per AGENTS.md §Documentation, new modules must update Key Files table, Database Tables section, and README.md config reference.src/modules/starboard.js,starboard_poststable, and starboard config are not documented. safeSend()not used (src/modules/starboard.js:300,311): DirectstarboardChannel.send()calls should usesafeSend()wrapper per project conventions.
🔵 Nitpick (1):
3. Silent return on missing channel (src/modules/starboard.js:376): handleReactionRemove silently returns when starboard channel not found — should log a warning for consistency with handleReactionAdd.
Previously flagged issues now resolved: Missing GuildMessageReactions intent ✅, missing Partials config ✅, dead guild variable in events.js ✅, redundant index in migration ✅, startup logging for starboard ✅.
Fix all issues with AI prompt
Fix the following issues in the volvox-bot starboard PR (branch: feat/starboard):
1. In `src/modules/starboard.js`:
- Import `safeSend` from `'../utils/safeSend.js'`
- Replace `starboardChannel.send(...)` on lines 300 and 311 with `safeSend(starboardChannel, ...)`
- In `handleReactionRemove` around line 376, change the silent `if (!starboardChannel) return;` to:
```js
if (!starboardChannel) {
warn('Starboard channel not found', { channelId: sbConfig.channelId });
return;
}
```
2. In `AGENTS.md`:
- Add `src/modules/starboard.js | Starboard — showcase popular messages in a dedicated channel` to the Key Files table
- Add `starboard_posts | Starboard dedup tracking — maps source messages to starboard embeds` to the Database Tables section
- Update Common Pitfall #3 to: "Discord intents — the bot needs MessageContent, GuildMembers, GuildVoiceStates, and GuildMessageReactions intents enabled"
3. In `README.md`, add a Starboard config section after Moderation and before Permissions:
### Starboard (`starboard`)
| Key | Type | Description |
|-----|------|-------------|
| `enabled` | boolean | Enable starboard feature |
| `channelId` | string | Channel to post starboard embeds |
| `threshold` | number | Minimum star count to post (default: 3) |
| `emoji` | string | Emoji to track, or `*` for any emoji (default: ⭐) |
| `selfStarAllowed` | boolean | Allow message authors to star their own messages (default: false) |
| `ignoredChannels` | string[] | Channel IDs to exclude from starboard |
There was a problem hiding this comment.
4 issues found (1 critical, 2 warnings, 1 nitpick). See inline comments for details.
🔴 Critical (1):
- Broken test (
tests/modules/starboard.test.js:112):resolveStarboardConfigtest expectsemojito be'⭐'butSTARBOARD_DEFAULTS.emojiwas changed to'*'in commit3ec439f. This test will fail.
🟡 Warning (2):
2. Missing documentation (AGENTS.md + README.md): Per AGENTS.md §Documentation, new modules must update Key Files table, Database Tables section, Common Pitfalls, and README.md config reference.
3. safeSend() not used (src/modules/starboard.js:300,311): Direct starboardChannel.send() calls should use safeSend() wrapper per project conventions.
🔵 Nitpick (1):
4. Silent return on missing channel (src/modules/starboard.js:376): handleReactionRemove silently returns when starboard channel not found — should log a warning for consistency with handleReactionAdd.
Previously flagged issues now resolved: Missing GuildMessageReactions intent ✅, missing Partials config ✅, dead guild variable in events.js ✅, redundant index in migration ✅, startup logging ✅, feedback loop guard ✅.
Fix all issues with AI prompt
Fix the following issues in the volvox-bot starboard PR (branch: feat/starboard):
1. In `tests/modules/starboard.test.js` line 112:
- Change `expect(result.emoji).toBe('⭐');` to `expect(result.emoji).toBe('*');`
- STARBOARD_DEFAULTS.emoji was changed to '*' but this test wasn't updated
2. In `src/modules/starboard.js`:
- Add import: `import { safeSend } from '../utils/safeSend.js';`
- Line 300: Replace `starboardChannel.send({ content, embeds: [embed] })` with `safeSend(starboardChannel, { content, embeds: [embed] })`
- Line 311: Replace `starboardChannel.send({ content, embeds: [embed] })` with `safeSend(starboardChannel, { content, embeds: [embed] })`
- Line 376: Change `if (!starboardChannel) return;` to:
```js
if (!starboardChannel) {
warn('Starboard channel not found', { channelId: sbConfig.channelId });
return;
}
```
3. In `AGENTS.md`:
- Add `src/modules/starboard.js | Starboard — showcase popular messages in a dedicated channel` to the Key Files table (after the events.js row)
- Add `starboard_posts | Starboard dedup tracking — maps source messages to starboard embeds` to the Database Tables section
- Update Common Pitfall #3 to: "Discord intents — the bot needs MessageContent, GuildMembers, GuildVoiceStates, and GuildMessageReactions intents enabled"
4. In `README.md`, add a Starboard config section after Moderation and before Permissions (around line 201):
### Starboard (`starboard`)
| Key | Type | Description |
|-----|------|-------------|
| `enabled` | boolean | Enable starboard feature |
| `channelId` | string | Channel to post starboard embeds |
| `threshold` | number | Minimum star count to post (default: 3) |
| `emoji` | string | Emoji to track, or `*` for any emoji (default: `*`) |
| `selfStarAllowed` | boolean | Allow message authors to star their own messages (default: false) |
| `ignoredChannels` | string[] | Channel IDs to exclude from starboard |
There was a problem hiding this comment.
Review Summary — 4 issues found (1 critical, 2 warnings, 1 nitpick)
CI is failing — 3 test failures in starboard.test.js (lines 258, 280, 356).
🔴 Critical (1)
- Broken test expectations (
tests/modules/starboard.test.js:258,280,356): ThreegetStarCounttests expect'*'(U+002A asterisk) for the emoji field, but the code returns'⭐'(U+2B50 star emoji). Confirmed failing in CI:AssertionError: expected '⭐' to be '*'.
🟡 Warning (2)
- Missing AGENTS.md documentation (
AGENTS.md): Per §Documentation,src/modules/starboard.jsmust be added to the Key Files table,starboard_poststo the Database Tables section, and Common Pitfall #3 should mentionGuildMessageReactionsintent. - Missing README.md documentation (
README.md): New config sections require a README.md config reference (perconfig.json→ README.md convention). No starboard section exists.
🔵 Nitpick (1)
- Silent return on missing channel (
src/modules/starboard.js:377):handleReactionRemovesilently returns when starboard channel not found — should log a warning for consistency withhandleReactionAdd(line 282).
Previously flagged issues — now resolved ✅
- Missing
GuildMessageReactionsintent ✅ - Missing
Partialsconfig ✅ - Dead
guildvariable in events.js ✅ - Redundant index in migration ✅
- Startup logging for starboard ✅
- Feedback loop guard ✅
safeSendusage ✅
Fix all issues with AI prompt
Fix the following issues in the volvox-bot starboard PR (branch: feat/starboard):
1. In `tests/modules/starboard.test.js`:
- Line 258: Change `expect(result.emoji).toBe('*');` to `expect(result.emoji).toBe('⭐');`
- Line 280: Change `expect(result.emoji).toBe('*');` to `expect(result.emoji).toBe('⭐');`
- Line 356: Change `expect(result.emoji).toBe('*');` to `expect(result.emoji).toBe('⭐');`
These tests expect '*' (asterisk) but getStarCount returns '⭐' (star emoji)
2. In `src/modules/starboard.js` line 377:
Change `if (!starboardChannel) return;` to:
if (!starboardChannel) {
warn('Starboard channel not found', { channelId: sbConfig.channelId });
return;
}
3. In `AGENTS.md`:
- Add `src/modules/starboard.js | Starboard — showcase popular messages in a dedicated channel` to the Key Files table (after events.js row)
- Add `starboard_posts | Starboard dedup tracking — maps source messages to starboard embeds` to the Database Tables section
- Update Common Pitfall #3 to: "Discord intents — the bot needs MessageContent, GuildMembers, GuildVoiceStates, and GuildMessageReactions intents enabled"
4. In `README.md`, add a Starboard config section in the Configuration reference (after Moderation):
### Starboard (`starboard`)
| Key | Type | Description |
|-----|------|-------------|
| `enabled` | boolean | Enable starboard feature |
| `channelId` | string | Channel to post starboard embeds |
| `threshold` | number | Minimum star count to post (default: 3) |
| `emoji` | string | Emoji to track, or `*` for any emoji (default: `*`) |
| `selfStarAllowed` | boolean | Allow message authors to star their own messages (default: false) |
| `ignoredChannels` | string[] | Channel IDs to exclude from starboard |
… warn log - Fix three test assertions that expected '*' instead of '⭐' for getStarCount return values (lines 258, 280, 356) - Add warn log to handleReactionRemove when starboard channel not found (mirrors handleReactionAdd behavior)
There was a problem hiding this comment.
Review Summary — 1 issue (documentation)
🟡 Warning (1)
Missing AGENTS.md and README.md documentation updates (src/modules/starboard.js): Per AGENTS.md §Documentation ("Keep docs up to date — this is non-negotiable"), new modules must update:
- AGENTS.md Key Files table — add
src/modules/starboard.js | Starboard — showcase popular messages in a dedicated channel - AGENTS.md Database Tables — add
starboard_posts | Starboard dedup tracking — maps source messages to starboard embeds - AGENTS.md Common Pitfall #3 — update to include
GuildMessageReactionsintent - README.md Configuration reference — add a Starboard (
starboard) config section (same format as AI, Triage, Welcome, Moderation)
✅ Previously flagged issues — all resolved
- Missing
GuildMessageReactionsintent ✅ - Missing
Partialsconfig ✅ - Dead
guildvariable in events.js ✅ - Redundant index in migration ✅
- Startup logging for starboard ✅
- Feedback loop guard ✅
safeSendusage ✅- Broken test assertions ✅
- Missing warn log in
handleReactionRemove✅
✅ CI status
All tests pass, lint clean.
Fix all issues with AI prompt
Fix the documentation gaps in the volvox-bot starboard PR (branch: feat/starboard):
1. In `AGENTS.md`:
- After the `src/modules/events.js` row in the Key Files table (line 35), add:
| `src/modules/starboard.js` | Starboard — showcase popular messages in a dedicated channel |
- After the `mod_scheduled_actions` row in the Database Tables section (line 137), add:
| `starboard_posts` | Starboard dedup tracking — maps source messages to starboard embeds |
- Update Common Pitfall #3 (line 223) from:
"Discord intents — the bot needs MessageContent, GuildMembers, and GuildVoiceStates intents enabled"
to:
"Discord intents — the bot needs MessageContent, GuildMembers, GuildVoiceStates, and GuildMessageReactions intents enabled"
2. In `README.md`, after the Moderation section (after line 203, before Permissions), add:
### Starboard (`starboard`)
| Key | Type | Description |
|-----|------|-------------|
| `enabled` | boolean | Enable starboard feature |
| `channelId` | string | Channel to post starboard embeds |
| `threshold` | number | Minimum star count to post (default: 3) |
| `emoji` | string | Emoji to track, or `*` for any emoji (default: `*`) |
| `selfStarAllowed` | boolean | Allow message authors to star their own messages (default: false) |
| `ignoredChannels` | string[] | Channel IDs to exclude from starboard |
|
🔧 PR Patrol sweep — Thu Feb 26 @ 2:45 PM No code changes needed — all 31 starboard tests passing ✅ Threads resolved (6 total):
|
Starboard Feature
When a message gets enough star reactions (configurable threshold), it gets reposted to a dedicated starboard channel with a gold embed.
What's included
002_starboard-posts.cjs):starboard_poststable for dedup trackingsrc/modules/starboard.js): Full starboard logichandleReactionAdd/handleReactionRemove— post, update, or remove starboard embedsbuildStarboardEmbed— gold (#FFD700) embed with author avatar, source channel, star count, jump linkgetStarCount— counts reactions with self-star exclusionfindStarboardPost,insertStarboardPost,updateStarboardPostCount,deleteStarboardPostsrc/modules/events.js):MessageReactionAdd/MessageReactionRemovelisteners with config gateconfig.json):starboardsection with defaultsConfig
{ "starboard": { "enabled": false, "channelId": null, "threshold": 3, "emoji": "⭐", "selfStarAllowed": false, "ignoredChannels": [] } }Behavior
Tests
Closes #48