Skip to content

fix(web): show all guild categories in dashboard selector#477

Open
BillChirico wants to merge 17 commits intomainfrom
fix/guild-selector-categories
Open

fix(web): show all guild categories in dashboard selector#477
BillChirico wants to merge 17 commits intomainfrom
fix/guild-selector-categories

Conversation

@BillChirico
Copy link
Copy Markdown
Collaborator

Summary

  • return all user guilds from the Discord directory response and mark whether the bot is installed
  • split the server selector into Infrastructure Hubs, Add Bot, and Community Hubs with invite actions
  • cover the new invite/community flows with selector, hook, and Discord utility tests

Testing

  • pnpm test -- tests/hooks/use-guild-role.test.ts tests/lib/discord.test.ts tests/components/layout/server-selector.test.tsx
  • npx biome check --write web/src web/tests
  • npm run build
  • (cd web && npm run build)

Closes #426

Copilot AI review requested due to automatic review settings April 11, 2026 18:20
@github-project-automation github-project-automation bot moved this to Backlog in Volvox.Bot Apr 11, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 11, 2026

⚠️ No Changeset found

Latest commit: 7109a00

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@railway-app
Copy link
Copy Markdown

railway-app bot commented Apr 11, 2026

🚅 Deployed to the volvox-bot-pr-477 environment in volvox-bot

Service Status Web Updated (UTC)
web ✅ Success (View Logs) Apr 18, 2026 at 10:44 pm
bot ❌ Build Failed (View Logs) Web Apr 18, 2026 at 10:44 pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 11, 2026

Warning

Rate limit exceeded

@BillChirico has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 58 minutes and 29 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 58 minutes and 29 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7f66515-a11a-4afa-9eba-9b1302b9845d

📥 Commits

Reviewing files that changed from the base of the PR and between 1406e49 and 7109a00.

📒 Files selected for processing (8)
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/components/layout/server-selector.tsx
  • web/src/hooks/use-guild-role.ts
  • web/src/lib/bot-api-proxy.ts
  • web/src/lib/discord.server.ts
  • web/src/types/discord.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📝 Walkthrough

Walkthrough

Replaces two-way guild partitioning with three categories (infrastructure, addBot, community); adds canInviteBot and extends getBotInviteUrl(guildId?); refactors the server selector into a categorized "Server Directory" with per-category loading/empty states and invite/link behaviors; makes MutualGuild.botPresent optional and updates server-side guild-fetching and tests.

Changes

