chore(backend): take the bullmq, jwks-rsa and escape-string-regexp majors - #2188
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…jors Three dependabot major bumps that each needed a code change to land, taken together because they all touch apps/backend and each one on its own branch re-conflicted the others on pnpm-lock.yaml. bullmq 5 to 6 removed `repeat` from JobsOptions. It is ignored rather than rejected, so the seven recurring registrations would have gone quiet without any error. All seven moved to Queue.upsertJobScheduler, keeping their existing ids and intervals so a deploy does not stack duplicates. The five schedulers that had no test now have one. escape-string-regexp went ESM only at v5 and this backend compiles to CommonJS, so requiring it throws at runtime. The dependency is replaced by a local helper matching 5.0.0 exactly, including the \x2d form for a hyphen that Unicode-mode patterns require. jwks-rsa 3 to 4 pulls jose 6, which is ESM only. Jest now transforms it.
ankit-yc
force-pushed
the
chore/dependency-majors
branch
from
August 14, 2026 22:58
aa87ce9 to
a683bf2
Compare
|
|
|
|
This was referenced Aug 14, 2026
ankit-yc
pushed a commit
that referenced
this pull request
Aug 15, 2026
…ix search escaping Three defects from the bullmq/jwks-rsa/escape-string-regexp majors (#2188). None reached production: only the frontend redeployed on that commit. bullmq 6 moved ioredis from a direct dependency to an OPTIONAL peer, and pnpm's auto-install-peers does not install optional peers, so the driver dropped out of the lockfile entirely. bull.config.ts passes a plain options object as `connection`, so bullmq has to require('ioredis') itself and threw "BullMQ could not load the optional 'ioredis' package". initQueues is awaited before app.listen inside a catch that exits, so this was a whole-backend outage on next deploy. ioredis is now a direct dependency, pinned to the 5.11.1 line main already ran. The scheduler ids carried across the migration unchanged, but that was the wrong thing to check: bullmq 5 never keyed a repeatable by jobId, it keyed by the md5 of name:jobId:endDate:tz:every. upsertJobScheduler keys by the plain id, so the upsert added a second entry beside the old one in the same repeat zset, and bullmq 6 still schedules from the legacy shape. Every recurring job would have fired twice, indefinitely: duplicate no-show marking, duplicate task reminders to users, doubled lab polling. initQueues now prunes the md5 entries before upserting. The escape helper was replaced by a LIKE escape. Both call sites feed the value into Prisma `contains`, which is an ILIKE pattern and not a regular expression, so regex escaping was always wrong. It only looked correct because a backslash before an ordinary character is a no-op in LIKE. Emitting \x2d for a hyphen broke that: "Jean-Luc" searched for "Jeanx2dLuc" and matched nothing. Escaping backslash, percent and underscore instead makes the search mean exactly what was typed, and stops user input acting as a wildcard. The scheduler suites mock every queue module, so no real Queue is ever built and they could not have caught the first two. redis-driver.test.ts checks the dependency graph itself instead.
ankit-yc
pushed a commit
that referenced
this pull request
Aug 15, 2026
…ix search escaping Three defects from the bullmq/jwks-rsa/escape-string-regexp majors (#2188). None reached production: only the frontend redeployed on that commit. bullmq 6 moved ioredis from a direct dependency to an OPTIONAL peer, and pnpm's auto-install-peers does not install optional peers, so the driver dropped out of the lockfile entirely. bull.config.ts passes a plain options object as `connection`, so bullmq has to require('ioredis') itself and threw "BullMQ could not load the optional 'ioredis' package". initQueues is awaited before app.listen inside a catch that exits, so this was a whole-backend outage on next deploy. ioredis is now a direct dependency, pinned to the 5.11.1 line main already ran. The scheduler ids carried across the migration unchanged, but that was the wrong thing to check: bullmq 5 never keyed a repeatable by jobId, it keyed by the md5 of name:jobId:endDate:tz:every. upsertJobScheduler keys by the plain id, so the upsert added a second entry beside the old one in the same repeat zset, and bullmq 6 still schedules from the legacy shape. Every recurring job would have fired twice, indefinitely: duplicate no-show marking, duplicate task reminders to users, doubled lab polling. initQueues now prunes the md5 entries before upserting. The escape helper was replaced by a LIKE escape. Both call sites feed the value into Prisma `contains`, which is an ILIKE pattern and not a regular expression, so regex escaping was always wrong. It only looked correct because a backslash before an ordinary character is a no-op in LIKE. Emitting \x2d for a hyphen broke that: "Jean-Luc" searched for "Jeanx2dLuc" and matched nothing. Escaping backslash, percent and underscore instead makes the search mean exactly what was typed, and stops user input acting as a wildcard. The scheduler suites mock every queue module, so no real Queue is ever built and they could not have caught the first two. redis-driver.test.ts checks the dependency graph itself instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



PR Checklist
What is the current behavior?
Three dependabot major bumps have been open and red because each needs a code change to land: bullmq #2182, escape-string-regexp #2119 and jwks-rsa #2118. They all touch
apps/backendand all touchpnpm-lock.yaml, so merging them one at a time put each one into conflict with the other two. They are taken together here so there is one lockfile resolution and one validation run.The behaviour being corrected in each case:
repeatfromJobsOptions. It is now dropped silently rather than rejected, so the seven recurring registrations inapps/backend/src/queueswould have stopped firing on upgrade with nothing logged and nothing thrown.requireing it throws at runtime.What is the new behavior?
bullmq. All seven recurring registrations moved from
Queue.add(..., { repeat, jobId })toQueue.upsertJobScheduler(id, { every }, { name, data }). Every scheduler id and every interval is unchanged, so a deploy re-uses the existing schedulers rather than stacking duplicates alongside them.Five of the six scheduler modules had no test at all. They have one now:
apps/backend/test/queues/schedulers.test.tscovers each registration's id, cadence and job name, asserts that recurrence no longer goes throughQueue.add, asserts ids are stable across a restart, and asserts that all six recurring jobs across the app hold distinct ids.escape-string-regexp. The dependency is removed in favour of
apps/backend/src/utils/escape-regexp.ts. Pinning to the last CommonJS release would leave the same wall in front of every future bump, and the implementation is two replacements against a fixed specification. Behaviour matches 5.0.0 exactly, including the\x2dform for a hyphen: a plain backslash-hyphen is valid in most patterns but rejected by the stricter grammar Unicode-mode patterns use, so the numeric escape is the form that is always safe. The test asserts against an inlined copy of the 5.0.0 implementation rather than against a restatement of the new one.jwks-rsa.
apps/backend/jest.config.cjsnow transforms jose through ts-jest withallowJs, and narrowstransformIgnorePatternsto just that package rather than opening upnode_modulesgenerally.Impact area
apps/backendandpackages/auth. No API surface, route, schema or migration changes. The queue work is a same-behaviour port to the new bullmq API.Validation performed
Run locally on this branch, on Node 20:
pnpm run type-check- 17/17 tasks passpnpm run lint- 10/10 tasks passpnpm run test:scripts- 71 pass, 0 failapps/backendfull suite - 255 suites, 4848 tests, all passingCoverage on everything this PR adds or changes:
appointment.scheduler.tsidexx-reference.scheduler.tslab-results.scheduler.tslab-status.scheduler.tstask-schedule.scheduler.tstask.schedulers.tsutils/escape-regexp.tsThe new tests were mutation tested rather than just run, since a test that passes against correct code proves nothing on its own. Each of these was applied to the source and the suite confirmed to go red, then reverted and confirmed green again:
lab-status.scheduler.tsto the oldrepeat-on-addAPI - 3 tests faillab-resultsthe same scheduler id aslab-status- 2 tests failRelated Issue(s)
Supersedes and closes #2182, #2119 and #2118.