Skip to content

fix(batch): bullmq worker requires maxretriesperrequest null redis - #1665

Merged
LucasSantana-Dev merged 7 commits into
mainfrom
fix/batch-worker-bullmq-redis
Jul 2, 2026
Merged

fix(batch): bullmq worker requires maxretriesperrequest null redis#1665
LucasSantana-Dev merged 7 commits into
mainfrom
fix/batch-worker-bullmq-redis

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixed BullMQ Worker startup failure caused by redis maxRetriesPerRequest: 3 config
  • Created dedicated redis connection for BullMQ with maxRetriesPerRequest: null
  • Added proper lifecycle management and error handling for BullMQ redis connection

Root Cause

BullMQ Worker strictly requires a redis connection with maxRetriesPerRequest: null to avoid connection state queueing conflicts. The shared redis client was configured with maxRetriesPerRequest: 3, which caused:

Error: BullMQ: Your redis options maxRetriesPerRequest must be null
TypeError: Cannot read properties of undefined (reading 'client')

Changes

  • Created createBullMQRedisConnection() function with correct ioredis options
  • Updated startBatchJobWorker() to instantiate BullMQ redis separately
  • Added cleanup logic in stopBatchJobWorker() to disconnect the BullMQ redis instance
  • Updated unit tests to verify BullMQ connection config and proper cleanup

Verification

  • 16 tests passing for batchJobWorker
  • Type check passing for all workspaces
  • No type errors in the updated code

Closes #1652


Summary by cubic

Fixes the batch bullmq worker by using a dedicated ioredis connection with maxRetriesPerRequest: null and lazy connect. Prevents startup failures, handles missing shared Redis, and ensures clean shutdown. Closes #1652.

  • Bug Fixes
    • Added createBullMQRedisConnection() using ENVIRONMENT_CONFIG with maxRetriesPerRequest: null and lazyConnect: true.
    • Worker now uses this dedicated connection and returns early if the shared Redis client is unavailable.
    • On executor registration or startup failure and on shutdown, we disconnect BullMQ Redis and clear the worker reference; tests cover connection options, usage, and cleanup.

Written for commit 22fc6af. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved batch job worker reliability by using a dedicated Redis connection for background processing.
    • Added stronger startup failure handling to ensure the dedicated connection is disconnected and cleared correctly.
    • Ensured shutdown always releases the dedicated Redis connection, even if worker closing throws.
  • Tests
    • Updated and expanded worker tests to cover Redis unavailable behavior and verify that shutdown disconnects the dedicated connection.

BullMQ Worker requires a redis connection with maxRetriesPerRequest: null to
avoid connection state conflicts. The shared redis client was configured with
maxRetriesPerRequest: 3, which caused BullMQ to fail at startup with:
"BullMQ: Your redis options maxRetriesPerRequest must be null"

Fix by creating a dedicated redis connection for BullMQ with the correct
config, separate from the shared client. Updated Worker initialization to use
this connection. Added proper cleanup of the BullMQ redis connection in
stopBatchJobWorker and error handling paths.

Updated unit tests to verify:
- BullMQ redis connection created with maxRetriesPerRequest: null
- Worker receives the dedicated BullMQ connection
- BullMQ redis connection properly disconnected on shutdown

Closes #1652
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3e414907-185d-4f99-a589-dbf827be4f95

📥 Commits

Reviewing files that changed from the base of the PR and between 48d6569 and 22fc6af.

📒 Files selected for processing (1)
  • packages/bot/src/workers/batchJobWorker.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bot/src/workers/batchJobWorker.ts

📝 Walkthrough

Walkthrough

The batch job worker now uses a dedicated BullMQ Redis connection with maxRetriesPerRequest: null, cleans it up on startup failure and shutdown, and updates the worker spec to mock and verify the shared Redis and BullMQ Redis paths separately.

Changes

Dedicated BullMQ Redis connection

Layer / File(s) Summary
Worker connection state and dedicated Redis creation
packages/bot/src/workers/batchJobWorker.ts
Adds a Redis import and bullmqRedis state, implements createBullMQRedisConnection() with maxRetriesPerRequest: null and lazyConnect: true, and wires startBatchJobWorker() to use the dedicated connection after checking shared redis availability.
Failure and shutdown cleanup
packages/bot/src/workers/batchJobWorker.ts
Disconnects the dedicated Redis connection when executor registration or Worker creation fails, and stopBatchJobWorker() disconnects it in a finally block while closing and nulling the worker.
Spec updates for dual Redis mocking
packages/bot/src/workers/batchJobWorker.spec.ts
Reworks the test harness to separate sharedRedis from a BullMQ-specific MockRedis/ioredis mock with disconnect, adds ENVIRONMENT_CONFIG.REDIS mocking, and updates assertions for worker options and disconnect behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: backend, non-destructive-confirmed

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: fixing the BullMQ worker Redis configuration to use maxRetriesPerRequest null.
Linked Issues check ✅ Passed The PR implements the BullMQ-specific Redis connection, null maxRetriesPerRequest, and cleanup/error handling required by #1652.
Out of Scope Changes check ✅ Passed The changes stay focused on the batch worker Redis/BullMQ startup fix and related tests, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/batch-worker-bullmq-redis

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

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 2 files

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

Re-trigger cubic

Comment thread packages/bot/src/workers/batchJobWorker.ts Outdated
Comment thread packages/bot/src/workers/batchJobWorker.ts Outdated
@LucasSantana-Dev
LucasSantana-Dev enabled auto-merge (squash) July 2, 2026 03:16

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Requires human review: Bug fix creating a dedicated Redis connection for BullMQ worker. Changes involve core infrastructure (Redis connection lifecycle, error handling) and could impact job processing stability if connection setup or cleanup contains defects.

Re-trigger cubic

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/bot/src/workers/batchJobWorker.spec.ts (1)

57-67: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Keep the Redis mock instance aligned with bullmqRedisCtor. When a custom ctor is passed, mockBullmqRedis still reflects the fallback branch, so the helper returns a different object than the ctor path. If this helper is meant to support custom Redis constructors, derive the returned instance from that path too, or drop the extra return value.

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

In `@packages/bot/src/workers/batchJobWorker.spec.ts` around lines 57 - 67, The
Redis mock setup in batchJobWorker.spec.ts is not aligned with the custom
constructor path, so the helper can return a different instance than the one
created by bullmqRedisCtor. Update the mock construction around
MockRedis/mockBullmqRedis so the returned Redis instance is derived from the
custom ctor when provided, or remove the separate fallback instance entirely if
it is not needed. Keep the behavior consistent for both the default and
ctor-injected paths so tests exercise the same object that BullMQ would use.
packages/bot/src/workers/batchJobWorker.ts (2)

198-201: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

disconnect() is synchronous — await/try-catch around it don't add real protection.

ioredis#disconnect() Disconnect from Redis. and does not return a Promise, so the await at lines 200/238 resolves immediately regardless of actual socket teardown, and the try/catch at lines 237-245 will rarely have anything to catch. If waiting for a clean close (e.g., no dropped in-flight replies) matters, Redis#quit() is the documented alternative: "If you want to wait for the pending replies, use Redis#quit instead." This is purely a robustness nit since lazyConnect: true means these failure paths likely never established a real connection anyway.

Also applies to: 235-248, 271-274

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

In `@packages/bot/src/workers/batchJobWorker.ts` around lines 198 - 201,
`bullmqRedis.disconnect()` in `batchJobWorker` is being treated like an async
cleanup step, but it is synchronous and the surrounding `await`/try-catch gives
a false sense of protection. Update the cleanup paths in the
executor-registration failure handling and the related teardown blocks to call
`disconnect()` directly, or switch to `quit()` only if you truly need to wait
for pending replies; keep the nulling/reset logic in the same `batchJobWorker`
cleanup flow.

149-166: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider adding an error listener on the dedicated connection.

createBullMQRedisConnection() never attaches an .on('error', ...) handler to bullmqRedis. BullMQ's own production guidance recommends this explicitly: "It is really useful to attach a handler for the error event which will be triggered when there are connection issues. This will be helpful when debugging your queues and prevent "unhandled errors"." Given this file exists specifically to fix a Redis-connectivity startup failure (#1652), it's worth having visibility into connection-level errors on this dedicated client rather than relying solely on BullMQ's internal handling.

