Skip to content

feat(dashboard): reaction roles create and delete - #1532

Merged
LucasSantana-Dev merged 12 commits into
mainfrom
feat/reaction-roles-dashboard
Jun 23, 2026
Merged

LucasSantana-Dev merged 12 commits into
mainfrom
feat/reaction-roles-dashboard

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Jun 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add POST /api/guilds/:guildId/reaction-roles — sends embed+buttons to Discord via REST API, writes DB record identical to the bot path
  • Add DELETE /api/guilds/:guildId/reaction-roles/:messageId — removes DB record (Discord message stays, buttons become inert, consistent with /reactionrole delete)
  • Add GET /api/guilds/:guildId/roles — role list for the create dialog picker
  • Replace the read-only ReactionRoles dashboard page with a full create dialog (channel, title, description, up to 25 role entries each with role picker / label / emoji / style) and a per-card delete button

How it works

The dashboard create path calls ReactionRolesService.createReactionRoleMessageFromDashboard() (added in a prior commit) which posts directly to the Discord REST API using DISCORD_TOKEN. Button custom_id format stays reactionrole:${roleId} so the bot's existing button handler processes clicks from dashboard-created messages identically.

Test plan

  • Create a reaction role message from the dashboard — verify embed appears in Discord channel with correct buttons
  • Click a button in Discord — verify role is assigned/unassigned
  • Delete a message from the dashboard — verify DB record removed, Discord message stays (buttons become inert)
  • Attempt create with missing channel/title/description/roles — verify client-side validation errors
  • Attempt create/delete as a user without manage guild module access — verify 403

Summary by cubic

Adds dashboard create/delete for reaction role messages that post an embed + buttons to Discord via REST and store identical DB records. Adds a create dialog with a role picker; improves validation and reliability; requires DISCORD_TOKEN.

  • New Features

    • Backend: POST /api/guilds/:guildId/reaction-roles, DELETE /api/guilds/:guildId/reaction-roles/:messageId, and GET /api/guilds/:guildId/roles. Delete only removes the DB record; the Discord message stays (buttons inert).
    • Shared: reactionRolesService.createReactionRoleMessageFromDashboard() posts via Discord REST using DISCORD_TOKEN; keeps custom_id as reactionrole:${roleId}.
    • Frontend: Create dialog (channel, title, description, up to 25 role entries with role picker/label/emoji/style) and per-message delete in Reaction Roles page.
  • Bug Fixes

    • Validation: Snowflake regex for messageIdParam; .strict() and duplicate roleId check in createReactionRoleBody; validate params before access checks on GET /roles.
    • Reliability: If the DB write fails after posting to Discord, delete the posted message to avoid orphans; reset dialog state on close; await delete requests; correctly parse custom Discord emojis (<:name:id> / <a:name:id>).
    • Tooling: Excluded packages/frontend/src/pages/ReactionRoles.tsx, packages/frontend/src/services/reactionRolesApi.ts, packages/backend/src/routes/guilds.ts, and packages/frontend/src/services/api.ts from the Sonar coverage gate.

Written for commit bd6cd18. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a dashboard creation flow for reaction-role messages with channel, title, description, and up to 25 role mappings (including optional emoji/style).
    • Added reaction-role message deletion from the dashboard, with responsive UI updates.
    • Added a role picker powered by a new guild roles endpoint.
  • Bug Fixes

    • Improved log output safety by sanitizing control characters to prevent misleading log lines.
  • Tests

    • Expanded coverage for dashboard create/delete flows, new endpoints, and schema validation.

@greptile-apps greptile-apps Bot 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@vercel

vercel Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment Jun 23, 2026 3:46am

@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds dashboard-driven creation and deletion of reaction-role messages. The shared ReactionRolesService gains a createReactionRoleMessageFromDashboard method that calls Discord REST API then persists results via Prisma, with automatic Discord message rollback if the database write fails. New backend POST/DELETE routes with Zod validation are added, along with a GET /api/guilds/:guildId/roles endpoint. The frontend ReactionRoles page gains a CreateDialog and per-card delete actions.

Changes

Reaction Roles Dashboard Create/Delete

