Skip to content

Conversation

@caoerz-helen
Copy link

Summary

This PR refactors src/database/mongo/sorted/add.js to reduce the reported complexity of sortedSetsAdd() 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.js implements 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:

  • inserting new members into a sorted set,
  • updating a member’s score if it already exists,
  • doing the correct database updates so the sorted ordering can be maintained and queried efficiently.

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 the sortedSetsAdd() 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 in src/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: Split sortedSetsAdd() 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.log print statements insidesortedSetsAdd().

UI actions attempted (no prints appeared in logs):

  • Admin → Manage → Categories → reordering categories (reorder + save): no print statements
  • Creating posts / commenting under a post: no print statements
  • Other general browsing actions that might touch sorting/state: no print statements

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:

  • these UI actions may use a different code path than sortedSetsAdd(), or
  • the trigger requires a different workflow/user role that I do not have in my current setup (e.g., actions requiring a second user account such as voting).

Because 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): pass
  • npm run lint (local): pass

Rationale: 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.

test2 test1 lint qlty smells

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:

  • The refactor does not change function inputs/outputs or the database operations being performed.
  • For each logical branch in the original sortedSetsAdd() implementation, the refactor preserves the same:
    • conditions under which a write occurs,
    • computed values used for the write (e.g., scores/members),
    • target key(s) being updated,
    • and error-handling behavior.

The refactor is structure-preserving:

  • I reduced nesting/branching, but each decision point still leads to the same database updates as before.
  • Any extracted helper functions are pure reorganizations of existing logic (same inputs → same outputs), which means the refactor is equivalent by substitution.

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

smells before change qlty smells

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants