Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #1368

Merged
merged 32 commits into from
Jan 29, 2025
Merged

Dev #1368

merged 32 commits into from
Jan 29, 2025

Conversation

holashchand
Copy link
Collaborator

@holashchand holashchand commented Jan 29, 2025

Summary by CodeRabbit

Based on the comprehensive summary, here are the release notes:

Release Notes

  • New Features

    • Added email notification functionality for HRMS module
    • Introduced household type support in household management
    • Enhanced project search capabilities with ancestor project ID filtering
  • Improvements

    • Updated project and household models to support new beneficiary and household types
    • Improved validation for household and project operations
    • Refined user creation and search processes
  • Bug Fixes

    • Resolved issues with project and household search functionality
    • Enhanced error handling for beneficiary and user management
  • Technical Updates

    • Upgraded dependencies across multiple services
    • Improved type safety in various models
    • Standardized configuration management

kanishq-egov and others added 30 commits August 5, 2024 18:04
* HLM-6385: added changes for IRS activity track and closed household concepts

* HLM-6385: added changes for IRS activity track and closed household concepts, added db migration script, validations for closed household

* HLM-6385: added changes for location tracking

* HLM-6385: added changes for location points

* HLM-6385: added clientReferenceId and tenantId in LocationPoint, updated Location_capture model

* HLM-6385, HCMPRE-46: Updated changes as per design review

* HLM-6385, HCMPRE-46: Added Location capture changes

* HLM-6385, HCMPRE-46: Added UserAction changes

* HLM-6385, HCMPRE-46: updated common models, replaced digit models with service-common

* Revert "HLM-6385, HCMPRE-46: updated common models, replaced digit models with service-common"

This reverts commit 6abdea4.

* HLM-6385, HCMPRE-46: updated table informations and columns for migration scripts

* reverting BoundaryUtil change

* reverting BoundaryUtil changes

* HLM-6385, HCMPRE-46: updated validators and IRSConsumer

* HLM-6385, HCMPRE-46: updated validators

* HLM-6385, HCMPRE-46: updated project configuration

* HLM-6385, HCMPRE-49: updated models to have isDeleted as it is required in common utils enrichment code

* HLM-6385, HCMPRE-46: updated the projectid field, added notnull annotation

* HLM-6385, HCMPRE-46: updated all the changes related to enrichment

* HLM-6385, HCMPRE-46: made action field notnull

* HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields

* HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields, HCMPRE-116, HCMPRE-117

* HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields, HCMPRE-116, HCMPRE-117, added in services

* HLM-6385, HCMPRE-46: removed outdated changes from Task.java

* removed all user location models

* Refactored from LocationCapture model to UserAction and packges from irs to useraction

* HLM-6385 - lat/long irs name changes

