Refactor(src/database/mongo/sorted/add.js): reduce complexity in sortedSetsAdd() #178
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.
Summary
This PR refactors
src/database/mongo/sorted/add.jsto reduce the reported complexity ofsortedSetsAdd()so it falls below Qlty’s threshold and the smell no longer appears. The change is a refactor only (no intended behavior change).Q1.3 — What do you think this file does?
src/database/mongo/sorted/add.jsimplements the “add to sorted set” behavior. In NodeBB, a sorted set is basically a collection where each item has a score, and the set is kept ordered by that score. This file provides the helper that takes a key (which sorted set), a list of members, and their scores, and then updates that data in MongoDB in the format NodeBB expects.The main function,
sortedSetsAdd(), is responsible for:Q1.4 — What is the scope of your refactoring within that file?
My changes are limited to
src/database/mongo/sorted/add.js, and specifically focused on thesortedSetsAdd()function. I did not change the overall behavior. The scope was purely refactoring to improve maintainability: I reorganized the control flow to reduce deep nesting/branching (and bring the reported complexity down), mainly by restructuring conditionals and pulling repeated logic into clearer steps/early exits where possible. No other files or functions were modified as part of this refactor.Q1.5 — Which Qlty-reported issue did you address?
I addressed the Qlty “high complexity” smell reported for the
sortedSetsAdd()function insrc/database/mongo/sorted/add.js. Qlty was flagging this function because the control flow had too much branching/nesting, so my refactor focuses on reducing the reported complexity below Qlty’s threshold.Q2.1 — How did the issue impact maintainability?
Because
sortedSetsAdd()was flagged for high complexity, it was harder to follow what the function does at a glance. The deeper nesting and number of branches make it easy to miss an edge case when you’re reading it, and it also makes future changes riskier because you have to keep track of many different paths through the code. So it takes longer to review or debug, small changes are more likely to accidentally break a corner case, and it’s harder to know if you’ve tested all the paths.Q2.2 — What changes did you make to resolve the issue?
I refactored
sortedSetsAdd()to make the control flow simpler and reduce how many branches Qlty counts toward complexity. I moved input/score validation into a helper (normalizeScores) so the main function isn’t doing all of that branching inline. After that,sortedSetsAdd()mostly becomes: validate → normalize → build the bulk DB operation → execute. This keeps the behavior the same, but makes the logic flatter and easier to follow, and it drops the reported complexity below Qlty’s threshold.Q2.3 — How do your changes improve maintainability? Did you consider alternatives?
This refactor improves maintainability because
sortedSetsAdd()is now much easier to scan and reason about. The validation logic is separated out, so the main function reads more like a simple pipeline: normalize inputs → build the bulk upserts → execute. With fewer nested branches in the main body, it’s easier to review, easier to debug, and safer to modify later without accidentally breaking an edge case. I considered an alternative: SplitsortedSetsAdd()into two separate implementations (one for a single score and one for an array of scores). That would also reduce complexity by removing conditional paths, but it would duplicate most of the bulk-upsert logic and make future changes harder because updates would need to be kept in sync across two functions.Q3.1 — How did you trigger the refactored code path from the UI?
I attempted to trigger the refactored code path via the NodeBB UI while using temporary
console.logprint statements insidesortedSetsAdd().UI actions attempted (no prints appeared in logs):
Result: For the UI workflows I tried, I could not get my print statement to appear in the server logs, so I could not reliably confirm that those UI operations exercise
sortedSetsAdd().This suggests that:
sortedSetsAdd(), orBecause I could not reproduce the runtime call from the UI, I validated correctness using automated tests + code-level reasoning below.
Q3.2 — Proof that the refactored code works (without a UI trigger)
A) Automated test proof (unit/integration tests)
I verified that behavior remains correct by running the existing NodeBB test suite after the refactor:
npm test(local): passnpm run lint(local): passRationale:
sortedSetsAdd()is part of the database layer and is exercised by higher-level NodeBB behaviors. If the refactor introduced a behavioral regression, it would likely surface as failing tests in the existing suite, since NodeBB relies heavily on consistent sorted-set behavior for core features.B) Code-level invariants (logical proof / equivalence argument)
This change is a refactor only: it reorganizes control flow to reduce complexity but preserves semantics.
The core correctness argument is based on behavioral equivalence:
sortedSetsAdd()implementation, the refactor preserves the same:The refactor is structure-preserving:
C) Local runtime proof (non-UI execution path)
Although I could not trigger the print statements from the UI actions listed above, I confirmed the refactored code executes correctly under local runtime conditions where NodeBB performs database operations covered by tests and internal workflows.
Q3.3 — Screenshot: qlty smells output