♻️ Proposed addition
 function createBullMQRedisConnection(): Redis {
     // No try/catch: with lazyConnect the constructor never touches the
     // network — connection errors surface later through BullMQ's own
     // error handling, so a catch here would be a false safety net.
-    return new Redis({
+    const connection = new Redis({
         host: ENVIRONMENT_CONFIG.REDIS.HOST,
         port: ENVIRONMENT_CONFIG.REDIS.PORT,
         password: ENVIRONMENT_CONFIG.REDIS.PASSWORD,
         db: ENVIRONMENT_CONFIG.REDIS.DB,
         // BullMQ requirement: must be null to avoid request queueing conflicts
         maxRetriesPerRequest: null,
         lazyConnect: true,
     })
+    connection.on('error', (error) => {
+        errorLog({ message: 'BullMQ redis connection error', error })
+    })
+    return connection
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bot/src/workers/batchJobWorker.ts` around lines 149 - 166, The
dedicated Redis client created in createBullMQRedisConnection() is missing an
error event handler, so connection-level failures can be hidden or become
unhandled. Update the BullMQ Redis setup in batchJobWorker.ts by attaching an
.on('error', ...) listener to the Redis instance returned from
createBullMQRedisConnection(), and log the error with enough context to help
debug queue connectivity issues.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/bot/src/workers/batchJobWorker.ts`:
- Around line 254-276: The shutdown flow in stopBatchJobWorker leaves a stale
worker reference if worker.close() throws because worker = null is only set on
the success path. Move the worker reset into the finally block in
stopBatchJobWorker so the module state is cleared unconditionally after any
close attempt, alongside the existing bullmqRedis cleanup, and keep the logging
in the try/catch unchanged.

---

Nitpick comments:
In `@packages/bot/src/workers/batchJobWorker.spec.ts`:
- Around line 57-67: The Redis mock setup in batchJobWorker.spec.ts is not
aligned with the custom constructor path, so the helper can return a different
instance than the one created by bullmqRedisCtor. Update the mock construction
around MockRedis/mockBullmqRedis so the returned Redis instance is derived from
the custom ctor when provided, or remove the separate fallback instance entirely
if it is not needed. Keep the behavior consistent for both the default and
ctor-injected paths so tests exercise the same object that BullMQ would use.

In `@packages/bot/src/workers/batchJobWorker.ts`:
- Around line 198-201: `bullmqRedis.disconnect()` in `batchJobWorker` is being
treated like an async cleanup step, but it is synchronous and the surrounding
`await`/try-catch gives a false sense of protection. Update the cleanup paths in
the executor-registration failure handling and the related teardown blocks to
call `disconnect()` directly, or switch to `quit()` only if you truly need to
wait for pending replies; keep the nulling/reset logic in the same
`batchJobWorker` cleanup flow.
- Around line 149-166: The dedicated Redis client created in
createBullMQRedisConnection() is missing an error event handler, so
connection-level failures can be hidden or become unhandled. Update the BullMQ
Redis setup in batchJobWorker.ts by attaching an .on('error', ...) listener to
the Redis instance returned from createBullMQRedisConnection(), and log the
error with enough context to help debug queue connectivity issues.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1c3b22ba-f2b7-48d6-aa45-47a3ab2252b6

📥 Commits

Reviewing files that changed from the base of the PR and between 54f1f73 and 48d6569.

📒 Files selected for processing (2)
  • packages/bot/src/workers/batchJobWorker.spec.ts
  • packages/bot/src/workers/batchJobWorker.ts

Comment thread packages/bot/src/workers/batchJobWorker.ts
auto-merge was automatically disabled July 2, 2026 06:13

Pull Request is not mergeable

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Requires human review: Changes Redis connection handling and worker lifecycle for BullMQ; requires human review to verify correctness.

Re-trigger cubic

@LucasSantana-Dev
LucasSantana-Dev enabled auto-merge (squash) July 2, 2026 07:31
@sonarqubecloud

sonarqubecloud Bot commented Jul 2, 2026

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit f5adffe into main Jul 2, 2026
41 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/batch-worker-bullmq-redis branch July 2, 2026 07:36
LucasSantana-Dev added a commit that referenced this pull request Jul 2, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>2.28.1</summary>

##
[2.28.1](v2.28.0...v2.28.1)
(2026-07-02)


### Bug Fixes

* **batch:** bullmq worker requires maxretriesperrequest null redis
([#1665](#1665))
([f5adffe](f5adffe))
* **bot:** wire role exclusion enforcement + guildmembers intent
([#1668](#1668))
([e8145af](e8145af))
* **sonar:** clear main reliability gate - s1244 and tailwind v4 fps
([#1671](#1671))
([c12059d](c12059d))
* **telemetry:** un-silence skip-reason emoji prefill errors
([#1660](#1660))
([5eabbd2](5eabbd2))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
LucasSantana-Dev added a commit that referenced this pull request Jul 9, 2026
:robot: I have created a release *beep* *boop*
---


<details><summary>2.33.0</summary>

##
[2.33.0](https://github.com/LucasSantana-Dev/Lucky/compare/v2.32.3...v2.33.0)
(2026-07-09)


### Features

* **autoplay:** add implicit-dislike-penalty signal
([#1374](https://github.com/LucasSantana-Dev/Lucky/issues/1374))
([593c0ad](https://github.com/LucasSantana-Dev/Lucky/commit/593c0ada5b732b4a48d63204c8e849c4b5057677))
* **autoplay:** add recency-decay signal for queue diversity
([#1376](https://github.com/LucasSantana-Dev/Lucky/issues/1376))
([b85e2a0](https://github.com/LucasSantana-Dev/Lucky/commit/b85e2a0f5d79efd04590d17db58faee5f5a50d38))
* **autoplay:** boost candidates for frequently replayed tracks
([#1370](https://github.com/LucasSantana-Dev/Lucky/issues/1370))
([215edea](https://github.com/LucasSantana-Dev/Lucky/commit/215edea22b8e99ab114f3450323a5f5de61ce6fb))
* **autoplay:** guild opt-out toggle for sertanejo veto
([#1087](https://github.com/LucasSantana-Dev/Lucky/issues/1087))
([#1373](https://github.com/LucasSantana-Dev/Lucky/issues/1373))
([6cb5588](https://github.com/LucasSantana-Dev/Lucky/commit/6cb55883f850aca68f4a6d5c2d5a3e5b492df8d5))
* **autoplay:** guild-scope implicit dislike for autoplay skips
([#1578](https://github.com/LucasSantana-Dev/Lucky/issues/1578))
([70b8596](https://github.com/LucasSantana-Dev/Lucky/commit/70b8596e7d4a0de5468e701f111c288aef9abe35))
* **autoplay:** hit@k eval harness for recommendation scoring
([#1577](https://github.com/LucasSantana-Dev/Lucky/issues/1577))
([2a0c6c4](https://github.com/LucasSantana-Dev/Lucky/commit/2a0c6c43f83fc5bf2f552549f3dfc832aeb8a95f))
* **autoplay:** instrument outcome eval to disambiguate
[#1275](https://github.com/LucasSantana-Dev/Lucky/issues/1275)
([#1491](https://github.com/LucasSantana-Dev/Lucky/issues/1491))
([1921ab5](https://github.com/LucasSantana-Dev/Lucky/commit/1921ab58ac8de1826fe73a931a02a9a5bf9c7541))
* **autoplay:** quick-wins batch — mood-cache clear, provider telemetry,
accept-rate
([#1090](https://github.com/LucasSantana-Dev/Lucky/issues/1090)
[#1083](https://github.com/LucasSantana-Dev/Lucky/issues/1083)
[#1086](https://github.com/LucasSantana-Dev/Lucky/issues/1086))
([#1102](https://github.com/LucasSantana-Dev/Lucky/issues/1102))
([7d7e4f5](https://github.com/LucasSantana-Dev/Lucky/commit/7d7e4f5451a67eac311c72270e9fe59c7aa4ff98))
* **backend:** add zod validation to artists and toggles routes
([#1189](https://github.com/LucasSantana-Dev/Lucky/issues/1189))
([#1334](https://github.com/LucasSantana-Dev/Lucky/issues/1334))
([b59fb35](https://github.com/LucasSantana-Dev/Lucky/commit/b59fb35244d9f1712d0730035c154ba471e34544))
* **backend:** dedup key for support-report intake
([#1319](https://github.com/LucasSantana-Dev/Lucky/issues/1319))
([#1328](https://github.com/LucasSantana-Dev/Lucky/issues/1328))
([4d95307](https://github.com/LucasSantana-Dev/Lucky/commit/4d9530762e37c97440e2e6a6957886ff41fcc1b6))
* **backend:** move session store from Redis to Postgres
([#1111](https://github.com/LucasSantana-Dev/Lucky/issues/1111))
([#1396](https://github.com/LucasSantana-Dev/Lucky/issues/1396))
([ff5e0b6](https://github.com/LucasSantana-Dev/Lucky/commit/ff5e0b684aa369a208a3e01d9c9a8c4cc53e4308))
* **backend:** read-only guild members/roles service endpoints
([#1691](https://github.com/LucasSantana-Dev/Lucky/issues/1691))
([fd04b6e](https://github.com/LucasSantana-Dev/Lucky/commit/fd04b6ef5f8a1609a468bb97f43213df488af8a8))
* **backend:** request-id correlation middleware for
[#1286](https://github.com/LucasSantana-Dev/Lucky/issues/1286)
([#1417](https://github.com/LucasSantana-Dev/Lucky/issues/1417))
([671ed4c](https://github.com/LucasSantana-Dev/Lucky/commit/671ed4c90471670f68346b493eade85d55a92ee9))
* **backend:** support intake + admin routes + staff notification
([#1241](https://github.com/LucasSantana-Dev/Lucky/issues/1241))
([280faeb](https://github.com/LucasSantana-Dev/Lucky/commit/280faeb983e02ae498960cb98b1ca10e7f44af2f))
* **backend:** wire moderation executor into
GuildAutomationExecutionService
([#1066](https://github.com/LucasSantana-Dev/Lucky/issues/1066))
([43ed8db](https://github.com/LucasSantana-Dev/Lucky/commit/43ed8db3906c826d8f01738fc5a49052c7f94862))
* **batch:** batch-operation framework + bulk-move-messages flagship
([#1564](https://github.com/LucasSantana-Dev/Lucky/issues/1564))
([9d11bf5](https://github.com/LucasSantana-Dev/Lucky/commit/9d11bf5d985dc9765b75eecb0bc798e2fe0c6443))
* **bot:** /vaga command builds job posts with auto-tagged roles
([#1682](https://github.com/LucasSantana-Dev/Lucky/issues/1682))
([963e457](https://github.com/LucasSantana-Dev/Lucky/commit/963e457af6402437b10138124052df524af37a99))
* **bot:** add RSS bridge service for Criativaria guides
([#1608](https://github.com/LucasSantana-Dev/Lucky/issues/1608))
([2807cad](https://github.com/LucasSantana-Dev/Lucky/commit/2807cada542424d3e4b15eaf76ec56d6b7250c8a))
* **bot:** add weekly community digest service
([#1609](https://github.com/LucasSantana-Dev/Lucky/issues/1609))
([2a653bf](https://github.com/LucasSantana-Dev/Lucky/commit/2a653bff32f3e5afa15cb73aae4d41e0476da859))
* **bot:** afk status with mention replies
([#1689](https://github.com/LucasSantana-Dev/Lucky/issues/1689))
([d8b5ba1](https://github.com/LucasSantana-Dev/Lucky/commit/d8b5ba101ea69033f18d9236481c9f8225867f08))
* **bot:** criativaria live twitch notification (poll every 2 min)
([#1613](https://github.com/LucasSantana-Dev/Lucky/issues/1613))
([e1d10b6](https://github.com/LucasSantana-Dev/Lucky/commit/e1d10b6efa7dd570867f4e678e9d0f6e30368bf7))
* **bot:** extend mod-log posting, fix twitch startup silence
([#1698](https://github.com/LucasSantana-Dev/Lucky/issues/1698))
([fb48065](https://github.com/LucasSantana-Dev/Lucky/commit/fb4806554220e604094aee1e27a498376ad566ff))
* **bot:** instrument serversetup criativaria invocations
([#1288](https://github.com/LucasSantana-Dev/Lucky/issues/1288))
([#1390](https://github.com/LucasSantana-Dev/Lucky/issues/1390))
([c37f021](https://github.com/LucasSantana-Dev/Lucky/commit/c37f021f3c28a13a6a58ed2529dcc5e3269892b1))
* **bot:** persistent giveaways with reaction entry
([#1690](https://github.com/LucasSantana-Dev/Lucky/issues/1690))
([b715af9](https://github.com/LucasSantana-Dev/Lucky/commit/b715af9df16ad016eaa7feda5f6e287d2b441933))
* **bot:** post moderation case embeds to the mod-log channel
([#1696](https://github.com/LucasSantana-Dev/Lucky/issues/1696))
([884da0f](https://github.com/LucasSantana-Dev/Lucky/commit/884da0fc5d8d689751c02ab4546911d11dc11fb8))
* **bot:** reminders with /remind and delivery scheduler
([#1686](https://github.com/LucasSantana-Dev/Lucky/issues/1686))
([1228290](https://github.com/LucasSantana-Dev/Lucky/commit/12282903a07538c75869c5eabb24f2823fb7411d))
* **bot:** smart custom commands via generic command-kind seam (ADR
2026-07-03)
([#1684](https://github.com/LucasSantana-Dev/Lucky/issues/1684))
([f0c446c](https://github.com/LucasSantana-Dev/Lucky/commit/f0c446c5dad1ab343b9a8df57f7b89ea3eaccaa2))
* **bot:** starboard seeding and one-time first-star dm
([#1685](https://github.com/LucasSantana-Dev/Lucky/issues/1685))
([e12e2e4](https://github.com/LucasSantana-Dev/Lucky/commit/e12e2e4e18a1d5fc256c1c83b818384c8366fe60))
* **bot:** surface support url + correlation id in command error embeds
([#1240](https://github.com/LucasSantana-Dev/Lucky/issues/1240))
([1cc004b](https://github.com/LucasSantana-Dev/Lucky/commit/1cc004bcd4d14a36dc7c6d31442c6264972cdc24))
* **bot:** utility join-onboarding message + in-bot growth adr
([#1506](https://github.com/LucasSantana-Dev/Lucky/issues/1506))
([0a23775](https://github.com/LucasSantana-Dev/Lucky/commit/0a23775cdb458479e0e1b23ad1e42679d6036d57))
* **dashboard:** add role groups management page
([#1678](https://github.com/LucasSantana-Dev/Lucky/issues/1678))
([bb8bc2c](https://github.com/LucasSantana-Dev/Lucky/commit/bb8bc2c9d2e2a0dd2cccd3ff690c16531a576016))
* **dashboard:** reaction roles create and delete
([c5c351c](https://github.com/LucasSantana-Dev/Lucky/commit/c5c351cddeb494cbcebce5448f96538bd8f97954))
* **dashboard:** refresh, single server switcher, i18n, avatar+cursor
([#1546](https://github.com/LucasSantana-Dev/Lucky/issues/1546))
([abda321](https://github.com/LucasSantana-Dev/Lucky/commit/abda3219eb4e5fdbb376b619cf3ab99f390fdefc))
* **db:** add check constraints on guild_settings bounds
([#1124](https://github.com/LucasSantana-Dev/Lucky/issues/1124))
([#1338](https://github.com/LucasSantana-Dev/Lucky/issues/1338))
([a7c7400](https://github.com/LucasSantana-Dev/Lucky/commit/a7c74007bbb0df43e45e88de52971e3858ee729a))
* **deploy:** SHA-pinned deploys + auto-rollback on health failure
([#1230](https://github.com/LucasSantana-Dev/Lucky/issues/1230))
([e24f128](https://github.com/LucasSantana-Dev/Lucky/commit/e24f1284d89edc9a8a72cb2135df580c8f7467a7))
* **frontend:** add music surface pages and components
([bb40e9c](https://github.com/LucasSantana-Dev/Lucky/commit/bb40e9c667a79bfd588b1fc13a61b55c457c2fd8))
* **frontend:** add ServerLogs + ServerSettings UI pages
([#965](https://github.com/LucasSantana-Dev/Lucky/issues/965))
([89961d3](https://github.com/LucasSantana-Dev/Lucky/commit/89961d324aed39001737e1f9873b7def200aaa65))
* growth surfaces — /invite, landing SEO + CTA, guild telemetry
([#1494](https://github.com/LucasSantana-Dev/Lucky/issues/1494))
([205876d](https://github.com/LucasSantana-Dev/Lucky/commit/205876d4ad9ba415840abc4207ca9ac98a99e7f4))
* guild integrations pack
([#1669](https://github.com/LucasSantana-Dev/Lucky/issues/1669))
([64a41a4](https://github.com/LucasSantana-Dev/Lucky/commit/64a41a48a1147b06ca18e36cbd5f9a4551321d23))
* **guild-automation:** wire AutoMessages executor into execution
service ([#906](https://github.com/LucasSantana-Dev/Lucky/issues/906))
([#950](https://github.com/LucasSantana-Dev/Lucky/issues/950))
([b5e444b](https://github.com/LucasSantana-Dev/Lucky/commit/b5e444b20dc836cf2fc29c6d70ccb67c7ac2ae9e))
* **infra:** homelab staging environment for visual PR review
([#1547](https://github.com/LucasSantana-Dev/Lucky/issues/1547))
([c15fa38](https://github.com/LucasSantana-Dev/Lucky/commit/c15fa388a61db9d1c3cfe880885f32d6020a629d))
* **levels:** show member display names on leaderboard, not raw ids
([eb0d700](https://github.com/LucasSantana-Dev/Lucky/commit/eb0d7009a0519bb6c00f6dcab2865c7c571779ce))
* **logs:** async context propagation, discord alerts, noise filtering
([#1510](https://github.com/LucasSantana-Dev/Lucky/issues/1510))
([a952c54](https://github.com/LucasSantana-Dev/Lucky/commit/a952c5400518f29c650abb286fada80caf34f2cd))
* **moderation:** move a message to another channel via right-click
([#1516](https://github.com/LucasSantana-Dev/Lucky/issues/1516))
([9822893](https://github.com/LucasSantana-Dev/Lucky/commit/98228930177479a078016c1c20e1ba43d393b7fd))
* **music:** add previous-track command end to end
([#1239](https://github.com/LucasSantana-Dev/Lucky/issues/1239))
([#1347](https://github.com/LucasSantana-Dev/Lucky/issues/1347))
([7771167](https://github.com/LucasSantana-Dev/Lucky/commit/7771167e7cc1534c561d6bad3cfbd2bcf85e261f))
* **observability:** alert on redis control publish failures
([#1401](https://github.com/LucasSantana-Dev/Lucky/issues/1401))
([6e46cd7](https://github.com/LucasSantana-Dev/Lucky/commit/6e46cd7ab193dedbff4a7b62ac0c6060489a4607))
* **observability:** capture escaping errors to Sentry at chokepoints
([#1229](https://github.com/LucasSantana-Dev/Lucky/issues/1229))
([9448de4](https://github.com/LucasSantana-Dev/Lucky/commit/9448de4b2a4c41145a3db443faff3df1e5dae1b1))
* **observability:** deploy markers, heartbeat, alerts (Layers 1-3)
([#1103](https://github.com/LucasSantana-Dev/Lucky/issues/1103))
([24568c0](https://github.com/LucasSantana-Dev/Lucky/commit/24568c02af1b802624d08f184fa64dcadcc413b3))
* **queue:** queueResolver telemetry pilot
([#1084](https://github.com/LucasSantana-Dev/Lucky/issues/1084))
([#1100](https://github.com/LucasSantana-Dev/Lucky/issues/1100))
([527609a](https://github.com/LucasSantana-Dev/Lucky/commit/527609a86a3f1b67bda3dbf8b62b371213dc77ff))
* **reaction-roles:** editable form, emoji picker, formatting, media,
export/import
([#1544](https://github.com/LucasSantana-Dev/Lucky/issues/1544))
([ac5e0e9](https://github.com/LucasSantana-Dev/Lucky/commit/ac5e0e988a27468eb75ace887795ed80c2d75b5f))
* **role-groups:** composite add-styled-role v1
([#1557](https://github.com/LucasSantana-Dev/Lucky/issues/1557))
([c869811](https://github.com/LucasSantana-Dev/Lucky/commit/c8698117666b066f4f7aa5ad5bc38602321e6cd7))
* **security:** add security headers + csp report-only
([#1283](https://github.com/LucasSantana-Dev/Lucky/issues/1283))
([#1315](https://github.com/LucasSantana-Dev/Lucky/issues/1315))
([7413a1c](https://github.com/LucasSantana-Dev/Lucky/commit/7413a1cebe733cd62f583ed197cd3bba50428e82))
* **security:** collect CSP violations via report-uri sink
([#1283](https://github.com/LucasSantana-Dev/Lucky/issues/1283))
([#1415](https://github.com/LucasSantana-Dev/Lucky/issues/1415))
([6f68aa3](https://github.com/LucasSantana-Dev/Lucky/commit/6f68aa31b8d9a9582e36de85c77e32d58d8adfd5))
* service announce endpoint with timing-safe key + channel allowlist
([#1681](https://github.com/LucasSantana-Dev/Lucky/issues/1681))
([3fbf022](https://github.com/LucasSantana-Dev/Lucky/commit/3fbf02256d8aed9fb4df067dcba7d87389317acb))
* **settings:** add Discord role management page (CRUD + bulk-delete)
([#1524](https://github.com/LucasSantana-Dev/Lucky/issues/1524))
([7db3ca2](https://github.com/LucasSantana-Dev/Lucky/commit/7db3ca240dba8906cb2247266c806c1a178c58fe))
* **shared:** add reactionroles executor (capture/diff/apply)
([142882c](https://github.com/LucasSantana-Dev/Lucky/commit/142882cbe8cc23e12c6c183abd965d25231e1d4c))
* **shared:** support report foundation
([#1223](https://github.com/LucasSantana-Dev/Lucky/issues/1223))
([#1228](https://github.com/LucasSantana-Dev/Lucky/issues/1228))
([77258bc](https://github.com/LucasSantana-Dev/Lucky/commit/77258bc47c26dd58978112882a2793944d0b78e4))
* skip-reason telemetry via emoji reactions on now-playing
([#1377](https://github.com/LucasSantana-Dev/Lucky/issues/1377))
([5b1959f](https://github.com/LucasSantana-Dev/Lucky/commit/5b1959fd96057c396baf17f9929e6a32f9737eed))
* **staging:** opt-in test bot for pre-merge live smoke
([#1692](https://github.com/LucasSantana-Dev/Lucky/issues/1692))
([c54eaba](https://github.com/LucasSantana-Dev/Lucky/commit/c54eabab1525d04297b6241eba7ea979826159b1))
* **twitch:** add stream.offline, channel.update and channel.raid
EventSub events
([#1531](https://github.com/LucasSantana-Dev/Lucky/issues/1531))
([b05a9cf](https://github.com/LucasSantana-Dev/Lucky/commit/b05a9cfeab0fb6e389a70171e5e2264ae8a7577f))
* **twitch:** follower and subscriber role sync
([#1509](https://github.com/LucasSantana-Dev/Lucky/issues/1509))
([d353bc0](https://github.com/LucasSantana-Dev/Lucky/commit/d353bc068614da2310bf50393a3b321842bb8044))
* **ui:** community pages — Starboard and Levels as connected components
([fafa2ac](https://github.com/LucasSantana-Dev/Lucky/commit/fafa2ac225ba6af8c903acfda8bf45abed865606))
* **web:** per-route seo metadata + sitemap, robots, og-image
([79a5f0d](https://github.com/LucasSantana-Dev/Lucky/commit/79a5f0d88e2e9e5102822e9ff34222b280e082c2)),
closes [#1131](https://github.com/LucasSantana-Dev/Lucky/issues/1131)
[#1132](https://github.com/LucasSantana-Dev/Lucky/issues/1132)
* **web:** public /support form + admin report view + error-state wiring
([#1245](https://github.com/LucasSantana-Dev/Lucky/issues/1245))
([19d855e](https://github.com/LucasSantana-Dev/Lucky/commit/19d855e50ce7332280a7ae3e91f9bf8650c5ea21))


### Bug Fixes

* add missing fetch timeouts to GuildService Discord API calls
([#1641](https://github.com/LucasSantana-Dev/Lucky/issues/1641))
([a8a57d5](https://github.com/LucasSantana-Dev/Lucky/commit/a8a57d5b780e900e0fa856804910ef8e3ed67d7a))
* add timeouts to unbounded external fetch calls
([#1333](https://github.com/LucasSantana-Dev/Lucky/issues/1333))
([38dde55](https://github.com/LucasSantana-Dev/Lucky/commit/38dde55fb8631185fed7e3e025d94362fef68e13))
* **api:** wrap automod + moderation settings responses as { settings }
([#1142](https://github.com/LucasSantana-Dev/Lucky/issues/1142))
([04893fd](https://github.com/LucasSantana-Dev/Lucky/commit/04893fd55ef570eca5e8a0682798639a9b1b40e7))
* auth loop between web dashboard and api subdomains
([572e320](https://github.com/LucasSantana-Dev/Lucky/commit/572e320ef803d195a96eb0f66ec42445f73a1931))
* **auth:** log session lookup failures in optional auth
([#1286](https://github.com/LucasSantana-Dev/Lucky/issues/1286))
([ff2b3ab](https://github.com/LucasSantana-Dev/Lucky/commit/ff2b3ab9f3f06dd3b81194f4e3e3f8a113f523f5))
* **automod:** remove dead warn/mute/kick/ban switch cases
([#1511](https://github.com/LucasSantana-Dev/Lucky/issues/1511))
([8ec8ed7](https://github.com/LucasSantana-Dev/Lucky/commit/8ec8ed76cbba1e30442fe17c9f15aa9ccf494dff))
* **autoplay:** capture skip rejections (symmetric completion threshold)
([#1276](https://github.com/LucasSantana-Dev/Lucky/issues/1276))
([c282414](https://github.com/LucasSantana-Dev/Lucky/commit/c282414346bf6c2247ed5d8a22c0c9bfcc5fdeb2))
* **autoplay:** key track start-time per track, not per guild
([#1275](https://github.com/LucasSantana-Dev/Lucky/issues/1275))
([#1483](https://github.com/LucasSantana-Dev/Lucky/issues/1483))
([0853a90](https://github.com/LucasSantana-Dev/Lucky/commit/0853a90412ed64c6e9cec7732311e5648cdb49f1))
* **autoplay:** prevent over-queueing; ensure evicted recs get terminal
events ([#1589](https://github.com/LucasSantana-Dev/Lucky/issues/1589))
([815d763](https://github.com/LucasSantana-Dev/Lucky/commit/815d763329d60580f8034232b606d7d0b2814684))
* **autoplay:** provenance-aware genre guards open the seed neighborhood
([#1272](https://github.com/LucasSantana-Dev/Lucky/issues/1272))
([405af1e](https://github.com/LucasSantana-Dev/Lucky/commit/405af1eae055f661a42310717c39adab6aa220a4))
* **autoplay:** weight popularity over name similarity in similar mode
([#1273](https://github.com/LucasSantana-Dev/Lucky/issues/1273))
([cb24a7e](https://github.com/LucasSantana-Dev/Lucky/commit/cb24a7e9c6993b72be780c72710c524459f591d6))
* **backend:** add validateparams to forums route guildid and slug
([#1602](https://github.com/LucasSantana-Dev/Lucky/issues/1602))
([a7102f4](https://github.com/LucasSantana-Dev/Lucky/commit/a7102f4c5f54405af37d631bfd45506b8cef4615))
* **backend:** assert required env vars at startup and fail fast
([#1169](https://github.com/LucasSantana-Dev/Lucky/issues/1169))
([107e235](https://github.com/LucasSantana-Dev/Lucky/commit/107e235d6b22d7097dd67980b5944ad1bc138c65))
* **backend:** bound pagination limit on leaderboard + starboard entries
([#1307](https://github.com/LucasSantana-Dev/Lucky/issues/1307))
([c2b5cbe](https://github.com/LucasSantana-Dev/Lucky/commit/c2b5cbe2beceb2dc5761f74fb63eda03790de5d7))
* **backend:** degrade gracefully on external fetch timeouts
([#1342](https://github.com/LucasSantana-Dev/Lucky/issues/1342))
([#1345](https://github.com/LucasSantana-Dev/Lucky/issues/1345))
([5de7b69](https://github.com/LucasSantana-Dev/Lucky/commit/5de7b694e7215fd979ef506f66cb7d1f91067249))
* **backend:** enforce discord snowflake validation on all guild routes
([#1172](https://github.com/LucasSantana-Dev/Lucky/issues/1172))
([ec25670](https://github.com/LucasSantana-Dev/Lucky/commit/ec25670ea76a571c96ad20fc4e7df72d9ecf8255))
* **backend:** guard timingsafeequal against length mismatch in lastfm
route ([#1719](https://github.com/LucasSantana-Dev/Lucky/issues/1719))
([6d58671](https://github.com/LucasSantana-Dev/Lucky/commit/6d586711c804be9f66199338330ca0746c4e8fe5))
* **backend:** harden role + reaction-role write-path error handling
([#1543](https://github.com/LucasSantana-Dev/Lucky/issues/1543))
([18a36ba](https://github.com/LucasSantana-Dev/Lucky/commit/18a36ba673ffaa6e5a0f1d35f28bcd62a1c9c64c))
* **backend:** log swallowed spotify search errors
([#1285](https://github.com/LucasSantana-Dev/Lucky/issues/1285))
([#1318](https://github.com/LucasSantana-Dev/Lucky/issues/1318))
([72a7431](https://github.com/LucasSantana-Dev/Lucky/commit/72a74317105f6ae6aedb817344f79bcf0a16b373))
* **backend:** propagate db errors from deleteReactionRoleMessage
([#1604](https://github.com/LucasSantana-Dev/Lucky/issues/1604))
([b36fad0](https://github.com/LucasSantana-Dev/Lucky/commit/b36fad097822dd8013b02e5fd21d2cb536bab317))
* **backend:** replayed named creates return existing row
([#1320](https://github.com/LucasSantana-Dev/Lucky/issues/1320))
([#1326](https://github.com/LucasSantana-Dev/Lucky/issues/1326))
([be2b30c](https://github.com/LucasSantana-Dev/Lucky/commit/be2b30cdb69ad8d94665eb8ae2afb93c325bd5ce))
* **backend:** restrict cors allowlist to first-party hosts
([#1247](https://github.com/LucasSantana-Dev/Lucky/issues/1247))
([6021120](https://github.com/LucasSantana-Dev/Lucky/commit/602112012a2e42b0a0cbb7e5d1d2aa4299d9d7c1))
* **backend:** validate guildId snowflake on all 18 music routes
([#1297](https://github.com/LucasSantana-Dev/Lucky/issues/1297))
([b93cfb5](https://github.com/LucasSantana-Dev/Lucky/commit/b93cfb565288a36bb9c0cbb36640eadb874505d6))
* **backend:** wrap Spotify routes in asyncHandler
([#1184](https://github.com/LucasSantana-Dev/Lucky/issues/1184))
([#1219](https://github.com/LucasSantana-Dev/Lucky/issues/1219))
([a3be33b](https://github.com/LucasSantana-Dev/Lucky/commit/a3be33bceca656ff76325b3a7a10e53e4af83058))
* **batch:** bullmq worker requires maxretriesperrequest null redis
([#1665](https://github.com/LucasSantana-Dev/Lucky/issues/1665))
([f5adffe](https://github.com/LucasSantana-Dev/Lucky/commit/f5adffe8f17df02362ac34d619ad35836706e614))
* **bot:** accurate reply when previous button has no history
([#1191](https://github.com/LucasSantana-Dev/Lucky/issues/1191))
([#1331](https://github.com/LucasSantana-Dev/Lucky/issues/1331))
([eb9b2ea](https://github.com/LucasSantana-Dev/Lucky/commit/eb9b2ea28b1f0581910f73833e09caec41f50f34))
* **bot:** bound all Spotify API fetches with an 8s abort deadline
([#1302](https://github.com/LucasSantana-Dev/Lucky/issues/1302))
([b283159](https://github.com/LucasSantana-Dev/Lucky/commit/b2831594ecc1d456d6f683e89a2b22a996b9beb7))
* **bot:** capture failed error-replies to Sentry in interaction handler
([#1175](https://github.com/LucasSantana-Dev/Lucky/issues/1175))
([45665c2](https://github.com/LucasSantana-Dev/Lucky/commit/45665c2aff006ab26c8c0d6a3e2658df36d66aba))
* **bot:** catch floating promises in setTimeout callbacks
([#1210](https://github.com/LucasSantana-Dev/Lucky/issues/1210))
([#1218](https://github.com/LucasSantana-Dev/Lucky/issues/1218))
([8e790f9](https://github.com/LucasSantana-Dev/Lucky/commit/8e790f95f321da6b6e32206c4d29600dffef9401))
* **bot:** catch resume errors in skip delayed play
([#1353](https://github.com/LucasSantana-Dev/Lucky/issues/1353))
([#1354](https://github.com/LucasSantana-Dev/Lucky/issues/1354))
([c2d2758](https://github.com/LucasSantana-Dev/Lucky/commit/c2d275872fbab168a1e7c603ca415ab3d3284c27))
* **bot:** catch settings fetch errors in idle disconnect scheduling
([#1361](https://github.com/LucasSantana-Dev/Lucky/issues/1361))
([61b82e4](https://github.com/LucasSantana-Dev/Lucky/commit/61b82e4ce2f6f016b22ed5b0f6b672a4da55f0cb))
* **bot:** clear presence rotation interval on shutdown
([#1171](https://github.com/LucasSantana-Dev/Lucky/issues/1171))
([c6d35f5](https://github.com/LucasSantana-Dev/Lucky/commit/c6d35f5dee0a520b31ca51e7d0ad51105c09ad92))
* **bot:** collect /vaga descricao via modal, not a single-line option
([#1701](https://github.com/LucasSantana-Dev/Lucky/issues/1701))
([ba20cd8](https://github.com/LucasSantana-Dev/Lucky/commit/ba20cd8f0857983e0f0765e16cf91722ba568e6c))
* **bot:** dead-man heartbeat + exit on fatal init failure
([#1656](https://github.com/LucasSantana-Dev/Lucky/issues/1656))
([e379f5f](https://github.com/LucasSantana-Dev/Lucky/commit/e379f5f8bd62cfa6173cd514f1c83b5ef2080c65))
* **bot:** expand SoundCloud short links before discord-player
resolution
([#1177](https://github.com/LucasSantana-Dev/Lucky/issues/1177))
([ff84610](https://github.com/LucasSantana-Dev/Lucky/commit/ff84610786cfffbd3c106d168aad475543e32d16))
* **bot:** extend graceful bot-perm guard to mgmt + automod
([#1502](https://github.com/LucasSantana-Dev/Lucky/issues/1502))
([1ee510d](https://github.com/LucasSantana-Dev/Lucky/commit/1ee510dd3773d7f55d5a0b7d7e2be7bc0e027c17))
* **bot:** graceful bot-permission guard + moderation pilot
([#1498](https://github.com/LucasSantana-Dev/Lucky/issues/1498))
([#1499](https://github.com/LucasSantana-Dev/Lucky/issues/1499))
([e2664ce](https://github.com/LucasSantana-Dev/Lucky/commit/e2664ce97b6d99a63521036d3d4b5dbd0a051878))
* **bot:** ground autoplay on seed similarity + genre-condition scoring
([#1268](https://github.com/LucasSantana-Dev/Lucky/issues/1268))
([aeacbc6](https://github.com/LucasSantana-Dev/Lucky/commit/aeacbc61ce2618159d56333c22943777febf2dba))
* **bot:** harden youtube extractor registration
([#1468](https://github.com/LucasSantana-Dev/Lucky/issues/1468))
([#1472](https://github.com/LucasSantana-Dev/Lucky/issues/1472))
([2e7f1bb](https://github.com/LucasSantana-Dev/Lucky/commit/2e7f1bbec46aab6d68d19aa07a4a503027d304bd))
* **bot:** healthcheck gateway readiness instead of redis tcp ping
([#1047](https://github.com/LucasSantana-Dev/Lucky/issues/1047))
([5ce2514](https://github.com/LucasSantana-Dev/Lucky/commit/5ce2514d5fe6b73b8f1c869a63544e7f02977cb1))
* **bot:** lastfm-similar score crushed ~100x by match/100
([#1269](https://github.com/LucasSantana-Dev/Lucky/issues/1269))
([f6bba72](https://github.com/LucasSantana-Dev/Lucky/commit/f6bba729f3943edfb2e370015d93dc4b6a58d83b))
* **bot:** process threadcreate regardless of newlycreated flag
([#1606](https://github.com/LucasSantana-Dev/Lucky/issues/1606))
([be08786](https://github.com/LucasSantana-Dev/Lucky/commit/be08786eeac2b1213a58f1487d7d5b5eba53686a))
* **bot:** queue summary position is milliseconds, not seconds
([#1202](https://github.com/LucasSantana-Dev/Lucky/issues/1202))
([#1330](https://github.com/LucasSantana-Dev/Lucky/issues/1330))
([efa9800](https://github.com/LucasSantana-Dev/Lucky/commit/efa98005cafc9e4cbacfcd8cc7f28b7bd5e26b6e))
* **bot:** reject timeout in session restore race instead of resolving
null ([#1170](https://github.com/LucasSantana-Dev/Lucky/issues/1170))
([2456fb9](https://github.com/LucasSantana-Dev/Lucky/commit/2456fb9bc38c291c870e244e42ebbc26d119acdd))
* **bot:** skip startup session restore into empty voice channel
([#1469](https://github.com/LucasSantana-Dev/Lucky/issues/1469))
([dbcc08c](https://github.com/LucasSantana-Dev/Lucky/commit/dbcc08ce511b0f19b1bc2c490c584113485e59b3))
* **bot:** startup session restore scans postgres, not redis
([#1119](https://github.com/LucasSantana-Dev/Lucky/issues/1119))
([2636ba1](https://github.com/LucasSantana-Dev/Lucky/commit/2636ba1f8b0e379f7c3068778055cb6e643a9b0d))
* **bot:** stop all schedulers/timers on shutdown
([#1197](https://github.com/LucasSantana-Dev/Lucky/issues/1197))
([#1205](https://github.com/LucasSantana-Dev/Lucky/issues/1205))
([7180579](https://github.com/LucasSantana-Dev/Lucky/commit/71805799de105dd1cf33e158c958857035d502cc))
* **bot:** tear down Discord client on initializer step failure
([#1180](https://github.com/LucasSantana-Dev/Lucky/issues/1180))
([d81ac68](https://github.com/LucasSantana-Dev/Lucky/commit/d81ac683a3235a1b3fe39fa39eccb7aa971ce52a))
* **bot:** thread real Client into endGiveaway
([#1383](https://github.com/LucasSantana-Dev/Lucky/issues/1383))
([#1388](https://github.com/LucasSantana-Dev/Lucky/issues/1388))
([d3b274a](https://github.com/LucasSantana-Dev/Lucky/commit/d3b274afa694ae8b35e3052ba8a366afee32d98f))
* **bot:** validate text-based channel before send in embed command
([#1253](https://github.com/LucasSantana-Dev/Lucky/issues/1253))
([5add32f](https://github.com/LucasSantana-Dev/Lucky/commit/5add32f7e4d88164b89fe73e7ea8c9dcaf17f909))
* **bot:** wire role exclusion enforcement + guildmembers intent
([#1668](https://github.com/LucasSantana-Dev/Lucky/issues/1668))
([e8145af](https://github.com/LucasSantana-Dev/Lucky/commit/e8145afe9f4765b927b077d3df471a2280087e14))
* **bot:** wire setupwebmusichandler at startup
([#1321](https://github.com/LucasSantana-Dev/Lucky/issues/1321))
([#1351](https://github.com/LucasSantana-Dev/Lucky/issues/1351))
([dc68e7e](https://github.com/LucasSantana-Dev/Lucky/commit/dc68e7efce26598161380c60bedb1a728a72748d))
* bound external calls — Discord-429 storm + Musical-Taste hang
([#1141](https://github.com/LucasSantana-Dev/Lucky/issues/1141))
([739d653](https://github.com/LucasSantana-Dev/Lucky/commit/739d653271a12b5a278d141545c3b5618f39f50c))
* bound music queue params, type rolegroup mapping, harden ci lint
([#1588](https://github.com/LucasSantana-Dev/Lucky/issues/1588))
([309d5d9](https://github.com/LucasSantana-Dev/Lucky/commit/309d5d9c9bbb04d2362fd0fe65e2db0f677169c1))
* **ci:** add bot to required containers and replace dead unhealthy grep
([#1054](https://github.com/LucasSantana-Dev/Lucky/issues/1054))
([b16109e](https://github.com/LucasSantana-Dev/Lucky/commit/b16109ee1de691d9d1bac69ade0168a9a69b0a75))
* **ci:** add figurinhas2026 to Vercel deploy watch
([#1063](https://github.com/LucasSantana-Dev/Lucky/issues/1063))
([b3f5e64](https://github.com/LucasSantana-Dev/Lucky/commit/b3f5e6465be5a77222ad9eccb109c2df7c169a94))
* **ci:** archive squash-merged release branch instead of failing FF
([#946](https://github.com/LucasSantana-Dev/Lucky/issues/946))
([111e860](https://github.com/LucasSantana-Dev/Lucky/commit/111e860a9efa24590ee89e975da4ab7886aaacaf))
* **ci:** cf pages deploy uses root lockfile (stops silent failure)
([#1673](https://github.com/LucasSantana-Dev/Lucky/issues/1673))
([8824fc3](https://github.com/LucasSantana-Dev/Lucky/commit/8824fc377e17bd4938b8af7d21050b2aa47b4982))
* **ci:** danger node 24 compatibility
([#1659](https://github.com/LucasSantana-Dev/Lucky/issues/1659))
([862426a](https://github.com/LucasSantana-Dev/Lucky/commit/862426a32f7d786644a02c8bde5a4c5d1e6bb6e8))
* **ci:** grant review-tools caller the scopes its reusables require
([#1424](https://github.com/LucasSantana-Dev/Lucky/issues/1424))
([c215675](https://github.com/LucasSantana-Dev/Lucky/commit/c2156759754ed65cfecb8f8fa9b25f5347522f5c))
* **ci:** hard-fail deploy on sustained 429 instead of silent oauth pass
([#1045](https://github.com/LucasSantana-Dev/Lucky/issues/1045))
([2a6b05c](https://github.com/LucasSantana-Dev/Lucky/commit/2a6b05ccaad42dbade7b4ae374e27f8661b9ac0b))
* **ci:** lockfile-hash BuildKit npm cache key to prevent esbuild
version mismatch
([#1016](https://github.com/LucasSantana-Dev/Lucky/issues/1016))
([1b3c258](https://github.com/LucasSantana-Dev/Lucky/commit/1b3c2584baf7a9361da89bf911267ca6876ff667))
* **ci:** lockfile-hash BuildKit npm cache key to prevent esbuild
version mismatch
([#1065](https://github.com/LucasSantana-Dev/Lucky/issues/1065))
([3579966](https://github.com/LucasSantana-Dev/Lucky/commit/35799666b5acc8f90b109eef03757912d192379a))
* **ci:** lockfile-hash BuildKit npm cache key to prevent esbuild
version mismatch
([#1067](https://github.com/LucasSantana-Dev/Lucky/issues/1067))
([7c5c447](https://github.com/LucasSantana-Dev/Lucky/commit/7c5c447ebb128b2ea2cb4bc717c3a3d1d8a56c6c))
* **ci:** lockfile-hash BuildKit npm cache key to prevent esbuild
version mismatch
([#1075](https://github.com/LucasSantana-Dev/Lucky/issues/1075))
([00ee269](https://github.com/LucasSantana-Dev/Lucky/commit/00ee26962d35622af8bcaeb7a84f79bddb7ce5d8))
* **ci:** lowercase image ref in yt-dlp smoke test
([e6267f5](https://github.com/LucasSantana-Dev/Lucky/commit/e6267f516dc50c417be6cbebdfe1d9b1358368c0))
* **ci:** lowercase image ref in yt-dlp smoke test
([ccb2855](https://github.com/LucasSantana-Dev/Lucky/commit/ccb2855745d1640c5a75a2aaebdc1fd61605578a))
* **ci:** make husky optional in prepare script to unblock docker builds
([#1060](https://github.com/LucasSantana-Dev/Lucky/issues/1060))
([9bf7c0e](https://github.com/LucasSantana-Dev/Lucky/commit/9bf7c0e91e671eb1347d37d1265d6a2beb376d68))
* **ci:** pin GitHub Actions to commit SHAs, scope secrets, harden
Renovate
([#1706](https://github.com/LucasSantana-Dev/Lucky/issues/1706))
([1239e28](https://github.com/LucasSantana-Dev/Lucky/commit/1239e286df0e222f4a0b39f328c622901a96f916))
* **ci:** post error commit status on deploy lock contention
([#1052](https://github.com/LucasSantana-Dev/Lucky/issues/1052))
([869d6f0](https://github.com/LucasSantana-Dev/Lucky/commit/869d6f03eae0f807befa1f712ec3a4e6c422aa9d))
* **ci:** quality/Lint green again — core rules off for bot/shared at
root lint
([#1364](https://github.com/LucasSantana-Dev/Lucky/issues/1364))
([#1365](https://github.com/LucasSantana-Dev/Lucky/issues/1365))
([cc2322f](https://github.com/LucasSantana-Dev/Lucky/commit/cc2322f0ed999ffe1aabd341b1371260ace718d5))
* **ci:** scope docker build cache per matrix service
([#1712](https://github.com/LucasSantana-Dev/Lucky/issues/1712))
([3ed9aae](https://github.com/LucasSantana-Dev/Lucky/commit/3ed9aaec6e93ec713144427d2e8290300e214c15))
* **ci:** skip docker-build validation for non-docker-relevant PRs
([#1711](https://github.com/LucasSantana-Dev/Lucky/issues/1711))
([5ea19ea](https://github.com/LucasSantana-Dev/Lucky/commit/5ea19eabf162c7ab82a1bd242979df8d8354156e))
* **ci:** surface async deploy failures via commit statuses
([#1046](https://github.com/LucasSantana-Dev/Lucky/issues/1046))
([b0838ac](https://github.com/LucasSantana-Dev/Lucky/commit/b0838aca3cd3f7d69024619c4eb37eecea337b7f))
* **ci:** use v-prefixed trivy-action tag
([#934](https://github.com/LucasSantana-Dev/Lucky/issues/934))
([ffae3cf](https://github.com/LucasSantana-Dev/Lucky/commit/ffae3cfbb0941c6ca16a8bf387511c811cd6ed82))
* **codeql:** resolve open codeql alerts
([0e0dfbe](https://github.com/LucasSantana-Dev/Lucky/commit/0e0dfbe5c027788dcc94953a67b52bbe93cc952b))
* **compose:** tag container logs so loki labels them by name
([#1476](https://github.com/LucasSantana-Dev/Lucky/issues/1476))
([4e956df](https://github.com/LucasSantana-Dev/Lucky/commit/4e956dfaad3ab88ea4d7d1f2db5874b3535f4cdd))
* **deploy:** derive require_running_containers from docker compose
([#1601](https://github.com/LucasSantana-Dev/Lucky/issues/1601))
([5715249](https://github.com/LucasSantana-Dev/Lucky/commit/571524924f2efe0cd7b5ab0d990631a86f220378))
* **deploy:** persist last-good across deploys (gitignore it)
([#1234](https://github.com/LucasSantana-Dev/Lucky/issues/1234))
([44f6487](https://github.com/LucasSantana-Dev/Lucky/commit/44f6487bf6fad06c4bcab3f688feb7f974696719))
* **deploy:** pin to short image tag; never build under a pinned tag
([#1232](https://github.com/LucasSantana-Dev/Lucky/issues/1232))
([d874d59](https://github.com/LucasSantana-Dev/Lucky/commit/d874d59bf8bb49588c08c51226975cc80b8827b3))
* **deploy:** probe nginx health on container port 8080 not 80
([#1236](https://github.com/LucasSantana-Dev/Lucky/issues/1236))
([918689d](https://github.com/LucasSantana-Dev/Lucky/commit/918689dc29c7bd7163caa5bec2b0336cb508fd43))
* **deploy:** read webhook hooks.json from live directory mount
([#1231](https://github.com/LucasSantana-Dev/Lucky/issues/1231))
([e559f42](https://github.com/LucasSantana-Dev/Lucky/commit/e559f4260bf115400ecde124b6406275e42fd888))
* **deploy:** record auto-rollback last-good from image commit-sha
([#1235](https://github.com/LucasSantana-Dev/Lucky/issues/1235))
([9cc21e7](https://github.com/LucasSantana-Dev/Lucky/commit/9cc21e76d49a8fb0f3ea74a73ce7dcf59f460861))
* **deploy:** ship prisma cli in production images + unify esbuild
([#1080](https://github.com/LucasSantana-Dev/Lucky/issues/1080))
([8e422b3](https://github.com/LucasSantana-Dev/Lucky/commit/8e422b391dd939f12abf9dea5ab2501cd5777968))
* **deploy:** verify + cache-correct the frontend so deploys actually
reach users
([#1576](https://github.com/LucasSantana-Dev/Lucky/issues/1576))
([9178576](https://github.com/LucasSantana-Dev/Lucky/commit/9178576c2c3d9b2743b5417f2516f6d9208cacd8))
* **deploy:** wire GITHUB_DEPLOY_STATUS_TOKEN into lucky-webhook
container
([#1597](https://github.com/LucasSantana-Dev/Lucky/issues/1597))
([ad4b7ed](https://github.com/LucasSantana-Dev/Lucky/commit/ad4b7ed32a66ab945ed610333a58131379b7cc08))
* **deps:** bump multer to 2.2.0 to fix high-severity dos advisory
([#1493](https://github.com/LucasSantana-Dev/Lucky/issues/1493))
([4d57ac8](https://github.com/LucasSantana-Dev/Lucky/commit/4d57ac87b0b016ffd8d79306c0705f1294c9a37a))
* **deps:** bump qs to 6.15.2 and hono to 4.12.25 (audit)
([#1295](https://github.com/LucasSantana-Dev/Lucky/issues/1295))
([ae5d949](https://github.com/LucasSantana-Dev/Lucky/commit/ae5d949c2f756eb554a24621c952cd8021b7a580))
* **deps:** pin piscina 4.9.3 for high-severity rce advisory
([#1504](https://github.com/LucasSantana-Dev/Lucky/issues/1504))
([10b68e6](https://github.com/LucasSantana-Dev/Lucky/commit/10b68e6597bae7c39286662293f1587780df0a30))
* **deps:** resolve npm audit vulnerabilities (1 critical + 5 moderate)
([#1708](https://github.com/LucasSantana-Dev/Lucky/issues/1708))
([e2b07bf](https://github.com/LucasSantana-Dev/Lucky/commit/e2b07bfece040e3f65bf0e62ff5a7565b93b670d))
* **docker:** add C toolchain to deps-production for opus source-build
fallback
([#1310](https://github.com/LucasSantana-Dev/Lucky/issues/1310))
([5ed7f11](https://github.com/LucasSantana-Dev/Lucky/commit/5ed7f11e0747eef6f303d1aa8f3f1fe8889eb351))
* **docker:** bump npm to patch bundled undici/tar CVEs in base image
([#1709](https://github.com/LucasSantana-Dev/Lucky/issues/1709))
([a635a0c](https://github.com/LucasSantana-Dev/Lucky/commit/a635a0c33c77ff99cd27369d3a8398ea51cc96de))
* **docker:** copy CHANGELOG.md into frontend build context
([#937](https://github.com/LucasSantana-Dev/Lucky/issues/937))
([44f302e](https://github.com/LucasSantana-Dev/Lucky/commit/44f302e3faf8fd448558660e964ac93aaf5ef88f))
* **download:** drop invalid --extract-flat flag from yt-dlp download
([#1488](https://github.com/LucasSantana-Dev/Lucky/issues/1488))
([9d29144](https://github.com/LucasSantana-Dev/Lucky/commit/9d291441d59ce7a01e717ad04f6844ac3d8b7947))
* **frontend:** default add-to-discord cta to public application id
([#1495](https://github.com/LucasSantana-Dev/Lucky/issues/1495))
([efda71e](https://github.com/LucasSantana-Dev/Lucky/commit/efda71e38c7152abb0d5fca2a708cbe960720ec4))
* **frontend:** fix CF Pages API routing and remove Vercel Analytics
([#1596](https://github.com/LucasSantana-Dev/Lucky/issues/1596))
([2902984](https://github.com/LucasSantana-Dev/Lucky/commit/2902984146f090eca210149eb84ea6e593c40747))
* **frontend:** flush moderation empty state (stray dark band)
([#1693](https://github.com/LucasSantana-Dev/Lucky/issues/1693))
([c64041a](https://github.com/LucasSantana-Dev/Lucky/commit/c64041a9e5aa25d411ad5115cfa0038d779a693b))
* **frontend:** healthcheck uses busybox wget, not bash /dev/tcp
([#1106](https://github.com/LucasSantana-Dev/Lucky/issues/1106))
([ec7a449](https://github.com/LucasSantana-Dev/Lucky/commit/ec7a449140eb53be135db321d0b9ca8274aafd30))
* guard unsafe external API response handling
([#1207](https://github.com/LucasSantana-Dev/Lucky/issues/1207))
([#1217](https://github.com/LucasSantana-Dev/Lucky/issues/1217))
([3b26b72](https://github.com/LucasSantana-Dev/Lucky/commit/3b26b7279312643523533d945ee0d2e85d7b9337))
* **help:** split large command categories across embed fields
([#1489](https://github.com/LucasSantana-Dev/Lucky/issues/1489))
([0fa5786](https://github.com/LucasSantana-Dev/Lucky/commit/0fa578646fe0671eda85eb6b36db076c6e0fafb1))
* **infra:** route staging via host port
([#1548](https://github.com/LucasSantana-Dev/Lucky/issues/1548))
([fe5b153](https://github.com/LucasSantana-Dev/Lucky/commit/fe5b153b2ebadbfaf20f67c95e964f3f06d443fe))
* **infra:** staging deploy git ownership
([#1554](https://github.com/LucasSantana-Dev/Lucky/issues/1554))
([de5a322](https://github.com/LucasSantana-Dev/Lucky/commit/de5a3220dac6bd517280405c69097eaca8885380))
* **infra:** staging deploy health check
([#1556](https://github.com/LucasSantana-Dev/Lucky/issues/1556))
([fda6eea](https://github.com/LucasSantana-Dev/Lucky/commit/fda6eea11e2da3f215538850445d4b9dcfd9e394))
* **logs:** serialize server logs with level, message and actor
([#1677](https://github.com/LucasSantana-Dev/Lucky/issues/1677))
([acd8fe3](https://github.com/LucasSantana-Dev/Lucky/commit/acd8fe31493931cd1cba5e93ed46d93bd35fe514))
* **middleware:** resolve guildAccess non-atomic session+context
staleness window
([5a64dd1](https://github.com/LucasSantana-Dev/Lucky/commit/5a64dd17bb1d9143c82eee49821c38e75a7f13ab))
* **moderation:** route context menus in the live event handler
([#1517](https://github.com/LucasSantana-Dev/Lucky/issues/1517))
([0232237](https://github.com/LucasSantana-Dev/Lucky/commit/0232237d9912dac9281b2e53902c4487542b98ce))
* **music:** re-target music guild FKs to discordId
([#1270](https://github.com/LucasSantana-Dev/Lucky/issues/1270))
([765d9d8](https://github.com/LucasSantana-Dev/Lucky/commit/765d9d81d2b3e776b24d70e8089056f010dd6351))
* **music:** surface youtube unavailability instead of generic errors
([#1146](https://github.com/LucasSantana-Dev/Lucky/issues/1146))
([0e66fe2](https://github.com/LucasSantana-Dev/Lucky/commit/0e66fe2e2f7f70dcdabb81e18a25cff0bdf32a50))
* **player:** warn not error on bridge exhaustion for unplayable tracks
([#1507](https://github.com/LucasSantana-Dev/Lucky/issues/1507))
([d7a4a58](https://github.com/LucasSantana-Dev/Lucky/commit/d7a4a5885ffa74fe5cbf22819df08a4dbc53e729))
* **play:** isolate post-play background ops
([#1085](https://github.com/LucasSantana-Dev/Lucky/issues/1085))
([#1101](https://github.com/LucasSantana-Dev/Lucky/issues/1101))
([ba994c4](https://github.com/LucasSantana-Dev/Lucky/commit/ba994c428253737826bbd10540112714cc0d4c6f))
* **reaction-roles:** PUT panel edit deletes mappings by cuid not
snowflake
([#1675](https://github.com/LucasSantana-Dev/Lucky/issues/1675))
([#1676](https://github.com/LucasSantana-Dev/Lucky/issues/1676))
([a51c70f](https://github.com/LucasSantana-Dev/Lucky/commit/a51c70f77dac207c5c76c8b1155f77a033a5e04b))
* **reaction-roles:** validate roleIds, fix update rollback, serialize
concurrent appends
([#1587](https://github.com/LucasSantana-Dev/Lucky/issues/1587))
([6873ac8](https://github.com/LucasSantana-Dev/Lucky/commit/6873ac8d398aa26f50d6a204d7d1de83557a402e))
* **release:** set group-pull-request-title-pattern so releases auto-tag
([#1521](https://github.com/LucasSantana-Dev/Lucky/issues/1521))
([b0e0f5f](https://github.com/LucasSantana-Dev/Lucky/commit/b0e0f5f40497c4be98135acb66b24a79e6763df2))
* **release:** set pull-request-title-pattern to include version
([#1514](https://github.com/LucasSantana-Dev/Lucky/issues/1514))
([cde12ec](https://github.com/LucasSantana-Dev/Lucky/commit/cde12ecc9881b1ca496fb0112e98d3bae2910c8e))
* **release:** tag-guard reconciles autorelease label
([#1561](https://github.com/LucasSantana-Dev/Lucky/issues/1561))
([#1583](https://github.com/LucasSantana-Dev/Lucky/issues/1583))
([6505f44](https://github.com/LucasSantana-Dev/Lucky/commit/6505f446b55fd2eb5ca5c87c5d105f2da975e28c))
* resolve discord 429 rate-limit storm and archived thread crash
([#1078](https://github.com/LucasSantana-Dev/Lucky/issues/1078))
([e79858e](https://github.com/LucasSantana-Dev/Lucky/commit/e79858ec7505b441bf538e7c38452476bd3f78f1))
* resolve Prettier syntax error in queueManipulation.spec.ts
([#985](https://github.com/LucasSantana-Dev/Lucky/issues/985))
([7cf4c83](https://github.com/LucasSantana-Dev/Lucky/commit/7cf4c83ee45da7ade4559957ff7a707a3b15871a))
* **schema:** add unique guild+thread constraint to GuildForumThread
([#1607](https://github.com/LucasSantana-Dev/Lucky/issues/1607))
([6c4c8ab](https://github.com/LucasSantana-Dev/Lucky/commit/6c4c8ab9a7488149dece8f486160ca3125d17a4e))
* **security:** bump vite 8.0.16 + form-data 4.0.6 for high advisories
([#1457](https://github.com/LucasSantana-Dev/Lucky/issues/1457))
([58d21d5](https://github.com/LucasSantana-Dev/Lucky/commit/58d21d56ad437bb5526dd5dcc9e5af3603d4b310))
* **security:** pass staging webhook secret via env not argv
([#1600](https://github.com/LucasSantana-Dev/Lucky/issues/1600))
([d12efc5](https://github.com/LucasSantana-Dev/Lucky/commit/d12efc519570026cf9a6f1b075d57b99d41898e2))
* **security:** redact operational diagnostics from
/api/health/auth-config
([#1710](https://github.com/LucasSantana-Dev/Lucky/issues/1710))
([e1b6b61](https://github.com/LucasSantana-Dev/Lucky/commit/e1b6b61c493eabd4d633d9600c46ad29a3ffc781))
* **security:** redact secrets/PII from logs
([#1208](https://github.com/LucasSantana-Dev/Lucky/issues/1208))
([#1220](https://github.com/LucasSantana-Dev/Lucky/issues/1220))
([2a09f90](https://github.com/LucasSantana-Dev/Lucky/commit/2a09f900c87e9ca1ef8c50a5ece6b1d7eecbc11e))
* **security:** resolve CodeQL/Semgrep findings (XSS, cookie, log
injection, nginx headers)
([#1707](https://github.com/LucasSantana-Dev/Lucky/issues/1707))
([3a30135](https://github.com/LucasSantana-Dev/Lucky/commit/3a301358d7cae1091bcbb79a1ff17c638317e641))
* **security:** verify bot authorship before trusting slug marker
([#1599](https://github.com/LucasSantana-Dev/Lucky/issues/1599))
([23bf73a](https://github.com/LucasSantana-Dev/Lucky/commit/23bf73a3e7db054d63ab7faea60db66124fbbfe9))
* **shared:** drop buggy token-overlap util + optimize levenshtein
([#1246](https://github.com/LucasSantana-Dev/Lucky/issues/1246))
([5b65d47](https://github.com/LucasSantana-Dev/Lucky/commit/5b65d4768f0e3bf19ca9e211957ce2fec07ef4f6))
* **shared:** env-isolate environment.test.ts (no secret dumps)
([#1292](https://github.com/LucasSantana-Dev/Lucky/issues/1292))
([588037c](https://github.com/LucasSantana-Dev/Lucky/commit/588037cf8b3a7424ad922b15d28aeb8548eb082e))
* **shared:** export ./utils/monitoring subpath — fixes lucky-bot
crash-loop
([#1105](https://github.com/LucasSantana-Dev/Lucky/issues/1105))
([2c959f3](https://github.com/LucasSantana-Dev/Lucky/commit/2c959f3d9765acdedab969faaaa229869a657ded))
* **shared:** export config/* subpath for prod esm resolution
([#1250](https://github.com/LucasSantana-Dev/Lucky/issues/1250))
([f4167a8](https://github.com/LucasSantana-Dev/Lucky/commit/f4167a80f2b78a693e9aacf5744358137e400f17))
* **shared:** export utils/support subpath for prod esm resolution
([#1248](https://github.com/LucasSantana-Dev/Lucky/issues/1248))
([8d3c092](https://github.com/LucasSantana-Dev/Lucky/commit/8d3c09265997e360e050d9006b55e12c8320abf3))
* **shared:** guard JSON.parse on embed data in CustomCommandService
([#1168](https://github.com/LucasSantana-Dev/Lucky/issues/1168))
([1c46b55](https://github.com/LucasSantana-Dev/Lucky/commit/1c46b557d7bcd5c847aca14c0562cae8a9bb77a0))
* **shared:** log db error in feature-toggle override read
([#1286](https://github.com/LucasSantana-Dev/Lucky/issues/1286))
([#1411](https://github.com/LucasSantana-Dev/Lucky/issues/1411))
([0dfc409](https://github.com/LucasSantana-Dev/Lucky/commit/0dfc4091c1e688569f656851b39f06716eecb4a0))
* **shared:** make LevelService.addXP atomic to prevent lost XP under
concurrency
([#1178](https://github.com/LucasSantana-Dev/Lucky/issues/1178))
([d1edffe](https://github.com/LucasSantana-Dev/Lucky/commit/d1edffe1c410b7393e184c796edeec83e4a17cae))
* **shared:** make read-then-write service paths atomic
([#1199](https://github.com/LucasSantana-Dev/Lucky/issues/1199))
([#1340](https://github.com/LucasSantana-Dev/Lucky/issues/1340))
([ba1b840](https://github.com/LucasSantana-Dev/Lucky/commit/ba1b840accb4858837c0b46e8018b4d1bcd53291))
* **shared:** normalize embed template name on gettemplate
([#1327](https://github.com/LucasSantana-Dev/Lucky/issues/1327))
([#1350](https://github.com/LucasSantana-Dev/Lucky/issues/1350))
([d221b57](https://github.com/LucasSantana-Dev/Lucky/commit/d221b577db03473f0930747362c65861aae501fa))
* **shared:** safe env parsing via parseIntEnv helper
([#1209](https://github.com/LucasSantana-Dev/Lucky/issues/1209))
([#1335](https://github.com/LucasSantana-Dev/Lucky/issues/1335))
([32e3684](https://github.com/LucasSantana-Dev/Lucky/commit/32e36849ac0b8c9b3e839fc24a97f1f6c1972376))
* **shared:** surface Redis client init errors instead of silent swallow
([#1176](https://github.com/LucasSantana-Dev/Lucky/issues/1176))
([157c14e](https://github.com/LucasSantana-Dev/Lucky/commit/157c14ec558a5fffd54e34400eb6a0b02a5a2763))
* **shared:** validate EmbedData shape with Zod before storing custom
commands
([#1179](https://github.com/LucasSantana-Dev/Lucky/issues/1179))
([7419b0e](https://github.com/LucasSantana-Dev/Lucky/commit/7419b0e1f4a4547b8a019c184fe63a41c2dcb017))
* **shared:** validate guildautomation json on read
([#1194](https://github.com/LucasSantana-Dev/Lucky/issues/1194))
([#1346](https://github.com/LucasSantana-Dev/Lucky/issues/1346))
([93d9eea](https://github.com/LucasSantana-Dev/Lucky/commit/93d9eea104c989485b125eb2de494a8032c2f6b4))
* **shared:** wrap ModerationService.createCase in transaction to
prevent duplicate case numbers
([#1167](https://github.com/LucasSantana-Dev/Lucky/issues/1167))
([be52580](https://github.com/LucasSantana-Dev/Lucky/commit/be5258049b6826c4a7141d4b00a8b6f6777d332e))
* **sonar:** clear main reliability gate - s1244 and tailwind v4 fps
([#1671](https://github.com/LucasSantana-Dev/Lucky/issues/1671))
([c12059d](https://github.com/LucasSantana-Dev/Lucky/commit/c12059dfc059db1915706723659812b088c5f34c))
* **spotify:** log oauth token-exchange failures
([#1286](https://github.com/LucasSantana-Dev/Lucky/issues/1286) track b)
([8306c35](https://github.com/LucasSantana-Dev/Lucky/commit/8306c35b19587d5b59e8092c0e245a2ed087b658))
* **telemetry:** un-silence skip-reason emoji prefill errors
([#1660](https://github.com/LucasSantana-Dev/Lucky/issues/1660))
([5eabbd2](https://github.com/LucasSantana-Dev/Lucky/commit/5eabbd2bad04ee92885766ba7184219ea17e5758))
* **test:** close open handles causing jest force-exit in bot suite
([#1605](https://github.com/LucasSantana-Dev/Lucky/issues/1605))
([cf2a026](https://github.com/LucasSantana-Dev/Lucky/commit/cf2a026d4852e2889eb18e1a0ce2389d73da3333))
* **twitch:** add debug logging for skipped channel notifications
([#947](https://github.com/LucasSantana-Dev/Lucky/issues/947))
([0dcf1c2](https://github.com/LucasSantana-Dev/Lucky/commit/0dcf1c2e5c32cda64f80e21f20a9e888715f6ca8))
* **twitch:** re-subscribe to EventSub after unexpected reconnect
([#870](https://github.com/LucasSantana-Dev/Lucky/issues/870))
([#1395](https://github.com/LucasSantana-Dev/Lucky/issues/1395))
([78a30f3](https://github.com/LucasSantana-Dev/Lucky/commit/78a30f31b9e97bd9e5fe86397ce5bdca272c0c10))
* **twitch:** refresh bot subscriptions on web add/remove
([#870](https://github.com/LucasSantana-Dev/Lucky/issues/870))
([939d4b3](https://github.com/LucasSantana-Dev/Lucky/commit/939d4b3721158d0c52c2f9c7944709baf38d35c0))
* **ui:** address CodeRabbit findings on
[#856](https://github.com/LucasSantana-Dev/Lucky/issues/856)
([56f2c82](https://github.com/LucasSantana-Dev/Lucky/commit/56f2c823eeec6bf2d468595fec509284b31e82da))
* **web:** clear auth check promise on settle, not via 100ms timer
([#1311](https://github.com/LucasSantana-Dev/Lucky/issues/1311))
([5cc8eef](https://github.com/LucasSantana-Dev/Lucky/commit/5cc8eefd7d83a5319175b056616ffe097a031299))
* **web:** GuildAutomation error state when both fetches reject
([#1144](https://github.com/LucasSantana-Dev/Lucky/issues/1144))
([f789aa3](https://github.com/LucasSantana-Dev/Lucky/commit/f789aa3e0e110958a0d56230c8273caaca4e6a85))
* **web:** language dropdown switches app language via radio group
([d4fdd98](https://github.com/LucasSantana-Dev/Lucky/commit/d4fdd9880f1246eb985b1214899302eb7b115192))
* **web:** relabel landing RepoCard stats to real servers/users
([#1145](https://github.com/LucasSantana-Dev/Lucky/issues/1145))
([2d63983](https://github.com/LucasSantana-Dev/Lucky/commit/2d6398374f9f0081575992d978c7f57f22005858))
* **web:** remove dead featuresStore toggle code + rollback on failure
([#1147](https://github.com/LucasSantana-Dev/Lucky/issues/1147))
([f8697fb](https://github.com/LucasSantana-Dev/Lucky/commit/f8697fb36532a76f5106dd0fb1bc9d13e5351c71))
* **web:** report swallowed member-context fetch error to Sentry
([#1286](https://github.com/LucasSantana-Dev/Lucky/issues/1286) B3)
([#1416](https://github.com/LucasSantana-Dev/Lucky/issues/1416))
([85f141d](https://github.com/LucasSantana-Dev/Lucky/commit/85f141d7926ef9eeec4a1195dda9702df25d7c02))
* **web:** route handled errors to Sentry, enforce no-console
([#1296](https://github.com/LucasSantana-Dev/Lucky/issues/1296))
([a34e777](https://github.com/LucasSantana-Dev/Lucky/commit/a34e777d1627ad3a2715b49f211c4b7bd3e74266))
* **web:** surface swallowed fetch errors instead of silent catch
([#1254](https://github.com/LucasSantana-Dev/Lucky/issues/1254))
([6afb0cd](https://github.com/LucasSantana-Dev/Lucky/commit/6afb0cd4f1a81f5c5e1616c7925c7bc75b9524b6))


### Performance Improvements

* **bot:** bound autoplay Maps + parallelize replenisher awaits
([#1215](https://github.com/LucasSantana-Dev/Lucky/issues/1215))
([1e55afa](https://github.com/LucasSantana-Dev/Lucky/commit/1e55afa125acbb60f0b1d28ff9c168a5e32b8ead))
* **bot:** bound external scrobbler track cache with lru+ttl
([#1282](https://github.com/LucasSantana-Dev/Lucky/issues/1282))
([#1316](https://github.com/LucasSantana-Dev/Lucky/issues/1316))
([7f29efc](https://github.com/LucasSantana-Dev/Lucky/commit/7f29efce0ea9ad0b6ad1dff6edfae57d4f15b2f8))
* bound unbounded findMany queries
([#1206](https://github.com/LucasSantana-Dev/Lucky/issues/1206))
([#1214](https://github.com/LucasSantana-Dev/Lucky/issues/1214))
([cdc0082](https://github.com/LucasSantana-Dev/Lucky/commit/cdc0082b64f407c313850e00864055b669bec3d8))
* **shared:** batch recommendation telemetry counts in one groupBy
([#1308](https://github.com/LucasSantana-Dev/Lucky/issues/1308))
([e5a5973](https://github.com/LucasSantana-Dev/Lucky/commit/e5a5973d9c25d5926ab576b13265fe05c2d87032))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Release 2.33.0 ships smarter autoplay, new role management in the
dashboard, better moderation and Twitch integrations, and stronger
observability/security. It also includes wide-ranging fixes and
performance improvements across bot, backend, and web.

- **New Features**
- Autoplay scoring upgrades: implicit dislike penalty, recency decay,
replay boost, and evaluation harness.
- Dashboard: role groups and reaction roles management with editor
(emoji picker, media, import/export).
- Moderation and guild tools: move message via context menu, batch
operations (bulk move), AFK, reminders, giveaways, smart custom
commands, starboard seeding.
- Integrations: Twitch follower/subscriber role sync and new EventSub
events; RSS bridge and weekly digest.
- Backend/Web: support intake with admin views, Postgres session store,
server logs/settings pages, previous-track command, per-route SEO and
sitemap.
- Observability/Security: request-id correlation, deploy markers/alerts,
CSP headers and violation collection.

- **Bug Fixes**
- Timeouts and guardrails on external calls with graceful degradation;
mitigations for Discord 429 storms.
- Hardening for reaction roles, role writes, guild route validation,
JSON parsing, and DB constraints; atomic write paths.
- Bot stability: safer session restore and shutdown, extractor
registration, clearer YouTube errors, accurate previous button replies.
- CI/CD and deploy reliability: SHA-pinned deploys, health probes, cache
correctness, pinned actions, verified frontend caching.
- Security: dependency updates, redacted logs/health output, and
CodeQL/Semgrep findings resolved.

<sup>Written for commit 22727a164df9bd407b3493dd3459ca46984664c4.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/LucasSantana-Dev/Lucky/pull/1733?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added release notes for version 2.33.0, highlighting new features, bug
fixes, and performance improvements.
* **Chores**
  * Updated the project version to 2.33.0.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

fix(batch): batch job worker fails to start in prod v2.26.0 — BullMQ requires redis maxRetriesPerRequest: null

1 participant