Skip to content

feat(bot): named music session save/restore/list/delete - #489

Merged
LucasSantana-Dev merged 6 commits into
mainfrom
feature/named-sessions
Apr 7, 2026
Merged

LucasSantana-Dev merged 6 commits into
mainfrom
feature/named-sessions

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Apr 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Added NamedSessionService with Redis-backed named session storage (max 10 per guild, 30-day TTL)
  • Enhanced /session command with 4 subcommands: save <name>, restore <name>, list, delete <name>
  • Added autocomplete support for session names in restore and delete subcommands
  • Added srem() to shared Redis client interface for Set member removal
  • Exported toSnapshotTrack() from sessionSnapshots for reuse
  • 27 new service tests + updated event handler tests

Test plan

  • npm run test:bot — 1449 tests pass (27 new)
  • npm run build — compiles without errors
  • Manual: /session save party-mix → /session list → /stop → /session restore party-mix → queue restored
  • Manual: /session delete party-mix removes session
  • Verify autocomplete shows session names when typing

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Replaced snapshot-based music sessions with a named-session system for /session command
    • Added save, list, delete, and restore subcommands for managing named sessions
    • Implemented autocomplete suggestions for session names in restore and delete subcommands
    • Sessions persist for 30 days with a maximum of 10 sessions per guild and 25 tracks per session
    • Session names must be lowercase alphanumeric with hyphens (1-32 characters)
  • Tests

    • Added comprehensive test coverage for named-session functionality and autocomplete interactions

@vercel

vercel Bot commented Apr 6, 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 Apr 7, 2026 4:27pm

Request Review

@github-actions

github-actions Bot commented Apr 6, 2026 •

Copy link
Copy Markdown

Size Change: 0 B

Total Size: 319 kB

ℹ️ View Unchanged
Filename Size
packages/frontend/dist/assets/ActionPanel-0VcwHxp8.js 400 B
packages/frontend/dist/assets/api-DklHG1ir.js 2.89 kB
packages/frontend/dist/assets/authStore-BeN9G4Ir.js 554 B
packages/frontend/dist/assets/AutoMessages-ClkUjYmn.js 2.67 kB
packages/frontend/dist/assets/AutoMod-CvKIJ0mp.js 4.09 kB
packages/frontend/dist/assets/badge-DaCRvtca.js 497 B
packages/frontend/dist/assets/Card-BDz-oBOW.js 454 B
packages/frontend/dist/assets/CommandsConfig-cal6wU1z.js 1.47 kB
packages/frontend/dist/assets/Config-DVGoL1zP.js 1.67 kB
packages/frontend/dist/assets/CustomCommands-CknJy4y9.js 2.15 kB
packages/frontend/dist/assets/DashboardOverview-D95f7gjT.js 2.54 kB
packages/frontend/dist/assets/dialog-AhaNIEIJ.js 949 B
packages/frontend/dist/assets/EmbedBuilder-JAX71mWN.js 3.34 kB
packages/frontend/dist/assets/Features-DBkKzC-r.js 2.84 kB
packages/frontend/dist/assets/GuildAutomation-DyTwGWdM.js 2.92 kB
packages/frontend/dist/assets/guildStore-Cprk-J95.js 793 B
packages/frontend/dist/assets/index-aZCOBalW.js 28.1 kB
packages/frontend/dist/assets/index-Cftz9xgB.css 14.4 kB
packages/frontend/dist/assets/input-Di8R--1I.js 462 B
packages/frontend/dist/assets/label-BcdNG6YT.js 488 B
packages/frontend/dist/assets/LastFm-Bd3t0pM2.js 1.74 kB
packages/frontend/dist/assets/Levels-C3BSZhfT.js 2.63 kB
packages/frontend/dist/assets/Login-7SA4E0Sn.js 2.51 kB
packages/frontend/dist/assets/Lyrics-NhZREYDH.js 1.33 kB
packages/frontend/dist/assets/Moderation-D8RGdrlQ.js 3.85 kB
packages/frontend/dist/assets/Music-DniCq6Ba.js 6.13 kB
packages/frontend/dist/assets/MusicConfig-CQ1AaPka.js 1.6 kB
packages/frontend/dist/assets/PrivacyPolicy-Cjg0fmEj.js 1.38 kB
packages/frontend/dist/assets/ReactionRoles-BsBOx_io.js 1.88 kB
packages/frontend/dist/assets/rolldown-runtime-COnpUsM8.js 467 B
packages/frontend/dist/assets/SectionHeader-BYj1R5tB.js 384 B
packages/frontend/dist/assets/select-DpnoiTxP.js 1.22 kB
packages/frontend/dist/assets/ServerLogs-C5qfGwVu.js 2.9 kB
packages/frontend/dist/assets/ServerSettings-CG7NnjNX.js 4.21 kB
packages/frontend/dist/assets/ServersPage--4ubUXoi.js 2.91 kB
packages/frontend/dist/assets/Skeleton-BZM8o63U.js 236 B
packages/frontend/dist/assets/Starboard-BSrGbOOn.js 2.07 kB
packages/frontend/dist/assets/StatTile-CbeWfJXD.js 605 B
packages/frontend/dist/assets/switch-D3jR1x5k.js 540 B
packages/frontend/dist/assets/TermsOfService-D5hRv0pK.js 1.37 kB
packages/frontend/dist/assets/TrackHistory-BhKTw1Ku.js 1.89 kB
packages/frontend/dist/assets/TwitchNotifications-YYr2spVX.js 2.28 kB
packages/frontend/dist/assets/usePageMetadata-tceaMDX4.js 325 B
packages/frontend/dist/assets/utils-sCAuCDq1.js 148 B
packages/frontend/dist/assets/vendor-forms-DmZCnE0r.js 25.4 kB
packages/frontend/dist/assets/vendor-radix-D5pOdkfi.js 33.5 kB
packages/frontend/dist/assets/vendor-react-COlHTipr.js 55.6 kB
packages/frontend/dist/assets/vendor-state-Bu2rokas.js 22 kB
packages/frontend/dist/assets/vendor-ui-BF57p9mS.js 64.2 kB