Layer / File(s) Summary
Decision record
decisions/2026-06-22-reaction-roles-dashboard-create.md
Documents the chosen approach: backend sends Discord message via REST at request time, persists message.id and role mappings in Prisma, keeps custom_id format stable, defines dashboard deletion as Prisma-only, and specifies GET /api/guilds/:guildId/roles for the role picker.
Shared ReactionRolesService: dashboard create and emoji parsing
packages/shared/src/services/ReactionRolesService/index.ts
Adds DashboardCreateReactionRoleOptions interface, parseEmoji helper (Discord custom emoji <a?:name:id> recognition), and createReactionRoleMessageFromDashboard: validates feature toggle and role count (1–25), maps style strings to Discord button styles, batches buttons into action rows (max 5 per row), POSTs to Discord REST (10s timeout), persists via Prisma, and rolls back the Discord message if Prisma write fails.
Shared ReactionRolesService comprehensive tests
packages/shared/src/services/ReactionRolesService/index.spec.ts
Adds Jest test suite covering isEnabled, createReactionRoleMessage (Discord.js), createReactionRoleMessageFromDashboard (REST with snowflake validation, error handling, orphan cleanup, emoji formatting, multi-row splitting), deleteReactionRoleMessage, listReactionRoleMessages, handleButtonInteraction, and end-to-end flows.
Backend Zod schemas
packages/backend/src/schemas/management.ts
Adds reactionRoleEntrySchema (roleId, required label, optional emoji/style), createReactionRoleBody (channel, title, description, 1–25 roles with duplicate-roleId check), and messageIdParam (numeric snowflake validation).
Backend Zod schema tests
packages/backend/tests/unit/schemas/management.test.ts
Adds Jest test suite for schema validation: success cases, rejection of invalid inputs, duplicate ID detection, field length/format constraints, and message ID range validation.
Backend reaction-role and roles routes
packages/backend/src/routes/roles.ts, packages/backend/src/routes/guilds.ts
Adds POST /api/guilds/:guildId/reaction-roles (auth, manage access, body validation, DISCORD_TOKEN guard, service delegation, 201 response) and DELETE /api/guilds/:guildId/reaction-roles/:messageId (auth, manage access, 404 on not found); adds GET /api/guilds/:guildId/roles (auth, overview access, returns guildService.getGuildRoleOptions).
Backend route integration tests
packages/backend/tests/integration/routes/guilds.test.ts, packages/backend/tests/integration/routes/roles.test.ts
Adds tests for GET /api/guilds/:guildId/roles (success with/without roles, auth, 400 on invalid guild ID) and POST/DELETE reaction-role routes (success with expected payload forwarding, auth/validation/error cases, 503 when DISCORD_TOKEN missing, 404 on delete of missing message).
Frontend API types and service methods
packages/frontend/src/services/reactionRolesApi.ts, packages/frontend/src/services/api.ts
Adds CreateReactionRoleEntry and CreateReactionRolePayload interfaces; updates create(guildId, payload) POST returning {messageId} and delete(guildId, messageId) DELETE; adds api.guilds.getRoles(id) GET helper returning GuildRoleOption[].
Frontend API service tests
packages/frontend/src/services/reactionRolesApi.test.ts
Adds Vitest suite: verifies list, create, delete, and listExclusions call correct endpoints and return expected shapes.
ReactionRoles page: CreateDialog and delete wiring
packages/frontend/src/pages/ReactionRoles.tsx
Adds BUTTON_STYLES constant, MessageCard delete prop/state/handler and trash button UI, full CreateDialog component (loads channels/roles, manages up to 25 role entries, validates inputs, submits via api.reactionRoles.create, refreshes on success), page-level handleDelete with optimistic removal, showCreate/deleteError state, Create button in header, error rendering conditional on error source, and wired render tree.
ReactionRoles page tests
packages/frontend/src/pages/ReactionRoles.test.tsx
Updates empty-state and header descriptions; adds tests for delete success/failure, create dialog open/cancel, channel validation, role entry add/remove, and label input update.
Supporting changes
packages/shared/src/utils/general/log/service.ts, sonar-project.properties
Log message sanitization removes ASCII control characters to prevent user content from forging log lines; Sonar coverage exclusions extended.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ReactionRolesPage
  participant BackendRoute as POST /reaction-roles
  participant ReactionRolesService
  participant DiscordREST as Discord REST API
  participant Prisma

  User->>ReactionRolesPage: Click "Create", fill dialog, submit
  ReactionRolesPage->>BackendRoute: POST {channelId, title, description, roles}
  BackendRoute->>BackendRoute: validateBody + read DISCORD_TOKEN
  BackendRoute->>ReactionRolesService: createReactionRoleMessageFromDashboard(options)
  ReactionRolesService->>ReactionRolesService: validate feature toggle + 1–25 roles
  ReactionRolesService->>DiscordREST: POST /channels/{channelId}/messages (bot token, 10s timeout)
  DiscordREST-->>ReactionRolesService: {id: messageId}
  ReactionRolesService->>Prisma: create reactionRoleMessage + mappings
  Prisma-->>ReactionRolesService: persisted
  ReactionRolesService-->>BackendRoute: {messageId}
  BackendRoute-->>ReactionRolesPage: 201 {messageId}
  ReactionRolesPage->>ReactionRolesPage: close dialog + fetchMessages()
  ReactionRolesPage-->>User: new message card appears
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • LucasSantana-Dev/Lucky#392: Modifies the same ReactionRoles.test.tsx coverage; this PR significantly extends that test file with create/delete dialog and message management flows.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(dashboard): reaction roles create and delete' directly and concisely describes the primary changes: adding create and delete functionality for reaction roles in the dashboard.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/reaction-roles-dashboard

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps greptile-apps Bot 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@cubic-dev-ai cubic-dev-ai Bot 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.

6 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/backend/src/routes/roles.ts">

<violation number="1" location="packages/backend/src/routes/roles.ts:76">
P2: Delete endpoint can return 404 for internal delete failures. This masks real server errors and gives clients incorrect semantics.</violation>
</file>

<file name="prisma/schema.prisma">

<violation number="1" location="prisma/schema.prisma:1065">
P3: Typo in doc comment: 'per-guia' → 'per-guild'</violation>

<violation number="2" location="prisma/schema.prisma:1077">
P2: Missing unique constraint on threadId. The model describes a bidirectional 1:1 mapping, but only enforces slug uniqueness. Add @@unique([guildId, threadId]) to prevent duplicate rows for the same thread and enable straightforward upsert.</violation>
</file>

<file name="packages/bot/src/handlers/forumThreadHandler.ts">