* HLM Downsync Incremental product changes pull from impel (#831)

* HLM Downsync Incremental product changes pull from impel

* HLM removed impel specific changes

* renamed Project type filter code constant

* HLM updated beneficiary based search

* HLM updated downsync search, cycles is required only when it is smc based campaign

* HCM - removed project task resource quantity validator

* HLM updated downsync logic as per review comments

* HCMPRE-216 : Added Administration failed status for validation when task resource is empty or when status is ADMINISTRATION_FAILED

* HCMPRE-216: updated task status

* HCMPRE-216: changed to ADMINISTRATION_FAILED

* HLM-6385: updated with code review comments

* HLM-6385: added changes as per review comments, and added correct logs wherever required.

* HLM-6385: code review comments addressed.

* HLM-6385: review comment added for error handling on LocationCaptureRepository

* HLM-6385: another batch of coderabbitai code review comments addressed.

* HLM-6385: added more logs in repository for useraction and location capture

* HLM-6385: updated the code as per code review comments from @kavi-egov

---------

Co-authored-by: kavi_elrey <25226238+kavi-egov@users.noreply.github.com>
Co-authored-by: Holash Chand <holash.c@beehyv.com>
* HLM closed household status

* HCMPRE-240: validate no resource task status scenario with configurable statuses

* HCMPRE-240: fixed issues related to string trimming

* HLM fixed rowversion referral bug, mis placement of rowversion validator

* HCMPRE-240: code review changes

* HCMPRE-242: updated for null resources and address check

* HCMPRE-242: added for proper null check

* HCMPRE-242: added checks for task resource where ever applicable

* HCMPRE-242: updated taskstatus to enum from string

* HCMPRE-242, HCMPRE-240: renamed task's status field to taskStatus field, as there is contradiction with EgovModel status field

* HCMPRE-242: fixed dupcalite entity cache issue for existing entity validation during bulk create

* HCMPRE-242: updated project test case for taskStatus field contraints changes : not null

* HCMPRE-242: fix generic repository code

* HCMPRE-242: added taskstatus migration script

* HCMPRE-240: updated PtIsResourceEmptyValidator, for task status

* HLM-242: added changes as per code review

* Revert "HCMPRE-242: added taskstatus migration script", and removed status field from EgovModel, and rename TaskStatus to status

This reverts commit 7caf0c4.

* HCMPRE-240: FIXED all task status reference

---------

Co-authored-by: sivajiganesh-dev <sivajiganesh.dev@gmail.com>
* HLM rowmapper issue in household, referral fixed

* HCMPRE-255: updated the changes for household

* reverted local changes commit by mistake
* added logic for cascading project date updates

* updated application.properties

* refactored logic for using ProjectRequest pojo to send message to kafka instead of Ancestor and Descendant Projects pojo

* added comments and enhanced search project logic

* made public back to private

* made  more concise the method in project service separated create project map logic

* separated concerns of update based on action whether null or updateProjectDates

* updated action logic for just test purpose

* updated version of health-service-models library

* update logic

* updated final logic for cascading update project dates based on flag in project request

* reverted config

* reverted config 2

* added multiple line comments

* udpated error messages
* HLM fixed issues in useraction existent entity validator

* updated after code review comments
* updated version for hcm v1.5 release

* HLM updated the code as per code review from code rabbit

* HCMPRE-209: updated code review comments and code documentation
* removed digit-models from health-services-models library

* removed digit-models from health-services-models library

* added SMSRequest model

* Updated individual models

* Updating health services models version in health services common library

* version bump

* hcmpre-309: merged removed-digit-models and rebase to dev

* HLM-309: updated common models version

---------

Co-authored-by: shubhang-egov <shubhang.dhanesha@egovernments.org>
* HCMPRE-169 code review comments

* HCMPRE-169 adding code comments

* HCMPRE-169 adding code comments

* HCMPRE-169 changing mdms v2 field name for uom

* HCMPRE-169 code review comments

* HCMPRE-169 code review comments
* HCMPRE-218 adding validation for name validation

* HCMPRE-218 adding validation for name validation

* HCMPRE-218 moving "$." into constants

* HCMPRE-218 code review comments

---------

Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com>
* Removed the project facility mapping validation check as it is not required

* Removed the project facilty valaidation check in ValidatorUtil.java

* Removed the local receiverId in ValidatorUtil.java

---------

Co-authored-by: Shashwat12-egov <shashwat.k@egovernments.org>
* Removed the project facility mapping validation check as it is not required

* Removed the project facilty valaidation check in ValidatorUtil.java

* Removed the local receiverId in ValidatorUtil.java

* Validating the sender and receiver based on transactiontype

* Validating the sender and receiver based on transactiontype

* Corrected the validation for the failed case

* Added the comments

---------

Co-authored-by: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com>
Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com>
* update service definition api added

* fix values persister config

* fix "values" persister config

* active added in service definition persister config

* resolved code review comments

* added includeDeleted parameter in search

* fix some issues

* fix create api
* changed additionalDetails to additionalFields

* boolean data type added in attribute definition

* Added the filter for isActive

* changed the serviceDefinition.code size from character varying(64) to character varying(256)

* Revert "changed the serviceDefinition.code size from character varying(64) to character varying(256)"

This reverts commit 24c971f.

* Revert "Added the filter for isActive"

This reverts commit 09d65c4.

* changed the code character size from 64 to 256 (#1147)

Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>

* added validation for boolean data type in service-request

---------

Co-authored-by: yashita-egov <yashita.bansal@egovernments.org>
Co-authored-by: Jagankumar <53823168+jagankumar-egov@users.noreply.github.com>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>
* HCMPRE-469: added changes for facility count

* HCMPRE-469: added changes for models, added totalCount fields in required model classes

* HCMPRE-469: added changes for project facility, project staff, project resource, hf-referral, stock and stock reconciliation, also added helper function in common utils for findWithCount

* HCMPRE-469: added changes for removing digit-models deprecated dependency, replaced with tracer library references and mdms client references

* HCMPRE-469: added changes for project service, removed reference for digits model

* Removed the dev from version

* Removed the dev from version of common libraries

* Removed the dev from version of common libraries

* Removed the order by id statement while searching the facility

* Removed setting of total count line from the FacilityService file

* Removed setting of total count line from the FacilityService file

---------

Co-authored-by: Shashwat12-egov <shashwat.k@egovernments.org>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>
… resource-generator service) (#1176)

* HCMPRE-599 updating Plan service models

* HCMPRE-599 updating Plan service models

* HCMPRE-599 changes

* HCMPRE-599 adding census POJOs

* HCMPRE-599changes for triggering pland census records on workflow status

* HCMPRE-599 app.prop changes for resource generator service

* Renaming resource-estimation-service to resource-generator

* HCMPRE-1078  enrichment of resource mapping

* HCMPRE-1122 changing processing logic

* HCMPRE-1122 changing processing logic

* HCMPRE-1122 updating operation related validations

* HCMPRE-1122 adding method comments

* enhancement in facilityCatchmentConsumer

* enhancement in facilityCatchmentConsumer

* removing catchement topic that was added before

* added wf validation for approving estimations

* adding additionalDetails as string while preparing rows for batchUpdate

* adding additionalDetails as string while preparing rows for batchUpdate

* HCMPRE-1094 changes for facility mapping create trigger on workflow

* reverting the change in census-bulk-api

* parsing additional details in bulk update api

* Added plan config name in plan employee's and plan facility's search criteria

* Bypassing validations for operations when source is CUSTOM

* added workflow validations

* removing unused service constants

* Changes for triggering plan-facility mapping

* adding project factory data create host

* handling case for empty areaCodes in search criteria

* handling case for empty areaCodes in search criteria

* adding project factory data create host

* Adding facility create trigger status

* Adding additionalField table in census

* adding plan config name in plan employee and plan facility pojo

* Adding additionalField table in census

* implemented partial search in plan config name

* Changing datatype of value

* HCMPRE-1162 enrich additionalfieldForCensus

* HCMPRE-1162 enrich additionalfieldForCensus

* updated query builder for census

* handling null pointer exception on updating additional details

* Changes to allow assumption values in input

* Removing older method for getting input value

* Making editable false for uploaded additional field during census create

* HCMPRE-853 removing lat long fields from additional field overridekeys

* Changes for adding execution order for operations

* Changes for adding execution order for operations

* Adding facilityName column and enriching servingPop

* HCMPRE-853 added chnages for census search and fetching boundarycodes from one sheet

* HCMPRE-853 changes for updating file with approved census data

* HCMPRE-853 adding logs

* pull from microplanning-dev

* HCMPRE-853 integrating with project factory with updated resources

* modification in wf-service

* workflow auto-assignee issue

* HCMPRE-853 commenting project factory integration

* adding pagination for plan-employee api

* changed the data type of BigDecimal

* HCMPRE-1282 changes for updating estimates into plan

* HCMPRE-1282 app.prop changes

* Adding case for when celltype is formula.

* enriching additional details with additional field key-value

* modified orderBy clause

* made changes in order by clause

* added facilityType

* pull from microplanning-dev

* making fuzzy search cAse-insenSItive

* making fuzzy search cAse-insenSItive

* making fuzzy search cAse-insenSItive

* pull from microplanning-dev

* pull from microplanning-dev

* modified pagination

* HCMPRE-1282 changes for updating approved plans into file for campaign integration

* added planConfigStatus in search criteria

* HCMPRE-1282 changes for updating approved plans into file for campaign integration

* HCMPRE-771 merging multiple alter table migration scripts into create table scripts.

* Adding workflow restricted roles in census

* Adding workflow restricted roles in census

* Fixing limit and adding check for empty row

* Fixing limit and adding check for empty row

* added ranked query for plan employee assignment

* added ranked query for plan employee assignment

* HCMPRE-1300 DB migration script cleanup

* adding plan bulk update topic

* Adding facility name in census additional details

* Wf auto assignment to multiple people

* Wf auto assignment to multiple people

* Adding boundaryTypeHierarchy Pojos and search endpoint

* enriching jurisdiction mapping in census

* changing jurisdictionMapping from jsonIgnore to jsonProperty

* optimizing the enrichment functions and adding comments

* handling null pointer exception

* Wf auto assignment to multiple people

* Set last modified time on update call

* enriching serving population with sum of confirmed target population of serving boundaries

* Reverting campaign update at the end.

* modifying Wf for send back actions

* enriching jurisdiction mapping in plan

* setting assignees separetly for send back actions

* Changing assignee column to Text in db

* Changing assignee column to Text in db

* enriching jurisdiction mapping

* Changing validation logic for operations

* enriching jurisdiction mapping

* Changes for only validating when operation is active

* Sort operations in planconfig search by execution order

* Sort operations in planconfig search by execution order

* Sort operations in planconfig search by execution order

* Sort operations in planconfig search by execution order

* type casting jurisdiction into list

* Adding census changelog

* Adding census changelog

* Adding census changelog

* Adding census changelog

* Adding census changelog

* Show on UI false for lat long fields

* Updated plan service CHANGELOG

* update plan config validation

* Adding jurisdiction mapping in plan facility

* Changing all collection dataType from list to set in API search criteria

* Changing all collection dataType from list to set in API search criteria

* removing validation for operation source

* adding overloaded method for query builder in plan

* adding overloaded method for query builder in plan

* Adding validation to check for duplicates

* pull from census-bulk-api

* pull from census-bulk-api

* Removing comments from WF in resource generator

* Decreasing min size of assumptionvalue in Operation POJO to 1.

* Changing mdms master in plan service for hierarchyConfig

* changing min size of resource type in resource pojo

* increasing request size for producer

* changed version from 1.1.0 to 1.0.0

* changed version from 1.1.0 to 1.0.0

* changing the order

* changing the order

* changing the order

* Increasing request size in application.properties

* Updating resource generator changelog

* Updating resource generator changelog

* Adding boundaryAncestralPath for Plan Facility API

* Adding boundaryAncestralPath for Plan Facility API

* Adding ProjectFactory consumer in Plan Facility Service

* Adding ProjectFactory consumer in Plan Facility Service

* Adding plan changelog

* Adding empty list as service boundary when null in consumer for project-factory

* Increasing the max-request-size in census producer configuration

* Increasing the max-request-size in plan producer configuration

* Adding orderBy clause for plan search query

* Removing unused census consumer

* Replacing map from set for duplicate check in census row mapper

* Replacing map from set for duplicate check in plan config row mapper

* Replacing map from set for duplicate check in census row mapper

* Replacing map from set for duplicate check in census row mapper

* Replacing map from set for duplicate check in plan config row mapper

* Replacing map from set for duplicate check in plan row mapper

* Clearing set on new census entry

* Clearing set on new plan entry

* Clearing set on new plan config entry

---------

Co-authored-by: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com>
Co-authored-by: Tanishi Goyal <tanishi.goyal@egovernments.org>
* Beneficiary Type enum added

* clf model changes

* Changed version to 25

---------

Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>
* added enum beneficiary type

* changed validation from mdms to additonal details

* resolved library conflicts

* added beneficiary type

* changed health- model version

* health-service-model verson changed in project service

* changed health-service model version in project service

* resolved review comments

* separte out model changes
* updated changelog for health-services-model

* updated changelog

* Update CHANGELOG.md

---------

Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com>
…ervice for email notification feature, UUID and role search changes, Pagination and case insensitive fuzzy search in user name (#1337)

* Total count enhancement in HRMS

* Corrected count query logic

* Fixed HRMS total count

* Fixed hrms uuids search

* Fixed HRMS search response

* added email notification service

* added email notification service

* changing implementation partner

* Adding last modified date sorting clause in HRMS search query

* Adding case insensitive search

* Revert "Adding last modified date sorting clause in HRMS search query"

This reverts commit c287376.

* changing implementation partner

* HCMPRE-1333- Removed dense rank query; using sequential calls to get child table data. (#1210)

* Revert "HCMPRE-1333- Removed dense rank query; using sequential calls to get child table data. (#1210)"

This reverts commit 2d2d4cc.

* Added comments and resolved some coderabbit review comments

* Removing IndividualBulkResponse class and importing from library

* updating version for org.egov.services.services-common

* using IndividualBulkResponse class in egov-hrms

---------

Co-authored-by: Shashwat Mishra <shashwat.mishra@egovernments.org>
Co-authored-by: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>
* Added support to search projects based on ancestor ids

* changed ancestor ids to a boolean isAncestorProjectId

* minor fix

* Fixed java heap problem due to no filter in include descendants, include ancestors etc queries

* Added support to find root level project

* Added missing parameter

* Added code comments

* incremented version of project service

* added change log
* HCMPRE-1254-Adding household type for communal living facility

* HCMPRE-1254-Fixed community validator

* HCMPRE-1254-household type rowmapper

* model dev change

* changing search param to string

* changing pom snapshot

* Family type search query

* equal ignore case

* fetching null records also

* household type change validator

* adding brackets in household type

* review comment fixes

* models version to 24

* adding comment

* Removing models changes as it has been added in other PR

* adding default and not null in householdType

---------

Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com>
* Dev (#1235)

* Hlm 6385 irs changes (#841)

* HLM-6385: added changes for IRS activity track and closed household concepts

* HLM-6385: added changes for IRS activity track and closed household concepts, added db migration script, validations for closed household

* HLM-6385: added changes for location tracking

* HLM-6385: added changes for location points

* HLM-6385: added clientReferenceId and tenantId in LocationPoint, updated Location_capture model

* HLM-6385, HCMPRE-46: Updated changes as per design review

* HLM-6385, HCMPRE-46: Added Location capture changes

* HLM-6385, HCMPRE-46: Added UserAction changes

* HLM-6385, HCMPRE-46: updated common models, replaced digit models with service-common

* Revert "HLM-6385, HCMPRE-46: updated common models, replaced digit models with service-common"

This reverts commit 6abdea4.

* HLM-6385, HCMPRE-46: updated table informations and columns for migration scripts

* reverting BoundaryUtil change

* reverting BoundaryUtil changes

* HLM-6385, HCMPRE-46: updated validators and IRSConsumer

* HLM-6385, HCMPRE-46: updated validators

* HLM-6385, HCMPRE-46: updated project configuration

* HLM-6385, HCMPRE-49: updated models to have isDeleted as it is required in common utils enrichment code

* HLM-6385, HCMPRE-46: updated the projectid field, added notnull annotation

* HLM-6385, HCMPRE-46: updated all the changes related to enrichment

* HLM-6385, HCMPRE-46: made action field notnull

* HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields

* HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields, HCMPRE-116, HCMPRE-117

* HLM-6385, HCMPRE-46: updated locationCapture and userAction with mandatory latitude, longitude, locationAccuracy fields, HCMPRE-116, HCMPRE-117, added in services

* HLM-6385, HCMPRE-46: removed outdated changes from Task.java

* removed all user location models

* Refactored from LocationCapture model to UserAction and packges from irs to useraction

* HLM-6385 - lat/long irs name changes

* HLM Downsync Incremental product changes pull from impel (#831)

* HLM Downsync Incremental product changes pull from impel

* HLM removed impel specific changes

* renamed Project type filter code constant

* HLM updated beneficiary based search

* HLM updated downsync search, cycles is required only when it is smc based campaign

* HCM - removed project task resource quantity validator

* HLM updated downsync logic as per review comments

* HCMPRE-216 : Added Administration failed status for validation when task resource is empty or when status is ADMINISTRATION_FAILED

* HCMPRE-216: updated task status

* HCMPRE-216: changed to ADMINISTRATION_FAILED

* HLM-6385: updated with code review comments

* HLM-6385: added changes as per review comments, and added correct logs wherever required.

* HLM-6385: code review comments addressed.

* HLM-6385: review comment added for error handling on LocationCaptureRepository

* HLM-6385: another batch of coderabbitai code review comments addressed.

* HLM-6385: added more logs in repository for useraction and location capture

* HLM-6385: updated the code as per code review comments from @kavi-egov

---------

Co-authored-by: kavi_elrey <25226238+kavi-egov@users.noreply.github.com>
Co-authored-by: Holash Chand <holash.c@beehyv.com>

* Hcmpre 240 (#846)

* HLM closed household status

* HCMPRE-240: validate no resource task status scenario with configurable statuses

* HCMPRE-240: fixed issues related to string trimming

* HLM fixed rowversion referral bug, mis placement of rowversion validator

* HCMPRE-240: code review changes

* HCMPRE-242: updated for null resources and address check

* HCMPRE-242: added for proper null check

* HCMPRE-242: added checks for task resource where ever applicable

* HCMPRE-242: updated taskstatus to enum from string

* HCMPRE-242, HCMPRE-240: renamed task's status field to taskStatus field, as there is contradiction with EgovModel status field

* HCMPRE-242: fixed dupcalite entity cache issue for existing entity validation during bulk create

* HCMPRE-242: updated project test case for taskStatus field contraints changes : not null

* HCMPRE-242: fix generic repository code

* HCMPRE-242: added taskstatus migration script

* HCMPRE-240: updated PtIsResourceEmptyValidator, for task status

* HLM-242: added changes as per code review

* Revert "HCMPRE-242: added taskstatus migration script", and removed status field from EgovModel, and rename TaskStatus to status

This reverts commit 7caf0c4.

* HCMPRE-240: FIXED all task status reference

---------

Co-authored-by: sivajiganesh-dev <sivajiganesh.dev@gmail.com>

* HLM rowmapper issue in household, referral fixed (#848)

* HLM rowmapper issue in household, referral fixed

* HCMPRE-255: updated the changes for household

* reverted local changes commit by mistake

* added logic for cascading project date updates (#834)

* added logic for cascading project date updates

* updated application.properties

* refactored logic for using ProjectRequest pojo to send message to kafka instead of Ancestor and Descendant Projects pojo

* added comments and enhanced search project logic

* made public back to private

* made  more concise the method in project service separated create project map logic

* separated concerns of update based on action whether null or updateProjectDates

* updated action logic for just test purpose

* updated version of health-service-models library

* update logic

* updated final logic for cascading update project dates based on flag in project request

* reverted config

* reverted config 2

* added multiple line comments

* udpated error messages

* HLM fixed issues in useraction existent entity validator (#850)

* HLM fixed issues in useraction existent entity validator

* updated after code review comments

* updated version for hcm v1.5 release (#852)

* updated version for hcm v1.5 release

* HLM updated the code as per code review from code rabbit

* HCMPRE-209: updated code review comments and code documentation

* Hcmpre 309 rebase (#857)

* removed digit-models from health-services-models library

* removed digit-models from health-services-models library

* added SMSRequest model

* Updated individual models

* Updating health services models version in health services common library

* version bump

* hcmpre-309: merged removed-digit-models and rebase to dev

* HLM-309: updated common models version

---------

Co-authored-by: shubhang-egov <shubhang.dhanesha@egovernments.org>

* HCMPRE-169 code review comments (#835)

* HCMPRE-169 code review comments

* HCMPRE-169 adding code comments

* HCMPRE-169 adding code comments

* HCMPRE-169 changing mdms v2 field name for uom

* HCMPRE-169 code review comments

* HCMPRE-169 code review comments

* HCMPRE-218 adding validation for plan config name  (#844)

* HCMPRE-218 adding validation for name validation

* HCMPRE-218 adding validation for name validation

* HCMPRE-218 moving "$." into constants

* HCMPRE-218 code review comments

---------

Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com>

* HCMPRE-646: added changes (#897)

* Update CODEOWNERS (#924)

* Hcmpre 639 shashwat changes (#919)

* Removed the project facility mapping validation check as it is not required

* Removed the project facilty valaidation check in ValidatorUtil.java

* Removed the local receiverId in ValidatorUtil.java

---------

Co-authored-by: Shashwat12-egov <shashwat.k@egovernments.org>

* Fixed multiple role search in individual service (#992)

* Hcmpre 639 shashwat changes (#973)

* Removed the project facility mapping validation check as it is not required

* Removed the project facilty valaidation check in ValidatorUtil.java

* Removed the local receiverId in ValidatorUtil.java

* Validating the sender and receiver based on transactiontype

* Validating the sender and receiver based on transactiontype

* Corrected the validation for the failed case

* Added the comments

---------

Co-authored-by: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com>
Co-authored-by: kavi_elrey@1993 <25226238+kavi-egov@users.noreply.github.com>

* HCMPRE-371: Added service definition update api (#996)

* update service definition api added

* fix values persister config

* fix "values" persister config

* active added in service definition persister config

* resolved code review comments

* added includeDeleted parameter in search

* fix some issues

* fix create api

* Update ValidatorUtil.java (#1112)

* added-search-criterias-project-service (#1169)

* Service additional field (#1146)

* changed additionalDetails to additionalFields

* boolean data type added in attribute definition

* Added the filter for isActive

* changed the serviceDefinition.code size from character varying(64) to character varying(256)

* Revert "changed the serviceDefinition.code size from character varying(64) to character varying(256)"

This reverts commit 24c971f.

* Revert "Added the filter for isActive"

This reverts commit 09d65c4.

* changed the code character size from 64 to 256 (#1147)

Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>

* added validation for boolean data type in service-request

---------

Co-authored-by: yashita-egov <yashita.bansal@egovernments.org>
Co-authored-by: Jagankumar <53823168+jagankumar-egov@users.noreply.github.com>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>

* Hcmpre 469 pagination all (#891)

* HCMPRE-469: added changes for facility count

* HCMPRE-469: added changes for models, added totalCount fields in required model classes

* HCMPRE-469: added changes for project facility, project staff, project resource, hf-referral, stock and stock reconciliation, also added helper function in common utils for findWithCount

* HCMPRE-469: added changes for removing digit-models deprecated dependency, replaced with tracer library references and mdms client references

* HCMPRE-469: added changes for project service, removed reference for digits model

* Removed the dev from version

* Removed the dev from version of common libraries

* Removed the dev from version of common libraries

* Removed the order by id statement while searching the facility

* Removed setting of total count line from the FacilityService file

* Removed setting of total count line from the FacilityService file

---------

Co-authored-by: Shashwat12-egov <shashwat.k@egovernments.org>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>

* PR to develop branch for Microplanning v0.1 (changes in plan-service, resource-generator service) (#1176)

* HCMPRE-599 updating Plan service models

* HCMPRE-599 updating Plan service models

* HCMPRE-599 changes

* HCMPRE-599 adding census POJOs

* HCMPRE-599changes for triggering pland census records on workflow status

* HCMPRE-599 app.prop changes for resource generator service

* Renaming resource-estimation-service to resource-generator

* HCMPRE-1078  enrichment of resource mapping

* HCMPRE-1122 changing processing logic

* HCMPRE-1122 changing processing logic

* HCMPRE-1122 updating operation related validations

* HCMPRE-1122 adding method comments

* enhancement in facilityCatchmentConsumer

* enhancement in facilityCatchmentConsumer

* removing catchement topic that was added before

* added wf validation for approving estimations

* adding additionalDetails as string while preparing rows for batchUpdate

* adding additionalDetails as string while preparing rows for batchUpdate

* HCMPRE-1094 changes for facility mapping create trigger on workflow

* reverting the change in census-bulk-api

* parsing additional details in bulk update api

* Added plan config name in plan employee's and plan facility's search criteria

* Bypassing validations for operations when source is CUSTOM

* added workflow validations

* removing unused service constants

* Changes for triggering plan-facility mapping

* adding project factory data create host

* handling case for empty areaCodes in search criteria

* handling case for empty areaCodes in search criteria

* adding project factory data create host

* Adding facility create trigger status

* Adding additionalField table in census

* adding plan config name in plan employee and plan facility pojo

* Adding additionalField table in census

* implemented partial search in plan config name

* Changing datatype of value

* HCMPRE-1162 enrich additionalfieldForCensus

* HCMPRE-1162 enrich additionalfieldForCensus

* updated query builder for census

* handling null pointer exception on updating additional details

* Changes to allow assumption values in input

* Removing older method for getting input value

* Making editable false for uploaded additional field during census create

* HCMPRE-853 removing lat long fields from additional field overridekeys

* Changes for adding execution order for operations

* Changes for adding execution order for operations

* Adding facilityName column and enriching servingPop

* HCMPRE-853 added chnages for census search and fetching boundarycodes from one sheet

* HCMPRE-853 changes for updating file with approved census data

* HCMPRE-853 adding logs

* pull from microplanning-dev

* HCMPRE-853 integrating with project factory with updated resources

* modification in wf-service

* workflow auto-assignee issue

* HCMPRE-853 commenting project factory integration

* adding pagination for plan-employee api

* changed the data type of BigDecimal

* HCMPRE-1282 changes for updating estimates into plan

* HCMPRE-1282 app.prop changes

* Adding case for when celltype is formula.

* enriching additional details with additional field key-value

* modified orderBy clause

* made changes in order by clause

* added facilityType

* pull from microplanning-dev

* making fuzzy search cAse-insenSItive

* making fuzzy search cAse-insenSItive

* making fuzzy search cAse-insenSItive

* pull from microplanning-dev

* pull from microplanning-dev

* modified pagination

* HCMPRE-1282 changes for updating approved plans into file for campaign integration

* added planConfigStatus in search criteria

* HCMPRE-1282 changes for updating approved plans into file for campaign integration

* HCMPRE-771 merging multiple alter table migration scripts into create table scripts.

* Adding workflow restricted roles in census

* Adding workflow restricted roles in census

* Fixing limit and adding check for empty row

* Fixing limit and adding check for empty row

* added ranked query for plan employee assignment

* added ranked query for plan employee assignment

* HCMPRE-1300 DB migration script cleanup

* adding plan bulk update topic

* Adding facility name in census additional details

* Wf auto assignment to multiple people

* Wf auto assignment to multiple people

* Adding boundaryTypeHierarchy Pojos and search endpoint

* enriching jurisdiction mapping in census

* changing jurisdictionMapping from jsonIgnore to jsonProperty

* optimizing the enrichment functions and adding comments

* handling null pointer exception

* Wf auto assignment to multiple people

* Set last modified time on update call

* enriching serving population with sum of confirmed target population of serving boundaries

* Reverting campaign update at the end.

* modifying Wf for send back actions

* enriching jurisdiction mapping in plan

* setting assignees separetly for send back actions

* Changing assignee column to Text in db

* Changing assignee column to Text in db

* enriching jurisdiction mapping

* Changing validation logic for operations

* enriching jurisdiction mapping

* Changes for only validating when operation is active

* Sort operations in planconfig search by execution order

* Sort operations in planconfig search by execution order

* Sort operations in planconfig search by execution order

* Sort operations in planconfig search by execution order

* type casting jurisdiction into list

* Adding census changelog

* Adding census changelog

* Adding census changelog

* Adding census changelog

* Adding census changelog

* Show on UI false for lat long fields

* Updated plan service CHANGELOG

* update plan config validation

* Adding jurisdiction mapping in plan facility

* Changing all collection dataType from list to set in API search criteria

* Changing all collection dataType from list to set in API search criteria

* removing validation for operation source

* adding overloaded method for query builder in plan

* adding overloaded method for query builder in plan

* Adding validation to check for duplicates

* pull from census-bulk-api

* pull from census-bulk-api

* Removing comments from WF in resource generator

* Decreasing min size of assumptionvalue in Operation POJO to 1.

* Changing mdms master in plan service for hierarchyConfig

* changing min size of resource type in resource pojo

* increasing request size for producer

* changed version from 1.1.0 to 1.0.0

* changed version from 1.1.0 to 1.0.0

* changing the order

* changing the order

* changing the order

* Increasing request size in application.properties

* Updating resource generator changelog

* Updating resource generator changelog

* Adding boundaryAncestralPath for Plan Facility API

* Adding boundaryAncestralPath for Plan Facility API

* Adding ProjectFactory consumer in Plan Facility Service

* Adding ProjectFactory consumer in Plan Facility Service

* Adding plan changelog

* Adding empty list as service boundary when null in consumer for project-factory

* Increasing the max-request-size in census producer configuration

* Increasing the max-request-size in plan producer configuration

* Adding orderBy clause for plan search query

* Removing unused census consumer

* Replacing map from set for duplicate check in census row mapper

* Replacing map from set for duplicate check in plan config row mapper

* Replacing map from set for duplicate check in census row mapper

* Replacing map from set for duplicate check in census row mapper

* Replacing map from set for duplicate check in plan config row mapper

* Replacing map from set for duplicate check in plan row mapper

* Clearing set on new census entry

* Clearing set on new plan entry

* Clearing set on new plan config entry

---------

Co-authored-by: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com>
Co-authored-by: Tanishi Goyal <tanishi.goyal@egovernments.org>

---------

Co-authored-by: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com>
Co-authored-by: kavi_elrey <25226238+kavi-egov@users.noreply.github.com>
Co-authored-by: Holash Chand <holash.c@beehyv.com>
Co-authored-by: sivajiganesh-dev <sivajiganesh.dev@gmail.com>
Co-authored-by: nitish-egov <137176807+nitish-egov@users.noreply.github.com>
Co-authored-by: shubhang-egov <shubhang.dhanesha@egovernments.org>
Co-authored-by: Priyanka-eGov <74049060+Priyanka-eGov@users.noreply.github.com>
Co-authored-by: Shashwat12-egov <shashwat.k@egovernments.org>
Co-authored-by: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com>
Co-authored-by: yashita-egov <yashita.bansal@egovernments.org>
Co-authored-by: Jagankumar <53823168+jagankumar-egov@users.noreply.github.com>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>
Co-authored-by: Tanishi Goyal <tanishi.goyal@egovernments.org>

* Moving PlanValidator and PlanEnricher to respective folders. (#1280)

* fixed import issues (#1281)

Co-authored-by: kavi_elrey <25226238+kavi-egov@users.noreply.github.com>

---------

Co-authored-by: Naveen J <83631045+naveen-egov@users.noreply.github.com>
Co-authored-by: kanishq-egov <138671649+kanishq-egov@users.noreply.github.com>
Co-authored-by: kavi_elrey <25226238+kavi-egov@users.noreply.github.com>
Co-authored-by: sivajiganesh-dev <sivajiganesh.dev@gmail.com>
Co-authored-by: nitish-egov <137176807+nitish-egov@users.noreply.github.com>
Co-authored-by: shubhang-egov <shubhang.dhanesha@egovernments.org>
Co-authored-by: Priyanka-eGov <74049060+Priyanka-eGov@users.noreply.github.com>
Co-authored-by: Shashwat12-egov <shashwat.k@egovernments.org>
Co-authored-by: Shashwat Mishra <71879793+shashwat-egov@users.noreply.github.com>
Co-authored-by: yashita-egov <yashita.bansal@egovernments.org>
Co-authored-by: Jagankumar <53823168+jagankumar-egov@users.noreply.github.com>
Co-authored-by: shubhang-eGov <70943369+shubhang-eGov@users.noreply.github.com>
Co-authored-by: Tanishi Goyal <tanishi.goyal@egovernments.org>
Copy link
Contributor

coderabbitai bot commented Jan 29, 2025

Walkthrough

This pull request introduces comprehensive changes across multiple services, focusing on enhancing email notifications, household management, and project search capabilities. The modifications span several modules including HRMS, Household, and Project services, with key updates involving email notification infrastructure, household type management, and project search functionality. The changes introduce new configuration properties, service methods, and data models to support more flexible and feature-rich interactions.

Changes

File/Module Change Summary
core-services/egov-hrms/pom.xml Updated project version to 1.3.0, added PostgreSQL dependency version 42.7.1
core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java Added email notification configuration properties
core-services/egov-hrms/src/main/java/org/egov/hrms/service/NotificationService.java Introduced processEmailNotification method for handling email notifications
health-services/household/pom.xml Updated project version to 1.1.5, updated dependency versions
health-services/household/src/main/resources/db/migration/main/V20241114114225__household_type_ddl.sql Added householdType column to HOUSEHOLD table
health-services/project/pom.xml Updated project version to 1.1.6, updated dependency versions
health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java Added isAncestorProjectId parameter for project search functionality

Sequence Diagram

sequenceDiagram
    participant Client
    participant ProjectService
    participant ProjectRepository
    participant Database

    Client->>ProjectService: searchProject(request, isAncestorProjectId=true)
    ProjectService->>ProjectRepository: getProjects(request, isAncestorProjectId=true)
    ProjectRepository->>Database: Query projects with ancestor relationship
    Database-->>ProjectRepository: Return matching projects
    ProjectRepository-->>ProjectService: Return project list
    ProjectService-->>Client: Return projects including ancestors
Loading

Possibly related PRs

Suggested Reviewers

  • sathishp-eGov
  • kavi-egov
  • shashwat-egov

Poem

🐰 Hopping through code with glee,
Emails dance, households free,
Projects search with ancestral might,
Our system grows, oh what a delight!
CodeRabbit's magic, version by version, 🚀

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kavi-egov kavi-egov merged commit 1585e2f into master Jan 29, 2025
4 of 6 checks passed
Copy link
Contributor

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

🛑 Comments failed to post (93)
health-services/project/src/main/java/org/egov/project/repository/rowmapper/TargetRowMapper.java (1)

44-44: 💡 Codebase verification

Add null check when using BeneficiaryType.fromValue()

The fromValue() method returns null for invalid values, which will cause a NullPointerException when used directly. The database column being varchar(64) means invalid values are possible. Add a null check and appropriate error handling:

BeneficiaryType beneficiaryType = BeneficiaryType.fromValue(target_beneficiaryType);
if (beneficiaryType == null) {
    throw new CustomException("INVALID_BENEFICIARY_TYPE", 
        "Invalid beneficiary type: " + target_beneficiaryType);
}
🔗 Analysis chain

Add error handling for invalid beneficiary types.

The BeneficiaryType.fromValue() call could throw a runtime exception if an invalid value is encountered in the database. Consider adding error handling to gracefully handle such cases.

Let's verify the possible values in the database:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential invalid beneficiary types in the database
# Note: This helps identify if there are any values that might cause runtime exceptions

# Search for SQL schema files to understand valid beneficiary types
fd -e sql | xargs rg -i 'beneficiaryType|beneficiary_type'

# Search for enum definition to compare with database values
ast-grep --pattern 'enum BeneficiaryType {
  $$$
}'

Length of output: 478


Script:

#!/bin/bash
# Find BeneficiaryType enum definition and its usage
rg -A 10 "enum BeneficiaryType" 

# Find usages of fromValue to see error handling patterns
rg "BeneficiaryType\.fromValue"

# Look for similar enum handling patterns
rg "fromValue.*throw"

Length of output: 1714


Script:

#!/bin/bash
# Get complete BeneficiaryType enum implementation
cat "health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryType.java"

Length of output: 762

health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHouseholdResponse.java (2)

12-16: 🧹 Nitpick (assertive)

Consider adding @JsonIgnoreProperties(ignoreUnknown = true) annotation.

Adding this annotation would make the class more resilient to API changes by ignoring unknown properties during deserialization.

 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
+@JsonIgnoreProperties(ignoreUnknown = true)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)

22-23: ⚠️ Potential issue

Fix field naming convention and type.

  1. The field name "Households" violates Java naming conventions. Field names should start with lowercase letters.
  2. Based on the context and class name, this field should be a List to handle multiple households.

Apply this diff to fix both issues:

 @JsonProperty("Households")
-private DownsyncCLFHousehold Households;
+private List<DownsyncCLFHousehold> households;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	@JsonProperty("Households")
	private List<DownsyncCLFHousehold> households;
health-services/household/src/main/java/org/egov/household/validators/household/HCommunityValidator.java (5)

3-24: 🧹 Nitpick (assertive)

Consider utilizing the @slf4j logger.

The class is annotated with @Slf4j but doesn't use any logging statements. Consider adding appropriate logging for better observability, especially for validation failures.


48-56: 🧹 Nitpick (assertive)

Extract error creation logic to a separate method.

The error creation logic could be extracted to improve readability and reusability.

+    private Error createCommunityAccessError() {
+        return Error.builder()
+                .errorMessage("User doesn't have permission to create/update community household")
+                .errorCode("COMMUNITY_USER_ACCESS_DENIED")
+                .type(Error.ErrorType.NON_RECOVERABLE)
+                .exception(new CustomException("COMMUNITY_USER_ACCESS_DENIED",
+                        "User doesn't have permission to create/update community household"))
+                .build();
+    }
+
     @Override
     public Map<Household, List<Error>> validate(HouseholdBulkRequest request) {
         // ... existing code ...
-                Error error = Error.builder()
-                        .errorMessage("User doesn't have permission to create/update community household")
-                        .errorCode("COMMUNITY_USER_ACCESS_DENIED")
-                        .type(Error.ErrorType.NON_RECOVERABLE)
-                        .exception(new CustomException("COMMUNITY_USER_ACCESS_DENIED",
-                                "User doesn't have permission to create/update community household"))
-                        .build();
+                Error error = createCommunityAccessError();
                 populateErrorDetails(household, error, errorDetailsMap);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    private Error createCommunityAccessError() {
        return Error.builder()
                .errorMessage("User doesn't have permission to create/update community household")
                .errorCode("COMMUNITY_USER_ACCESS_DENIED")
                .type(Error.ErrorType.NON_RECOVERABLE)
                .exception(new CustomException("COMMUNITY_USER_ACCESS_DENIED",
                        "User doesn't have permission to create/update community household"))
                .build();
    }

                Error error = createCommunityAccessError();
                // Populate error details for the household
                populateErrorDetails(household, error, errorDetailsMap);
            });

43-47: ⚠️ Potential issue

Add null checks for UserInfo and roles.

The code assumes UserInfo and roles are non-null, which could lead to NullPointerException.

+        if (request.getRequestInfo() == null 
+                || request.getRequestInfo().getUserInfo() == null 
+                || request.getRequestInfo().getUserInfo().getRoles() == null) {
+            throw new CustomException("INVALID_REQUEST", "Request info, user info, or roles cannot be null");
+        }
         if (!CollectionUtils.isEmpty(communityHouseholds) &&
                 request.getRequestInfo().getUserInfo().getRoles()
                 .stream()
                 .noneMatch(role -> role.getCode().equals(configuration.getCommunityHouseholdCreatorRoleCode()))) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        if (request.getRequestInfo() == null 
                || request.getRequestInfo().getUserInfo() == null 
                || request.getRequestInfo().getUserInfo().getRoles() == null) {
            throw new CustomException("INVALID_REQUEST", "Request info, user info, or roles cannot be null");
        }
        if (!CollectionUtils.isEmpty(communityHouseholds) &&
                request.getRequestInfo().getUserInfo().getRoles()
                .stream()
                .noneMatch(role -> role.getCode().equals(configuration.getCommunityHouseholdCreatorRoleCode()))) {
            communityHouseholds.forEach(household -> {

34-59: 🧹 Nitpick (assertive)

Add logging for validation failures.

Add appropriate logging statements to track validation failures:

     @Override
     public Map<Household, List<Error>> validate(HouseholdBulkRequest request) {
         HashMap<Household, List<Error>> errorDetailsMap = new HashMap<>();
+        log.debug("Starting community household validation");
         
         // ... existing code ...
         
         if (!CollectionUtils.isEmpty(communityHouseholds) &&
                 request.getRequestInfo().getUserInfo().getRoles()
                 .stream()
                 .noneMatch(role -> role.getCode().equals(configuration.getCommunityHouseholdCreatorRoleCode()))) {
+            log.error("User lacks permission to manage community households. User roles: {}",
+                    request.getRequestInfo().getUserInfo().getRoles());
             communityHouseholds.forEach(household -> {
                 // ... error creation ...
             });
         }
+        log.debug("Completed community household validation. Found {} errors", errorDetailsMap.size());
         return errorDetailsMap;
     }

Committable suggestion skipped: line range outside the PR's diff.


37-41: 🧹 Nitpick (assertive)

Consider optimizing the stream operation.

The stream operation could be more efficient by combining the filter conditions:

-        List<Household> communityHouseholds = request.getHouseholds()
-                .stream()
-                .filter(household -> household.getHouseholdType() != null &&
-                        household.getHouseholdType().equals(HouseHoldType.COMMUNITY))
-                .toList();
+        List<Household> communityHouseholds = request.getHouseholds()
+                .stream()
+                .filter(household -> HouseHoldType.COMMUNITY.equals(household.getHouseholdType()))
+                .toList();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        List<Household> communityHouseholds = request.getHouseholds()
                .stream()
                .filter(household -> HouseHoldType.COMMUNITY.equals(household.getHouseholdType()))
                .toList();
health-services/project/src/main/java/org/egov/project/repository/querybuilder/ProjectAddressQueryBuilder.java (3)

75-84: 🧹 Nitpick (assertive)

LGTM! Consider enhancing the comment block.

The implementation correctly handles both exact matches and hierarchical relationships using prepared statements. The comment could be more descriptive about the pattern matching behavior.

-            /*
-            * If isAncestorProjectId is set to true, Then either id equals to project id or projectHierarchy
-            *  should have id of the project
-             */
+            /*
+             * Handles ancestor-descendant relationship in project hierarchy:
+             * 1. Direct match: project.id equals the search criteria
+             * 2. Hierarchical match: projectHierarchy contains the search criteria
+             *    Example: If project A has id "1" and its descendants have
+             *    projectHierarchy values like "1", "1.2", "1.2.3", etc.,
+             *    searching for id "1" with isAncestorProjectId=true will match all of them.
+             */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            /*
             * Handles ancestor-descendant relationship in project hierarchy:
             * 1. Direct match: project.id equals the search criteria
             * 2. Hierarchical match: projectHierarchy contains the search criteria
             *    Example: If project A has id "1" and its descendants have
             *    projectHierarchy values like "1", "1.2", "1.2.3", etc.,
             *    searching for id "1" with isAncestorProjectId=true will match all of them.
             */
            if (isAncestorProjectId && StringUtils.isNotBlank(project.getId())) {
                addClauseIfRequired(preparedStmtList, queryBuilder);
                queryBuilder.append(" ( prj.projectHierarchy LIKE ? OR prj.id =? ) ");
                preparedStmtList.add('%' + project.getId() + '%');
                preparedStmtList.add(project.getId());
            } else if (StringUtils.isNotBlank(project.getId())) {

394-395: 🧹 Nitpick (assertive)

Add method documentation for clarity.

The method implementation is correct, but it lacks documentation explaining its purpose and parameters.

+    /**
+     * Returns query string to get total count of projects based on search criteria
+     *
+     * @param projects List of projects to search for
+     * @param tenantId Tenant identifier
+     * @param lastChangedSince Filter by last modified time
+     * @param includeDeleted Include deleted records if true
+     * @param createdFrom Filter by creation time start
+     * @param createdTo Filter by creation time end
+     * @param isAncestorProjectId If true, matches projects where id equals project id or exists in projectHierarchy
+     * @param preparedStatement List to store prepared statement parameters
+     * @return SQL query string for counting matching projects
+     */
     public String getSearchCountQueryString(List<Project> projects, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId, List<Object> preparedStatement) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    /**
     * Returns query string to get total count of projects based on search criteria
     *
     * @param projects List of projects to search for
     * @param tenantId Tenant identifier
     * @param lastChangedSince Filter by last modified time
     * @param includeDeleted Include deleted records if true
     * @param createdFrom Filter by creation time start
     * @param createdTo Filter by creation time end
     * @param isAncestorProjectId If true, matches projects where id equals project id or exists in projectHierarchy
     * @param preparedStatement List to store prepared statement parameters
     * @return SQL query string for counting matching projects
     */
    public String getSearchCountQueryString(List<Project> projects, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId, List<Object> preparedStatement) {
        String query = getProjectSearchQuery(projects, config.getMaxLimit(), config.getDefaultOffset(), tenantId, lastChangedSince, includeDeleted, createdFrom, createdTo, isAncestorProjectId, preparedStatement, true);

49-53: 🧹 Nitpick (assertive)

Enhance method documentation for better clarity.

While the documentation explains the purpose of isAncestorProjectId, it would be beneficial to add:

  • Example usage scenarios
  • Impact on query behavior
  • Return value description
     /**
      * Constructs project search query based on conditions
-     * @param isAncestorProjectId if set to true, project id in the projects would be considered as ancestor project id.
+     * @param projects List of projects to search for
+     * @param limit Maximum number of records to return
+     * @param offset Number of records to skip
+     * @param tenantId Tenant identifier
+     * @param lastChangedSince Filter by last modified time
+     * @param includeDeleted Include deleted records if true
+     * @param createdFrom Filter by creation time start
+     * @param createdTo Filter by creation time end
+     * @param isAncestorProjectId If true, matches projects where id equals project id or exists in projectHierarchy
+     * @param preparedStmtList List to store prepared statement parameters
+     * @param isCountQuery If true, returns count query instead of select query
+     * @return Constructed SQL query string
      */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    /**
     * Constructs project search query based on conditions
     * @param projects List of projects to search for
     * @param limit Maximum number of records to return
     * @param offset Number of records to skip
     * @param tenantId Tenant identifier
     * @param lastChangedSince Filter by last modified time
     * @param includeDeleted Include deleted records if true
     * @param createdFrom Filter by creation time start
     * @param createdTo Filter by creation time end
     * @param isAncestorProjectId If true, matches projects where id equals project id or exists in projectHierarchy
     * @param preparedStmtList List to store prepared statement parameters
     * @param isCountQuery If true, returns count query instead of select query
     * @return Constructed SQL query string
     */
    public String getProjectSearchQuery(List<Project> projects, Integer limit, Integer offset, String tenantId, Long lastChangedSince, Boolean includeDeleted, Long createdFrom, Long createdTo, boolean isAncestorProjectId, List<Object> preparedStmtList, boolean isCountQuery) {
health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCLFHousehold.java (3)

19-20: 🧹 Nitpick (assertive)

Rename JSON property to match field name convention.

The JSON property name "HouseholdCountMap" doesn't follow the camelCase convention used in the field name. Additionally, the name suggests it's a Map but it's actually a List.

-    @JsonProperty("HouseholdCountMap")
+    @JsonProperty("householdMemberCountMap")
     List<HouseholdMemberMap> householdMemberCountMap;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	@JsonProperty("householdMemberCountMap")
	List<HouseholdMemberMap> householdMemberCountMap;

8-8: 🧹 Nitpick (assertive)

Remove unused import.

The org.egov.common.models.household.Household import is not used in this class.

-import org.egov.common.models.household.Household;

18-24: 🧹 Nitpick (assertive)

Add documentation and validation constraints.

Please consider the following improvements:

  1. Add class-level documentation explaining the purpose and usage of this model
  2. Add property-level documentation
  3. Consider adding validation annotations if any fields are required

Example improvement:

+/**
+ * Data model for household downsync operations in CLF context.
+ * Used to transfer household member mapping information along with downsync criteria.
+ */
 public class DownsyncCLFHousehold {
+    /**
+     * List of household member mappings containing count information
+     */
     @JsonProperty("HouseholdCountMap")
+    @NotNull
     List<HouseholdMemberMap> householdMemberCountMap;

+    /**
+     * Criteria for the downsync operation
+     */
     @JsonProperty("DownsyncCriteria")
+    @NotNull
     DownsyncCriteria downsyncCriteria;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

/**
 * Data model for household downsync operations in CLF context.
 * Used to transfer household member mapping information along with downsync criteria.
 */
public class DownsyncCLFHousehold {
    /**
     * List of household member mappings containing count information
     */
    @JsonProperty("HouseholdCountMap")
    @NotNull
    List<HouseholdMemberMap> householdMemberCountMap;

    /**
     * Criteria for the downsync operation
     */
    @JsonProperty("DownsyncCriteria")
    @NotNull
    DownsyncCriteria downsyncCriteria;
}
health-services/household/src/main/java/org/egov/household/validators/household/HCommunityTypeValidator.java (5)

29-29: 🧹 Nitpick (assertive)

Consider more specific configuration property naming.

The configuration property isHouseholdTypeSameValidation could be more specific to this validator's purpose, such as isCommunityHouseholdValidationEnabled or preventMixedHouseholdTypes.


19-25: 🧹 Nitpick (assertive)

LGTM! Well-structured class with proper dependency injection.

The constructor injection and final field are good practices. Note that the @Autowired annotation on the constructor is optional in newer Spring versions when there's only one constructor.

-    @Autowired
     public HCommunityTypeValidator(HouseholdConfiguration configuration) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

public class HCommunityTypeValidator implements Validator<HouseholdBulkRequest, Household> {
    private final HouseholdConfiguration configuration;

    public HCommunityTypeValidator(HouseholdConfiguration configuration) {
        this.configuration = configuration;
    }

31-35: 🧹 Nitpick (assertive)

Optimize stream operation and add null safety.

The stream operation can be more efficient and safer with proper null checks.

-            List<Household> communityHouseholds = request.getHouseholds()
-                    .stream()
-                    .filter(household -> household.getHouseholdType() != null &&
-                            household.getHouseholdType().equals(HouseHoldType.COMMUNITY))
-                    .toList();
+            List<Household> communityHouseholds = request.getHouseholds()
+                    .stream()
+                    .filter(household -> HouseHoldType.COMMUNITY.equals(household.getHouseholdType()))
+                    .toList();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            List<Household> communityHouseholds = request.getHouseholds()
                    .stream()
                    .filter(household -> HouseHoldType.COMMUNITY.equals(household.getHouseholdType()))
                    .toList();

40-45: 🧹 Nitpick (assertive)

Refactor error handling to avoid message duplication.

The error message is duplicated in both the Error and CustomException. Consider extracting it to a constant and making the message more descriptive.

+    private static final String ERROR_CODE = "COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST";
+    private static final String ERROR_MESSAGE = "Cannot process community households along with family households in the same request. Please submit them separately.";

     // In the validate method:
     Error error = Error.builder()
-            .errorMessage("Community and Family household cannot be in same request")
-            .errorCode("COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST")
+            .errorMessage(ERROR_MESSAGE)
+            .errorCode(ERROR_CODE)
             .type(Error.ErrorType.NON_RECOVERABLE)
-            .exception(new CustomException("COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST", "Community and Family household cannot be in same request"))
+            .exception(new CustomException(ERROR_CODE, ERROR_MESSAGE))
             .build();

Committable suggestion skipped: line range outside the PR's diff.


27-52: ⚠️ Potential issue

Add null check for request households.

The validation should handle the case where request.getHouseholds() is null to prevent NullPointerException.

     public Map<Household, List<Error>> validate(HouseholdBulkRequest request) {
         HashMap<Household, List<Error>> errorDetailsMap = new HashMap<>();
+        if (CollectionUtils.isEmpty(request.getHouseholds())) {
+            return errorDetailsMap;
+        }
         if (configuration.isHouseholdTypeSameValidation()) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    public Map<Household, List<Error>> validate(HouseholdBulkRequest request) {
        HashMap<Household, List<Error>> errorDetailsMap = new HashMap<>();
        if (CollectionUtils.isEmpty(request.getHouseholds())) {
            return errorDetailsMap;
        }
        if (configuration.isHouseholdTypeSameValidation()) {
            // validate if request contains households of different householdTypes
            List<Household> communityHouseholds = request.getHouseholds()
                    .stream()
                    .filter(household -> household.getHouseholdType() != null &&
                            household.getHouseholdType().equals(HouseHoldType.COMMUNITY))
                    .toList();

            if (!CollectionUtils.isEmpty(communityHouseholds) &&
                    request.getHouseholds().size() != communityHouseholds.size()) {
                communityHouseholds.forEach(household -> {
                    Error error = Error.builder()
                            .errorMessage("Community and Family household cannot be in same request")
                            .errorCode("COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST")
                            .type(Error.ErrorType.NON_RECOVERABLE)
                            .exception(new CustomException("COMMUNITY_AND_FAMILY_HOUSEHOLD_IN_SAME_REQUEST", "Community and Family household cannot be in same request"))
                            .build();
                    // Populate error details for the household
                    populateErrorDetails(household, error, errorDetailsMap);
                });
            }
        }
        return errorDetailsMap;
    }
core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeSearchCriteria.java (1)

46-46: 🧹 Nitpick (assertive)

Add size validation for userServiceUuids field.

Consider adding a @SiZe constraint similar to other String fields in the class.

+    @Size(max = 250)
     private List<String> userServiceUuids;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    @Size(max = 250)
	private List<String> userServiceUuids;
health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/HouseholdMemberMap.java (2)

9-13: 🧹 Nitpick (assertive)

Consider adding JSON handling annotations.

Since this is a DTO class used in downsync operations, consider adding these annotations to make it more robust:

+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.io.Serializable;

 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
+@JsonIgnoreProperties(ignoreUnknown = true)
-public class HouseholdMemberMap {
+public class HouseholdMemberMap implements Serializable {
+    private static final long serialVersionUID = 1L;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class HouseholdMemberMap implements Serializable {
    private static final long serialVersionUID = 1L;

15-17: 🧹 Nitpick (assertive)

Add field validation and documentation.

Consider these improvements for better robustness and maintainability:

+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Min;
+
+    /**
+     * The household entity associated with this mapping
+     */
+    @NotNull(message = "Household cannot be null")
     private Household household;

+    /**
+     * Number of members in the household
+     */
+    @NotNull(message = "Number of members cannot be null")
+    @Min(value = 0, message = "Number of members cannot be negative")
     private Integer numberOfMembers;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Min;

    /**
     * The household entity associated with this mapping
     */
    @NotNull(message = "Household cannot be null")
	private Household household;

    /**
     * Number of members in the household
     */
    @NotNull(message = "Number of members cannot be null")
    @Min(value = 0, message = "Number of members cannot be negative")
	private Integer numberOfMembers;
core-services/egov-hrms/src/main/java/org/egov/hrms/utils/HRMSConstants.java (1)

33-34: 💡 Codebase verification

Potential unused constant HEALTH_HRMS_EMAIL_CODE

While HEALTH_HRMS_LOCALIZATION_MODULE_CODE is properly used for localization, HEALTH_HRMS_EMAIL_CODE appears to be unused in the codebase. Consider either:

  • Implementing the feature that uses this constant
  • Removing it if it's no longer needed
  • Verifying if the constant value matches the actual localization key if the feature exists
🔗 Analysis chain

LGTM! Verify the constant values match the configuration.

The new constants follow proper naming conventions and are well-placed with other localization-related constants.

Run this script to verify the constant values match the configured localization codes:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the localization codes exist and are being used correctly

# Search for the module code usage
rg -l "rainmaker-hr"

# Search for the email localization code usage
rg -l "HEALTH_HRMS_EMAIL_CODE"

Length of output: 285


Script:

#!/bin/bash
# Check how rainmaker-hr is used in NotificationUtil
rg -B 2 -A 2 "rainmaker-hr" core-services/egov-hrms/src/main/java/org/egov/hrms/utils/NotificationUtil.java

# Look for potential TODO comments or incomplete implementations
rg -i "todo|fixme|pending" core-services/egov-hrms/src/main/java/org/egov/hrms/utils/NotificationUtil.java

# Check for any email-related code that might use the email code constant
ast-grep --pattern 'email'

Length of output: 4282


Script:

#!/bin/bash
# Search for HEALTH_HRMS_EMAIL_CODE in configuration files and localization data
rg -l -g "*.yml" -g "*.yaml" -g "*.json" "HEALTH_HRMS_EMAIL_CODE"

# Search for any health-related localization or configuration files
fd -e yml -e yaml -e json . | grep -i "health.*local\|local.*health"

Length of output: 136

health-services/project/src/main/java/org/egov/project/repository/ProjectRepository.java (9)

72-75: 🧹 Nitpick (assertive)

Add clarity to the Javadoc.
Your Javadoc for isAncestorProjectId is concise. Consider expanding the description with an example of how setting isAncestorProjectId = true changes the search outcome.


84-86: 🧹 Nitpick (assertive)

Improve clarity for created collections.
The approach of pre-initializing targets and documents as empty lists is fine; consider extracting them into private helper methods if these lines appear in multiple places.


95-101: 🧹 Nitpick (assertive)

Validate handling of includeDescendants.
Similar to ancestors, confirm that searching for descendants does not cause performance issues for large tree structures. Consider introducing pagination if the potential set of descendants is large.


104-105: 🧹 Nitpick (assertive)

Confirm concurrency usage.
Your calls to getTargetsBasedOnProjectIds run synchronously. If you anticipate scaling or concurrency improvements, consider asynchronous fetching in the future.


124-126: 🧹 Nitpick (assertive)

Avoid code duplication.
This block repeats the same structure of fetching targets and documents if projectIds is not empty. Consider extracting to a helper method to reduce duplication across the repository.


127-133: 🧹 Nitpick (assertive)

Confirm coverage for multi-level ancestors.
getProjectAncestors may traverse multiple levels. If the code only expects direct parents, consider clarifying or limiting recursion for extremely deep hierarchies.

Would you like help implementing a limit on ancestor traversal depth for large or cyclical hierarchies?


135-141: 🧹 Nitpick (assertive)

Check for descendant recursion.
Similar to ancestors, verify that getProjectDescendants does not lead to performance bottlenecks or cycles. Consider adding mechanism to detect or handle cyclical references if possible.


147-149: 🧹 Nitpick (assertive)

Parallel or batched fetching possibility.
Fetching documents is identical to fetching targets. Look for ways to combine these queries or run them in parallel to reduce round trips to the DB.


353-355: 🛠️ Refactor suggestion

Add validation for large counts.
getProjectCount might return very large numbers. Ensure the returned integer doesn’t overflow. Java’s Integer can handle up to around 2.1 billion. Consider Long for counts if you expect more.

- public Integer getProjectCount(...)
+ public Long getProjectCount(...)

Committable suggestion skipped: line range outside the PR's diff.

health-services/project/src/main/java/org/egov/project/service/ProjectService.java (4)

82-86: 🧹 Nitpick (assertive)

Add usage example to Javadoc.
Consider offering a quick example in the comment that shows how isAncestorProjectId = true can broaden the project search.


135-135: 🧹 Nitpick (assertive)

Refine max limit usage.
Using projectConfiguration.getMaxLimit() is valid. Confirm that large updates do not cause performance issues if many projects are updated in one request.


290-291: 🧹 Nitpick (assertive)

Consider caching.
When searching ancestors and descendants (with includeAncestors and includeDescendants), repeated queries for the same sets can be expensive. A short-term cache may help.


312-312: 🧹 Nitpick (assertive)

Limit duplication in fetch of parent projects.
Group repeated logic for fetching parent/ancestor projects in a shared helper if used across multiple methods.

health-services/project/CHANGELOG.md (1)

3-4: 🧹 Nitpick (assertive)

Fix markdown formatting.

Add blank lines around headings and lists to comply with markdown best practices:

 All notable changes to this module will be documented in this file.
 
+
 ## 1.1.6 - 2025-01-27
+
 - Added isAncestorProjectId param for search projects API to support search projects with ancestor project id as well
+
 
 ## 1.1.5 - 2024-08-07
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

## 1.1.6 - 2025-01-27

- Added isAncestorProjectId param for search projects API to support search projects with ancestor project id as well
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


4-4: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)

health-services/household/src/main/java/org/egov/household/service/HouseholdService.java (2)

17-17: 🧹 Nitpick (assertive)

Avoid wildcard imports for better maintainability.

Consider using explicit imports instead of the wildcard import org.egov.household.validators.household.*. Explicit imports make dependencies clearer, prevent naming conflicts, and improve code maintainability.


68-71: 💡 Codebase verification

Household type change validation needs refinement

The current implementation blocks all household type changes without considering valid transition scenarios. Issues found:

  • The validator throws NON_RECOVERABLE errors for any type change without business rules for allowed transitions
  • Configuration properties (household.type.same.validation) exist but aren't utilized
  • No dedicated test coverage for type change validation scenarios
🔗 Analysis chain

Verify household type change validation logic and test coverage.

The update operation now includes additional validators, particularly for household type changes. Please ensure:

  1. The HHouseholdTypeChangeValidator correctly handles all possible type transition scenarios
  2. Adequate test coverage exists for type change validations

Run this script to analyze the type change validation logic and test coverage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find type change validator implementation and related tests

echo "Searching for type change validator implementation..."
rg -A 20 "class HHouseholdTypeChangeValidator" --type java

echo "Searching for test coverage..."
rg -A 10 "test.*HouseholdTypeChange" --type java

Length of output: 3852


Script:

#!/bin/bash
# Get complete validator implementation and related code

echo "Full validator implementation:"
rg -A 50 "class HHouseholdTypeChangeValidator" --type java

echo -e "\nSearching for test files:"
rg -l "class.*Test.*Household" --type java

echo -e "\nSearching for household type definitions:"
rg "enum.*HouseholdType|class.*HouseholdType" --type java

Length of output: 9385


Script:

#!/bin/bash
# Search for missing pieces of the validator implementation and related code

echo "Searching for changeInHouseholdType method:"
rg -A 20 "changeInHouseholdType" --type java

echo -e "\nSearching for test files (broader pattern):"
rg -l "HouseholdTest|test.*Household|Household.*Test" --type java

echo -e "\nSearching for household type in model/domain:"
fd -e java . | xargs rg "household.*type"

Length of output: 7756

health-services/libraries/health-services-models/src/main/java/org/egov/common/models/referralmanagement/beneficiarydownsync/DownsyncCriteria.java (1)

38-39: 🧹 Nitpick (assertive)

Consider adding validation constraints and improving field placement.

  1. Consider adding validation constraints to householdId similar to other ID fields.
  2. Consider moving the field next to other ID fields (projectId, tenantId) for better code organization.
 @NotNull
 private String tenantId;
 
+private String householdId;
+
 @Default
 private Boolean includeDeleted = false;
 
 @Default
 private Integer offset = 0;
 
 @Default
 private Integer limit = 50;
 
 private Long totalCount;

-private String householdId;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	@NotNull
	private String tenantId;
	
	private String householdId;

	@Default
	private Boolean includeDeleted = false;
	
	@Default
	private Integer offset = 0;
	
	@Default
	private Integer limit = 50;
	
	private Long totalCount;
health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseHoldType.java (2)

8-14: 🧹 Nitpick (assertive)

Fix inconsistent spacing in enum declarations.

Remove extra blank lines between enum constants for consistent formatting.

 public enum HouseHoldType {
-
   FAMILY("FAMILY"),
-
   COMMUNITY("COMMUNITY"),
-
   OTHER("OTHER");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	FAMILY("FAMILY"),
	COMMUNITY("COMMUNITY"),
	OTHER("OTHER");

21-29: 🛠️ Refactor suggestion

Improve error handling and JSON serialization.

  1. The fromValue method returns null for invalid values, which could lead to NPEs. Consider throwing an IllegalArgumentException instead.
  2. For consistency with BeneficiaryType, consider adding @JsonValue to the toString method.
 @JsonCreator
 public static HouseHoldType fromValue(String text) {
   for (HouseHoldType b : HouseHoldType.values()) {
     if (String.valueOf(b.value).equalsIgnoreCase(text)) {
       return b;
     }
   }
-  return null;
+  throw new IllegalArgumentException("Unknown HouseHoldType: " + text);
 }

+@Override
+@JsonValue
+public String toString() {
+  return String.valueOf(value);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	@JsonCreator
	public static HouseHoldType fromValue(String text) {
		for (HouseHoldType b : HouseHoldType.values()) {
			if (String.valueOf(b.value).equalsIgnoreCase(text)) {
				return b;
			}
		}
		throw new IllegalArgumentException("Unknown HouseHoldType: " + text);
	}

	@Override
	@JsonValue
	public String toString() {
		return String.valueOf(value);
	}
health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/BeneficiaryType.java (2)

7-12: 🧹 Nitpick (assertive)

Fix code formatting issues.

  1. Remove extra blank lines
  2. Fix indentation (use spaces instead of tabs)
  3. Add spaces after control flow statements
 public enum BeneficiaryType {
-
   HOUSEHOLD("HOUSEHOLD"),
-
   INDIVIDUAL("INDIVIDUAL");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

public enum BeneficiaryType {
    HOUSEHOLD("HOUSEHOLD"),
    INDIVIDUAL("INDIVIDUAL");

25-34: 🛠️ Refactor suggestion

Improve error handling in fromValue method.

Similar to HouseHoldType, returning null for invalid values could lead to NPEs. Consider throwing an IllegalArgumentException instead.

 @JsonCreator
 public static BeneficiaryType fromValue(String text) {
   for(BeneficiaryType a:BeneficiaryType.values()){
     if(String.valueOf(a.value).equalsIgnoreCase(text)){
       return a;
     }
   }
-  return null;
+  throw new IllegalArgumentException("Unknown BeneficiaryType: " + text);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

		@JsonCreator
		public static BeneficiaryType fromValue(String text) {
			for(BeneficiaryType a:BeneficiaryType.values()){
				if(String.valueOf(a.value).equalsIgnoreCase(text)){
					return a;
				}
			}
			throw new IllegalArgumentException("Unknown BeneficiaryType: " + text);
		}
health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/Target.java (1)

34-34: 🧹 Nitpick (assertive)

Add validation and documentation for beneficiaryType field.

Consider adding:

  1. @NotNull validation if this is a required field
  2. JavaDoc documentation explaining the purpose and valid values of this field
+    /**
+     * Type of beneficiary for this target.
+     * Valid values are HOUSEHOLD and INDIVIDUAL.
+     */
+    @NotNull
     @JsonProperty("beneficiaryType")
     private BeneficiaryType beneficiaryType = null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    /**
     * Type of beneficiary for this target.
     * Valid values are HOUSEHOLD and INDIVIDUAL.
     */
    @NotNull
    @JsonProperty("beneficiaryType")
    private BeneficiaryType beneficiaryType = null;
health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/Household.java (1)

30-30: 💡 Codebase verification

Member count validation is completely removed without replacement

The removal of @range validation means there are no constraints on the memberCount field at any layer:

  • No model-level range validation (only @NotNull remains)
  • No service-layer validation
  • No database constraints

This could allow invalid values like negative numbers or unreasonably large values to be stored. Consider either:

  • Restoring the @range validation
  • Adding appropriate database CHECK constraints
  • Implementing service-layer validation
🔗 Analysis chain

Verify the removal of member count validation.

The @range validation constraint has been commented out, which could allow invalid member counts. Was this intentional? If so, please document the rationale.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any other validation constraints or business logic for memberCount
rg -A 5 "memberCount" --type java

Length of output: 3060


Script:

#!/bin/bash
# Check for business validations in service layer and DB schema
echo "=== Checking service layer validations ==="
rg -B 2 -A 2 "memberCount|numberOfMembers" "health-services/household/src/main/java/org/egov/household/service"

echo -e "\n=== Checking DB schema ==="
fd -e sql . health-services/household/src/main/resources/db/migration

echo -e "\n=== Checking recent changes and documentation ==="
cat health-services/household/README.md 2>/dev/null || echo "README not found"

Length of output: 5370


Script:

#!/bin/bash
# Check the initial household table creation script for numberOfMembers constraints
cat health-services/household/src/main/resources/db/migration/main/V20221221165250__household_household_create_ddl.sql

Length of output: 729

health-services/libraries/health-services-models/src/main/java/org/egov/common/models/household/HouseholdSearch.java (1)

40-42: ⚠️ Potential issue

Use HouseHoldType enum for consistency.

The householdType field is defined as String, while the same field in Household.java uses the HouseHoldType enum. This inconsistency could lead to type safety issues.

Apply this diff to maintain consistency:

    @JsonProperty("householdType")
-   private String householdType = null;
+   private HouseHoldType householdType = null;

Committable suggestion skipped: line range outside the PR's diff.

health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java (1)

85-88: 🧹 Nitpick (assertive)

Consider extracting the householdType query logic to a separate method.

The logic for handling null values as family type is duplicated in both find and findByRadius methods. Consider extracting this to a reusable method to improve maintainability.

+    private String handleFamilyHouseholdType(String query, HouseholdSearch searchObject) {
+        if (searchObject.getHouseholdType() != null && searchObject.getHouseholdType().equalsIgnoreCase("FAMILY")) {
+            return query.replace("householdType=:householdType", "(householdType!='COMMUNITY' OR householdType IS NULL)");
+        }
+        return query;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        // To consider null values present in db as family if family parameter is passed
        if (searchObject.getHouseholdType() != null && searchObject.getHouseholdType().equalsIgnoreCase("FAMILY")) {
            query = query.replace("householdType=:householdType", "(householdType!='COMMUNITY' OR householdType IS NULL)");
        }

    private String handleFamilyHouseholdType(String query, HouseholdSearch searchObject) {
        if (searchObject.getHouseholdType() != null && searchObject.getHouseholdType().equalsIgnoreCase("FAMILY")) {
            return query.replace("householdType=:householdType", "(householdType!='COMMUNITY' OR householdType IS NULL)");
        }
        return query;
    }
health-services/household/CHANGELOG.md (1)

6-6: 🧹 Nitpick (assertive)

Fix typo in changelog entry.

There's a typo in "heath models". It should be "health models".

-Upgraded to heath models 1.0.25
+Upgraded to health models 1.0.25
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

- Upgraded to health models 1.0.25
health-services/libraries/health-services-models/CHANGELOG.md (1)

4-4: 🧹 Nitpick (assertive)

Maintain consistent verb forms in changelog entries.

The line mixes past tense ("Added") with present tense ("update"). Use consistent past tense for all entries.

-Added BeneficiaryType Enum and update in ProjectType, Target models
+Added BeneficiaryType Enum and updated ProjectType, Target models
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

- Added BeneficiaryType Enum and updated ProjectType, Target models
🧰 Tools
🪛 LanguageTool

[uncategorized] ~4-~4: This verb may not be in the correct form. Consider using a different form for this context.
Context: ...-01-03 - Added BeneficiaryType Enum and update in ProjectType, Target models - Added H...

(AI_EN_LECTOR_REPLACEMENT_VERB_FORM)

health-services/household/src/main/resources/household-persister.yml (1)

15-16: ⚠️ Potential issue

Fix inconsistent field naming.

There's an inconsistency in the field naming:

  • The INSERT query uses numberOfMembers
  • The JSON mapping uses memberCount

This inconsistency could lead to data mapping issues.

Apply this diff to fix the inconsistency:

-            - jsonPath: $.*.memberCount
+            - jsonPath: $.*.numberOfMembers
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            - jsonPath: $.*.householdType
            - jsonPath: $.*.numberOfMembers
health-services/household/src/main/java/org/egov/household/validators/household/HHouseholdTypeChangeValidator.java (5)

60-67: 🧹 Nitpick (assertive)

Avoid catching generic Exception.

Catching Exception may mask underlying errors that deserve targeted handling. Consider using more specific exceptions or applying a specialized error-handling mechanism to ensure better error categorization.


73-75: 🧹 Nitpick (assertive)

Re-evaluate NON_RECOVERABLE error type.

Labeling a household type change as NON_RECOVERABLE might be too severe. Consider whether this error is truly unrecoverable and if partial or user-driven fixes are possible, especially if the household type change might be valid under certain conditions.


34-81: 🧹 Nitpick (assertive)

Consider concurrency and partial updates.

When multiple households are validated concurrently or partially, ensure that the current approach of searching and comparing household types is transactionally consistent. Otherwise, changes could be overwritten or incorrectly flagged if updates occur mid-validation.

Also applies to: 84-96


90-91: ⚠️ Potential issue

Prevent potential NullPointerException.

Directly invoking .equals() could throw an exception if getHouseholdType() returns null. Use Objects.equals(existingEntity.getHouseholdType(), eMap.get(existingEntity.getId()).getHouseholdType()) or add null checks to safeguard against a NullPointerException.

-if (!existingEntity.getHouseholdType().equals(eMap.get(existingEntity.getId()).getHouseholdType())) {
+if (!Objects.equals(existingEntity.getHouseholdType(),
+        eMap.get(existingEntity.getId()).getHouseholdType())) {
     entitiesWithHouseholdTypeChange.add(eMap.get(existingEntity.getId()));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

                if (!Objects.equals(existingEntity.getHouseholdType(),
                        eMap.get(existingEntity.getId()).getHouseholdType())) {
                    entitiesWithHouseholdTypeChange.add(eMap.get(existingEntity.getId()));

39-49: 💡 Codebase verification

Add null checks before adding ID and clientReferenceId to lists.

The fields id and clientReferenceId are not annotated with @NotNull in either the Household class or its parent classes (EgovOfflineModel, EgovModel). Adding them directly to lists without null checks could cause NullPointerExceptions. Consider adding null checks:

entities.forEach(household -> {
    if (household.getId() != null) {
        idList.add(household.getId());
    }
    if (household.getClientReferenceId() != null) {
        clientReferenceIdList.add(household.getClientReferenceId());
    }
});
🔗 Analysis chain

Validate null references for ID and clientReferenceId.

If getId() or getClientReferenceId() can be null, adding them to the lists may cause NullPointerExceptions downstream. Please verify these fields and consider applying null-checks or validations as appropriate.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that Household's ID & clientReferenceId are never null in the codebase.

# Step 1: Search all usage of Household constructors or builders to confirm ID & clientReferenceId are mandatory
rg -A 3 "new Household" 
rg -A 3 "Household.builder("

Length of output: 4464


Script:

#!/bin/bash
# Find Household class definition and check field declarations
echo "=== Household Class Definition ==="
fd -e java Household.java -x cat {}

echo -e "\n=== Validation Patterns ==="
# Look for validation annotations or null checks on these fields
rg -B 2 -A 2 "@NotNull|@NotBlank" --type java

echo -e "\n=== Builder Pattern Usage ==="
# Search for builder pattern usage without parenthesis
rg "Household\.builder\b" -A 3

echo -e "\n=== Other Validators ==="
# Check other validators' handling of these fields
fd -e java -p "validator" -x cat {}

Length of output: 66806


Script:

#!/bin/bash
# Search for Household class definition and field declarations
echo "=== Household Class Definition ==="
rg -B 2 -A 2 "class Household" --type java

echo -e "\n=== ID and ClientReferenceId Fields ==="
# Look for id and clientReferenceId field declarations
rg -B 2 -A 2 "(\bid\b|clientReferenceId)" --type java

echo -e "\n=== Validation Patterns ==="
# Search for validation annotations or null checks on these fields
rg -B 2 -A 2 "@NotNull.*id|@NotBlank.*id|@NotNull.*clientReferenceId|@NotBlank.*clientReferenceId" --type java

echo -e "\n=== Usage in Validators ==="
# Check how validators handle these fields
fd -e java -p "validator" -x rg -l "getId\(\)|getClientReferenceId\(\)" {}

Length of output: 71091


Script:

#!/bin/bash
# Search for Household class definition and field declarations
echo "=== Household Class Fields ==="
rg -B 2 -A 2 "class Household.*\{" -g "*.java" -A 20

echo -e "\n=== Validation Annotations ==="
# Look for validation annotations on id and clientReferenceId
rg "@NotNull|@NotBlank|@Valid" -g "Household.java" -B 2 -A 2

echo -e "\n=== Validator Usage ==="
# Check how validators handle these fields
fd -e java -p "validator" -x rg -l "getId\(\)|getClientReferenceId\(\)" {}

Length of output: 81180


Script:

#!/bin/bash
# Find Household class and its parent class definition
echo "=== Household Model Class ==="
fd -e java -p "models.*Household.java" -x cat {}

echo -e "\n=== Parent Class (EgovOfflineModel) ==="
fd -e java -p "EgovOfflineModel.java" -x cat {}

echo -e "\n=== Validation Patterns in Models ==="
# Look for validation annotations in model classes
rg -B 2 -A 2 "@NotNull|@NotBlank|@Valid" --type java -g "**/models/**"

Length of output: 70243


Script:

#!/bin/bash
# Find EgovModel class definition
echo "=== EgovModel Class ==="
fd -e java -p "EgovModel.java" -x cat {}

echo -e "\n=== Validators ==="
# Look for validators handling these fields
fd -e java -p "validator" -x rg -l "getId\(\)|getClientReferenceId\(\)|id|clientReferenceId" {}

echo -e "\n=== Service Layer Usage ==="
# Check how services handle these fields
fd -e java -p "service" -x rg -l "getId\(\)|getClientReferenceId\(\)|id|clientReferenceId" {}

Length of output: 65886

core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmailRequest.java (2)

6-12: 🧹 Nitpick (assertive)

Consider adding @DaTa annotation for complete bean functionality.

While the current Lombok annotations provide basic functionality, adding @Data would provide additional useful methods like equals() and hashCode().


1-16: 🧹 Nitpick (assertive)

Add class-level documentation.

Consider adding comprehensive JavaDoc to describe:

  • The purpose of this class
  • Usage examples
  • Description of fields
core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/Email.java (2)

11-16: 🧹 Nitpick (assertive)

Remove redundant Lombok annotations.

@Data already includes @Getter, @Setter, and other functionality. Consider keeping only @Data, @Builder, @NoArgsConstructor, and @AllArgsConstructor.


28-29: 🧹 Nitpick (assertive)

Consider adding documentation for isHTML field.

Add JavaDoc to clarify the impact of this boolean flag on email rendering.

health-services/household/src/main/java/org/egov/household/config/HouseholdConfiguration.java (2)

49-50: 🛠️ Refactor suggestion

Add default value and validation for communityHouseholdCreatorRoleCode.

Consider:

  1. Adding a default value to prevent null pointer issues
  2. Adding validation to ensure the role code is not empty when required
-@Value("${household.type.community.creator.role}")
+@Value("${household.type.community.creator.role:COMMUNITY_USER}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    @Value("${household.type.community.creator.role:COMMUNITY_USER}")
    private String communityHouseholdCreatorRoleCode;

46-47: 🛠️ Refactor suggestion

Add default value for householdTypeSameValidation.

Consider providing a default value in the @value annotation to prevent issues if the property is not defined:

-@Value("${household.type.same.validation}")
+@Value("${household.type.same.validation:false}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    @Value("${household.type.same.validation:false}")
    private boolean householdTypeSameValidation;
core-services/egov-hrms/src/main/java/org/egov/hrms/web/models/IndividualBulkResponse.java (2)

37-40: 🧹 Nitpick (assertive)

Consider using primitive type for totalCount.

Since totalCount appears to be a required field with a default value, consider using the primitive long instead of Long to avoid unnecessary boxing/unboxing:

-private Long totalCount = 0L;
+private long totalCount = 0L;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    @JsonProperty("TotalCount")
    @Valid
    @Builder.Default
    private long totalCount = 0L;

46-52: 🧹 Nitpick (assertive)

Optimize addIndividualItem method.

Consider initializing the list in the constructor or using @Builder.Default to avoid repeated null checks:

-private List<Individual> individual = null;
+@Builder.Default
+private List<Individual> individual = new ArrayList<>();

 public IndividualBulkResponse addIndividualItem(Individual individualItem) {
-    if (this.individual == null) {
-        this.individual = new ArrayList<>();
-    }
     this.individual.add(individualItem);
     return this;
 }

Committable suggestion skipped: line range outside the PR's diff.

core-services/egov-hrms/src/main/java/org/egov/hrms/consumer/HrmsConsumer.java (1)

35-39: 🧹 Nitpick (assertive)

Add null checks and validation for the request.

While the Kafka listener configuration is correct, the request handling could be more robust:

  1. Add null check for the topic parameter
  2. Validate the employeeRequest after conversion
 @KafkaListener(topics = {"${kafka.topics.hrms.updateData}", "${kafka.topics.hrms.email.notification}"})
 public void listenUpdateEmployeeData(final HashMap<String, Object> record,@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
     try {
+        if (topic == null) {
+            log.error("Received null topic");
+            return;
+        }
         EmployeeRequest employeeRequest = mapper.convertValue(record, EmployeeRequest.class);
+        if (employeeRequest == null || employeeRequest.getEmployee() == null) {
+            log.error("Invalid employee request");
+            return;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    @KafkaListener(topics = {"${kafka.topics.hrms.updateData}", "${kafka.topics.hrms.email.notification}"})
    public void listenUpdateEmployeeData(final HashMap<String, Object> record,@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
        try {
            if (topic == null) {
                log.error("Received null topic");
                return;
            }
            EmployeeRequest employeeRequest = mapper.convertValue(record, EmployeeRequest.class);
            if (employeeRequest == null || employeeRequest.getEmployee() == null) {
                log.error("Invalid employee request");
                return;
            }
core-services/egov-hrms/src/main/java/org/egov/hrms/web/contract/EmployeeResponse.java (1)

73-76: 🧹 Nitpick (assertive)

Maintain consistency in JSON property naming.

The totalCount field implementation differs from UserResponse:

  1. This class exposes the field with @JsonProperty while UserResponse hides it with @JsonIgnore
  2. The JSON property name uses PascalCase ("TotalCount") while other properties use camelCase

Consider standardizing the approach:

-@JsonProperty("TotalCount")
+@JsonProperty("totalCount")
 @Builder.Default
 private Long totalCount = 0L;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	@JsonProperty("totalCount")
	@Builder.Default
	private Long totalCount = 0L;

core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java (2)

85-91: 🧹 Nitpick (assertive)

Group related Kafka topic properties together.

The email notification Kafka topic properties should be grouped with other Kafka topic properties for better maintainability.

Move the email notification topic properties to be with other Kafka topic properties:

-// Email
-@Value("${kafka.topics.notification.email}")
-private String emailNotifTopic;
-
-@Value("${notification.email.enabled}")
-private Boolean isEmailNotificationEnabled;
 
 //Kafka Topics
+@Value("${kafka.topics.notification.email}")
+private String emailNotifTopic;
+
 @Value("${kafka.topics.save.service}")
 public String saveEmployeeTopic;

Also applies to: 106-107


151-156: 🧹 Nitpick (assertive)

Group email-related configuration properties together.

The email notification implementation partner properties should be grouped with other email-related properties for better organization.

core-services/egov-hrms/src/main/java/org/egov/hrms/utils/NotificationUtil.java (10)

124-125: 🛠️ Refactor suggestion

Use HTML parser instead of string indices.

The current implementation uses string indices to parse HTML content, which is fragile and prone to errors. Consider using an HTML parser library.

-String subject = customizedMsg.substring(customizedMsg.indexOf("<h2>")+4, customizedMsg.indexOf("</h2>"));
-String body = customizedMsg.substring(customizedMsg.indexOf("</h2>")+5);
+org.jsoup.nodes.Document doc = org.jsoup.Jsoup.parse(customizedMsg);
+String subject = doc.select("h2").first().text();
+doc.select("h2").remove();
+String body = doc.body().html();

Add the following dependency to your pom.xml:

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.4</version>
</dependency>

124-125: 🛠️ Refactor suggestion

Use HTML parser instead of substring for extracting email content.

The current implementation uses substring to parse HTML content, which is fragile and may break if the HTML structure changes.

Consider using an HTML parser library like jsoup:

+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
-String subject = customizedMsg.substring(customizedMsg.indexOf("<h2>")+4, customizedMsg.indexOf("</h2>"));
-String body = customizedMsg.substring(customizedMsg.indexOf("</h2>")+5);
+Document doc = Jsoup.parse(customizedMsg);
+String subject = doc.select("h2").text();
+String body = doc.body().html();

Committable suggestion skipped: line range outside the PR's diff.


73-80: 🛠️ Refactor suggestion

Add error handling for potential null response.

The method should handle potential null responses from the REST call to prevent NullPointerException.

 public String getLocalizationMessages(EmployeeRequest employeeRequest) {
     RequestInfoWrapper requestInfoWrapper = new RequestInfoWrapper();
     requestInfoWrapper.setRequestInfo(employeeRequest.getRequestInfo());
 
     LinkedHashMap responseMap = (LinkedHashMap) restCallRepository.fetchResult(getUri(employeeRequest), requestInfoWrapper);
+    if (responseMap == null) {
+        log.error("No response received from localization service");
+        return null;
+    }
     return new JSONObject(responseMap).toString();
 }

Committable suggestion skipped: line range outside the PR's diff.


73-80: 🛠️ Refactor suggestion

Add error handling for REST call failures.

The method should handle potential exceptions from RestCallRepository.fetchResult() to prevent null pointer exceptions and provide better error reporting.

 public String getLocalizationMessages(EmployeeRequest employeeRequest) {
+    try {
         RequestInfoWrapper requestInfoWrapper = new RequestInfoWrapper();
         requestInfoWrapper.setRequestInfo(employeeRequest.getRequestInfo());
 
         LinkedHashMap responseMap = (LinkedHashMap) restCallRepository.fetchResult(getUri(employeeRequest), requestInfoWrapper);
         return new JSONObject(responseMap).toString();
+    } catch (Exception e) {
+        log.error("Error fetching localization messages", e);
+        return "{}";
+    }
 }

Committable suggestion skipped: line range outside the PR's diff.


92-93: ⚠️ Potential issue

Fix message ID splitting logic.

The message ID splitting logic has potential issues:

  1. The condition uses split("|") which splits on regex OR operator. Use split("\\|") instead.
  2. No handling of malformed message IDs.
-if (!StringUtils.isEmpty(employeeRequest.getRequestInfo().getMsgId()) && employeeRequest.getRequestInfo().getMsgId().split("|").length >= 2)
-    locale = employeeRequest.getRequestInfo().getMsgId().split("\\|")[1];
+String msgId = employeeRequest.getRequestInfo().getMsgId();
+if (!StringUtils.isEmpty(msgId)) {
+    String[] parts = msgId.split("\\|");
+    if (parts.length >= 2 && !StringUtils.isEmpty(parts[1])) {
+        locale = parts[1];
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        String msgId = employeeRequest.getRequestInfo().getMsgId();
        if (!StringUtils.isEmpty(msgId)) {
            String[] parts = msgId.split("\\|");
            if (parts.length >= 2 && !StringUtils.isEmpty(parts[1])) {
                locale = parts[1];
            }
        }

92-93: ⚠️ Potential issue

Add bounds check for message ID split operation.

The split operation on msgId could throw an ArrayIndexOutOfBoundsException if the string doesn't contain the expected delimiter.

Apply this diff to add a safer check:

-if (!StringUtils.isEmpty(employeeRequest.getRequestInfo().getMsgId()) && employeeRequest.getRequestInfo().getMsgId().split("|").length >= 2)
-    locale = employeeRequest.getRequestInfo().getMsgId().split("\\|")[1];
+String msgId = employeeRequest.getRequestInfo().getMsgId();
+if (!StringUtils.isEmpty(msgId)) {
+    String[] parts = msgId.split("\\|");
+    if (parts.length >= 2) {
+        locale = parts[1];
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        String msgId = employeeRequest.getRequestInfo().getMsgId();
        if (!StringUtils.isEmpty(msgId)) {
            String[] parts = msgId.split("\\|");
            if (parts.length >= 2) {
                locale = parts[1];
            }
        }

148-149: ⚠️ Potential issue

Avoid logging sensitive information.

The current implementation logs the entire email request which might contain sensitive information. Consider logging only non-sensitive fields or masking sensitive data.

-log.info("Email Request -> " + emailRequest.toString());
+log.info("Email sent to -> " + maskEmail(emailRequest.getEmail().getEmailTo()));
 log.info("EMAIL notification sent!");

+private String maskEmail(Set<String> emails) {
+    return emails.stream()
+        .map(email -> email.replaceAll("(?<=.{3}).(?=.*@)", "*"))
+        .collect(Collectors.joining(", "));
+}

Committable suggestion skipped: line range outside the PR's diff.


140-153: 🛠️ Refactor suggestion

Add error handling for producer failures.

The method should handle potential exceptions from producer.push() to ensure reliable email delivery tracking.

 public void sendEmail(List<EmailRequest> emailRequestList) {
     if (propertiesManager.getIsEmailNotificationEnabled()) {
         if (CollectionUtils.isEmpty(emailRequestList)) {
             log.error("No Emails Found!");
         } else {
             for (EmailRequest emailRequest : emailRequestList) {
+                try {
                     producer.push(propertiesManager.getEmailNotifTopic(), emailRequest);
                     log.info("Email Request -> " + emailRequest.toString());
                     log.info("EMAIL notification sent!");
+                } catch (Exception e) {
+                    log.error("Failed to send email to {}: {}", 
+                        emailRequest.getEmail().getEmailTo(), 
+                        e.getMessage());
+                }
             }
         }
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    public void sendEmail(List<EmailRequest> emailRequestList) {
        if (propertiesManager.getIsEmailNotificationEnabled()) {
            if (CollectionUtils.isEmpty(emailRequestList)) {
                log.error("No Emails Found!");
            } else {
                for (EmailRequest emailRequest : emailRequestList) {
                    try {
                        producer.push(propertiesManager.getEmailNotifTopic(), emailRequest);
                        log.info("Email Request -> " + emailRequest.toString());
                        log.info("EMAIL notification sent!");
                    } catch (Exception e) {
                        log.error("Failed to send email to {}: {}", 
                            emailRequest.getEmail().getEmailTo(), 
                            e.getMessage());
                    }
                }
            }
        }
    }

88-100: 🛠️ Refactor suggestion

Add null checks for configuration properties.

The method should validate that the required configuration properties from propertiesManager are not null.

 public StringBuilder getUri(EmployeeRequest employeeRequest) {
+    if (propertiesManager.getLocalizationHost() == null || propertiesManager.getLocalizationSearchEndpoint() == null) {
+        throw new IllegalStateException("Localization host or search endpoint is not configured");
+    }
     String tenantId = employeeRequest.getEmployees().get(0).getTenantId().split("\\.")[0];
 
     String locale = HRMS_LOCALIZATION_ENG_LOCALE_CODE;
     if (!StringUtils.isEmpty(employeeRequest.getRequestInfo().getMsgId()) && employeeRequest.getRequestInfo().getMsgId().split("|").length >= 2)
         locale = employeeRequest.getRequestInfo().getMsgId().split("\\|")[1];
 
     StringBuilder uri = new StringBuilder();
     uri.append(propertiesManager.getLocalizationHost()).append(propertiesManager.getLocalizationSearchEndpoint())
             .append("?").append("locale=").append(locale).append("&tenantId=").append(tenantId).append("&module=").append(HEALTH_HRMS_LOCALIZATION_MODULE_CODE);
 
     return uri;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    public StringBuilder getUri(EmployeeRequest employeeRequest) {
        if (propertiesManager.getLocalizationHost() == null || propertiesManager.getLocalizationSearchEndpoint() == null) {
            throw new IllegalStateException("Localization host or search endpoint is not configured");
        }
        String tenantId = employeeRequest.getEmployees().get(0).getTenantId().split("\\.")[0];

        String locale = HRMS_LOCALIZATION_ENG_LOCALE_CODE;
        if (!StringUtils.isEmpty(employeeRequest.getRequestInfo().getMsgId()) && employeeRequest.getRequestInfo().getMsgId().split("|").length >= 2)
            locale = employeeRequest.getRequestInfo().getMsgId().split("\\|")[1];

        StringBuilder uri = new StringBuilder();
        uri.append(propertiesManager.getLocalizationHost()).append(propertiesManager.getLocalizationSearchEndpoint())
                .append("?").append("locale=").append(locale).append("&tenantId=").append(tenantId).append("&module=").append(HEALTH_HRMS_LOCALIZATION_MODULE_CODE);

        return uri;
    }

110-133: 🛠️ Refactor suggestion

Add validation for email template format and required placeholders.

The method should validate the email template format and ensure all required placeholders are present to prevent runtime errors.

 public List<EmailRequest> createEmailRequest(EmployeeRequest employeeRequest, String emailTemplate) {
+    if (StringUtils.isEmpty(emailTemplate) || !emailTemplate.contains("<h2>") || !emailTemplate.contains("</h2>")) {
+        throw new IllegalArgumentException("Invalid email template format");
+    }
+
+    // Validate required placeholders
+    String[] requiredPlaceholders = {"{User's name}", "{Username}", "{Password}", "{website URL}", "{Implementation partner}"};
+    for (String placeholder : requiredPlaceholders) {
+        if (!emailTemplate.contains(placeholder)) {
+            throw new IllegalArgumentException("Missing required placeholder: " + placeholder);
+        }
+    }
+
     RequestInfo requestInfo = employeeRequest.getRequestInfo();
     List<EmailRequest> emailRequest = new LinkedList<>();
 
     for (Employee employee : employeeRequest.getEmployees()) {
+        if (StringUtils.isEmpty(employee.getUser().getEmailId())) {
+            log.warn("Skipping email for employee {} as email ID is missing", employee.getCode());
+            continue;
+        }
         String customizedMsg = emailTemplate.replace("{User's name}", employee.getUser().getName());
         customizedMsg = customizedMsg.replace("{Username}", employee.getCode());
         customizedMsg = customizedMsg.replace("{Password}", employee.getUser().getPassword());
         customizedMsg = customizedMsg.replace("{website URL}", propertiesManager.getEmailNotificationWebsiteLink());
         customizedMsg = customizedMsg.replace("{Implementation partner}", propertiesManager.getEmailNotificationImplementationPartner());
 
         String subject = customizedMsg.substring(customizedMsg.indexOf("<h2>")+4, customizedMsg.indexOf("</h2>"));
         String body = customizedMsg.substring(customizedMsg.indexOf("</h2>")+5);
 
         Email emailObj = Email.builder().emailTo(Collections.singleton(employee.getUser().getEmailId())).isHTML(true).body(body).subject(subject).build();
         EmailRequest email = new EmailRequest(requestInfo, emailObj);
         emailRequest.add(email);
     }
     return emailRequest;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    public List<EmailRequest> createEmailRequest(EmployeeRequest employeeRequest, String emailTemplate) {
        if (StringUtils.isEmpty(emailTemplate) || !emailTemplate.contains("<h2>") || !emailTemplate.contains("</h2>")) {
            throw new IllegalArgumentException("Invalid email template format");
        }

        // Validate required placeholders
        String[] requiredPlaceholders = {"{User's name}", "{Username}", "{Password}", "{website URL}", "{Implementation partner}"};
        for (String placeholder : requiredPlaceholders) {
            if (!emailTemplate.contains(placeholder)) {
                throw new IllegalArgumentException("Missing required placeholder: " + placeholder);
            }
        }

        RequestInfo requestInfo = employeeRequest.getRequestInfo();
        List<EmailRequest> emailRequest = new LinkedList<>();

        // Iterate over each employee details and create email request for each employee.
        for (Employee employee : employeeRequest.getEmployees()) {
            if (StringUtils.isEmpty(employee.getUser().getEmailId())) {
                log.warn("Skipping email for employee {} as email ID is missing", employee.getCode());
                continue;
            }
            String customizedMsg = emailTemplate.replace("{User's name}", employee.getUser().getName());
            customizedMsg = customizedMsg.replace("{Username}", employee.getCode());
            customizedMsg = customizedMsg.replace("{Password}", employee.getUser().getPassword());
            customizedMsg = customizedMsg.replace("{website URL}", propertiesManager.getEmailNotificationWebsiteLink());
            customizedMsg = customizedMsg.replace("{Implementation partner}", propertiesManager.getEmailNotificationImplementationPartner());

            // Get email subject and email body from the provided email template.
            String subject = customizedMsg.substring(customizedMsg.indexOf("<h2>")+4, customizedMsg.indexOf("</h2>"));
            String body = customizedMsg.substring(customizedMsg.indexOf("</h2>")+5);

            // Create the email object with the employee's email id, subject and customized email body created.
            Email emailObj = Email.builder().emailTo(Collections.singleton(employee.getUser().getEmailId())).isHTML(true).body(body).subject(subject).build();
            EmailRequest email = new EmailRequest(requestInfo, emailObj);
            emailRequest.add(email);
        }
        return emailRequest;
    }
core-services/egov-hrms/src/main/java/org/egov/hrms/service/NotificationService.java (3)

211-227: 🛠️ Refactor suggestion

Improve error handling and add transaction management.

The current implementation has the following issues:

  1. Generic error message in catch block.
  2. No transaction management for database operations.
  3. No retries for transient failures.
+@Transactional
 public void processEmailNotification(EmployeeRequest employeeRequest) {
     if (employeeRequest == null || CollectionUtils.isEmpty(employeeRequest.getEmployees())) {
         log.error("Invalid employee request received for email notification");
         return;
     }
     try {
         String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
+        if (localizationMessages == null) {
+            log.error("Failed to fetch localization messages for tenant: {}", 
+                employeeRequest.getEmployees().get(0).getTenantId());
+            return;
+        }
         String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);
+        if (messageTemplate == null) {
+            log.error("Failed to fetch message template for code: {}", 
+                HEALTH_HRMS_EMAIL_LOCALIZATION_CODE);
+            return;
+        }
 
         List<EmailRequest> emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
         notificationUtil.sendEmail(emailRequests);
     } catch (Exception e) {
-        log.error("Error processing email notification for given employees");
+        log.error("Error processing email notification for employees: {}", 
+            employeeRequest.getEmployees().stream()
+                .map(emp -> emp.getCode())
+                .collect(Collectors.joining(", ")), e);
+        throw new RuntimeException("Failed to process email notification", e);
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

@Transactional
public void processEmailNotification(EmployeeRequest employeeRequest) {
    if (employeeRequest == null || CollectionUtils.isEmpty(employeeRequest.getEmployees())) {
        log.error("Invalid employee request received for email notification");
        return;
    }
    try {
        String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
        if (localizationMessages == null) {
            log.error("Failed to fetch localization messages for tenant: {}", 
                employeeRequest.getEmployees().get(0).getTenantId());
            return;
        }
        String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);
        if (messageTemplate == null) {
            log.error("Failed to fetch message template for code: {}", 
                HEALTH_HRMS_EMAIL_LOCALIZATION_CODE);
            return;
        }

        List<EmailRequest> emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
        notificationUtil.sendEmail(emailRequests);
    } catch (Exception e) {
        log.error("Error processing email notification for employees: {}", 
            employeeRequest.getEmployees().stream()
                .map(emp -> emp.getCode())
                .collect(Collectors.joining(", ")), e);
        throw new RuntimeException("Failed to process email notification", e);
    }
}

211-227: 🛠️ Refactor suggestion

Improve exception handling in email notification processing.

The catch-all exception block loses valuable error information and may hide specific issues that need different handling.

Apply this diff to improve error handling:

 try {
     String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
     String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);

     List<EmailRequest> emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
     notificationUtil.sendEmail(emailRequests);
-} catch (Exception e) {
-    log.error("Error processing email notification for given employees");
+} catch (IllegalArgumentException e) {
+    log.error("Invalid input while processing email notification: {}", e.getMessage());
+} catch (RuntimeException e) {
+    log.error("Error processing email notification: {}", e.getMessage(), e);
+    throw new RuntimeException("Failed to process email notification", e);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

	public void processEmailNotification(EmployeeRequest employeeRequest) {
		if (employeeRequest == null || CollectionUtils.isEmpty(employeeRequest.getEmployees())) {
			log.error("Invalid employee request received for email notification");
			return;
		}
		try {
			// Fetch localization messages and get email message template for HEALTH_HRMS_EMAIL_LOCALIZATION_CODE template code.
			String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
			String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);

			// Create email requests from the employee details provided in the employeeRequest.
			List<EmailRequest> emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
			notificationUtil.sendEmail(emailRequests);
		} catch (IllegalArgumentException e) {
			log.error("Invalid input while processing email notification: {}", e.getMessage());
		} catch (RuntimeException e) {
			log.error("Error processing email notification: {}", e.getMessage(), e);
			throw new RuntimeException("Failed to process email notification", e);
		}
	}

211-227: 🛠️ Refactor suggestion

Enhance error handling and add retry mechanism.

The method uses a generic catch block which might hide important errors. Consider:

  1. Adding specific exception handling
  2. Implementing a retry mechanism for transient failures
  3. Adding metrics for monitoring
 public void processEmailNotification(EmployeeRequest employeeRequest) {
     if (employeeRequest == null || CollectionUtils.isEmpty(employeeRequest.getEmployees())) {
         log.error("Invalid employee request received for email notification");
         return;
     }
+    int maxRetries = 3;
+    int retryCount = 0;
+    while (retryCount < maxRetries) {
         try {
             String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
             String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);
 
             List<EmailRequest> emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
             notificationUtil.sendEmail(emailRequests);
+            break;
+        } catch (ResourceAccessException e) {
+            log.error("Network error while processing email notification", e);
+            retryCount++;
+            if (retryCount < maxRetries) {
+                try {
+                    Thread.sleep(1000 * retryCount);
+                } catch (InterruptedException ie) {
+                    Thread.currentThread().interrupt();
+                    break;
+                }
+            }
         } catch (Exception e) {
-            log.error("Error processing email notification for given employees");
+            log.error("Error processing email notification for given employees", e);
+            break;
         }
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

public void processEmailNotification(EmployeeRequest employeeRequest) {
    if (employeeRequest == null || CollectionUtils.isEmpty(employeeRequest.getEmployees())) {
        log.error("Invalid employee request received for email notification");
        return;
    }
    int maxRetries = 3;
    int retryCount = 0;
    while (retryCount < maxRetries) {
        try {
            String localizationMessages = notificationUtil.getLocalizationMessages(employeeRequest);
            String messageTemplate = notificationUtil.getMessageTemplate(HEALTH_HRMS_EMAIL_LOCALIZATION_CODE, localizationMessages);

            List<EmailRequest> emailRequests = notificationUtil.createEmailRequest(employeeRequest, messageTemplate);
            notificationUtil.sendEmail(emailRequests);
            break;
        } catch (ResourceAccessException e) {
            log.error("Network error while processing email notification", e);
            retryCount++;
            if (retryCount < maxRetries) {
                try {
                    Thread.sleep(1000 * retryCount);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        } catch (Exception e) {
            log.error("Error processing email notification for given employees", e);
            break;
        }
    }
}
core-services/egov-hrms/src/main/java/org/egov/hrms/service/IndividualService.java (6)

319-321: ⚠️ Potential issue

Add null checks and validation for skills mapping.

The skills mapping logic could throw NullPointerException if roles are null. Also, using role codes directly as skill levels might not be appropriate.

-                .skills(userRequest.getUser().getRoles().stream().map(role -> Skill.builder()
-                        .type(role.getCode()).level(role.getCode())
-                        .build()).collect(Collectors.toList()))
+                .skills(userRequest.getUser().getRoles() != null ?
+                    userRequest.getUser().getRoles().stream()
+                        .filter(role -> role != null && role.getCode() != null)
+                        .map(role -> Skill.builder()
+                            .type(role.getCode())
+                            .level(determineSkillLevel(role.getCode()))
+                            .build())
+                        .collect(Collectors.toList())
+                    : null)

+private String determineSkillLevel(String roleCode) {
+    // Add logic to map role codes to appropriate skill levels
+    return "BASIC";
+}

Committable suggestion skipped: line range outside the PR's diff.


319-321: 🧹 Nitpick (assertive)

Improve skill level mapping logic.

Using the role code as both skill type and level may not accurately represent the user's skill levels.

Consider mapping skill levels based on role hierarchy or explicit level definitions:

-.skills(userRequest.getUser().getRoles().stream().map(role -> Skill.builder()
-        .type(role.getCode()).level(role.getCode())
-        .build()).collect(Collectors.toList()))
+.skills(userRequest.getUser().getRoles().stream().map(role -> Skill.builder()
+        .type(role.getCode())
+        .level(determineSkillLevel(role))
+        .build()).collect(Collectors.toList()))

+private String determineSkillLevel(Role role) {
+    // Map role codes to appropriate skill levels
+    switch(role.getCode()) {
+        case "ADMIN": return "EXPERT";
+        case "MANAGER": return "ADVANCED";
+        default: return "BASIC";
+    }
+}

Committable suggestion skipped: line range outside the PR's diff.


319-321: 🛠️ Refactor suggestion

Validate and improve role-to-skill mapping.

The current implementation assumes all roles can be mapped to skills and uses role codes for both skill type and level. This might not be appropriate for all roles.

-                .skills(userRequest.getUser().getRoles().stream().map(role -> Skill.builder()
-                        .type(role.getCode()).level(role.getCode())
-                        .build()).collect(Collectors.toList()))
+                .skills(userRequest.getUser().getRoles().stream()
+                        .filter(role -> isValidSkill(role.getCode()))
+                        .map(role -> Skill.builder()
+                                .type(getSkillType(role.getCode()))
+                                .level(getSkillLevel(role.getCode()))
+                                .build())
+                        .collect(Collectors.toList()))

+private boolean isValidSkill(String roleCode) {
+    // Add validation logic
+    return true;
+}

+private String getSkillType(String roleCode) {
+    // Add mapping logic
+    return roleCode;
+}

+private String getSkillLevel(String roleCode) {
+    // Add mapping logic
+    return "INTERMEDIATE";
+}

Committable suggestion skipped: line range outside the PR's diff.


66-79: 🛠️ Refactor suggestion

Reduce code duplication and add locality validation.

The method duplicates code from createUser. Consider refactoring to a common method and add locality code validation.

+private UserResponse createUserInternal(UserRequest userRequest, String localityCode) {
+    if (localityCode != null && !isValidLocalityCode(localityCode)) {
+        log.error("Invalid locality code: {}", localityCode);
+        throw new IllegalArgumentException("Invalid locality code");
+    }
+    IndividualRequest request = mapToIndividualRequest(userRequest, localityCode);
+    StringBuilder uri = new StringBuilder();
+    uri.append(propertiesManager.getIndividualHost());
+    uri.append(propertiesManager.getIndividualCreateEndpoint());
+    IndividualResponse response = restCallRepository
+            .fetchResult(uri, request, IndividualResponse.class);
+    UserResponse userResponse = null;
+    if (response != null && response.getIndividual() != null) {
+        log.info("response received from individual service");
+        userResponse = mapToUserResponse(response);
+    }
+    return userResponse;
+}

+private boolean isValidLocalityCode(String localityCode) {
+    // Add validation logic here
+    return true;
+}

 public UserResponse createUser(UserRequest userRequest) {
-    IndividualRequest request = mapToIndividualRequest(userRequest, null);
-    StringBuilder uri = new StringBuilder();
-    uri.append(propertiesManager.getIndividualHost());
-    uri.append(propertiesManager.getIndividualCreateEndpoint());
-    IndividualResponse response = restCallRepository
-            .fetchResult(uri, request, IndividualResponse.class);
-    UserResponse userResponse = null;
-    if (response != null && response.getIndividual() != null) {
-        log.info("response received from individual service");
-        userResponse = mapToUserResponse(response);
-    }
-    return userResponse;
+    return createUserInternal(userRequest, null);
 }

 public UserResponse createUserByLocality(UserRequest userRequest, String localityCode) {
-    IndividualRequest request = mapToIndividualRequest(userRequest,localityCode);
-    StringBuilder uri = new StringBuilder();
-    uri.append(propertiesManager.getIndividualHost());
-    uri.append(propertiesManager.getIndividualCreateEndpoint());
-    IndividualResponse response = restCallRepository
-            .fetchResult(uri, request, IndividualResponse.class);
-    UserResponse userResponse = null;
-    if (response != null && response.getIndividual() != null) {
-        log.info("response received from individual service");
-        userResponse = mapToUserResponse(response);
-    }
-    return userResponse;
+    return createUserInternal(userRequest, localityCode);
 }

Committable suggestion skipped: line range outside the PR's diff.


66-79: 🛠️ Refactor suggestion

Reduce code duplication in user creation methods.

The createUserByLocality method duplicates most of the code from createUser. Consider refactoring to reuse code.

Apply this diff to improve code reuse:

+private UserResponse createUserInternal(UserRequest userRequest, String localityCode) {
+    IndividualRequest request = mapToIndividualRequest(userRequest, localityCode);
+    StringBuilder uri = new StringBuilder();
+    uri.append(propertiesManager.getIndividualHost());
+    uri.append(propertiesManager.getIndividualCreateEndpoint());
+    IndividualResponse response = restCallRepository
+            .fetchResult(uri, request, IndividualResponse.class);
+    UserResponse userResponse = null;
+    if (response != null && response.getIndividual() != null) {
+        log.info("response received from individual service");
+        userResponse = mapToUserResponse(response);
+    }
+    return userResponse;
+}

-public UserResponse createUser(UserRequest userRequest) {
-    IndividualRequest request = mapToIndividualRequest(userRequest, null);
-    StringBuilder uri = new StringBuilder();
-    uri.append(propertiesManager.getIndividualHost());
-    uri.append(propertiesManager.getIndividualCreateEndpoint());
-    IndividualResponse response = restCallRepository
-            .fetchResult(uri, request, IndividualResponse.class);
-    UserResponse userResponse = null;
-    if (response != null && response.getIndividual() != null) {
-        log.info("response received from individual service");
-        userResponse = mapToUserResponse(response);
-    }
-    return userResponse;
-}
+public UserResponse createUser(UserRequest userRequest) {
+    return createUserInternal(userRequest, null);
+}

-public UserResponse createUserByLocality(UserRequest userRequest, String localityCode) {
-    IndividualRequest request = mapToIndividualRequest(userRequest,localityCode);
-    StringBuilder uri = new StringBuilder();
-    uri.append(propertiesManager.getIndividualHost());
-    uri.append(propertiesManager.getIndividualCreateEndpoint());
-    IndividualResponse response = restCallRepository
-            .fetchResult(uri, request, IndividualResponse.class);
-    UserResponse userResponse = null;
-    if (response != null && response.getIndividual() != null) {
-        log.info("response received from individual service");
-        userResponse = mapToUserResponse(response);
-    }
-    return userResponse;
-}
+public UserResponse createUserByLocality(UserRequest userRequest, String localityCode) {
+    return createUserInternal(userRequest, localityCode);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    private UserResponse createUserInternal(UserRequest userRequest, String localityCode) {
        IndividualRequest request = mapToIndividualRequest(userRequest, localityCode);
        StringBuilder uri = new StringBuilder();
        uri.append(propertiesManager.getIndividualHost());
        uri.append(propertiesManager.getIndividualCreateEndpoint());
        IndividualResponse response = restCallRepository
                .fetchResult(uri, request, IndividualResponse.class);
        UserResponse userResponse = null;
        if (response != null && response.getIndividual() != null) {
            log.info("response received from individual service");
            userResponse = mapToUserResponse(response);
        }
        return userResponse;
    }

    public UserResponse createUser(UserRequest userRequest) {
        return createUserInternal(userRequest, null);
    }

    public UserResponse createUserByLocality(UserRequest userRequest, String localityCode) {
        return createUserInternal(userRequest, localityCode);
    }

66-79: 🛠️ Refactor suggestion

Reduce code duplication and add locality validation.

The method duplicates code from createUser. Consider:

  1. Reusing the common logic
  2. Adding validation for localityCode
 public UserResponse createUserByLocality(UserRequest userRequest, String localityCode) {
+    if (StringUtils.isEmpty(localityCode)) {
+        throw new IllegalArgumentException("Locality code is required");
+    }
-    IndividualRequest request = mapToIndividualRequest(userRequest,localityCode);
-    StringBuilder uri = new StringBuilder();
-    uri.append(propertiesManager.getIndividualHost());
-    uri.append(propertiesManager.getIndividualCreateEndpoint());
-    IndividualResponse response = restCallRepository
-      .fetchResult(uri, request, IndividualResponse.class);
-    UserResponse userResponse = null;
-    if (response != null && response.getIndividual() != null) {
-        log.info("response received from individual service");
-        userResponse = mapToUserResponse(response);
-    }
-    return userResponse;
+    return createUser(userRequest, localityCode);
 }

+private UserResponse createUser(UserRequest userRequest, String localityCode) {
+    IndividualRequest request = mapToIndividualRequest(userRequest, localityCode);
+    StringBuilder uri = new StringBuilder();
+    uri.append(propertiesManager.getIndividualHost());
+    uri.append(propertiesManager.getIndividualCreateEndpoint());
+    IndividualResponse response = restCallRepository
+            .fetchResult(uri, request, IndividualResponse.class);
+    UserResponse userResponse = null;
+    if (response != null && response.getIndividual() != null) {
+        log.info("response received from individual service");
+        userResponse = mapToUserResponse(response);
+    }
+    return userResponse;
+}

Committable suggestion skipped: line range outside the PR's diff.

health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java (4)

101-101: 🧹 Nitpick (assertive)

Add index for createdtime column.

The query now orders by createdtime which could impact performance without a proper index.

Consider adding an index on the createdtime column to improve query performance. Note that this should be done through proper database migration processes as per team guidelines.


101-101: 🧹 Nitpick (assertive)

Consider adding an index for the createdtime column.

The query now orders by createdtime DESC. To optimize performance, ensure there's an index on the createdtime column.


229-230: 🧹 Nitpick (assertive)

Add index for case-insensitive search.

The query now uses ILIKE for case-insensitive search which could impact performance without a proper index.

Consider adding a functional index using lower(givenname) to improve case-insensitive search performance. Note that this should be done through proper database migration processes as per team guidelines.


229-231: 🧹 Nitpick (assertive)

Optimize case-insensitive search performance.

While ILIKE provides better user experience, it can impact performance. Consider:

  1. Creating a functional index on LOWER(givenname)
  2. Using LOWER() function with regular LIKE for better database compatibility
-            query = query + "AND givenname ILIKE :individualName ";
-            paramsMap.put("individualName", "%"+searchObject.getIndividualName()+"%");
+            query = query + "AND LOWER(givenname) LIKE LOWER(:individualName) ";
+            paramsMap.put("individualName", "%" + searchObject.getIndividualName().toLowerCase() + "%");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            query = query + "AND LOWER(givenname) LIKE LOWER(:individualName) ";
            paramsMap.put("individualName", "%" + searchObject.getIndividualName().toLowerCase() + "%");
        }
core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java (1)

272-279: ⚠️ Potential issue

Add null check for jurisdictions in locality extraction.

The locality extraction could throw NPE if jurisdictions is empty. Consider adding a null check or providing a default value.

Apply this diff to fix the potential NPE:

-String localityCode = (employee.getJurisdictions()!=null && !employee.getJurisdictions().isEmpty())? employee.getJurisdictions().get(0).getBoundary() : null;
+String localityCode = null;
+if (employee.getJurisdictions() != null && !employee.getJurisdictions().isEmpty() && employee.getJurisdictions().get(0) != null) {
+    localityCode = employee.getJurisdictions().get(0).getBoundary();
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

			UserResponse response;
			if(userService instanceof IndividualService) {
				String localityCode = null;
				if (employee.getJurisdictions() != null && !employee.getJurisdictions().isEmpty() && employee.getJurisdictions().get(0) != null) {
				    localityCode = employee.getJurisdictions().get(0).getBoundary();
				}
				response = individualService.createUserByLocality(request, localityCode);
			}
			else{
				response = userService.createUser(request);
			}
core-services/egov-hrms/src/main/resources/application.properties (1)

124-127: 🧹 Nitpick (assertive)

Consider moving website link to devops chart.

Based on previous learnings, the hrms.email.notification.website.link should be managed through the devops chart to support environment-specific values.

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.

10 participants