compressed-size-action

@coderabbitai

coderabbitai Bot commented Apr 7, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@LucasSantana-Dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 10 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 15 minutes and 10 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: CHILL

Plan: Pro

Run ID: 39e15c68-0d3a-4f25-8579-8e0b5235e77d

📥 Commits

Reviewing files that changed from the base of the PR and between 7203a33 and e00f290.

📒 Files selected for processing (11)
  • packages/bot/src/functions/music/commands/session.spec.ts
  • packages/bot/src/functions/music/commands/session.ts
  • packages/bot/src/handlers/eventHandler.spec.ts
  • packages/bot/src/handlers/eventHandler.ts
  • packages/bot/src/utils/music/namedSessions.spec.ts
  • packages/bot/src/utils/music/namedSessions.ts
  • packages/bot/src/utils/music/sessionSnapshots.ts
  • packages/shared/src/services/redis/client.ts
  • packages/shared/src/services/redis/operations.ts
  • packages/shared/src/services/redis/operations/stringOperations.ts
  • packages/shared/src/services/redis/types.ts
📝 Walkthrough

Walkthrough

The pull request migrates the music session system from snapshot-based storage to a named-session service backed by Redis. It introduces a new NamedSessionService with save/restore/list/delete operations, refactors the session command into multi-subcommand structure, adds autocomplete support for session names, extends Redis client with srem operations, and updates all related tests.

Changes

Cohort / File(s) Summary
Named Session Service
packages/bot/src/utils/music/namedSessions.ts, packages/bot/src/utils/music/namedSessions.spec.ts
New service for persisting named session snapshots in Redis with save/restore/list/delete operations. Enforces session name validation (^[a-z0-9-]{1,32}$), per-guild limits (10 sessions, 25 tracks max), 30-day TTL, and track resolution via queue player search with metadata attachment.
Session Command Refactor
packages/bot/src/functions/music/commands/session.ts, packages/bot/src/functions/music/commands/session.spec.ts
Replaced snapshot-based session system with multi-subcommand named-session workflow (save/restore/list/delete). Updated error handling, embed payloads, and service calls from musicSessionSnapshotService to namedSessionService. Test suite refactored with new mocks and assertion patterns.
Event Handler Autocomplete
packages/bot/src/handlers/eventHandler.ts, packages/bot/src/handlers/eventHandler.spec.ts
Added autocomplete handling to InteractionCreate that routes to new handleAutocomplete function. Provides session name suggestions for restore/delete subcommands via namedSessionService.list(), truncates to 25 choices per Discord limits, with dedicated error logging.
Redis Set Operations
packages/shared/src/services/redis/types.ts, packages/shared/src/services/redis/client.ts, packages/shared/src/services/redis/operations.ts, packages/shared/src/services/redis/operations/stringOperations.ts
Added srem(key, ...members): Promise<number> method across all Redis client abstraction layers for set member removal operations.
Snapshot Utility Export
packages/bot/src/utils/music/sessionSnapshots.ts
Exported toSnapshotTrack helper function to enable reuse by named session service for track normalization.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Discord API
    participant Command Handler
    participant Named Session Service
    participant Redis
    participant Queue Player

    User->>Discord API: /session save [name]
    Discord API->>Command Handler: execute session save subcommand
    Command Handler->>Named Session Service: save(queue, name, userId)
    Named Session Service->>Redis: check session count via smembers
    Redis-->>Named Session Service: existing sessions
    Named Session Service->>Named Session Service: validate name format & snapshot tracks
    Named Session Service->>Queue Player: extract current & upcoming tracks
    Queue Player-->>Named Session Service: track data
    Named Session Service->>Redis: setex(session_key, TTL, JSON)
    Redis-->>Named Session Service: stored
    Named Session Service->>Redis: sadd(guild_index, session_name)
    Redis-->>Named Session Service: added to index
    Named Session Service-->>Command Handler: saved session with metadata
    Command Handler->>Discord API: reply with session details
    Discord API-->>User: session saved confirmation