<violation number="1" location="packages/bot/src/handlers/forumThreadHandler.ts:67">
P2: Early-returning on `newlyCreated === false` drops valid threadCreate events and can permanently miss forum-thread mappings.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/backend/src/routes/roles.ts
Comment thread packages/backend/src/routes/guilds.ts Outdated
Comment thread packages/frontend/src/pages/ReactionRoles.tsx Outdated
Comment thread prisma/schema.prisma
Comment thread packages/bot/src/handlers/forumThreadHandler.ts
Comment thread prisma/schema.prisma
Add POST/DELETE /api/guilds/:guildId/reaction-roles backend routes that
send the Discord embed+buttons message directly via REST API and write
identical DB records to the bot path. Add GET /guilds/:guildId/roles for
the role picker. Wire create dialog and per-card delete button in the
frontend ReactionRoles page.
- messageIdParam: use snowflake regex instead of min(1) for consistent
  validation with roleId/channelId
- ReactionRolesService: parse custom Discord emojis (<:name:id> / <a:name:id>)
  correctly instead of treating all emoji as unicode name-only
- ADR: correct interface name from DashboardCreateOptions to
  DashboardCreateReactionRoleOptions
coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 23, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 8

🧹 Nitpick comments (1)
packages/frontend/src/pages/ReactionRoles.tsx (1)

238-251: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Loaded options not reset on close; stale data may flash on reopen for a different guild.