Cohort / File(s) Summary
Server selector UI
web/src/components/layout/server-selector.tsx
Refactored dropdown into a "Server Directory" with three sections: infrastructure, addBot, community. Added per-section headers, loading skeletons, empty states, badges, helper UI components, and category-driven trigger text. Persist/restore selection limited to infrastructure. addBot entries open invite URL or show disabled state; community entries navigate via window.location.href and show read-only/status badges.
Guild permission & invite helpers
web/src/hooks/use-guild-role.ts, web/src/lib/discord.ts
Added exported canInviteBot(guild: MutualGuild): boolean. Changed getBotInviteUrl()getBotInviteUrl(guildId?: string) and build invite URL via URL/searchParams, adding optional guild_id + disable_guild_select=true when provided.
Server-side guild fetching
web/src/lib/discord.server.ts, web/src/app/api/guilds/route.ts
Added getUserGuildDirectory(accessToken, signal) to return user guilds with optional botPresent annotation. fetchBotGuilds now rethrows abort-like errors; getMutualGuilds adjusted for bot-API availability. API route switched to getUserGuildDirectory and uses explicit guild.botPresent === true when filtering bot-installed guilds.
Types & runtime guard
web/src/types/discord.ts, web/src/components/layout/guild-directory-context.tsx
Made MutualGuild.botPresent optional (botPresent?: boolean). Expanded isMutualGuild runtime guard to validate icon, owner, permissions, features, and accept botPresent as `boolean
Tests — component & hooks
web/tests/components/layout/server-selector.test.tsx, web/tests/hooks/use-guild-role.test.ts
Updated server-selector tests for three-category UI, new loading text, invite-link behavior, community read-only routing, and selection interactions. Added tests for canInviteBot covering owner/admin/manage permissions and edge cases.
Tests — lib & API
web/tests/lib/discord.test.ts, web/tests/api/guilds.test.ts
Added tests for getBotInviteUrl(guildId). Reworked tests to cover getUserGuildDirectory behavior (bot-presence annotation, unknown/abort cases) and updated mocks/assertions from getMutualGuildsgetUserGuildDirectory. Adjusted fetchBotGuilds abort-behavior tests.
Guild directory context
web/src/components/layout/guild-directory-context.tsx
Adjusted filtering/validation to accommodate optional botPresent, affecting which guilds pass the runtime guard.
Minor cleanup
web/src/app/dashboard/logs/page.tsx
Removed a duplicate ErrorBoundary import and reordered imports; no functional changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.09% 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
Title check ✅ Passed The title 'fix(web): show all guild categories in dashboard selector' directly describes the main change: displaying all guild categories in the dashboard selector component.
Description check ✅ Passed The description clearly relates to the changeset, explaining the three-category split, new Discord directory function, and test additions that align with the code changes.
Linked Issues check ✅ Passed The PR substantially implements all acceptance criteria from #426: displays three distinct guild categories (Infrastructure/My Servers, Add Bot, Community), uses Discord OAuth2 endpoints with bot presence detection, shows role/permission indicators, includes invite actions for bot-absent guilds, and provides loading/empty states per category.
Out of Scope Changes check ✅ Passed All code changes are directly aligned with requirements in #426: guild directory fetching, three-category partitioning, permission-based invite logic, bot-presence detection, and comprehensive test coverage for new flows.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/guild-selector-categories
  • 🛠️ Publish Changes: Commit on current branch
  • 🛠️ Publish Changes: Create PR

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 and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48afc4a3dc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/src/lib/discord.server.ts
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 11, 2026

Coverage Status

coverage: 90.65% (+0.002%) from 90.648% — fix/guild-selector-categories into main

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the web dashboard guild selector to surface all user guilds, classify them into actionable categories (installed/manageable vs inviteable vs community/read-only), and adds test coverage for the new invite/community flows.

Changes:

  • Return all user guilds from the Discord directory API and annotate each with botPresent.
  • Update the ServerSelector UI to split guilds into “Infrastructure Hubs”, “Add Bot”, and “Community Hubs”, with an invite flow that can preselect a guild.
  • Add/adjust unit + component tests for the new invite URL builder, permission gating, and selector behavior.

Reviewed changes

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

Show a summary per file
File Description
web/src/lib/discord.server.ts Changes getMutualGuilds() to return all user guilds and set botPresent based on bot guild membership.
web/src/lib/discord.ts Enhances getBotInviteUrl() to optionally preselect a guild via OAuth parameters.
web/src/hooks/use-guild-role.ts Adds canInviteBot() helper to determine whether the user can invite the bot to a guild.
web/src/components/layout/server-selector.tsx Refactors selector UI into three categories with updated loading/empty states and invite/community actions.
web/tests/lib/discord.test.ts Adds tests for getBotInviteUrl() and updates mutual guild expectations to include botPresent=false rows.
web/tests/hooks/use-guild-role.test.ts Adds tests for canInviteBot() behavior.
web/tests/components/layout/server-selector.test.tsx Updates/extends tests to cover the new categorized selector behavior and invite/community flows.

Comment thread web/src/lib/discord.server.ts
Comment thread web/src/components/layout/server-selector.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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 `@web/src/components/layout/server-selector.tsx`:
- Around line 147-149: The "community" bucket currently includes any guild not
in infrastructureIds or addBotIds, which surfaces private/member-only servers;
update the guilds.filter used for the community key so it also checks the same
community-page eligibility predicate used by the community route. Concretely,
modify the filter in the community assignment (the guilds.filter expression) to
include the community-route eligibility check (e.g., the same function or
boolean used elsewhere such as isCommunityPageEligible(guild) or
canViewCommunityPage(guild)) in addition to the existing
!infrastructureIds.has(guild.id) and !addBotIds.has(guild.id) checks so only
guilds that actually support a public community page are included.
- Around line 377-404: The addBot rows (rendered from addBot and using
getBotInviteUrl, GuildRow and Button) are currently plain divs inside
DropdownMenuContent so they aren't in the menu's focus model; wrap each invite
row in a DropdownMenuItem (use the asChild prop) so the Button/anchor or
SectionBadge becomes the menu item and keyboard/arrow navigation can reach them,
and for unavailable invites wrap the SectionBadge in a DropdownMenuItem with
disabled or aria-disabled to preserve focusability and semantics.
- Around line 136-143: The current partitioning collapses unknown bot presence
into the Add Bot flow; update the filters so they explicitly check
guild.botPresent === true for infrastructureGuilds and guild.botPresent ===
false for addBotGuilds (treat undefined as "unknown" and exclude those guilds
from both install-based sets), and ensure downstream code (infrastructureIds,
addBotIds, and UI logic in server-selector.tsx) handles the unknown state
gracefully; also note getMutualGuilds() may return botPresent undefined so make
this explicit in the filtering logic to skip the install-based split when
presence couldn't be resolved.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 2ec31b6a-aeb7-4c53-b0d8-fb6f3190c9f7

📥 Commits

Reviewing files that changed from the base of the PR and between a2eff52 and 48afc4a.

📒 Files selected for processing (7)
  • web/src/components/layout/server-selector.tsx
  • web/src/hooks/use-guild-role.ts
  • web/src/lib/discord.server.ts
  • web/src/lib/discord.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📜 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). (9)
  • GitHub Check: Agent
  • GitHub Check: Greptile Review
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Test
  • GitHub Check: Docker Build Validation
  • GitHub Check: E2E Tests (2/2)
  • GitHub Check: E2E Tests (1/2)
  • GitHub Check: Typecheck & Build
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters

Files:

  • web/src/lib/discord.server.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/lib/discord.test.ts
  • web/src/components/layout/server-selector.tsx
  • web/src/lib/discord.ts
web/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Never use console.* methods in web dashboard code; use appropriate logging mechanisms for React applications

web/src/**/*.{ts,tsx}: New dashboard routes need title wiring in web/src/lib/page-titles.ts; use createPageMetadata() for SSR and keep DashboardTitleSync aligned for client navigation
Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components
Recharts dashboard views should use web/src/components/ui/stable-responsive-container.tsx; raw ResponsiveContainer mounts can spam width(-1)/height(-1) warnings when panels render before layout settles
Any visual dashboard or landing page change must be verified with Chrome DevTools MCP before calling it done; take a screenshot after the change
Check both light and dark themes if colors or theming changed
Check responsive behavior on mobile, tablet, and desktop if layout changed

Files:

  • web/src/lib/discord.server.ts
  • web/src/hooks/use-guild-role.ts
  • web/src/components/layout/server-selector.tsx
  • web/src/lib/discord.ts
**/*.{js,ts,jsx,tsx,mjs,mts}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM only; do not use CommonJS

Files:

  • web/src/lib/discord.server.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/lib/discord.test.ts
  • web/src/components/layout/server-selector.tsx
  • web/src/lib/discord.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use src/logger.js; do not use console.*
Use the safe Discord messaging helpers in src/utils/safeSend.js instead of raw reply/send/edit calls
Use parameterized SQL only; do not use string concatenation for SQL queries
Community features should be gated behind config..enabled; moderation commands are the exception

Files:

  • web/src/lib/discord.server.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/lib/discord.test.ts
  • web/src/components/layout/server-selector.tsx
  • web/src/lib/discord.ts
**/*.{js,ts,jsx,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Welcome-message variables use double braces only, like {{user}}; single braces are plain text and should not be documented, inserted, or parsed as variables

Files:

  • web/src/lib/discord.server.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/lib/discord.test.ts
  • web/src/components/layout/server-selector.tsx
  • web/src/lib/discord.ts
web/src/**/*.{ts,tsx,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Follow the design system when making changes to the UI/UX; see DESIGN.md for the design system and color palette

Files:

  • web/src/lib/discord.server.ts
  • web/src/hooks/use-guild-role.ts
  • web/src/components/layout/server-selector.tsx
  • web/src/lib/discord.ts
web/tests/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

web/tests/**/*.test.{ts,tsx}: Write web dashboard tests using Vitest 4 with the jsdom environment and React Testing Library, matching the web/src/ structure
Maintain test coverage thresholds of 85% across all metrics (statements, branches, functions, lines) for web dashboard tests

Files:

  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/lib/discord.test.ts
🧠 Learnings (6)
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components

Applied to files:

  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to src/commands/**/*.js : Guild owners should be explicitly exempted from role hierarchy restrictions in command handlers to match Discord permission model expectations

Applied to files:

  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/components/layout/server-selector.test.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/tests/**/*.test.{ts,tsx} : Write web dashboard tests using Vitest 4 with the `jsdom` environment and React Testing Library, matching the `web/src/` structure

Applied to files:

  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to tests/**/*.test.js : Write bot tests using Vitest 4 with the `node` environment, matching the `src/` structure in the `tests/` directory

Applied to files:

  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'

Applied to files:

  • web/tests/components/layout/server-selector.test.tsx
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to web/src/app/api/**/route.ts : Include guildId in signed WebSocket ticket payload when issuing tickets from dashboard endpoints

Applied to files:

  • web/src/lib/discord.ts
🔇 Additional comments (1)
web/src/lib/discord.ts (1)

22-36: Nice use of URL/searchParams.

This keeps the invite query construction encoded and avoids the usual string-concatenation mistakes around optional guild_id parameters.

Comment thread web/src/components/layout/server-selector.tsx
Comment thread web/src/components/layout/server-selector.tsx
Comment thread web/src/components/layout/server-selector.tsx Outdated
@github-project-automation github-project-automation bot moved this from Backlog to In Review in Volvox.Bot Apr 11, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 11, 2026

Greptile Summary

This PR replaces the mutual-guild-only dashboard selector with a three-bucket UI (Infrastructure Hubs / Add Bot / Community Hubs) by introducing getUserGuildDirectory, which returns all user guilds annotated with botPresent status, while keeping getUserGuilds (mutual-only) for auth proxying. Previously-flagged import issues (getMutualGuilds, MutualGuild) are resolved in the updated test files.

Confidence Score: 5/5

Safe to merge — all remaining findings are P2 style issues that don't affect runtime behavior.

All previously flagged issues (getMutualGuilds import, MutualGuild type) are resolved. Auth boundary is correctly preserved (getUserGuilds for auth proxy, getUserGuildDirectory for UI only). Degraded-bot-API path is well-tested and behaves correctly. Only finding is a trivial unused parameter in an inline callback.

No files require special attention.

Important Files Changed

Filename Overview
web/src/app/api/guilds/route.ts Switched to getUserGuildDirectory (all guilds with bot-presence annotation); applyAccessLevels correctly limits bot API queries to guilds where botPresent===true and batches in 100-guild chunks.
web/src/lib/discord.server.ts New getUserGuildDirectory returns all user guilds annotated with botPresent; getUserGuilds (for auth) is unchanged and still filters to mutual-only; both degrade gracefully when the bot API is unavailable.
web/src/components/layout/server-selector.tsx Three-bucket layout (Infrastructure Hubs / Add Bot / Community Hubs) is well-structured; one unused parameter in an onSelect callback that Biome will flag.
web/src/hooks/use-guild-role.ts canInviteBot deliberately relies on Discord permission bits rather than the API access field; explicitly tested and intentional.
web/src/components/layout/guild-directory-context.tsx isUserGuild validator accepts botPresent as undefined (unknown status) or boolean; context now surfaces all user guilds to the selector.
web/tests/lib/discord.test.ts Imports updated to getUserGuildDirectory and getUserGuilds (previously flagged getMutualGuilds issue is resolved); new describe blocks cover happy-path and degraded-bot-API scenarios.
web/tests/hooks/use-guild-role.test.ts Type renamed from MutualGuild to UserGuild (previously flagged issue resolved); canInviteBot and isGuildManageable tests cover both permission-bit and API-access-field paths.
web/tests/components/layout/server-selector.test.tsx Comprehensive rendering tests for all three bucket states; popup-blocker fix verified via window.open spy; localStorage restore and broadcast-deduplication paths covered.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[GET /api/guilds] --> B[getUserGuildDirectory]
    B --> C{Bot API available?}
    C -->|Yes| D[All user guilds\nbotPresent: true / false]
    C -->|No| E[All user guilds\nbotPresent: undefined]
    D --> F[applyAccessLevels\nfor botPresent===true guilds]
    E --> G[Return as-is\nskip access lookup]
    F --> H[Guild list to client]
    G --> H
    H --> I[GuildDirectoryContext]
    I --> J[ServerSelector useMemo]
    J --> K{Classify each guild}
    K -->|botPresent true/undefined & isGuildManageable| L[Infrastructure Hubs]
    K -->|botPresent false & canInviteBot| M[Add Bot]
    K -->|everything else| N[Community Hubs]
    subgraph Auth Proxy
    O[Protected route] --> P[getUserGuilds mutual only]
    P --> Q{Bot API available?}
    Q -->|Yes| R[Filter: bot in guild]
    Q -->|No| S[Fallback: all user guilds botPresent: true]
    end
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: web/src/components/layout/server-selector.tsx
Line: 352-355

Comment:
**Unused `e` parameter in `onSelect` callback**

The `e` parameter is declared but never referenced. Biome's `noUnusedVariables` rule will flag this.

```suggestion
                  onSelect={() => {
                    if (selectedGuild?.id === guild.id) return;
                    selectGuild(guild);
                  }}
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (10): Last reviewed commit: "fix: update test imports for UserGuild r..." | Re-trigger Greptile