Loading
sequenceDiagram
    actor User
    participant Discord API
    participant Handler (Autocomplete)
    participant Named Session Service
    participant Redis
    participant Command Handler
    participant Queue Player
    participant Voice Connection

    User->>Discord API: focus 'name' option in /session restore
    Discord API->>Handler (Autocomplete): InteractionCreate (autocomplete)
    Handler (Autocomplete)->>Named Session Service: list(guildId)
    Named Session Service->>Redis: smembers(guild_index)
    Redis-->>Named Session Service: session names
    Named Session Service->>Redis: get(session_key) for each name
    Redis-->>Named Session Service: sessions with metadata
    Named Session Service-->>Handler (Autocomplete): sorted summaries
    Handler (Autocomplete)->>Discord API: respond with name choices (max 25)
    Discord API-->>User: autocomplete suggestions
    
    User->>Discord API: select session name & execute /session restore
    Discord API->>Command Handler: execute session restore subcommand
    Command Handler->>Named Session Service: restore(queue, name, user)
    Named Session Service->>Redis: get(session_key)
    Redis-->>Named Session Service: stored snapshot
    Named Session Service->>Queue Player: search(track_query) for each snapshot track
    Queue Player-->>Named Session Service: resolved tracks with metadata
    Named Session Service->>Queue Player: addTrack() for each resolved track
    Queue Player-->>Named Session Service: tracks enqueued
    Named Session Service->>Queue Player: play() if not already playing
    Queue Player-->>Voice Connection: begin playback
    Named Session Service-->>Command Handler: { restoredCount }
    Command Handler->>Discord API: reply with restored track count
    Discord API-->>User: restore confirmation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introduction of a named music session system with save, restore, list, and delete functionality. It is specific, concise, and reflects the primary feature addition.

✏️ 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 feature/named-sessions

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.

- Added srem() to RedisClient interface, operations, and string ops
- Fixed namedSessions.ts: use smembers().length instead of scard()
- Fixed del() return type (boolean not number)
- Fixed test mocks: hoisting, boolean return types, isAutocomplete mock
Adds coverage for the autocomplete path introduced alongside named sessions:
- responds with session name choices for restore and delete subcommands
- caps responses at the Discord 25-choice limit
- returns empty list when guildId is missing
- returns empty list for unrelated commands
- swallows and logs errors from namedSessionService.list
@LucasSantana-Dev
LucasSantana-Dev force-pushed the feature/named-sessions branch from 7203a33 to e00f290 Compare April 7, 2026 16:25
@github-actions github-actions Bot removed the dependencies Pull requests that update a dependency file label Apr 7, 2026
@sonarqubecloud

sonarqubecloud Bot commented Apr 7, 2026

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 9738d86 into main Apr 7, 2026
11 checks passed
LucasSantana-Dev added a commit that referenced this pull request Apr 10, 2026
* feat(bot): export toSnapshotTrack for reuse

* feat(bot): add NamedSessionService for named queue sessions

* feat(bot): enhance /session with named save/restore/list/delete

* test(bot): add named session service and command tests

* fix(shared): add srem to redis client and fix named session type errors

- Added srem() to RedisClient interface, operations, and string ops
- Fixed namedSessions.ts: use smembers().length instead of scard()
- Fixed del() return type (boolean not number)
- Fixed test mocks: hoisting, boolean return types, isAutocomplete mock

* test(bot): cover handleAutocomplete branches for session name lookup

Adds coverage for the autocomplete path introduced alongside named sessions:
- responds with session name choices for restore and delete subcommands
- caps responses at the Discord 25-choice limit
- returns empty list when guildId is missing
- returns empty list for unrelated commands
- swallows and logs errors from namedSessionService.list
LucasSantana-Dev added a commit that referenced this pull request May 13, 2026
* feat(bot): export toSnapshotTrack for reuse

* feat(bot): add NamedSessionService for named queue sessions

* feat(bot): enhance /session with named save/restore/list/delete

* test(bot): add named session service and command tests

* fix(shared): add srem to redis client and fix named session type errors

- Added srem() to RedisClient interface, operations, and string ops
- Fixed namedSessions.ts: use smembers().length instead of scard()
- Fixed del() return type (boolean not number)
- Fixed test mocks: hoisting, boolean return types, isAutocomplete mock

* test(bot): cover handleAutocomplete branches for session name lookup

Adds coverage for the autocomplete path introduced alongside named sessions:
- responds with session name choices for restore and delete subcommands
- caps responses at the Discord 25-choice limit
- returns empty list when guildId is missing
- returns empty list for unrelated commands
- swallows and logs errors from namedSessionService.list
@LucasSantana-Dev
LucasSantana-Dev deleted the feature/named-sessions branch May 23, 2026 02:21

This branch was successfully deployed

1 active deployment
Preview — e00f2903 Deployed Apr 7, 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.

1 participant