Optimize updateAllUserStatus Query#2598
Conversation
Optimizes the database query in updateAllUserStatus by performing range filtering on the database level instead of in-memory application logic. Key Changes: - Added filter on futureStatus.from directly to the query. - Replaced the internal snapshot property _size with public size property. - Instantiated today once at the top of the updateAllUserStatus model.
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Walkthrough
ChangesFirestore Query Optimization in updateAllUserStatus
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@models/userStatus.js`:
- Around line 301-304: The query in userStatusModel combining an `in` filter on
`futureStatus.state` with a range filter on `futureStatus.from` requires a
composite Firestore index that is not currently defined in the repository.
Create a composite index for the `futureStatus.state` field (in ascending order)
and `futureStatus.from` field (in ascending order) either through the Firebase
Console or by adding it to the firestore.indexes.json configuration file and
deploying it. This index must be deployed to the production Firestore instance
before merging to avoid FAILED_PRECONDITION errors at runtime when the cron
executes.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 862df3df-1b4e-4a15-8e7f-af534058bd47
📒 Files selected for processing (1)
models/userStatus.js
|
@Soumava-221B please add proof for your changes, screen recording for the api request |
Removes obsolete date-comparison filters and dead code branches in models/userStatus.js. Since the query already filters by 'futureStatus.from <= today' (via commit 6a88a00), the corresponding nested checks are always true and have been simplified.
This reverts commit e6151c4.
…s updates Introduce comprehensive tests to verify the automatic updating of user status from Out-of-Office (OOO) to Active based on the scheduled start date. Key Changes: - Unit Tests: Added cases for updateAllUserStatus (past, today boundary, and future scenarios). - Integration Tests: Verified PATCH /users/status/update endpoint under superuser auth and checked DB states. - Clock Mocking: Utilized Sinon fake timers to ensure deterministic date-based testing.
| expect(response).to.have.status(401); | ||
| }); | ||
|
|
||
| it("Should update user status and return 200 for a superuser request", async function () { |
There was a problem hiding this comment.
where's the test for checking that future status documents aren't being read? And wasn't the update behaviour being tested in existing tests?
There was a problem hiding this comment.
Test for checking the future status documents is done by the combination of integration and unit test
Integration Test
In test/integration/userStatus.test.js:
It seeds three user status documents:
userToUpdateId(scheduled for yesterday, so it should update).userBoundaryUpdateId(scheduled for today, so it should update).userNotToUpdateId(scheduled for tomorrow, so it should NOT update).
It verifies that the document with the future date is ignored during the update run using these assertions:
API Response Assertions:
expect(response.body.data.usersCount).to.equal(2); // Only matches the 2 eligible documents
expect(response.body.data.oooUsersAltered).to.equal(2);Database State Assertion:
const nonUpdatedDoc = await userNotToUpdateStatusRef.get();
expect(nonUpdatedDoc.data().currentStatus.state).to.equal(userState.OOO);
expect(nonUpdatedDoc.data().futureStatus.state).to.equal(userState.ACTIVE); // remains untouchedUnit Test
In test/unit/models/userStatus.js:
The specific test is: Should not update user status when futureStatus.from > today (e.g. from is in the future).
It seeds a single user status document with a future date (today + 24 hours) and verifies:
const summary = await updateAllUserStatus();
expect(summary.usersCount).to.equal(0); // Verifies the query returned 0 documents to be read/updated
expect(summary.oooUsersAltered).to.equal(0);Previously the bulk update behaviour was not tested in the existing integration tests.
| const userBoundaryUpdateId = await addUser(userData[3]); | ||
|
|
||
| const userToUpdateStatusRef = firestore.collection("usersStatus").doc(); | ||
| await userToUpdateStatusRef.set({ |
There was a problem hiding this comment.
the mock value for userStatus can be defined in constants once and reused...there might be existing value that can be reused here
There was a problem hiding this comment.
Currently there is no exsisting constant in the codebase that can be reused directly for these tests.
There was a problem hiding this comment.
please define the constant then since you are using this in multiple places or you can reuse the same func you defined for other tests
| expect(response.data.futureStatus.state).to.equal("UPCOMING"); | ||
| }); | ||
|
|
||
| describe("updateAllUserStatus", function () { |
There was a problem hiding this comment.
- you can refactor all tests in this describe block, all of them users same userStatus mock data
- also please remove comments if aren't necessary
|
@Soumava-221B can you please add proof for your changes? screenshot or any other relevant recording... |
Sure Before the cron job run and calls the PATCH API (Query operation benchmark)
Manually hitting PATCH API endpoint
After the userStatus is updated (Query operation benchmark)
|
|
|
||
| const userToUpdateId = await addUser(userData[1]); | ||
| const userNotToUpdateId = await addUser(userData[2]); | ||
| const userBoundaryUpdateId = await addUser(userData[3]); |
There was a problem hiding this comment.
what's the boundaryUpdateId?
There was a problem hiding this comment.
The boundaryUpdateId is when the futureStatus.from is set to today
| await cleanDb(); | ||
| }); | ||
|
|
||
| function buildUserStatusMock( |
There was a problem hiding this comment.
- please use better function naming
- place this func ideally in a utils or helper file so it can be reused in multiple places
| const userNotToUpdateId = await addUser(userData[2]); | ||
| const userBoundaryUpdateId = await addUser(userData[3]); | ||
|
|
||
| const userToUpdateStatusRef = firestore.collection("usersStatus").doc(); |
There was a problem hiding this comment.
in lines 170, 193, 216, why are you querying collections three times? what behaviour are you testing here? does this match the pattern for logic used in actual function?
shouldn't the func query one time and then filter accordingly? let me know if i'm missing something
| const userBoundaryUpdateId = await addUser(userData[3]); | ||
|
|
||
| const userToUpdateStatusRef = firestore.collection("usersStatus").doc(); | ||
| await userToUpdateStatusRef.set({ |
There was a problem hiding this comment.
please define the constant then since you are using this in multiple places or you can reuse the same func you defined for other tests
| toUpdate = !toUpdate; | ||
| summary.oooUsersAltered++; | ||
| } else { | ||
| summary.oooUsersUnaltered++; |
There was a problem hiding this comment.
previously there was oooUsersUnaltered for keeping track of status that aren't updated, are we still using it anywhere for OOO users who's status aren't changed?
There was a problem hiding this comment.
Yes, we are still using it check line 296





Date: 16/06/2026
Developer Name: Soumava Das
Issue Ticket Number
#2597
Description
Optimize the updateAllUserStatus cron job by delegating scheduled status filtering to Firestore to reduce document reads.
Documentation Updated?
Under Feature Flag
Database Changes
Breaking Changes
Development Tested?
Screenshots
Screenshot 1
Test Coverage
Screenshot 1
Additional Notes