Comment thread web/src/hooks/use-guild-role.ts Outdated
Comment thread web/src/hooks/use-guild-role.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread web/src/components/layout/server-selector.tsx
Comment thread web/src/components/layout/guild-directory-context.tsx
Comment thread web/src/lib/discord.server.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/components/layout/guild-directory-context.tsx (1)

23-31: 🛠️ Refactor suggestion | 🟠 Major

Validate the fields the selector now branches on.

GuildDirectoryProvider is the only runtime boundary before these objects are treated as MutualGuild. With this PR, downstream logic now relies on owner, permissions, features, and access, but isMutualGuild() still admits anything that only has id, name, and botPresent. A partial /api/guilds payload can therefore misbucket guilds or blow up later in the invite/community flows.

♻️ Suggested hardening
 function isMutualGuild(value: unknown): value is MutualGuild {
   const g = value as Record<string, unknown>;
   return (
     typeof value === 'object' &&
     value !== null &&
     typeof g.id === 'string' &&
     typeof g.name === 'string' &&
+    typeof g.icon === 'string' || g.icon === null &&
+    typeof g.owner === 'boolean' &&
+    typeof g.permissions === 'string' &&
+    Array.isArray(g.features) &&
+    (g.access === undefined ||
+      g.access === 'owner' ||
+      g.access === 'admin' ||
+      g.access === 'moderator' ||
+      g.access === 'viewer' ||
+      g.access === 'bot-owner') &&
     (g.botPresent === undefined || typeof g.botPresent === 'boolean')
   );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/layout/guild-directory-context.tsx` around lines 23 - 31,
The type-guard isMutualGuild currently only checks id, name, and botPresent, but
downstream code in GuildDirectoryProvider and invite/community flows expects
owner, permissions, features, and access; update isMutualGuild to validate those
fields too by ensuring (when present) owner is a boolean, permissions is the
expected primitive (string or number as used elsewhere in the codebase),
features is an array of strings, and access is the expected string
enum/primitive; adjust the predicate to return false for partial/invalid shapes
so GuildDirectoryProvider doesn't misbucket or pass malformed guild objects
downstream.
♻️ Duplicate comments (1)
web/src/components/layout/server-selector.tsx (1)

149-151: ⚠️ Potential issue | 🟠 Major

Only include public, enabled community guilds in this bucket.

Right now community is the catch-all for every guild that is neither infrastructure nor addBot, so private/member-only leftovers and botPresent === undefined cases still get a /community/${guild.id} link. That doesn't match the PR objective for Community Hubs, which is limited to guilds with a public community page, and it also surfaces community navigation even when the feature is disabled. Reuse the same community-page eligibility check and config.<feature>.enabled gate that the community route uses before adding a guild here.

As per coding guidelines, "Community features should be gated behind config..enabled; moderation commands are the exception."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/layout/server-selector.tsx` around lines 149 - 151, The
community bucket currently includes every guild not in infrastructureIds or
addBotIds; restrict it to only public, enabled community guilds by reusing the
same eligibility predicate and feature gate the community route uses: replace
the guilds.filter callback for the community key with a check that ensures
config.community.enabled (or the relevant config.<feature>.enabled) is true and
that the guild passes the community-page eligibility function used elsewhere
(e.g., isCommunityPageEligible / communityPageEligibility which checks
public/communityPage and botPresent/member-only rules), while still excluding
infrastructureIds and addBotIds.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/hooks/use-guild-role.ts`:
- Around line 71-92: The function canInviteBot contains dead branches checking
guild.access values; remove the access comparisons (guild.access === 'owner' |
'bot-owner' | 'admin') and only use guild.owner and the permission-bit checks on
BigInt(guild.permissions) (using ADMINISTRATOR and MANAGE_GUILD) to decide
invite eligibility in canInviteBot; keep the try/catch around BigInt conversion
and return false on failure.

In `@web/src/lib/discord.server.ts`:
- Around line 301-355: The current getUserGuildsWithBotPresence swallows all
errors from fetchBotGuilds and treats them as "bot unavailable", which
incorrectly converts aborts/timeouts into degraded data; change the catch to
rethrow AbortError/timeouts and only degrade for non-abort failures. Concretely,
inside getUserGuildsWithBotPresence replace the fetchBotGuilds.catch handler so
it checks the thrown error (e.g., if err.name === 'AbortError' or err instanceof
DOMException && err.name === 'AbortError') and rethrows in that case; otherwise
log the warning and return { available: false, guilds: [] } as BotGuildResult.
This preserves the existing behavior for getUserGuildDirectory and
getMutualGuilds while ensuring aborts propagate out of
getUserGuildsWithBotPresence.

---

Outside diff comments:
In `@web/src/components/layout/guild-directory-context.tsx`:
- Around line 23-31: The type-guard isMutualGuild currently only checks id,
name, and botPresent, but downstream code in GuildDirectoryProvider and
invite/community flows expects owner, permissions, features, and access; update
isMutualGuild to validate those fields too by ensuring (when present) owner is a
boolean, permissions is the expected primitive (string or number as used
elsewhere in the codebase), features is an array of strings, and access is the
expected string enum/primitive; adjust the predicate to return false for
partial/invalid shapes so GuildDirectoryProvider doesn't misbucket or pass
malformed guild objects downstream.

---

Duplicate comments:
In `@web/src/components/layout/server-selector.tsx`:
- Around line 149-151: The community bucket currently includes every guild not
in infrastructureIds or addBotIds; restrict it to only public, enabled community
guilds by reusing the same eligibility predicate and feature gate the community
route uses: replace the guilds.filter callback for the community key with a
check that ensures config.community.enabled (or the relevant
config.<feature>.enabled) is true and that the guild passes the community-page
eligibility function used elsewhere (e.g., isCommunityPageEligible /
communityPageEligibility which checks public/communityPage and
botPresent/member-only rules), while still excluding infrastructureIds and
addBotIds.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 654ec729-c525-4164-819d-db1a2ac33460

📥 Commits

Reviewing files that changed from the base of the PR and between ae3dfb8 and d262fd0.

📒 Files selected for processing (10)
  • web/src/app/api/guilds/route.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/components/layout/server-selector.tsx
  • web/src/hooks/use-guild-role.ts
  • web/src/lib/discord.server.ts
  • web/src/types/discord.ts
  • web/tests/api/guilds.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📜 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). (11)
  • GitHub Check: CodeQL
  • GitHub Check: Agent
  • GitHub Check: Greptile Review
  • GitHub Check: Cursor Bugbot
  • GitHub Check: E2E Tests (2/2)
  • GitHub Check: Docker Build Validation
  • GitHub Check: E2E Tests (1/2)
  • GitHub Check: Test
  • GitHub Check: Typecheck & Build
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters

Files:

  • web/src/types/discord.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/src/components/layout/server-selector.tsx
  • web/tests/lib/discord.test.ts
web/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Never use console.* methods in web dashboard code; use appropriate logging mechanisms for React applications

web/src/**/*.{ts,tsx}: New dashboard routes need title wiring in web/src/lib/page-titles.ts; use createPageMetadata() for SSR and keep DashboardTitleSync aligned for client navigation
Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components
Recharts dashboard views should use web/src/components/ui/stable-responsive-container.tsx; raw ResponsiveContainer mounts can spam width(-1)/height(-1) warnings when panels render before layout settles
Any visual dashboard or landing page change must be verified with Chrome DevTools MCP before calling it done; take a screenshot after the change
Check both light and dark themes if colors or theming changed
Check responsive behavior on mobile, tablet, and desktop if layout changed

Files:

  • web/src/types/discord.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/src/lib/discord.server.ts
  • web/src/components/layout/server-selector.tsx
**/*.{js,ts,jsx,tsx,mjs,mts}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM only; do not use CommonJS

Files:

  • web/src/types/discord.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/src/components/layout/server-selector.tsx
  • web/tests/lib/discord.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use src/logger.js; do not use console.*
Use the safe Discord messaging helpers in src/utils/safeSend.js instead of raw reply/send/edit calls
Use parameterized SQL only; do not use string concatenation for SQL queries
Community features should be gated behind config..enabled; moderation commands are the exception

Files:

  • web/src/types/discord.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/src/components/layout/server-selector.tsx
  • web/tests/lib/discord.test.ts
**/*.{js,ts,jsx,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Welcome-message variables use double braces only, like {{user}}; single braces are plain text and should not be documented, inserted, or parsed as variables

Files:

  • web/src/types/discord.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/src/components/layout/server-selector.tsx
  • web/tests/lib/discord.test.ts
web/src/**/*.{ts,tsx,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Follow the design system when making changes to the UI/UX; see DESIGN.md for the design system and color palette

Files:

  • web/src/types/discord.ts
  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/src/lib/discord.server.ts
  • web/src/components/layout/server-selector.tsx
web/tests/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

web/tests/**/*.test.{ts,tsx}: Write web dashboard tests using Vitest 4 with the jsdom environment and React Testing Library, matching the web/src/ structure
Maintain test coverage thresholds of 85% across all metrics (statements, branches, functions, lines) for web dashboard tests

Files:

  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/api/guilds.test.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/tests/lib/discord.test.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to src/commands/**/*.js : Guild owners should be explicitly exempted from role hierarchy restrictions in command handlers to match Discord permission model expectations

Applied to files:

  • web/src/types/discord.ts
  • web/src/app/api/guilds/route.ts
  • web/src/hooks/use-guild-role.ts
  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components

Applied to files:

  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
  • web/tests/components/layout/server-selector.test.tsx
  • web/src/components/layout/server-selector.tsx
  • web/tests/lib/discord.test.ts
📚 Learning: 2026-03-11T17:18:17.626Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T17:18:17.626Z
Learning: Applies to src/**/{startup,command-register,reload}*.{js,ts} : Remove process.env.GUILD_ID runtime reads from bot startup and reload command registration

Applied to files:

  • web/src/components/layout/guild-directory-context.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to src/api/routes/*.js : Add adaptDeleteGuildIdParam in API route handlers to enforce guild moderation checks on DELETE requests without losing record id

Applied to files:

  • web/src/components/layout/guild-directory-context.tsx
  • web/src/app/api/guilds/route.ts
  • web/tests/api/guilds.test.ts
  • web/src/lib/discord.server.ts
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to web/src/app/api/**/route.ts : Include guildId in signed WebSocket ticket payload when issuing tickets from dashboard endpoints

Applied to files:

  • web/src/app/api/guilds/route.ts
  • web/src/lib/discord.server.ts
📚 Learning: 2026-03-10T23:29:51.063Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:29:51.063Z
Learning: Applies to src/api/routes/*.js : Apply requireGuildModerator authorization check to DELETE endpoints that modify guild-scoped resources

Applied to files:

  • web/src/app/api/guilds/route.ts
  • web/src/lib/discord.server.ts
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to src/api/ws/**/*.js : Enforce tenant scoping on WebSocket handlers: reject mismatched guildId in filters and require entry.guild_id === ws.guildId for broadcast matching

Applied to files:

  • web/src/app/api/guilds/route.ts
  • web/tests/api/guilds.test.ts
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to src/commands/reactionrole.js : Enforce invoker role hierarchy check in /reactionrole add command to prevent non-owner users from configuring roles at or above their highest role

Applied to files:

  • web/src/hooks/use-guild-role.ts
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/tests/**/*.test.{ts,tsx} : Write web dashboard tests using Vitest 4 with the `jsdom` environment and React Testing Library, matching the `web/src/` structure

Applied to files:

  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to tests/**/*.test.js : Write bot tests using Vitest 4 with the `node` environment, matching the `src/` structure in the `tests/` directory

Applied to files:

  • web/tests/hooks/use-guild-role.test.ts
  • web/tests/lib/discord.test.ts
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to src/api/ws/*.js : Bind audit-log WebSocket auth tickets to guild context by including nonce.expiry.guildId.hmac in ticket validation

Applied to files:

  • web/src/lib/discord.server.ts
📚 Learning: 2026-04-03T00:05:30.740Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-03T00:05:30.740Z
Learning: Do not persist GUILD_ID as a shared environment variable for multi-guild deployments; preserve dev-only guild-scoped deploy support via CLI flag instead

Applied to files:

  • web/src/lib/discord.server.ts
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to **/*.{js,ts,jsx,tsx} : Community features should be gated behind config.<feature>.enabled; moderation commands are the exception

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to config.json : All community features in `config.json` should be gated behind a `config.<feature>.enabled` flag; moderation commands are always available regardless of config settings

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/tests/**/*.test.{ts,tsx} : Maintain test coverage thresholds of 85% across all metrics (statements, branches, functions, lines) for web dashboard tests

Applied to files:

  • web/tests/lib/discord.test.ts
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to tests/**/*.test.js : Maintain test coverage thresholds: statements 85%, branches 82%, functions 85%, lines 85%; never lower thresholds—add tests to cover new code instead

Applied to files:

  • web/tests/lib/discord.test.ts

Comment thread web/src/hooks/use-guild-role.ts
Comment thread web/src/lib/discord.server.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d262fd0b6b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/src/lib/discord.server.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread web/src/components/layout/server-selector.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/tests/components/layout/server-selector.test.tsx (1)

253-261: 🧹 Nitpick | 🔵 Trivial

Test approach is fragile.

The test relies on the last occurrence of "Default Server" text being the menu item. This assumption could break if the UI structure changes (e.g., additional labels or badges containing the server name).

Consider using a more specific selector targeting the menuitem role directly after the dropdown opens.

♻️ Suggested: More robust selector
     await user.click(
       screen.getByRole("button", { name: /Default Server/i }),
     );
-    const entries = await screen.findAllByText('Default Server');
-    await user.click(entries[entries.length - 1]);
+    const menuItem = await screen.findByRole('menuitem', { name: /Default Server/i });
+    await user.click(menuItem);

     expect(mockBroadcastSelectedGuild).toHaveBeenCalledTimes(1);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/tests/components/layout/server-selector.test.tsx` around lines 253 - 261,
The test is brittle because it selects the last text node 'Default Server'
instead of the specific dropdown item; after opening the dropdown (the click on
the button returned by screen.getByRole("button", { name: /Default Server/i })),
query for the menu item role for the option itself (e.g., use screen.findByRole
or screen.findAllByRole("menuitem", { name: /Default Server/i }) and pick the
specific item) and click that element instead of entries[entries.length - 1];
update the assertions to still expect mockBroadcastSelectedGuild and fetchSpy
calls after clicking the menuitem.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/layout/server-selector.tsx`:
- Around line 440-454: The DropdownMenuItem click handler uses
window.location.href causing a full reload; replace it with Next.js client-side
navigation by importing and using useRouter (or next/navigation's useRouter) and
call router.push(`/community/${guild.id}`) inside the onSelect callback of the
DropdownMenuItem (where GuildRow is rendered) to perform SPA-style navigation;
if you prefer prefetching or want an anchor, wrap the content with Next's Link
to `/community/${guild.id}` instead—ensure you update the import and handler in
server-selector.tsx where DropdownMenuItem and GuildRow are defined.

---

Outside diff comments:
In `@web/tests/components/layout/server-selector.test.tsx`:
- Around line 253-261: The test is brittle because it selects the last text node
'Default Server' instead of the specific dropdown item; after opening the
dropdown (the click on the button returned by screen.getByRole("button", { name:
/Default Server/i })), query for the menu item role for the option itself (e.g.,
use screen.findByRole or screen.findAllByRole("menuitem", { name: /Default
Server/i }) and pick the specific item) and click that element instead of
entries[entries.length - 1]; update the assertions to still expect
mockBroadcastSelectedGuild and fetchSpy calls after clicking the menuitem.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: e47b6fcf-96b1-4260-91a6-f76c99a7134b

📥 Commits

Reviewing files that changed from the base of the PR and between b11d030 and 057bdfb.

📒 Files selected for processing (2)
  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.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). (10)
  • GitHub Check: Agent
  • GitHub Check: Greptile Review
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Typecheck & Build
  • GitHub Check: Docker Build Validation
  • GitHub Check: E2E Tests (2/2)
  • GitHub Check: Test
  • GitHub Check: E2E Tests (1/2)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (actions)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters

Files:

  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.tsx
web/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Never use console.* methods in web dashboard code; use appropriate logging mechanisms for React applications

web/src/**/*.{ts,tsx}: New dashboard routes need title wiring in web/src/lib/page-titles.ts; use createPageMetadata() for SSR and keep DashboardTitleSync aligned for client navigation
Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components
Recharts dashboard views should use web/src/components/ui/stable-responsive-container.tsx; raw ResponsiveContainer mounts can spam width(-1)/height(-1) warnings when panels render before layout settles
Any visual dashboard or landing page change must be verified with Chrome DevTools MCP before calling it done; take a screenshot after the change
Check both light and dark themes if colors or theming changed
Check responsive behavior on mobile, tablet, and desktop if layout changed

Files:

  • web/src/components/layout/server-selector.tsx
**/*.{js,ts,jsx,tsx,mjs,mts}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM only; do not use CommonJS

Files:

  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use src/logger.js; do not use console.*
Use the safe Discord messaging helpers in src/utils/safeSend.js instead of raw reply/send/edit calls
Use parameterized SQL only; do not use string concatenation for SQL queries
Community features should be gated behind config..enabled; moderation commands are the exception

Files:

  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.tsx
**/*.{js,ts,jsx,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Welcome-message variables use double braces only, like {{user}}; single braces are plain text and should not be documented, inserted, or parsed as variables

Files:

  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.tsx
web/src/**/*.{ts,tsx,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Follow the design system when making changes to the UI/UX; see DESIGN.md for the design system and color palette

Files:

  • web/src/components/layout/server-selector.tsx
web/tests/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

web/tests/**/*.test.{ts,tsx}: Write web dashboard tests using Vitest 4 with the jsdom environment and React Testing Library, matching the web/src/ structure
Maintain test coverage thresholds of 85% across all metrics (statements, branches, functions, lines) for web dashboard tests

Files:

  • web/tests/components/layout/server-selector.test.tsx
🧠 Learnings (8)
📓 Common learnings
Learnt from: BillChirico
Repo: VolvoxLLC/volvox-bot PR: 477
File: web/src/components/layout/server-selector.tsx:136-153
Timestamp: 2026-04-11T22:42:46.710Z
Learning: In `web/src/components/layout/server-selector.tsx`, the community feature is intentionally NOT gated behind a global config flag. The `ServerSelector` renders a full guild directory across all guilds a user belongs to; community eligibility is per-guild, so gating each community entry would require N extra config fetches (one per guild). Per-guild community gating is handled instead in the selected-guild config surface (e.g. ConfigProvider), where the selected guild's config is already available.
📚 Learning: 2026-04-11T22:42:46.710Z
Learnt from: BillChirico
Repo: VolvoxLLC/volvox-bot PR: 477
File: web/src/components/layout/server-selector.tsx:136-153
Timestamp: 2026-04-11T22:42:46.710Z
Learning: In `web/src/components/layout/server-selector.tsx`, the community feature is intentionally NOT gated behind a global config flag. The `ServerSelector` renders a full guild directory across all guilds a user belongs to; community eligibility is per-guild, so gating each community entry would require N extra config fetches (one per guild). Per-guild community gating is handled instead in the selected-guild config surface (e.g. ConfigProvider), where the selected guild's config is already available.

Applied to files:

  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to **/*.{js,ts,jsx,tsx} : Community features should be gated behind config.<feature>.enabled; moderation commands are the exception

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to config.json : All community features in `config.json` should be gated behind a `config.<feature>.enabled` flag; moderation commands are always available regardless of config settings

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to src/commands/**/*.js : Guild owners should be explicitly exempted from role hierarchy restrictions in command handlers to match Discord permission model expectations

Applied to files:

  • web/src/components/layout/server-selector.tsx
  • web/tests/components/layout/server-selector.test.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : Any visual dashboard or landing page change must be verified with Chrome DevTools MCP before calling it done; take a screenshot after the change

Applied to files:

  • web/tests/components/layout/server-selector.test.tsx
🔇 Additional comments (17)
web/src/components/layout/server-selector.tsx (10)

1-20: LGTM!

Imports are clean and well-organized. The component properly uses GuildDirectoryProvider context as per the coding guidelines for dashboard clients needing the guild list.


53-79: LGTM!

Well-structured SectionBadge component with proper tone variants that align with the design system. The use of Readonly<> for props is a good practice.


81-133: LGTM!

The helper components (CategoryHeader, CategoryEmptyState, LoadingCategory) provide a consistent structure for the three-category layout. The loading skeleton now properly shows all three categories during load, which aligns with the new UI.


139-157: LGTM!

The three-bucket categorization logic correctly handles the unknown bot status case by including botPresent === undefined in the infrastructure bucket when the guild is manageable. This addresses the prior concern about losing dashboard access during bot API outages. The separation is clear:

  • infrastructure: manageable guilds where bot is present OR status unknown
  • addBot: explicitly botPresent === false AND can invite
  • community: everything else

159-182: LGTM!

The accessSummary now includes the unknown status count for user transparency, and the trigger logic properly cascades through the three categories with sensible fallbacks.


189-221: LGTM!

The selection persistence logic correctly scopes to the infrastructure bucket only, ensuring that restored selections are valid dashboard-accessible guilds. The fallback to infrastructure[0] when no saved selection exists is appropriate.


223-235: LGTM!

Loading state now properly displays skeleton loaders for all three categories, providing a clear preview of the upcoming content structure.


252-275: LGTM!

The empty state properly handles both scenarios: when the Discord client ID is available (showing invite button) and when it's missing (showing helpful instruction text).


348-381: LGTM!

Infrastructure hubs section properly:

  • Uses DropdownMenuItem for keyboard accessibility
  • Shows distinct "Live" vs "Status unknown" badges
  • Prevents re-selection of the already selected guild (Line 353)
  • Displays selection indicator for current guild

389-429: LGTM!

The Add Bot section properly:

  • Uses DropdownMenuItem for keyboard accessibility (addressing prior review)
  • Opens invite URLs in new tabs via window.open
  • Handles unavailable invite URLs with disabled state
  • The getBotInviteUrl(guild.id) correctly pre-selects the guild in Discord's OAuth flow
web/tests/components/layout/server-selector.test.tsx (7)

1-77: LGTM!

Test setup is comprehensive:

  • Proper mocking of next/image and broadcastSelectedGuild
  • Animation mock handles jsdom limitations
  • Environment variable cleanup in afterEach prevents test pollution

79-86: LGTM!

The loading state test correctly verifies the new three-category structure with "Infrastructure Hubs", "Add Bot", and "Community Hubs" labels.


320-371: LGTM!

This test properly:

  • Uses try/finally to ensure window.location restoration (addressing prior review)
  • Verifies community hub UI and navigation behavior
  • Confirms broadcastSelectedGuild is not called for community navigation

373-422: LGTM!

Comprehensive test for the add bot flow:

  • Properly mocks and restores window.open
  • Verifies invite URL contains guild_id and disable_guild_select=true
  • Confirms broadcastSelectedGuild is not called for invite actions

473-500: LGTM!

This test correctly verifies that explicit access: "moderator" makes a guild manageable regardless of Discord permission bits, which is important for the role hierarchy system.


502-532: LGTM!

Good defensive test ensuring invalid guild records from the API don't crash the component or pollute the UI.


424-471: The test is correct. A guild with permissions: '32' (MANAGE_GUILD) and owner: false is properly placed in the infrastructure bucket because:

  1. The guild has botPresent === undefined (unset)
  2. MANAGE_GUILD permission maps to the 'moderator' dashboard role via getGuildDashboardRole()
  3. isGuildManageable() returns true for 'moderator' role
  4. The bucketing logic includes guilds where (botPresent === true || botPresent === undefined) && isGuildManageable(guild) — both conditions are satisfied

The test expectations match the actual implementation.

			> Likely an incorrect or invalid review comment.

Comment thread web/src/components/layout/server-selector.tsx
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 057bdfb. Configure here.

Comment thread web/src/components/layout/server-selector.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/layout/server-selector.tsx`:
- Around line 159-171: The useMemo for accessSummary incorrectly lists
infrastructure.filter in its dependency array; update the dependency array to
depend on the actual data used (e.g., infrastructure) instead of the
Array.prototype method so the memo invalidates when infrastructure contents
change—specifically, in the accessSummary useMemo, replace infrastructure.filter
with infrastructure and keep the other dependencies (addBot.length,
community.length, infrastructure.length or just infrastructure) so that
formatServerCount and formatUnknownStatusCount results recompute correctly when
infrastructure changes.
- Line 389: The Add Bot section wrapper uses className "space-y-1.5 px-2" which
causes inconsistent horizontal padding versus the Infrastructure and Community
sections; update the layout in server-selector.tsx so padding is consistent
across sections by either removing "px-2" from the Add Bot container (the div
with className "space-y-1.5 px-2") or adding the same "px-2" wrapper to the
Infrastructure and Community section containers to match their horizontal
spacing.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: acf3fdee-b7b1-4d4e-8900-9a53c842b53b

📥 Commits

Reviewing files that changed from the base of the PR and between 057bdfb and 1406e49.

📒 Files selected for processing (1)
  • web/src/components/layout/server-selector.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). (9)
  • GitHub Check: Greptile Review
  • GitHub Check: Cursor Bugbot
  • GitHub Check: E2E Tests (2/2)
  • GitHub Check: Typecheck & Build
  • GitHub Check: Test
  • GitHub Check: E2E Tests (1/2)
  • GitHub Check: Docker Build Validation
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,ts,tsx}: Use single quotes for strings (except in JSON files); no double quotes
Always include semicolons at the end of statements
Use 2-space indentation (spaces, not tabs)
Always include trailing commas in multi-line arrays, objects, and function parameters
Maintain a maximum line width of 100 characters

Files:

  • web/src/components/layout/server-selector.tsx
web/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Never use console.* methods in web dashboard code; use appropriate logging mechanisms for React applications

web/src/**/*.{ts,tsx}: New dashboard routes need title wiring in web/src/lib/page-titles.ts; use createPageMetadata() for SSR and keep DashboardTitleSync aligned for client navigation
Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components
Recharts dashboard views should use web/src/components/ui/stable-responsive-container.tsx; raw ResponsiveContainer mounts can spam width(-1)/height(-1) warnings when panels render before layout settles
Any visual dashboard or landing page change must be verified with Chrome DevTools MCP before calling it done; take a screenshot after the change
Check both light and dark themes if colors or theming changed
Check responsive behavior on mobile, tablet, and desktop if layout changed

Files:

  • web/src/components/layout/server-selector.tsx
**/*.{js,ts,jsx,tsx,mjs,mts}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM only; do not use CommonJS

Files:

  • web/src/components/layout/server-selector.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use src/logger.js; do not use console.*
Use the safe Discord messaging helpers in src/utils/safeSend.js instead of raw reply/send/edit calls
Use parameterized SQL only; do not use string concatenation for SQL queries
Community features should be gated behind config..enabled; moderation commands are the exception

Files:

  • web/src/components/layout/server-selector.tsx
**/*.{js,ts,jsx,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Welcome-message variables use double braces only, like {{user}}; single braces are plain text and should not be documented, inserted, or parsed as variables

Files:

  • web/src/components/layout/server-selector.tsx
web/src/**/*.{ts,tsx,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Follow the design system when making changes to the UI/UX; see DESIGN.md for the design system and color palette

Files:

  • web/src/components/layout/server-selector.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: BillChirico
Repo: VolvoxLLC/volvox-bot PR: 477
File: web/src/components/layout/server-selector.tsx:136-153
Timestamp: 2026-04-11T22:42:46.710Z
Learning: In `web/src/components/layout/server-selector.tsx`, the community feature is intentionally NOT gated behind a global config flag. The `ServerSelector` renders a full guild directory across all guilds a user belongs to; community eligibility is per-guild, so gating each community entry would require N extra config fetches (one per guild). Per-guild community gating is handled instead in the selected-guild config surface (e.g. ConfigProvider), where the selected guild's config is already available.
📚 Learning: 2026-04-11T22:42:46.710Z
Learnt from: BillChirico
Repo: VolvoxLLC/volvox-bot PR: 477
File: web/src/components/layout/server-selector.tsx:136-153
Timestamp: 2026-04-11T22:42:46.710Z
Learning: In `web/src/components/layout/server-selector.tsx`, the community feature is intentionally NOT gated behind a global config flag. The `ServerSelector` renders a full guild directory across all guilds a user belongs to; community eligibility is per-guild, so gating each community entry would require N extra config fetches (one per guild). Per-guild community gating is handled instead in the selected-guild config surface (e.g. ConfigProvider), where the selected guild's config is already available.

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : Dashboard clients that need the guild list should consume GuildDirectoryProvider; do not stack extra /api/guilds fetch loops in leaf components

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-10T23:21:49.730Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-10T23:21:49.730Z
Learning: Applies to web/src/components/layout/dashboard-shell.tsx : Dashboard page titles should sync with route changes using DashboardTitleSync component mounted in dashboard-shell.tsx and canonical title string 'Volvox.Bot - AI Powered Discord Bot'

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to **/*.{js,ts,jsx,tsx} : Community features should be gated behind config.<feature>.enabled; moderation commands are the exception

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to config.json : All community features in `config.json` should be gated behind a `config.<feature>.enabled` flag; moderation commands are always available regardless of config settings

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-11T06:42:38.728Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T06:42:38.728Z
Learning: Applies to src/commands/**/*.js : Guild owners should be explicitly exempted from role hierarchy restrictions in command handlers to match Discord permission model expectations

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-04-09T20:31:03.263Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-09T20:31:03.263Z
Learning: Applies to web/src/**/*.{ts,tsx} : New dashboard routes need title wiring in web/src/lib/page-titles.ts; use createPageMetadata() for SSR and keep DashboardTitleSync aligned for client navigation

Applied to files:

  • web/src/components/layout/server-selector.tsx
📚 Learning: 2026-03-12T02:03:36.493Z
Learnt from: CR
Repo: VolvoxLLC/volvox-bot PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-03-12T02:03:36.493Z
Learning: Applies to web/src/app/dashboard/**/*.tsx : For dashboard routes, add a matcher entry to `dashboardTitleMatchers` in `web/src/lib/page-titles.ts`: use exact equality for leaf routes (`pathname === '/dashboard/my-route'`) and subtree checks (`pathname.startsWith('/dashboard/my-route/')`); export `metadata` using `createPageMetadata(title)` for SSR entry points

Applied to files:

  • web/src/components/layout/server-selector.tsx
🔇 Additional comments (1)
web/src/components/layout/server-selector.tsx (1)

440-454: Community navigation still uses full page reload.

A past review suggested using Next.js useRouter for client-side navigation instead of window.location.href. This remains unchanged—if /community/${guild.id} shares the same layout/providers as the dashboard, switching to router.push() would provide smoother SPA navigation. However, if a full reload is intentional (e.g., different page structure), this is acceptable.

Comment thread web/src/components/layout/server-selector.tsx Outdated
Comment thread web/src/components/layout/server-selector.tsx Outdated
- accessSummary useMemo: depend on array references instead of .length
  so content changes trigger recalculation
- Add Bot section: remove extra px-2 for consistent padding
- window.location.href in dropdown: kept as-is — full navigation
  is acceptable for cross-route dropdown selection
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 18, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Comment thread web/src/components/layout/server-selector.tsx
Comment thread web/src/types/discord.ts Outdated
Comment thread web/src/components/layout/server-selector.tsx
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 18, 2026

Note

Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 18, 2026

✅ Created PR with unit tests: #537

- server-selector: use onSelect instead of onClick on DropdownMenuItem
- discord.ts: rename MutualGuild to UserGuild for accurate semantics
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 18, 2026
Comment thread web/tests/lib/discord.test.ts Outdated
Comment thread web/tests/hooks/use-guild-role.test.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8d5ceaabba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/src/components/layout/server-selector.tsx Outdated
Comment thread web/src/lib/discord.server.ts
- discord.test.ts: getMutualGuilds → getUserGuilds
- use-guild-role.test.ts: MutualGuild → UserGuild
- server-selector: use onClick for window.open to avoid popup blocker
  (onSelect fires via setTimeout which browsers block for window.open)
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
14.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Comment thread web/src/lib/discord.server.ts
Comment thread web/src/components/layout/server-selector.tsx
Comment thread web/src/lib/bot-api-proxy.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7109a00964

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread web/src/components/layout/server-selector.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

fix(dashboard): navigation panel should show all guild categories — joined, invitable, and community-only

3 participants