Skip to content

Bug/fix full immunization 0 1#101

Merged
SauravBizbRolly merged 2 commits intorelease-3.10.0from
bug/fix_full_immunization_0_1
Nov 28, 2025
Merged

Bug/fix full immunization 0 1#101
SauravBizbRolly merged 2 commits intorelease-3.10.0from
bug/fix_full_immunization_0_1

Conversation

@SauravBizbRolly
Copy link
Collaborator

@SauravBizbRolly SauravBizbRolly commented Nov 28, 2025

📋 Description

JIRA ID:

fix full immunization for 1 year and 2 year

✅ Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • New feature (non-breaking change which adds functionality)
  • 🔥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🛠 Refactor (change that is neither a fix nor a new feature)
  • ⚙️ Config change (configuration file or build script updates)
  • 📚 Documentation (updates to docs or readme)
  • 🧪 Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • 🚀 Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

ℹ️ Additional Information

Please describe how the changes were tested, and include any relevant screenshots, logs, or other information that provides additional context.

Summary by CodeRabbit

  • Chores
    • Refined incentive calculation processing for vaccination records.
    • Enhanced user identification tracking in distribution operations.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

Walkthrough

Three methods in ChildCareServiceImpl were modified: incentive processing in getChildVaccinationDetails shifted to operate on the full list; saveOrsDistributionDetails changed user identification from JWT storage to DTO source; checkAndAddOrdDistributionIncentive updated username derivation to use database lookup instead of JWT storage.

Changes

Cohort / File(s) Summary
ChildCareServiceImpl method updates
src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java
Modified getChildVaccinationDetails to invoke checkAndAddIncentives on the complete vaccinationDetails list post-loop; changed saveOrsDistributionDetails to source userId from orsDistributionDTO.getUserName() instead of JWT storage; updated checkAndAddOrdDistributionIncentive to retrieve username via userRepo.getUserNamedByUserId() for both AM and CH incentive paths

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring extra attention:

  • Validate that shifting incentive processing to full-list operation in getChildVaccinationDetails does not introduce performance issues or duplicate processing
  • Confirm the change from JWT-derived to DTO-provided user identification in saveOrsDistributionDetails aligns with calling context and doesn't introduce data consistency risks
  • Verify the database lookup for username in checkAndAddOrdDistributionIncentive handles null/missing userId gracefully and maintains performance

Poem

🐰 Three methods hopped and changed their way,
From JWT whispers to data's say,
Incentives now batch, users shift source,
A refactor's dance, a smoother course! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Bug/fix full immunization 0 1' is vague and does not clearly convey what was fixed; the '0 1' suffix and lack of specificity make it unclear what the actual changes accomplish. Revise the title to be more specific and descriptive, e.g., 'Fix immunization incentive processing for vaccination details' or 'Correct user identification in immunization workflows' to better reflect the actual code changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bug/fix_full_immunization_0_1

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.

❤️ Share

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

@SauravBizbRolly
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@SauravBizbRolly SauravBizbRolly merged commit 59538a1 into release-3.10.0 Nov 28, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java (2)

335-351: Based on my verification, all concerns in the review comment are confirmed and accurate:

  1. O(N²) Performance Issue: ✓ Confirmed

    • checkAndAddIncentives(vaccinationDetails) is called at line 348 inside the forEach loop
    • For N items in vaccinationDetails, it executes N times
    • Each execution iterates over the entire list again (line 834)
    • Each iteration performs multiple DB queries and calls recordRepo.save()
  2. Side-Effect Concern: ✓ Confirmed

    • getChildVaccinationDetails is a read API but performs writes via createIncentiveRecord()recordRepo.save()
    • This violates the principle that read operations shouldn't have side effects
  3. Correct Pattern Exists: ✓ Confirmed

    • saveChildVaccinationDetails (line 380) correctly calls checkAndAddIncentives(vaccinationList) once after the loop ends
    • This is the pattern that should be used in getChildVaccinationDetails

The suggested diff is correct and matches the proper implementation pattern already used elsewhere in the file.


Avoid calling checkAndAddIncentives inside the per-item loop

checkAndAddIncentives(vaccinationDetails) is invoked once per element in vaccinationDetails, but each call re-iterates over the entire list and performs database queries and writes multiple times. This is O(N²) work and repeats side-effectful incentive logic on the same data.

If the intention is to process incentives once per request, call it once after you finish building result:

            vaccinationDetails.forEach(childVaccination -> {
                ChildVaccinationDTO vaccinationDTO = mapper.convertValue(childVaccination, ChildVaccinationDTO.class);
                BigInteger benId = beneficiaryRepo.getBenIdFromRegID(childVaccination.getBeneficiaryRegId());
                vaccinationDTO.setBeneficiaryId(benId.longValue());

                result.add(vaccinationDTO);
-               checkAndAddIncentives(vaccinationDetails);
            });
+           checkAndAddIncentives(vaccinationDetails);
            return result;

Also, this get* method now performs writes (creates incentive records). Please confirm this side effect is acceptable for a read API and won't surprise callers.


568-581: Based on my investigation, I have verified the security concerns raised in the review comment. Here's what I found:

Critical Findings:

  1. The endpoint is unauthenticated: The JwtUserIdValidationFilter has a hardcoded if (true) statement (line 84-87) that bypasses all JWT validation for every endpoint, including /ors/saveAll.

  2. Inconsistent user attribution pattern: Other methods in the codebase (lines 534, 460-463, 690, 717, 723) correctly use jwtUtil.getUserNameFromStorage() to derive the userId from the authenticated user. The saveOrsDistributionDetails method diverges from this pattern.

  3. No validation of payload userName: The controller simply passes the orsDistributionDTOS directly without validating that orsDistributionDTO.getUserName() is legitimate.

  4. Incentive creation risk: The method calls checkAndAddOrdDistributionIncentive(), which means a malicious client could attribute ORS distributions and associated incentives to arbitrary users.


Be explicit about trusting orsDistributionDTO.getUserName() as the user identity

The endpoint POST /ors/saveAll is currently unauthenticated and uses the username from the request payload without validation:

orsDistribution.setUserId(userRepo.getUserIdByName(orsDistributionDTO.getUserName()));

This deviates from the established pattern in the codebase (e.g., BeneficiaryServiceImpl, other ChildCareServiceImpl methods) which correctly use jwtUtil.getUserNameFromStorage() to derive the authenticated user.

Without validation, a malicious or buggy client can attribute ORS distributions and associated incentives to arbitrary users, enabling privilege escalation or fraud.

Recommendation: Either authenticate the endpoint and use jwtUtil.getUserNameFromStorage() to establish the user identity, or add explicit validation that orsDistributionDTO.getUserName() is non-null, known, and belongs to an authorized user.

🧹 Nitpick comments (1)
src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java (1)

731-751: Avoid duplicate username lookups and handle missing userId in ORS incentive creation

In checkAndAddOrdDistributionIncentive, you now derive createdBy from userRepo.getUserNamedByUserId(orsDistribution.getUserId()) for both AM and CH incentives:

createIncentiveRecordforOrsDistribution(
    orsDistribution,
    orsDistribution.getBeneficiaryId(),
    orsPacketActivityAM,
    userRepo.getUserNamedByUserId(orsDistribution.getUserId()),
    false
);
...
createIncentiveRecordforOrsDistribution(
    orsDistribution,
    orsDistribution.getBeneficiaryId(),
    orsPacketActivityCH,
    userRepo.getUserNamedByUserId(orsDistribution.getUserId()),
    true
);

Two points:

  1. userRepo.getUserNamedByUserId is called twice per record with the same userId. Cache it locally:
     orsDistributionList.forEach(orsDistribution -> {
+        String createdBy = userRepo.getUserNamedByUserId(orsDistribution.getUserId());
+        if (createdBy == null) {
+            logger.warn("No username found for userId {}", orsDistribution.getUserId());
+            return;
+        }
         IncentiveActivity orsPacketActivityAM =
             incentivesRepo.findIncentiveMasterByNameAndGroup("ORS_DISTRIBUTION", GroupName.CHILD_HEALTH.getDisplayName());
         IncentiveActivity orsPacketActivityCH =
             incentivesRepo.findIncentiveMasterByNameAndGroup("ORS_DISTRIBUTION", GroupName.ACTIVITY.getDisplayName());
         if (orsPacketActivityAM != null) {
             if (orsDistribution.getNumOrsPackets() != null) {
-                createIncentiveRecordforOrsDistribution(orsDistribution, orsDistribution.getBeneficiaryId(), orsPacketActivityAM, userRepo.getUserNamedByUserId(orsDistribution.getUserId()), false);
+                createIncentiveRecordforOrsDistribution(orsDistribution, orsDistribution.getBeneficiaryId(), orsPacketActivityAM, createdBy, false);
             }
         }
         if (orsPacketActivityCH != null) {
             if (orsDistribution.getNumOrsPackets() != null) {
-                createIncentiveRecordforOrsDistribution(orsDistribution, orsDistribution.getBeneficiaryId(), orsPacketActivityCH, userRepo.getUserNamedByUserId(orsDistribution.getUserId()), true);
+                createIncentiveRecordforOrsDistribution(orsDistribution, orsDistribution.getBeneficiaryId(), orsPacketActivityCH, createdBy, true);
             }
         }
     });
  1. If orsDistribution.getUserId() is ever null or invalid (e.g., because the DTO’s username didn’t resolve), createdBy becomes null and createIncentiveRecordforOrsDistribution will attempt beneficiaryRepo.getUserIDByUserName(createdBy), which can fail. The guard above (early return with a warning) avoids that.

Please verify that userId is always set before this method is called, or add similar defensive checks.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a40281 and 5ac503e.

📒 Files selected for processing (1)
  • src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java (3 hunks)

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.

1 participant