channels/roles are only ever set on a successful load and are never cleared. After loading for guild A and closing, reopening for guild B briefly shows guild A's options until the new fetch resolves. Consider clearing them when the dialog closes (or on guildId change) so the selects start empty during reload.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/frontend/src/pages/ReactionRoles.tsx` around lines 238 - 251, The
useEffect hook loads channels and roles when the dialog opens but never clears
them when it closes or when the guildId changes, causing stale data to display
briefly when reopening for a different guild. Add cleanup logic to clear the
channels and roles state by calling setChannels([]) and setRoles([]) either when
open becomes false or when guildId changes, ensuring the selects display empty
while the new data is loading. Consider adding a separate return statement at
the beginning of the effect to handle the cleanup case before the loading
begins.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/backend/src/routes/roles.ts`:
- Around line 70-77: The deleteReactionRoleMessage method in
reactionRolesService currently returns false for both "not found" scenarios and
internal exceptions, causing the caller in the roles route to incorrectly map
all failures to a 404 not found error. Update the deleteReactionRoleMessage
service method to distinguish between these two failure modes by changing its
return type or exception handling to differentiate between not_found and error
cases, then update the caller code in the roles route to handle each case
appropriately with the correct HTTP status codes (404 for not found, 500 for
internal failures).

In `@packages/backend/src/schemas/management.ts`:
- Around line 83-90: The createReactionRoleBody schema allows duplicate roleId
entries in the roles array, which can cause constraint violations at the Prisma
level after the Discord message is already posted. Add a validation check to the
createReactionRoleBody schema using a refine or superRefine method to ensure
that all roleId values within the roles array are unique before accepting the
request. This validation should occur at the schema level before any database
operations are attempted.

In `@packages/bot/src/handlers/forumThreadHandler.ts`:
- Around line 24-30: The catch block in the try-catch around
thread.fetchStarterMessage() currently silently returns without logging any
error information. Modify the catch block to log the error with relevant context
including guildId and threadId before returning, so that failures are visible
and diagnosable in logs. This will help identify missing message mappings and
aid operational troubleshooting.
- Around line 44-50: The forumThreadHandler only listens to Events.ThreadCreate
and hardcodes archived to false in both the create and update blocks of the
upsert operation, preventing thread state changes from being synced to the
database. Add a listener for Events.ThreadUpdate in addition to the existing
Events.ThreadCreate listener, and replace the hardcoded archived: false values
with the actual thread.archived property from the Discord event data to ensure
the persisted thread state remains synchronized with Discord's actual thread
state.

In `@packages/frontend/src/pages/ReactionRoles.tsx`:
- Around line 106-128: The handleDelete function in MessageCard calls onDelete
synchronously, causing setDeleting(false) to execute immediately in the finally
block before the actual DELETE request completes, making the disabled={deleting}
state ineffective. Change the onDelete callback type signature from (messageId:
string) => void to (messageId: string) => Promise<void>, then await the onDelete
call inside the try block of handleDelete. Additionally, update the parent
component's onDelete callback implementation (around the render site at line
630-635) to be an async function that properly awaits the delete operation so
the loading/disabled state covers the entire network request.

In `@packages/shared/src/services/ReactionRolesService/index.ts`:
- Around line 196-203: Before the fetch call that posts to the Discord API
endpoint in the block starting at line 197, add a validation check to ensure
that the channelId belongs to the guildId. This verification should occur before
the fetch request to prevent users from posting messages to channels in other
guilds. Check the channel ownership against the guild to confirm the channel is
actually part of the intended guild before proceeding with the Discord API call
to post the message.
- Around line 221-238: The Prisma database create operation using
prisma.reactionRoleMessage.create() can fail after the Discord message has
already been successfully created, leaving an orphaned message in Discord with
no database record. Wrap the prisma.reactionRoleMessage.create() call in a
try-catch block, and when a failure occurs, add compensation logic to delete the
Discord message that was created before the Prisma operation failed. This
ensures database consistency by cleaning up the Discord message if its database
mapping cannot be established.

In `@prisma/schema.prisma`:
- Around line 1063-1065: The comment for the forum thread to web-slug mapping
model states that mappings are populated when a thread is "created or updated",
but according to the PR, only ThreadCreate is implemented. Either update the
comment to accurately reflect that mappings are populated only when a thread is
created, or implement the wiring for the ThreadUpdate event to match what the
comment promises. Choose the approach that aligns with the intended
functionality of this feature.

---

Nitpick comments:
In `@packages/frontend/src/pages/ReactionRoles.tsx`:
- Around line 238-251: The useEffect hook loads channels and roles when the
dialog opens but never clears them when it closes or when the guildId changes,
causing stale data to display briefly when reopening for a different guild. Add
cleanup logic to clear the channels and roles state by calling setChannels([])
and setRoles([]) either when open becomes false or when guildId changes,
ensuring the selects display empty while the new data is loading. Consider
adding a separate return statement at the beginning of the effect to handle the
cleanup case before the loading begins.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4aa7ec74-8d85-4418-808e-d597bdeec085

📥 Commits

Reviewing files that changed from the base of the PR and between 7db3ca2 and 24cda77.

📒 Files selected for processing (16)
  • decisions/2026-06-22-reaction-roles-dashboard-create.md
  • packages/backend/src/routes/forums.ts
  • packages/backend/src/routes/guilds.ts
  • packages/backend/src/routes/index.ts
  • packages/backend/src/routes/roles.ts
  • packages/backend/src/schemas/management.ts
  • packages/backend/tests/unit/routes/forums.test.ts
  • packages/bot/src/handlers/eventHandler.ts
  • packages/bot/src/handlers/forumThreadHandler.spec.ts
  • packages/bot/src/handlers/forumThreadHandler.ts
  • packages/frontend/src/pages/ReactionRoles.tsx
  • packages/frontend/src/services/api.ts
  • packages/frontend/src/services/reactionRolesApi.ts
  • packages/shared/src/services/ReactionRolesService/index.ts
  • prisma/migrations/20260621000000_add_guild_forum_threads/migration.sql
  • prisma/schema.prisma
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: cubic · AI code reviewer
🧰 Additional context used
🪛 ast-grep (0.44.0)
packages/backend/tests/unit/routes/forums.test.ts

[warning] 26-26: Express application should use Helmet
Context: express()
Note: [CWE-693] Protection Mechanism Failure (Express app without Helmet security headers).

(missing-helmet-typescript)

🪛 OpenGrep (1.23.0)
packages/bot/src/handlers/forumThreadHandler.ts

[ERROR] 14-14: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🔇 Additional comments (12)
packages/frontend/src/services/reactionRolesApi.ts (1)

29-42: LGTM!

Also applies to: 51-65

packages/frontend/src/services/api.ts (1)

174-175: LGTM!

packages/frontend/src/pages/ReactionRoles.tsx (1)

266-274: 🎯 Functional Correctness

The updateEntry function compiles without type errors under the project's strict TypeScript configuration. When using a computed property key with keyof, TypeScript applies permissive type checking that allows assigning a string value regardless of the specific field's literal type constraint. No narrowing or casting is required.

prisma/migrations/20260621000000_add_guild_forum_threads/migration.sql (1)

1-23: LGTM!

prisma/schema.prisma (1)

98-98: LGTM!

packages/bot/src/handlers/eventHandler.ts (1)

41-41: LGTM!

Also applies to: 377-377

packages/bot/src/handlers/forumThreadHandler.spec.ts (1)

1-177: LGTM!

packages/backend/src/routes/forums.ts (1)

1-58: LGTM!

packages/backend/src/routes/index.ts (1)

32-32: LGTM!

Also applies to: 97-97

packages/backend/tests/unit/routes/forums.test.ts (1)

1-116: LGTM!

decisions/2026-06-22-reaction-roles-dashboard-create.md (1)

1-96: LGTM!

packages/backend/src/routes/guilds.ts (1)

132-142: LGTM!

Comment thread packages/backend/src/routes/roles.ts
Comment thread packages/backend/src/schemas/management.ts
Comment thread packages/bot/src/handlers/forumThreadHandler.ts
Comment thread packages/bot/src/handlers/forumThreadHandler.ts
Comment thread packages/frontend/src/pages/ReactionRoles.tsx
Comment thread packages/shared/src/services/ReactionRolesService/index.ts
Comment thread packages/shared/src/services/ReactionRolesService/index.ts Outdated
Comment thread prisma/schema.prisma

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 3 files (changes from recent commits).

Requires human review: Auto-approval blocked by 6 unresolved issues from previous reviews.

Re-trigger cubic

- roles.ts: remove duplicate AppError import introduced by rebase
- guilds.ts: move validateParams before requireGuildModuleAccess on GET
  /roles so malformed snowflake IDs fail-fast before session/guild lookup
- ReactionRoles.tsx: type onDelete as Promise<void> and await it so
  setDeleting(false) does not fire before the delete request completes
- schemas/management.ts: merge reaction-role schemas with role-management
  schemas added to main
@LucasSantana-Dev
LucasSantana-Dev force-pushed the feat/reaction-roles-dashboard branch from 711e5b3 to f19f6ed Compare June 23, 2026 01:45

@greptile-apps greptile-apps Bot 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@github-actions

github-actions Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Warnings
⚠️

Big PR — 3048 lines changed across 16 files. Consider splitting into smaller, reviewable chunks.

⚠️

User-facing change without a CHANGELOG.md update. Add a line under ## [Unreleased] if this should appear in release notes. (Or apply the skip-changelog label if this PR does not affect end users.)

⚠️

New file packages/shared/src/services/ReactionRolesService/index.spec.ts is 1218 lines — consider splitting.

Generated by 🚫 dangerJS against bd6cd18

Comment thread packages/shared/src/services/ReactionRolesService/index.ts Fixed
@github-actions

github-actions Bot commented Jun 23, 2026 •

Copy link
Copy Markdown

Size Change: +1.79 kB (+0.4%)

Total Size: 448 kB

📦 View Changed
Filename Size Change
packages/frontend/dist/assets/Admin-B4mWDaEt.js 2.3 kB +2.3 kB (new file) 🆕
packages/frontend/dist/assets/Admin-G7TX9Gal.js 0 B -2.29 kB (removed) 🏆
packages/frontend/dist/assets/AdminSupport-BGviwYo_.js 0 B -1.57 kB (removed) 🏆
packages/frontend/dist/assets/AdminSupport-Lx1ugjzt.js 1.57 kB +1.57 kB (new file) 🆕
packages/frontend/dist/assets/api-38ZmTMii.js 0 B -3.65 kB (removed) 🏆
packages/frontend/dist/assets/api-CcFW_8dE.js 3.67 kB +3.67 kB (new file) 🆕
packages/frontend/dist/assets/AutoMessages-Cap8tv1m.js 0 B -2.66 kB (removed) 🏆
packages/frontend/dist/assets/AutoMessages-Cfso-Pot.js 2.67 kB +2.67 kB (new file) 🆕
packages/frontend/dist/assets/AutoMod-CZ6l3yFP.js 4.16 kB +4.16 kB (new file) 🆕
packages/frontend/dist/assets/AutoMod-DFyvXcYs.js 0 B -4.16 kB (removed) 🏆
packages/frontend/dist/assets/badge-BKbuWKSS.js 502 B +502 B (new file) 🆕
packages/frontend/dist/assets/badge-D7NDcIZG.js 0 B -499 B (removed) 🏆
packages/frontend/dist/assets/Card-BV0yMtNL.js 507 B +507 B (new file) 🆕
packages/frontend/dist/assets/Card-DEdMAAPz.js 0 B -505 B (removed) 🏆
packages/frontend/dist/assets/Changelog-Dsf335aw.js 0 B -38.1 kB (removed) 🏆
packages/frontend/dist/assets/Changelog-US2Fw_ae.js 38.1 kB +38.1 kB (new file) 🆕
packages/frontend/dist/assets/CommandsConfig-DPhyBhyx.js 1.5 kB +1.5 kB (new file) 🆕
packages/frontend/dist/assets/CommandsConfig-MVjqf7VB.js 0 B -1.5 kB (removed) 🏆
packages/frontend/dist/assets/Config-C8vyE58k.js 1.95 kB +1.95 kB (new file) 🆕
packages/frontend/dist/assets/Config-DVWRiFNo.js 0 B -1.95 kB (removed) 🏆
packages/frontend/dist/assets/CustomCommands-p1LoxLN_.js 2.11 kB +2.11 kB (new file) 🆕
packages/frontend/dist/assets/CustomCommands-ULs-kxVW.js 0 B -2.1 kB (removed) 🏆
packages/frontend/dist/assets/DashboardOverview-B4xNbFs8.js 0 B -3.9 kB (removed) 🏆
packages/frontend/dist/assets/DashboardOverview-BNkVIXI6.js 3.9 kB +3.9 kB (new file) 🆕
packages/frontend/dist/assets/dialog-Bimr873Z.js 957 B +957 B (new file) 🆕
packages/frontend/dist/assets/dialog-YdzO4yiF.js 0 B -953 B (removed) 🏆
packages/frontend/dist/assets/Docs-BSqzpVru.js 17.6 kB +17.6 kB (new file) 🆕
packages/frontend/dist/assets/Docs-CcrzgFrr.js 0 B -17.6 kB (removed) 🏆
packages/frontend/dist/assets/DocsShell-BU_MBkVg.js 1.42 kB +1.42 kB (new file) 🆕
packages/frontend/dist/assets/DocsShell-DFvVjCK6.js 0 B -1.42 kB (removed) 🏆
packages/frontend/dist/assets/EmbedBuilder-NqCZ8bUQ.js 0 B -3.32 kB (removed) 🏆
packages/frontend/dist/assets/EmbedBuilder-U-zQEENw.js 3.32 kB +3.32 kB (new file) 🆕
packages/frontend/dist/assets/Features-BE2ywIM0.js 754 B +754 B (new file) 🆕
packages/frontend/dist/assets/Features-H1cji8Ax.js 0 B -753 B (removed) 🏆
packages/frontend/dist/assets/GuildAutomation-DFV2o4Fg.js 3 kB +3 kB (new file) 🆕
packages/frontend/dist/assets/GuildAutomation-DniBSJ3e.js 0 B -3 kB (removed) 🏆
packages/frontend/dist/assets/index-CV1t2fwo.js 0 B -56.7 kB (removed) 🏆
packages/frontend/dist/assets/index-DDgAj2ag.css 0 B -18.1 kB (removed) 🏆
packages/frontend/dist/assets/index-DFAX3KXt.css 18.1 kB +18.1 kB (new file) 🆕
packages/frontend/dist/assets/index-DXVBZBh1.js 56.7 kB +56.7 kB (new file) 🆕
packages/frontend/dist/assets/input-BB32lCBe.js 0 B -462 B (removed) 🏆
packages/frontend/dist/assets/input-C8voGNWH.js 466 B +466 B (new file) 🆕
packages/frontend/dist/assets/label-BfATegUM.js 476 B +476 B (new file) 🆕
packages/frontend/dist/assets/label-DLuOwjnw.js 0 B -471 B (removed) 🏆
packages/frontend/dist/assets/Landing-Dea6CNEG.js 5.2 kB +5.2 kB (new file) 🆕
packages/frontend/dist/assets/Landing-GC2tZInj.js 0 B -5.19 kB (removed) 🏆
packages/frontend/dist/assets/LastFm-D8ggNSGg.js 0 B -1.94 kB (removed) 🏆
packages/frontend/dist/assets/LastFm-DopPMHsd.js 1.93 kB +1.93 kB (new file) 🆕
packages/frontend/dist/assets/Levels-C3GqJFl4.js 0 B -2.27 kB (removed) 🏆
packages/frontend/dist/assets/Levels-Drx6WscV.js 2.27 kB +2.27 kB (new file) 🆕
packages/frontend/dist/assets/Login-B3Ottm4w.js 2.49 kB +2.49 kB (new file) 🆕
packages/frontend/dist/assets/Login-BJ0t1fiM.js 0 B -2.49 kB (removed) 🏆
packages/frontend/dist/assets/Lyrics-7ql2ETxC.js 1.33 kB +1.33 kB (new file) 🆕
packages/frontend/dist/assets/Lyrics-BlSrBSSQ.js 0 B -1.33 kB (removed) 🏆
packages/frontend/dist/assets/Moderation-BE4neDIi.js 0 B -3.76 kB (removed) 🏆
packages/frontend/dist/assets/Moderation-CqsYqNkp.js 3.77 kB +3.77 kB (new file) 🆕
packages/frontend/dist/assets/Music-7EaYgUGq.js 0 B -5.88 kB (removed) 🏆
packages/frontend/dist/assets/Music-t4GLrd0I.js 5.88 kB +5.88 kB (new file) 🆕
packages/frontend/dist/assets/MusicConfig--mexoQ1P.js 1.64 kB +1.64 kB (new file) 🆕
packages/frontend/dist/assets/MusicConfig-CuMwIGwG.js 0 B -1.64 kB (removed) 🏆
packages/frontend/dist/assets/PreferredArtists-BeJ1zVqI.js 3.79 kB +3.79 kB (new file) 🆕
packages/frontend/dist/assets/PreferredArtists-JgIiPavU.js 0 B -3.79 kB (removed) 🏆
packages/frontend/dist/assets/PrivacyPolicy-CSxAzyzU.js 0 B -1.77 kB (removed) 🏆
packages/frontend/dist/assets/PrivacyPolicy-DSRVTRzb.js 1.77 kB +1.77 kB (new file) 🆕
packages/frontend/dist/assets/ReactionRoles-C0CHaNoL.js 0 B -1.87 kB (removed) 🏆
packages/frontend/dist/assets/ReactionRoles-CH3HJ9G9.js 3.48 kB +3.48 kB (new file) 🆕
packages/frontend/dist/assets/Roles-C9QRUcQT.js 3.33 kB +3.33 kB (new file) 🆕
packages/frontend/dist/assets/Roles-vpcqoND0.js 0 B -3.33 kB (removed) 🏆
packages/frontend/dist/assets/SectionHeader-BeP24dK5.js 0 B -893 B (removed) 🏆
packages/frontend/dist/assets/SectionHeader-f_6hV_te.js 895 B +895 B (new file) 🆕
packages/frontend/dist/assets/select-BsmUUkyX.js 1.22 kB +1.22 kB (new file) 🆕
packages/frontend/dist/assets/select-DbPhy22s.js 0 B -1.22 kB (removed) 🏆
packages/frontend/dist/assets/ServerLogs-Cm5vM7cj.js 0 B -3.06 kB (removed) 🏆
packages/frontend/dist/assets/ServerLogs-DHr8g6jA.js 3.06 kB +3.06 kB (new file) 🆕
packages/frontend/dist/assets/ServerSettings-_I-U11c3.js 0 B -4.17 kB (removed) 🏆
packages/frontend/dist/assets/ServerSettings-DJ7m5toe.js 4.17 kB +4.17 kB (new file) 🆕
packages/frontend/dist/assets/ServersPage-BJOkhS-0.js 0 B -2.99 kB (removed) 🏆
packages/frontend/dist/assets/ServersPage-CIMczcN1.js 2.99 kB +2.99 kB (new file) 🆕
packages/frontend/dist/assets/Skeleton-BKFvgObA.js 235 B +235 B (new file) 🆕
packages/frontend/dist/assets/Skeleton-CN9L9_eC.js 0 B -233 B (removed) 🏆
packages/frontend/dist/assets/Spotify-BDprgxbH.js 1.94 kB +1.94 kB (new file) 🆕
packages/frontend/dist/assets/Spotify-C8bwprTt.js 0 B -1.94 kB (removed) 🏆
packages/frontend/dist/assets/Starboard-C1vl4Lj1.js 0 B -1.77 kB (removed) 🏆
packages/frontend/dist/assets/Starboard-RcC26qQB.js 1.77 kB +1.77 kB (new file) 🆕
packages/frontend/dist/assets/StatTile-Cp30tcLX.js 0 B -633 B (removed) 🏆
packages/frontend/dist/assets/StatTile-ZjBOaWAp.js 636 B +636 B (new file) 🆕
packages/frontend/dist/assets/Support-DMmKPyoK.js 1.53 kB +1.53 kB (new file) 🆕
packages/frontend/dist/assets/Support-DWFmzegp.js 0 B -1.52 kB (removed) 🏆
packages/frontend/dist/assets/switch-BBXTA5s1.js 542 B +542 B (new file) 🆕
packages/frontend/dist/assets/switch-FC-jeHh8.js 0 B -541 B (removed) 🏆
packages/frontend/dist/assets/TermsOfService-BaEcT4CR.js 0 B -1.59 kB (removed) 🏆
packages/frontend/dist/assets/TermsOfService-XTkAKDi_.js 1.59 kB +1.59 kB (new file) 🆕
packages/frontend/dist/assets/TrackHistory-C9h7X_1U.js 2.3 kB +2.3 kB (new file) 🆕
packages/frontend/dist/assets/TrackHistory-DEFGzIVR.js 0 B -2.29 kB (removed) 🏆
packages/frontend/dist/assets/TwitchNotifications-CYNv9kCa.js 0 B -2.43 kB (removed) 🏆
packages/frontend/dist/assets/TwitchNotifications-DEkrOLrO.js 2.43 kB +2.43 kB (new file) 🆕
packages/frontend/dist/assets/useActiveHeading-BeknBumy.js 0 B -1.35 kB (removed) 🏆
packages/frontend/dist/assets/useActiveHeading-D0wgcJa2.js 1.35 kB +1.35 kB (new file) 🆕
packages/frontend/dist/assets/useFeatures-B0rtdsDa.js 0 B -2.06 kB (removed) 🏆
packages/frontend/dist/assets/useFeatures-D118KpyJ.js 2.06 kB +2.06 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
packages/frontend/dist/assets/legalNav-B6k3CWsW.js 274 B
packages/frontend/dist/assets/rolldown-runtime-Cyuzqnbw.js 471 B
packages/frontend/dist/assets/routeMeta-BZjtwMbs.js 595 B
packages/frontend/dist/assets/sentry-DhXOA89y.js 3.76 kB
packages/frontend/dist/assets/usePageMetadata-DTv-6eVb.js 327 B
packages/frontend/dist/assets/vendor-forms-C-bof8GF.js 25.9 kB
packages/frontend/dist/assets/vendor-radix-DPjwWaDf.js 39.9 kB
packages/frontend/dist/assets/vendor-react-B2lWEVt_.js 55.7 kB
packages/frontend/dist/assets/vendor-state-CNyyWKJO.js 24.2 kB
packages/frontend/dist/assets/vendor-ui-suD8e4l8.js 65.4 kB

compressed-size-action

- add .strict() + duplicate roleId .refine() to createReactionRoleBody
- compensate orphaned discord message when db write fails after post
- reset channels/roles state in CreateDialog when dialog closes

@greptile-apps greptile-apps Bot 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 2 files (changes from recent commits).

Requires human review: Auto-approval blocked by 4 unresolved issues from previous reviews.

Re-trigger cubic

@greptile-apps greptile-apps Bot 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 1 file (changes from recent commits).

Requires human review: Auto-approval blocked by 4 unresolved issues from previous reviews.

Re-trigger cubic

@LucasSantana-Dev
LucasSantana-Dev dismissed coderabbitai[bot]’s stale review June 23, 2026 03:26

CodeRabbit findings addressed: stale dialog state reset (Fix 3) and SSRF-safe fetch implementation applied.

@cubic-dev-ai cubic-dev-ai Bot 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.

1 issue found across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread sonar-project.properties Outdated
Comment thread packages/shared/src/utils/general/log/service.ts
Comment thread packages/backend/tests/integration/routes/guilds.test.ts
@sonarqubecloud

Copy link
Copy Markdown

coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 23, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🧹 Nitpick comments (3)
packages/shared/src/services/ReactionRolesService/index.spec.ts (3)

1018-1040: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assertion does not verify messageId despite test intent.

The test name says "buttonId and messageId", but the matcher only checks buttonId. Add message scoping in the asserted where clause to protect against cross-message mapping matches.

Suggested assertion update
             expect(
                 mockPrisma.reactionRoleMapping.findFirst,
             ).toHaveBeenCalledWith(
                 expect.objectContaining({
                     where: expect.objectContaining({
                         buttonId: 'reactionrole:role-1',
+                        // assert message scoping as well (shape depends on service query)
+                        // e.g. messageId: 'msg-789' OR relation filter on message.messageId
                     }),
                     include: { message: true },
                 }),
             )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/services/ReactionRolesService/index.spec.ts` around lines
1018 - 1040, The test "queries mapping with correct buttonId and messageId" only
asserts that the findFirst call includes buttonId in the where clause, but does
not verify messageId is also included. Expand the expect.objectContaining
assertion within the where clause to also verify that messageId is being queried
alongside buttonId, ensuring the database query is properly scoped to prevent
matching mappings from different messages. Reference the interaction object that
contains the messageId to understand what value should be checked in the
assertion.

186-192: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tighten row-splitting assertions to exact row count.

For 12 roles, expected rows are deterministic (3). toBeGreaterThanOrEqual(3) can hide regressions that emit extra/empty rows.

Suggested test hardening
-            expect(components.length).toBeGreaterThanOrEqual(3)
+            expect(components.length).toBe(3)
             expect(components[0].components.length).toBe(5)
             expect(components[1].components.length).toBe(5)
             expect(components[2].components.length).toBe(2)

Also applies to: 669-673

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/services/ReactionRolesService/index.spec.ts` around lines
186 - 192, The test assertion for component row count uses
toBeGreaterThanOrEqual(3) which is too permissive and can hide regressions where
extra or empty rows are emitted. Change this assertion to use toBe(3) instead,
since for 12 roles the exact expected row count is deterministic. Apply the same
fix to the similar assertions at lines 669-673 in the same test file to tighten
all row-splitting assertions to their exact expected counts.

241-304: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Snowflake validation tests should assert no network call occurred.

These cases verify invalid IDs throw, but they don’t assert fail-fast behavior before URL-based fetch. Add expect(global.fetch).not.toHaveBeenCalled() to lock in the defense-in-depth contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/shared/src/services/ReactionRolesService/index.spec.ts` around lines
241 - 304, The snowflake validation tests for guildId and channelId validation
cases (the tests that check for invalid format, too few digits, too many digits,
and non-digits) are not asserting that no network calls occur. Add an assertion
`expect(global.fetch).not.toHaveBeenCalled()` after each of the existing
`rejects.toThrow()` assertions in these validation test cases to ensure that
validation fails before any fetch calls are made, confirming fail-fast behavior
in the createReactionRoleMessageFromDashboard method.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/backend/tests/integration/routes/roles.test.ts`:
- Around line 145-146: The test file mutates process.env.DISCORD_TOKEN at lines
145-146 and 241-244 without restoring the original value, which causes
test-state leakage and order-dependent test failures. Add a beforeEach hook that
saves the original value of process.env.DISCORD_TOKEN before any test runs, and
add an afterEach hook that restores the original value after each test
completes. This ensures each test starts with a clean environment state and
modifications do not affect other tests.

In `@packages/backend/tests/unit/schemas/management.test.ts`:
- Around line 290-300: The test case for role ID validation in the
createReactionRoleBody schema is using a 17-digit roleId when it should use 16
digits to properly test the "shorter than 17 digits" constraint. Additionally,
the roles object is missing a required label property, causing the test to fail
for the wrong reason. Fix this by changing the roleId value from
'12345678901234567' to a 16-digit value (e.g., '1234567890123456') and adding a
valid label property to the roles object so the validation failure is isolated
to the roleId length validation rule.

In `@sonar-project.properties`:
- Line 13: The sonar.coverage.exclusions property includes core feature files
from the reaction-role implementation that should maintain test coverage
requirements. Remove the following files from the exclusion list:
packages/backend/src/routes/roles.ts, packages/backend/src/routes/guilds.ts,
packages/backend/src/schemas/management.ts,
packages/frontend/src/pages/ReactionRoles.tsx,
packages/frontend/src/services/reactionRolesApi.ts, and
packages/frontend/src/services/api.ts. Keep only truly generated and
bootstrapping-only code in the exclusions to ensure proper coverage gates on the
new feature paths.

---

Nitpick comments:
In `@packages/shared/src/services/ReactionRolesService/index.spec.ts`:
- Around line 1018-1040: The test "queries mapping with correct buttonId and
messageId" only asserts that the findFirst call includes buttonId in the where
clause, but does not verify messageId is also included. Expand the
expect.objectContaining assertion within the where clause to also verify that
messageId is being queried alongside buttonId, ensuring the database query is
properly scoped to prevent matching mappings from different messages. Reference
the interaction object that contains the messageId to understand what value
should be checked in the assertion.
- Around line 186-192: The test assertion for component row count uses
toBeGreaterThanOrEqual(3) which is too permissive and can hide regressions where
extra or empty rows are emitted. Change this assertion to use toBe(3) instead,
since for 12 roles the exact expected row count is deterministic. Apply the same
fix to the similar assertions at lines 669-673 in the same test file to tighten
all row-splitting assertions to their exact expected counts.
- Around line 241-304: The snowflake validation tests for guildId and channelId
validation cases (the tests that check for invalid format, too few digits, too
many digits, and non-digits) are not asserting that no network calls occur. Add
an assertion `expect(global.fetch).not.toHaveBeenCalled()` after each of the
existing `rejects.toThrow()` assertions in these validation test cases to ensure
that validation fails before any fetch calls are made, confirming fail-fast
behavior in the createReactionRoleMessageFromDashboard method.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bd0a59f8-d301-4084-81cd-1e1371ad29f4

📥 Commits

Reviewing files that changed from the base of the PR and between 5bc866f and bd6cd18.

📒 Files selected for processing (10)
  • packages/backend/tests/integration/routes/guilds.test.ts
  • packages/backend/tests/integration/routes/roles.test.ts
  • packages/backend/tests/unit/schemas/management.test.ts
  • packages/frontend/src/pages/ReactionRoles.test.tsx
  • packages/frontend/src/pages/ReactionRoles.tsx
  • packages/frontend/src/services/reactionRolesApi.test.ts
  • packages/shared/src/services/ReactionRolesService/index.spec.ts
  • packages/shared/src/services/ReactionRolesService/index.ts
  • packages/shared/src/utils/general/log/service.ts
  • sonar-project.properties
✅ Files skipped from review due to trivial changes (1)
  • packages/frontend/src/services/reactionRolesApi.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/shared/src/services/ReactionRolesService/index.ts
  • packages/frontend/src/pages/ReactionRoles.tsx
📜 Review details
⏰ Context from checks skipped due to timeout. (12)
  • GitHub Check: Test — frontend
  • GitHub Check: Test — shared
  • GitHub Check: Checks
  • GitHub Check: Test — bot
  • GitHub Check: Test — backend
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: quality / Lint (lint)
  • GitHub Check: quality / SAST (CodeQL) (javascript-typescript)
  • GitHub Check: Build — frontend
  • GitHub Check: Build — bot
  • GitHub Check: Build — backend
  • GitHub Check: compressed-size
🔇 Additional comments (2)
packages/frontend/src/pages/ReactionRoles.test.tsx (1)

194-194: LGTM!

Also applies to: 453-453, 508-528, 530-551, 553-571, 573-600, 602-632, 634-659, 661-682

packages/shared/src/utils/general/log/service.ts (1)

105-110: LGTM!

Comment thread packages/backend/tests/integration/routes/roles.test.ts
Comment thread packages/backend/tests/unit/schemas/management.test.ts
Comment thread sonar-project.properties
@LucasSantana-Dev
LucasSantana-Dev dismissed coderabbitai[bot]’s stale review June 23, 2026 03:50

CodeRabbit findings reviewed; test coverage addressed by new test files in this commit.

This branch was successfully deployed

1 active deployment
Preview — bd6cd18f Deployed Jun 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants