Skip to content

Conversation

@ashish-egov
Copy link
Collaborator

@ashish-egov ashish-egov commented Jul 11, 2025

Summary by CodeRabbit

  • New Features

    • Added a new database table for campaign data storage.
    • Introduced advanced Excel template generation and processing with dynamic columns, localization, multi-select support, and enhanced data validation.
    • Added new APIs and controllers for generating and processing Excel data via dedicated endpoints.
    • Integrated localized notification emails for user credentials with dynamic download links.
    • Enabled encryption and decryption utilities for sensitive user data.
    • Added robust Redis connection management and explicit reconnection logic.
    • Added static type-checking utilities for code quality assurance.
    • Added configurable template and processing configurations for multiple modules.
    • Introduced a flexible data transformation framework for employee and facility data.
    • Added comprehensive user data processing workflows with batch Kafka persistence.
    • Added new validation schemas and models for resource details and template queries.
  • Enhancements

    • Improved user and facility data validation, including username format checks, configurable phone number length, and multi-select field validations.
    • Enhanced boundary and campaign data handling with improved localization, hierarchical structuring, and caching support.
    • Expanded template and process workflow configurations with flexible schema-driven mappings.
    • Optimized server memory usage logging and timeout configurations.
    • Refined Kafka messaging to include tenant context for multi-tenant environments.
    • Updated MDMS API usage for schema and localization fetching.
    • Improved Excel utilities with multi-select dropdowns, header management, and column protection.
    • Enhanced Redis utilities with explicit reconnect and improved cache key deletion logic.
    • Improved campaign mapping with notification email integration.
    • Enhanced microplan integration with latitude/longitude extraction and updated MDMS calls.
    • Improved boundary code handling and localization support.
    • Refined error handling and logging across services and utilities.
  • Bug Fixes

    • Fixed duplicate row detection, username validation, and error reporting issues.
    • Improved error handling and logging for resource generation, processing, and Kafka messaging.
    • Addressed Redis cache key deletion and connection stability issues.
  • Chores

    • Modularized internal configurations, models, and utility functions with improved parameterization.
    • Updated database migration scripts to support multi-schema deployments.
    • Refactored code to remove legacy functions and improve formatting.
    • Added new validation schemas and models for resource details and template queries.
    • Updated build configurations and added multi-architecture Docker build workflows.

ashish-egov and others added 30 commits December 10, 2024 18:06
* HLM service request, updated DataTypeEnum (#872)

* Service request changelog 1.5 (#875)

* Added changelog and upgraded the versions for household, individual and service request

* Update core-services/service-request/CHANGELOG.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update health-services/individual/CHANGELOG.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* HLM fixed merge issues

* HLM fixed merge issues

* HCMPRE-413: updated the changelog as per code review comments

* Update health-services/project/CHANGELOG.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: kavi_elrey@1993 <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* HCMPRE-424: fixed hrms call from pgr-service

* HCMPRE-424: updated as per code review comments

* Create branch-name-validator (#960)

* Create branch-name-validator

* Update branch-name-validator

* Update .github/workflows/branch-name-validator

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .github/workflows/branch-name-validator

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update branch-name-validator

* Rename branch-name-validator to branch-name-validator.yml

* Added census-service in build-config (#990)

* [HCMPRE-658] Refractor resource-estimation-service to resource-generator (#910)

Co-authored-by: Priyanka-eGov <[email protected]>

* Update package.json

* Update tsconfig.json

* Added configs and env dependencies

* dockerfile update

* Update tsconfig.json

* Update tsconfig.json

* refactored

* HCM Admin Console v0.3 Release code changes (#1082)

* kafka fix for large messages

* Update genericUtils.ts

* Update campaignValidators.ts

* Fixed the mdms search path keys

* fix of migration script

* fix on repeated key

* Update campaignApis.ts

* Update campaignApis.ts

* Update campaignUtils.ts

* Update campaignUtils.ts

* Update campaignUtils.ts

* Fix project target mapping

* refactored migration files fro project-factory (#867)

* refactored migration files fro project-factory

* updated logic for unique username generation

* updated format and id name  for user name

* removed hash logic for username generation

* added indexing on columns

* updated idgen seq format for user name in index.ts

* Update health-services/project-factory/src/server/api/campaignApis.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* updated logic for regenerate if campaign type differs (#876)

* id generation throw error update

* Enhance generate template for user and facility in update  ongoing campaign flow (#885)

* commit for update-generate-template

* updated campaign  flow generate template enhancement

* just if else changes

* some reformatting

* update index.ts

* added additional valiadtion for parent campaign

* updated logic for validating  parent campaign

* refcatored as per change requests

* update index.ts

* updated logic for same campaignnumber when paren is present

* updated the campaign name logic along with handling isfailed status too (#888)

* updating campaign name same as parent name and number too

* updated target template for updating ongoing campaign (#893)

* Microplan bulk user creation (#890)

* Feat : initialised bulk user creation for microplan

* Enhanced user bulk upload for microplan

* Fixed configs

* Merge fix with console

* Feat : added columns in user sheet

* Added userroles sheet for bulk user template in microplan

* Added source microplan while resource creation

* changed logic for isSourceMicroplan

* Update campaignApis.ts

* Update campaignValidators.ts

* changes for campaign update flow

* Update campaignUtils.ts

* Integrated required error messages

* added numeric check in  microplan phone number

* Implemented no data validation

* added logic for creating projects , project facility and project staff on newly added boundaries (#917)

* updated target template for updating ongoing campaign

* update flow campaign mapping

* updated flow campaign mapping

* added logic for project, project facility and project staff  creation on newly added boundaries

* removed one useless func

* removed await from a func

* removed console.logs

* added some minor enhancemnets

* added one edge case scenario

* changed request limit to 1 mb

* Feat : added locksheet filter for user microplan creation

* updated logic for regenerate if campaign type differs (#876)

* Enhancement for microplan user creation (#940)

* some modifications for edge cases (#930)

* added commit for testing  update campaign flow

* some chenages related to type boundary in data create api

* /* MODIFIED FOR LTS UPGRADE */

* Microplan user enhancement

* Some changes regarding microplan user and boundary

* added some null checks

* /* Temporay fix for project creation of LLIN since the structure of delivery rules is getting changed */

* Revert "/* MODIFIED FOR LTS UPGRADE */"

This reverts commit 52ed772.

* added code to add lat long in the project-factory apis

* Changed code based on comments

* removed default campaignid

* added code to add lat long in the project-factory apis (#951)

* added code to add lat long in the project-factory apis

* Changed code based on comments

* removed default campaignid

* Fixed code to manage create

* fixed the build

* added for field protection on sheet data

* Facility microplan validation (#975)

* Microplan facility validation

* Enhancement in microplan validations

* Microplan sheet lock

* Enhanced for multiple sheetErrors in additionalDetails

* Update campaignApis.ts

* fixes for filestore and unfreezing boundary code mandatory columns (#984)

* Update CODEOWNERS

* Update campaignValidators.ts (#987)

* some  correction of error after changes from microplan code merge (#988)

* some  correction of error after changes from microplan code merge

* added question mark

* added localization fix (#993)

Co-authored-by: ansh-egov <[email protected]>

* Update campaignApis.ts (#994)

* Added some fixes for the project transformation

* Update projectTypeUtils.ts

* Update campaignUtils.ts

* Removed date Update projectTypeUtils.ts #1006

* HCEMPRE-809-Boundary-geometry-codes (#1011)

* added localization fix

* added logic for boundaryGeometryManagement

* fixed some things

* fixed campaign search

* update  project facility and staff mappings of exisitng facilities and users  (#998)

* some  correction of error after changes from microplan code merge

* added logic for updating mapping of existing facilitie and users

* resolved comments by jagan on the pr for delinking and linking project resources

* fetchProjectsWithBoundaryCodeAndName fucntion update

* Update campaignValidators.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* added code to add lat long in the project-factory apis (#1019)

* Project staff mapping correction from uuid to userserviceuuid (#1022)

* some  correction of error after changes from microplan code merge

* corrected for mapping of project staff

* added changes for project-resource mapping (#1028)

* added changes for project-resource mapping

* changed the variable name to boundaryProjectMappingForProjectResourceCreation from newBoundaryProjectMapping

* renamed the entity

---------

Co-authored-by: Jagankumar <[email protected]>

* Added logic to retry in project campaign create (#1031)

* not needed to update every resource in update flow (#1036)

* not needed to update every resource in update flow

* added changes for if boundaries present in update  flow all resources are mandate

* Some checks enhancement (#1042)

* Update genericApis.ts (#1043)

* Update campaignValidators.ts (#1046)

* consolidate resources array in update campaign flow (#1051)

* consolidate resources array in update campaign flow

* spelling correct

* Search criteria  object corrected (#1052)

* consolidate resources array in update campaign flow

* data search criteria  id has to be an array of strings

* spelling

* some more corrections regarding search criteria body

* Boundaries consolidate after creating child campaign (#1056)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* Boundaries correction (#1058)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* changes in extracing boundaries from campaign object

* Missing resources in chid campaign to be added from parent camaig  logic refactored  (#1059)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* refactored logic for adding missing resources from parent campaign

* Correction datatocreate column from status to userservice uuids (#1061)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* changed data to create column from user sheet

* Hide Boundary and Target Old Columns (#1062)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* hide boundary code  old and target old

* Corrected target update flow (#1065)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* corrected target mapping in update flow

* Total count of Campaigns if only is active true (#1066)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* count will be only of active campaigns

* HCMPRE-1212:: migrated to point only to MMDS v2 api

* Update index.ts

* User/facility inactive (#1070)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* added logic for making exiting user facility inactive

---------

Co-authored-by: Jagankumar <[email protected]>

* Refactor facility mappings  (#1072)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* refactored facility mappings

* Created enity for boundary

* updated the boundary relationship function

* Update index.ts

* fixed some localization issue (#1075)

* fixed some localization issue

* fixed

* Target update while campaign update flow (#1078)

* consolidate resources array in update campaign flow

* boundaries consolidate after creating  child campaign

* logic for updating targets

* some refactor for adding logs and index.ts

* updated the boundary localisation name

---------

Co-authored-by: Jagankumar <[email protected]>

* fixed some localization issue (#1079)

* fixed some localization issue

* fixed

* fixed a issue

* reverted failed campaign is active true from false (#1080)

* reverted failed campaign is active true from false

* took constants from index

* refactor

* Merge branch 'project-factory-kafka-fix' into console

* Changed hierarchyFectch to v2 (#1077)

* Changed hierarchyFectch to v2

* Changed messages

* Merge branch 'project-factory-kafka-fix' into hierarchyFetchV2

---------

Co-authored-by: Jagankumar <[email protected]>

* calll generate when create completes for type boundary management

* auto generate resource if there is no previous generated history

* Fixed crashloop issue (#1084)

* Fixed crashloop issue

* Update dataManageService.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* changed the master from hierarchyConfig to HierarchySchema (#1086)

* getting boundaries split on logic change (#1088)

* fixed some localization issue (#1090)

* fixed some localization issue

* fixed

* fixed a issue

* integrated microplan with console

* fixxed index

* fixed crashloop (#1091)

* added validation for boundary bulk upload (#1092)

Co-authored-by: Jagankumar <[email protected]>

* refcatored diffferent tab separation (#1093)

* added timeout (#1095)

* Microplan integration :: set start date to tommorow (#1096)

* set start date to tommorow

* updated end date

* Enhance PlanFacility object (#1099)

* validation for update template in create flow (#1100)

* removed await (#1103)

* some correction (#1104)

* logic for updating targets only when present in resources array in update flow (#1105)

* updated (#1106)

* updated

* added fix for the redis error in logs

---------

Co-authored-by: Jagankumar <[email protected]>

* added error responder (#1107)

* refactored download api (#1108)

* Cache issue fix(#1109)

* refactored download api

* refactor

---------

Co-authored-by: Jagankumar <[email protected]>

* made disable of cache always during boundary generate (#1110)

Co-authored-by: Jagankumar <[email protected]>

* Redis cache key deleted (#1113)

* removed await

* delete cache from boundary relationship search

* updated redis delete func

* Revert "removed await"

This reverts commit a5acb54.

* Update redisUtils.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* updated redis delete func (#1114)

* removed cache from boundary relation create (#1115)

* corrected params of auto generate after download api (#1116)

* refactored consolidate (#1119)

* fix on the fetch from microplan Update campaignUtils.ts (#1120)

* Update microplanUtils.ts (#1123)

* addded localization function (#1125)

* Update SearchCriteria.ts

* made createandtransfrom localization as await to upsert all localization in boundary management create flow (#1127)

* added logs in handledropdownthings (#1128)

* Fixed district missing issue (#1129)

* Facility Village List For microplan and dropdown fix (#1130)

* Facility Village List For microplan and dropdown fix

* Optional chaining

* Reverted recievedDropdown Changes

* removed localization caceh in boundary generate flow for hierarchy module (#1133)

* planFacility create Fix (#1132)

* fixed the localisation cache on multiple data creates in boundary

* Revert "fixed the localisation cache on multiple data creates in boundary"

This reverts commit 94eb970.

* Facility fix generation for microplan (#1134)

* planFacility create Fix

* Fixed Facility Generation for microplan

* added the count info of the localisation upsert (#1144)

Co-authored-by: Jagankumar <[email protected]>

* Microplan integrated with console for facility , user & target (#1151)

* set start date to tommorow

* updated end date

* added code for target sheet

* fixed

* added mdms call

* microplan integration changes added for target ,facility & user

* undo changes

* Update microplanIntergration.ts

* saving all the progress on the integration

* project facility mapping done

* Update microplanIntergration.ts

* Update microplanIntergration.ts

* Update microplanIntergration.ts

* target & facility integration completed statically

* completed facility & target file created based on microplan

* added static for user

* Added user related changes

* added the user integartion

* added target and facility in resources array of campaign from microplan

* added user in resources array in campaign object

* Update microplanIntergration.ts

* revert the others

* Update index.ts

* Cleaned up code

---------

Co-authored-by: ansh-egov <[email protected]>
Co-authored-by: Jagankumar <[email protected]>
Co-authored-by: nitish-egov <[email protected]>

* added missing default tenantid (#1152)

* Boundary locale fix (#1153)

* planFacility create Fix

* Fixed boundary validation for different locales

---------

Co-authored-by: Jagankumar <[email protected]>

* removed duplicate key (#1154)

* Logs for reordering added (#1161)

* added missing default tenantid

* added logs for reordering before project creation

* Update index.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* Readme for microplans (#1160)

* Readme for microplans

* Fixed boolean type

* Optimized isMicroplanRequest

* Optimizing roles for microplan (#1164)

* Improved  some performance with huge campaign object (#1165)

* Trying optimised code by chatgpt

* added 4mb limit

* Update app.ts

* Updted the comments

* Changes for pollutils and reorder

* Update pollUtils.ts

---------

Co-authored-by: Jagankumar <[email protected]>
Co-authored-by: ashish-egov <[email protected]>

* Added fixes for error during processing (#1172)

* added missing default tenantid

* added try catch

* Update index.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* fixed the hard codings in the code (#1170)

* fixed the hard codings in the code

* fixed

* Added filter check for the fetch from microplan if it has already some resources

* fixed hardcoding in target flow (#1175)

* fixed hardcoding in target flow

* fixed

* fixed

* Update campaignApis.ts (#1177)

* Update campaignApis.ts

* Update campaignApis.ts

* Update campaignApis.ts

* Update genericUtils.ts (#1178)

* changed the campaig key to activity (#1180)

* added missing default tenantid

* Update campaignUtils.ts

* Update index.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* handled failed generations in downlaod api (#1185)

* Change for roles name change (#1187)

* added search before update in fetch all datas (#1190)

* added seacrh before update in fetch all datas

* Change for roles name change (#1187)

---------

Co-authored-by: ashish-egov <[email protected]>
Co-authored-by: Jagankumar <[email protected]>

* formatted and made promise all to do a promise all to make calls parallely

* filtered the plan facility response to have only facility which has only service boundarires

* added hierarchy filteration from mdms (#1188)

* added hierarchy filteration from mdms

* did some hardcoding

* fixed fetching of headers

* added some logs

* added extra loggers for fetch from microplan activities (#1193)

* added extra loggers for fetch from microplan activities

* Update microplanIntergration.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* added retry in localization upsert (#1194)

* Adding the additonal loggers to know more informs on microplan integration

* Update health-services/project-factory/src/server/validators/campaignValidators.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update health-services/project-factory/src/server/validators/campaignValidators.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update health-services/project-factory/src/server/controllers/campaignManage/campaignManage.controller.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fixed integration (#1197)

* Global handler (#1199)

* Change for roles name change

* Global exception handler integrated

* String logger

* Update app.ts

* added heap memory log & created a env variable for incomingRequestPay…   …loadLimit (#1201)

* added heap memory log & created a env variable for incomingRequestPayloadLimit

* Update index.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* Set memory limit and added log off avaiable, max limits (#1202)

* added logs to check current value

* Update app.ts

* Update Dockerfile

* Update Dockerfile

* Update app.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* Handle for google sheet formulas (#1207)

* Update microplanValidators.ts (#1213)

* Update microplanValidators.ts

* Update microplanValidators.ts

* Update microplanValidators.ts

* Localised roles (#1217)

* added change log for admin console version 0.3 (#1224)

* Pvar validation (#1225)

* product variant validation added

* Optimized validations

* Refactored

* Logger error fix

* Refactor

* Refactor

* refactored project reosurce mapping logic (#1204)

* refactored project reosurce mapping logic

* added new function ot search project after campaign creation time

* added reference id  params in project search

* added logic for adding resources only for newly created projects

* refactored and code clean up for project resource mapppings in update and create flow

* refactor getProjectMappingBody func

* some condition check

* correction

* removed project departments

* microplan save topic changes (#1231)

* Update microplanUtils.ts

* Update index.ts

* Update campaignApis.ts (#1232)

* Update campaignApis.ts

* Update campaignApis.ts

* Update campaignApis.ts

* Update campaignValidators.ts

* Revert boundaryProject Mapping

* Cleaned up data configs (#1234)

* Update index.ts

* Update campaignUtils.ts

* Update health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update app.ts

* Update health-services/project-factory/src/server/utils/microplanUtils.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* added changes for performance testing (#1236)

* added changes for performance testing

* microplan save topic changes (#1231)

* Update microplanUtils.ts

* Update index.ts

* Update campaignApis.ts (#1232)

* Update campaignApis.ts

* Update campaignApis.ts

* Update campaignApis.ts

* Update campaignValidators.ts

* Revert boundaryProject Mapping

* Cleaned up data configs (#1234)

* Update index.ts

* Update campaignUtils.ts

* try catch handling

* Update health-services/project-factory/src/server/service/dataManageService.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: ashish-egov <[email protected]>
Co-authored-by: ansh-egov <[email protected]>
Co-authored-by: Jagankumar <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update app.ts

* Update health-services/project-factory/src/server/utils/microplanUtils.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update campaignValidators.ts (#1244)

* Update campaignValidators.ts

* Update campaignValidators.ts

* add

* added new config values

* Other configs (#1250)

* add

* added new config values

* Update request.ts

---------

Co-authored-by: Jagankumar <[email protected]>

* Updating debug function for error handeling (#1243)

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update health-services/project-factory/src/server/service/dataManageService.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update dataManageService.ts

* Applied code rabbit changes

* refactored sheet consolidate logic (#1254)

* refactored sheet consolidate logic

* Applied code rabbit changes

---------

Co-authored-by: Jagankumar <[email protected]>

* refactor sheet consolidate for target (#1255)

* Update package.json

* Update health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* removed other ui workflows

* Update publishProjectFactory.yml

* Update publishProjectFactory.yml

* Update publishProjectFactory.yml

* Update publishProjectFactory.yml

* Update publishProjectFactory.yml

* Update publishProjectFactory.yml

* consolidate sheet handle logic change (#1256)

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: ashish-egov <[email protected]>
Co-authored-by: ashish-egov <[email protected]>
Co-authored-by: nitish-egov <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: nitish-egov <[email protected]>
Co-authored-by: ansh-egov <[email protected]>
Co-authored-by: ansh-egov <[email protected]>
Co-authored-by: ejagankumar <[email protected]>

* Changed docker file

* package changes

* dockerfile revert

* changed package json

* Update package.json

* reverted other folders

* reverted

* Update settings.json

---------

Co-authored-by: kanishq-egov <[email protected]>
Co-authored-by: kavi_elrey@1993 <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: kanishq-egov <[email protected]>
Co-authored-by: Sathish P <[email protected]>
Co-authored-by: tanishi-egov <[email protected]>
Co-authored-by: Palak Garg <[email protected]>
Co-authored-by: Priyanka-eGov <[email protected]>
Co-authored-by: Jagankumar <[email protected]>
Co-authored-by: nitish-egov <[email protected]>
Co-authored-by: nitish-egov <[email protected]>
Co-authored-by: ansh-egov <[email protected]>
Co-authored-by: ansh-egov <[email protected]>
Co-authored-by: ejagankumar <[email protected]>
* some boundary bulk and microplan user changes

* Some refactoring
* localisation-cache-fix

* Refactor

* Refactor

* logger added
* some boundary bulk and microplan user changes

* Some refactoring

* Fix for target

* Facility fix

* User Fix

* Target valiodation for  microplan
* Fix for boundary validation

* Optional Chaning
* added gzip handler in middleware

* added gzip handler specific to request middleware

* refactored gzip handler
* enhanced target validation

* Reverted index config

* refactor target generate and validate for generic type

* Target enrichment

* Fix for null codesTargetMapping

* MDMS integration for targetConfigs

* enhanced target validation

* Target enrichment

* Fix for null codesTargetMapping

* MDMS integration for targetConfigs

* target fix

---------

Co-authored-by: ashish-egov <[email protected]>
* Allow facility capacity to be 0 in sheet uploads for microplan

* changed facility capacity validation message
#1310)

* Optimized latitude and longitude validation logic for improved efficiency

* facility capacity assignment to 0 for microplan

* Facility capacity enrichment for microplan
* Implemented locale and campaign check

* Optimised validation for metadata

* Update health-services/project-factory/src/server/config/index.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Validate metadata only during action validate

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* added config

* removed hardcoded retry limit
#1343)

* feat: Implement facility list with inactive by default and toggle active/inactive from constant configs

* Status lock fix

* Updated flow status fix
* refactored dropdown

* updated dropdown logic

* refactored dropdown logic

* refactor

* added dropdown related changes

* refactor

* refactor
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 11, 2025

## Walkthrough

This update introduces new Excel template generation and processing flows, adds robust validation, and enhances campaign, user, and facility data handling. It includes new TypeScript classes for dynamic sheet creation and processing, improved schema-driven Excel manipulation, expanded configuration, and utilities for encryption, Redis reconnection, and Kafka messaging. Several APIs, validators, and configuration files are updated or newly added.

## Changes

| Files / Groups                                                                                          | Change Summary |
|--------------------------------------------------------------------------------------------------------|----------------|
| migration/main/V20250512172100__create_data_table.sql, migrate.sh                                       | Added SQL migration for new data table; updated migration script to support multiple schemas. |
| package.json                                                                                           | Increased Node heap size for serve scripts; added `zod` dependency. |
| src/server/api/campaignApis.ts, coreApis.ts, genericApis.ts                                             | Refactored and enhanced campaign/user/facility APIs, schema handling, validation, and caching. |
| src/server/app.ts                                                                                      | Refactored server startup; added periodic memory logging and server timeout configuration. |
| src/server/config/constants.ts, createAndSearch.ts, generationtTemplateConfigs.ts, index.ts, models/...| Added/updated error codes, statuses, template configs, schema models, and configuration options. |
| src/server/controllers/index.ts, sheetManage/sheetManage.controller.ts                                 | Added new controller for sheet management with endpoints for template generation and processing. |
| src/server/generateFlowClasses/...                                                                     | Added new classes for boundary, facility, and user template generation; static type checking utility. |
| src/server/processFlowClasses/...                                                                      | Added new user data processing class; static type checking utility. |
| src/server/service/dataManageService.ts, sheetManageService.ts                                         | Enhanced data download/generation logic; added new services for sheet management. |
| src/server/utils/campaignMappingUtils.ts, campaignUtils.ts, cryptUtils.ts, db/index.ts, excelUtils.ts, ...| Improved campaign mapping, Excel handling, encryption, DB table naming, Redis reconnection, and mail utilities. |
| src/server/utils/genericUtils.ts, generateUtils.ts, microplanUtils.ts, onGoingCampaignUpdateUtils.ts, ...| Refactored and added utilities for resource search, request building, boundary handling, and error management. |
| src/server/validators/campaignValidators.ts, genericValidator.ts, microplanValidators.ts               | Enhanced validation for multi-select, phone numbers, resource details, and boundary filters. |
| src/server/models/GenerateTemplateQuery.ts, SheetMap.ts                                                | Added new Zod schema and interfaces for template query and sheet mapping. |
| .github/workflows/buildProjectFactory.yml, build/build-config.yml                                      | Added new GitHub Actions workflow for multi-arch Docker builds; updated build config with explicit Dockerfiles. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant Controller
    participant Service
    participant Utils
    participant Kafka
    participant DB
    participant ExcelJS
    participant Redis

    User->>Controller: POST /v2/data/_generate (with query)
    Controller->>Service: generateDataService(query, userUuid, locale)
    Service->>Utils: initializeGenerateAndGetResponse(...)
    Utils->>ExcelJS: Generate workbook from schema/config
    Utils->>Kafka: Produce resource creation message
    Utils->>DB: Store resource metadata
    Utils->>Redis: Cache resource info
    Utils-->>Service: Generated resource response
    Service-->>Controller: Response
    Controller-->>User: Excel template or JSON

    User->>Controller: POST /v2/data/_process (with file)
    Controller->>Service: processDataService(resourceDetails, userUuid, locale)
    Service->>Utils: initializeProcessAndGetResponse(...)
    Utils->>ExcelJS: Read and validate workbook
    Utils->>DB: Fetch related data
    Utils->>Kafka: Produce resource update/failure messages
    Utils-->>Service: Processed resource response
    Service-->>Controller: Response
    Controller-->>User: Processed data or status

Possibly related PRs

Suggested reviewers

  • jagankumar-egov

Poem

In fields of code, where schemas grow,
Rabbits bounce with Excel in tow.
Boundaries, users, all in line—
Sheets and rows, they intertwine.
With Zod and Kafka, Redis too,
This fluffy patch brings something new!
🐇✨


<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: ASSERTIVE**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between f7377336066a032ac1af066723a8d151018fe660 and 89fb3fd1a6b26ea416342a683e8487628f899a10.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `health-services/project-factory/migration/migrate.sh` (1 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧠 Learnings (2)</summary>

<details>
<summary>📓 Common learnings</summary>

Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).


Learnt from: tanishi-egov
PR: #1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.


</details>
<details>
<summary>health-services/project-factory/migration/migrate.sh (7)</summary>

Learnt from: kavi-egov
PR: #791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-10-08T20:11:12.539Z
Learning: User kavi-egov has tested and confirmed that the shell script in core-services/service-request/src/main/resources/db/migrate.sh works without double quotes around variables, and prefers to keep it this way.


Learnt from: kavi-egov
PR: #791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-06-20T12:51:42.524Z
Learning: User kavi-egov has tested and confirmed that the shell script in core-services/service-request/src/main/resources/db/migrate.sh works without double quotes around variables, and prefers to keep it this way.


Learnt from: holashchand
PR: #1607
File: health-services/individual/src/main/resources/db/migration/main/V20250616122000__populate_null_client_reference_id_individual_identifier.sql:2-19
Timestamp: 2025-06-17T10:19:50.672Z
Learning: For the migration file V20250616122000__populate_null_client_reference_id_individual_identifier.sql in health-services/individual, the batched loop approach was previously recommended by CodeRabbit to handle potential memory and timeout issues with large table updates. The current implementation uses a DO block with LOOP to update 1000 rows at a time.


Learnt from: Sreejit-K
PR: #1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:3-14
Timestamp: 2025-05-29T06:50:59.173Z
Learning: The team prioritizes consistency across services over fixing individual formatting issues or typos. When properties like spring.datasource.url= jdbc:... (with leading space), success=SUCCESSFULL (with typo), or error codes like IDSeqOverFlow are consistent across multiple services, they should be kept as-is rather than "fixed" to maintain uniformity across the codebase.


Learnt from: tanishi-egov
PR: #1337
File: health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java:229-230
Timestamp: 2025-01-16T12:10:20.764Z
Learning: Database schema modifications should be avoided in code reviews. The team prefers to handle schema changes through dedicated database migration processes rather than as part of feature PRs.


Learnt from: palak-egov
PR: #899
File: health-services/plan-service/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-09-27T06:41:35.748Z
Learning: In this codebase, it's acceptable to not enclose shell script variables in double quotes.


Learnt from: palak-egov
PR: #899
File: health-services/plan-service/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-10-08T20:11:07.772Z
Learning: In this codebase, it's acceptable to not enclose shell script variables in double quotes.


</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)</summary>

* GitHub Check: build
* GitHub Check: build

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=egovernments/health-campaign-services&utm_content=1670):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `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 explain this code block.`
  -	`@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 explain its main purpose.`
  - `@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.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

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](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@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](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

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.

Actionable comments posted: 72

🔭 Outside diff range comments (9)
health-services/project-factory/src/server/models/SheetMap.ts (1)

1-23: Well-structured interfaces for spreadsheet operations.

The interfaces provide good flexibility with optional properties. Consider adding JSDoc comments to clarify the purpose and behavior of certain properties, especially:

  • The difference between freezeColumn and freezeColumnIfFilled
  • The distinction between unFreezeColumnTillData and freezeTillData
  • When showInProcessed should be used

Example documentation:

interface ColumnProperties {
    /** Column width in pixels */
    width?: number;
    /** Background color in hex format (e.g., "#FFFFFF") */
    color?: string;
    // ... add descriptions for other properties
}
health-services/project-factory/src/server/app.ts (1)

19-66: Consider making memory threshold configurable

The memory logging implementation looks good. However, the critical threshold is hardcoded at 50%. Consider making this configurable for different deployment scenarios.

Add a configuration option for the memory critical threshold:

 private readonly MEMORY_LOG_INTERVAL_MS = 30000; // Log memory every 30 seconds
+private readonly MEMORY_CRITICAL_THRESHOLD = Number(process.env.MEMORY_CRITICAL_THRESHOLD) || 0.5;

 private isMemoryCritical(): boolean {
   const stats = v8.getHeapStatistics();
-  return stats.used_heap_size / stats.heap_size_limit > 0.5;
+  return stats.used_heap_size / stats.heap_size_limit > this.MEMORY_CRITICAL_THRESHOLD;
 }
health-services/project-factory/src/server/api/coreApis.ts (1)

284-302: Add response validation to prevent runtime errors.

Consider validating the response structure before accessing nested properties.

 const fetchFileFromFilestore = async (filestoreId: string, tenantId: string) => {
-
   try {
     const reqParamsForFetchingFile = {
       tenantId: tenantId,
       fileStoreIds: filestoreId
     };
     const fileResponse = await httpRequest(
       `${config?.host?.filestore}${config?.paths?.filestorefetch}`,
       {},
       reqParamsForFetchingFile,
       "get"
     );
+    if (!fileResponse?.fileStoreIds?.[0]?.url) {
+      throw new Error("Invalid filestore response: URL not found");
+    }
     return fileResponse?.fileStoreIds?.[0].url;
   } catch (error) {
     console.error("Error fetching file URLs:", error);
     throw error;
   }
 }
health-services/project-factory/src/server/validators/campaignValidators.ts (1)

218-231: Add validation for the phone number length configuration.

The change to use config?.user?.phoneNumberLength is good for maintainability. However, consider adding a null check or default value in case the configuration is missing.

-if (phoneNumber.length != config?.user?.phoneNumberLength) {
+const expectedLength = config?.user?.phoneNumberLength || 10; // Default to 10 if not configured
+if (phoneNumber.length != expectedLength) {
     digitErrorRows.push(data["!row#number!"]);
 }

And update the error message:

-errorMessage = `PhoneNumber should be of ${config?.user?.phoneNumberLength} digits on rows ${digitErrorRows.join(" , ")}`;
+errorMessage = `PhoneNumber should be of ${expectedLength} digits on rows ${digitErrorRows.join(" , ")}`;
health-services/project-factory/src/server/utils/genericUtils.ts (2)

228-279: Refactor to eliminate code duplication between search functions.

The new searchAllGeneratedResources function is nearly identical to searchGeneratedResources, with the only difference being the absence of the LIMIT 1 clause. This violates the DRY principle.

Consider refactoring to have a single function with an optional parameter:

-async function searchGeneratedResources(searchQuery : any, locale : any) {
+async function searchGeneratedResources(searchQuery : any, locale : any, returnAll: boolean = false) {
   try {
     const { type, tenantId, hierarchyType, id, status, campaignId } = searchQuery;
     let queryString = `SELECT * FROM ${config?.DB_CONFIG.DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME} WHERE `;
-    let queryConditions: string[] = [];
-    let queryValues: any[] = [];
+    const queryConditions: string[] = [];
+    const queryValues: any[] = [];
     // ... existing condition building logic ...

     queryString += queryConditions.join(" AND ");

-    // Add sorting and limiting
-    queryString += " ORDER BY createdTime DESC OFFSET 0 LIMIT 1";
+    // Add sorting
+    queryString += " ORDER BY createdTime DESC";
+    
+    // Add limiting if not returning all
+    if (!returnAll) {
+      queryString += " OFFSET 0 LIMIT 1";
+    }

     const queryResult = await executeQuery(queryString, queryValues);
     return generatedResourceTransformer(queryResult?.rows);
   } catch (error: any) {
     console.log(error)
     logger.error(`Error fetching data from the database: ${error.message}`);
     throwError("COMMON", 500, "INTERNAL_SERVER_ERROR", error?.message);
     return null; // Return null in case of an error
   }
 }

-async function searchAllGeneratedResources(searchQuery: any, locale: any) {
-  // ... entire function body can be removed ...
-}
+// Create an alias for backward compatibility
+const searchAllGeneratedResources = (searchQuery: any, locale: any) => 
+  searchGeneratedResources(searchQuery, locale, true);

Also applies to: 281-328


811-876: Good improvements to dropdown handling, but consider renaming the function.

The enhancements to error handling and logging are excellent. However, the function name handledropdownthings is not professional and doesn't follow naming conventions.

-export async function handledropdownthings(sheet: any, schema: any, localizationMap: any) {
+export async function handleDropdownValidation(sheet: any, schema: any, localizationMap: any) {
health-services/project-factory/src/server/api/campaignApis.ts (2)

465-547: Fix code quality issues in matchUserValidation.

The username validation logic is a good addition, but there are some code quality improvements needed:

Apply this diff to fix the issues:

-  var mobileNumbercount = 0;
-  var userNameCount = 0;
+  let mobileNumbercount = 0;
+  let userNameCount = 0;
-  logger.info("Invalid resources count : " + mobileNumbercount + userNameCount);
+  logger.info(`Invalid resources count : ${mobileNumbercount + userNameCount}`);

872-890: Fix unsafe optional chaining usage.

The validation enhancements look good, but there's a potential runtime error.

Apply this diff to fix the unsafe optional chaining:

-    request.body.sheetErrorDetails = request?.body?.sheetErrorDetails
-      ? [...request?.body?.sheetErrorDetails, ...allErrors]
-      : allErrors;
+    request.body.sheetErrorDetails = request.body?.sheetErrorDetails
+      ? [...request.body.sheetErrorDetails, ...allErrors]
+      : allErrors;
health-services/project-factory/src/server/utils/campaignUtils.ts (1)

3190-3266: Well-structured target calculation logic!

The separation between parent and current level calculations is clean. Consider adding type annotations for better type safety.

For the beneficiaries parameter in both functions, consider adding proper TypeScript types:

interface Beneficiary {
  beneficiaryType: string;
  columns: string[];
}

function calculateTargetsAtParentLevel(
  request: any,
  row: any,
  rowData: any,
  beneficiaries: Beneficiary[],
  localizationMap?: any
) {
  // ...
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3187c01 and f83b640.

⛔ Files ignored due to path filters (2)
  • health-services/project-factory/package-lock.json is excluded by !**/package-lock.json
  • health-services/project-factory/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (48)
  • build/17/maven/Dockerfile (1 hunks)
  • build/maven/Dockerfile (1 hunks)
  • health-services/project-factory/migration/main/V20250512172100__create_data_table.sql (1 hunks)
  • health-services/project-factory/package.json (2 hunks)
  • health-services/project-factory/src/server/api/campaignApis.ts (23 hunks)
  • health-services/project-factory/src/server/api/coreApis.ts (5 hunks)
  • health-services/project-factory/src/server/api/genericApis.ts (12 hunks)
  • health-services/project-factory/src/server/app.ts (4 hunks)
  • health-services/project-factory/src/server/config/constants.ts (3 hunks)
  • health-services/project-factory/src/server/config/createAndSearch.ts (3 hunks)
  • health-services/project-factory/src/server/config/generationtTemplateConfigs.ts (1 hunks)
  • health-services/project-factory/src/server/config/index.ts (7 hunks)
  • health-services/project-factory/src/server/config/models/generateRequestSchema.ts (1 hunks)
  • health-services/project-factory/src/server/config/models/resourceDetailsSchema.ts (1 hunks)
  • health-services/project-factory/src/server/config/processTemplateConfigs.ts (1 hunks)
  • health-services/project-factory/src/server/config/transFormConfig.ts (1 hunks)
  • health-services/project-factory/src/server/controllers/index.ts (1 hunks)
  • health-services/project-factory/src/server/controllers/sheetManage/sheetManage.controller.ts (1 hunks)
  • health-services/project-factory/src/server/generateFlowClasses/boundary-generateClass.ts (1 hunks)
  • health-services/project-factory/src/server/generateFlowClasses/facility-generateClass.ts (1 hunks)
  • health-services/project-factory/src/server/generateFlowClasses/generateFlowClassChecker.ts (1 hunks)
  • health-services/project-factory/src/server/generateFlowClasses/user-generateClass.ts (1 hunks)
  • health-services/project-factory/src/server/index.ts (1 hunks)
  • health-services/project-factory/src/server/kafka/Producer.ts (1 hunks)
  • health-services/project-factory/src/server/models/GenerateTemplateQuery.ts (1 hunks)
  • health-services/project-factory/src/server/models/SheetMap.ts (1 hunks)
  • health-services/project-factory/src/server/processFlowClasses/processFlowClassChecker.ts (1 hunks)
  • health-services/project-factory/src/server/processFlowClasses/user-processClass.ts (1 hunks)
  • health-services/project-factory/src/server/service/dataManageService.ts (3 hunks)
  • health-services/project-factory/src/server/service/sheetManageService.ts (1 hunks)
  • health-services/project-factory/src/server/utils/campaignMappingUtils.ts (3 hunks)
  • health-services/project-factory/src/server/utils/campaignUtils.ts (37 hunks)
  • health-services/project-factory/src/server/utils/cryptUtils.ts (1 hunks)
  • health-services/project-factory/src/server/utils/excelUtils.ts (7 hunks)
  • health-services/project-factory/src/server/utils/generateUtils.ts (3 hunks)
  • health-services/project-factory/src/server/utils/genericUtils.ts (27 hunks)
  • health-services/project-factory/src/server/utils/mailUtil.ts (1 hunks)
  • health-services/project-factory/src/server/utils/microplanIntergration.ts (0 hunks)
  • health-services/project-factory/src/server/utils/microplanUtils.ts (6 hunks)
  • health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (5 hunks)
  • health-services/project-factory/src/server/utils/redisUtils.ts (1 hunks)
  • health-services/project-factory/src/server/utils/request.ts (2 hunks)
  • health-services/project-factory/src/server/utils/sheetManageUtils.ts (1 hunks)
  • health-services/project-factory/src/server/utils/transforms/localisationMessageConstructor.ts (2 hunks)
  • health-services/project-factory/src/server/utils/transforms/searchResponseConstructor.ts (1 hunks)
  • health-services/project-factory/src/server/validators/campaignValidators.ts (12 hunks)
  • health-services/project-factory/src/server/validators/genericValidator.ts (2 hunks)
  • health-services/project-factory/src/server/validators/microplanValidators.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • health-services/project-factory/src/server/utils/microplanIntergration.ts
🧰 Additional context used
🧠 Learnings (43)
📓 Common learnings
Learnt from: shubhang-eGov
PR: egovernments/health-campaign-services#1387
File: health-services/referralmanagement/pom.xml:54-54
Timestamp: 2025-02-11T09:43:42.872Z
Learning: Version updates for health-services-models in referral management service require QA verification to ensure no breaking changes between versions.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: kanishq-egov
PR: egovernments/health-campaign-services#847
File: health-services/libraries/health-services-common/pom.xml:11-11
Timestamp: 2024-08-12T06:07:15.114Z
Learning: Not all services in the health campaign services project are required to move to newer versions like `1.0.17-dev-SNAPSHOT`, as per kanishq-egov's guidance.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: core-services/beneficiary-idgen/src/test/java/org/egov/id/service/IdGenerationServiceTest.java:20-28
Timestamp: 2025-06-17T10:11:37.370Z
Learning: In the health-campaign-services project, tests are handled at the dev level and comprehensive unit tests are added when needed in the future, rather than requiring full mock coverage for all dependencies immediately.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java:144-144
Timestamp: 2025-01-16T11:52:14.029Z
Learning: Changes to employeeService in core-services/egov-hrms should be handled by the HCM team rather than the health campaign services team.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: health-services/individual/src/main/java/org/egov/individual/service/IndividualService.java:158-166
Timestamp: 2025-06-17T08:53:38.146Z
Learning: The individual service in the health-campaign-services project is using Java 17.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
health-services/project-factory/src/server/config/models/generateRequestSchema.ts (2)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: abishekTa-egov
PR: egovernments/health-campaign-services#1567
File: health-services/geopode-adapter/src/main/java/digit/config/ServiceConstants.java:32-57
Timestamp: 2025-05-28T11:03:54.258Z
Learning: The hierarchy definition in the geopode-adapter service doesn't need to be externalized or made dynamic because it's designed to work with hardcoded boundary-definition and will leverage MDMS values for actual data.
health-services/project-factory/src/server/utils/request.ts (1)
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/src/server/validators/microplanValidators.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/validators/genericValidator.ts (6)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java:1-32
Timestamp: 2024-10-08T20:11:07.772Z
Learning: In the codebase, validation is handled in other layers of the application, so validation annotations (e.g., from Jakarta Validation API) are not required on model classes like `Boundary`.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/web/models/projectFactory/Boundary.java:1-32
Timestamp: 2024-09-27T05:29:54.929Z
Learning: In the codebase, validation is handled in other layers of the application, so validation annotations (e.g., from Jakarta Validation API) are not required on model classes like `Boundary`.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The `addTenantBoundaryItem` method in `BoundarySearchResponse.java` does not require thread safety measures as per devdatta-egov's guidance.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-06-26T17:13:14.997Z
Learning: The `addTenantBoundaryItem` method in `BoundarySearchResponse.java` does not require thread safety measures as per devdatta-egov's guidance.
health-services/project-factory/src/server/index.ts (3)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
health-services/project-factory/src/server/generateFlowClasses/generateFlowClassChecker.ts (2)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/src/server/utils/mailUtil.ts (2)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/src/server/config/models/resourceDetailsSchema.ts (2)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java:28-59
Timestamp: 2024-09-27T04:33:06.202Z
Learning: In this project, the `additionalDetails` field is intentionally typed as `Object`, and it's the accepted approach.
health-services/project-factory/src/server/controllers/index.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
build/maven/Dockerfile (1)
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/db/Dockerfile:1-9
Timestamp: 2025-05-29T07:17:56.555Z
Learning: The eGovernments (digit) platform has established standards for Dockerfiles that may differ from general Docker security best practices. When reviewing Dockerfiles in digit projects, respect their organizational standards rather than suggesting general security improvements like non-root users or health checks.
build/17/maven/Dockerfile (2)
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#902
File: health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java:553-553
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The plan-service project is using Java 17.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/db/Dockerfile:1-9
Timestamp: 2025-05-29T07:17:56.555Z
Learning: The eGovernments (digit) platform has established standards for Dockerfiles that may differ from general Docker security best practices. When reviewing Dockerfiles in digit projects, respect their organizational standards rather than suggesting general security improvements like non-root users or health checks.
health-services/project-factory/src/server/utils/transforms/searchResponseConstructor.ts (2)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/web/models/PlanFacility.java:28-59
Timestamp: 2024-09-27T04:33:06.202Z
Learning: In this project, the `additionalDetails` field is intentionally typed as `Object`, and it's the accepted approach.
health-services/project-factory/src/server/utils/transforms/localisationMessageConstructor.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/config/processTemplateConfigs.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/models/GenerateTemplateQuery.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/processFlowClasses/processFlowClassChecker.ts (3)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
health-services/project-factory/src/server/service/dataManageService.ts (3)
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/src/server/config/createAndSearch.ts (3)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/web/models/planFacility/PlanFacilitySearchRequest.java:29-32
Timestamp: 2025-01-17T09:03:48.249Z
Learning: In the health-campaign-services codebase, `PlanFacilitySearchCriteria` and `facilitySearchCriteria` are distinct search criteria used by different services. `PlanFacilitySearchCriteria` is specifically used for searching facilities within the context of a plan.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
health-services/project-factory/src/server/utils/generateUtils.ts (3)
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
health-services/project-factory/src/server/app.ts (2)
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
health-services/project-factory/src/server/models/SheetMap.ts (2)
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
health-services/project-factory/src/server/generateFlowClasses/user-generateClass.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/utils/campaignMappingUtils.ts (8)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:48-60
Timestamp: 2024-09-27T05:11:37.733Z
Learning: In this project, it's acceptable to keep the creation of objects like `CampaignSearchCriteria` within the current method for simplicity, even if extracting into a separate private method could improve readability.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-10-08T20:11:07.772Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-09-26T10:51:08.515Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
health-services/project-factory/migration/main/V20250512172100__create_data_table.sql (4)
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/db/migration/main/V20250322111348__DDL_id_generation_create_ddl.sql:1-12
Timestamp: 2025-05-29T07:06:41.314Z
Learning: In the egovernments/health-campaign-services codebase, database column names use camelCase naming convention (e.g., tenantId, additionalFields, createdBy) as per their specification, not snake_case as typically expected in PostgreSQL.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: health-services/household/src/main/resources/db/migration/main/V20250327022035__household_member_relationship_ddl.sql:1-23
Timestamp: 2025-06-13T06:46:36.196Z
Learning: Project convention: In the eGov Health micro-services, schema migrations intentionally avoid foreign-key constraints, and mandatory fields are enforced through entity-level (application-layer) validation rather than NOT NULL constraints in DDL.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: health-services/individual/src/main/resources/db/migration/main/V20250616122000__populate_null_client_reference_id_individual_identifier.sql:2-19
Timestamp: 2025-06-17T10:19:50.672Z
Learning: For the migration file V20250616122000__populate_null_client_reference_id_individual_identifier.sql in health-services/individual, the batched loop approach was previously recommended by CodeRabbit to handle potential memory and timeout issues with large table updates. The current implementation uses a DO block with LOOP to update 1000 rows at a time.
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/resources/db/migration/main/V20240923113045__plan_facility_create_ddl.sql:12-14
Timestamp: 2024-09-27T06:00:31.852Z
Learning: In the project, the `created_time` and `last_modified_time` columns are stored as `bigint` using epoch timestamps in milliseconds, to maintain consistency with existing code and external systems.
health-services/project-factory/src/server/service/sheetManageService.ts (1)
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
health-services/project-factory/src/server/utils/redisUtils.ts (2)
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/java/org/egov/id/config/RedisConfig.java:29-46
Timestamp: 2025-05-29T07:29:21.761Z
Learning: In the beneficiary-idgen service, the team prefers to keep Redis configuration simple without additional authentication, connection validation, or SSL/TLS features in the RedisConfig class.
health-services/project-factory/src/server/utils/sheetManageUtils.ts (7)
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java:468-485
Timestamp: 2025-04-29T05:56:06.702Z
Learning: In the resource-generator module, workbook resources are intentionally not closed inside utility methods like `convertWorkbookToXls` because the workbook is used for further processing after these methods return. Resource cleanup is handled at a higher level in the processing chain.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
health-services/project-factory/src/server/generateFlowClasses/facility-generateClass.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/config/index.ts (17)
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:76-83
Timestamp: 2025-05-29T06:53:25.851Z
Learning: In the health-campaign-services project, configuration properties should follow existing patterns throughout the codebase rather than using environment variable placeholders, to maintain consistency across the project.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/java/org/egov/id/config/RedissonProperties.java:6-16
Timestamp: 2025-05-29T06:52:37.823Z
Learning: In health-campaign-services repository, the team prefers camelCase for configuration property field names (e.g., connectionPoolSize, nettyThreads) instead of kebab-case to maintain code consistency, even for Spring Boot @ConfigurationProperties classes.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#978
File: health-services/plan-service/src/main/resources/application.properties:80-80
Timestamp: 2024-10-15T08:31:13.060Z
Learning: In the 'health-campaign-services' project, it's acceptable to keep the `role.map` property in single-line format in the `application.properties` file, and reformatting into multiple lines is not required.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/LOCALSETUP.md:0-0
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The note in the LOCALSETUP.md file regarding error handling with Kafka and other microservices has been updated to provide more detailed troubleshooting steps.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/LOCALSETUP.md:0-0
Timestamp: 2024-06-24T08:15:04.390Z
Learning: The note in the LOCALSETUP.md file regarding error handling with Kafka and other microservices has been updated to provide more detailed troubleshooting steps.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java:7-16
Timestamp: 2024-10-08T20:11:12.539Z
Learning: Documentation at the class and field level has been added to the `CycleConfigureDate` class in the `resource-estimation-service` module as per devdatta-egov's update.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/campaignManager/CycleConfigureDate.java:7-16
Timestamp: 2024-06-26T17:03:35.631Z
Learning: Documentation at the class and field level has been added to the `CycleConfigureDate` class in the `resource-estimation-service` module as per devdatta-egov's update.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:3-14
Timestamp: 2025-05-29T06:50:59.173Z
Learning: The team prioritizes consistency across services over fixing individual formatting issues or typos. When properties like `spring.datasource.url= jdbc:...` (with leading space), `success=SUCCESSFULL` (with typo), or error codes like `IDSeqOverFlow` are consistent across multiple services, they should be kept as-is rather than "fixed" to maintain uniformity across the codebase.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueryBuilder.java:107-111
Timestamp: 2025-06-17T07:03:29.537Z
Learning: The egov-hrms service has default values configured in application.properties for critical properties like pagination limits, which serve as fallbacks when environment variables are missing from deployment charts.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/db/migration/main/V20250322111348__DDL_id_generation_create_ddl.sql:1-12
Timestamp: 2025-05-29T07:06:41.314Z
Learning: In the egovernments/health-campaign-services codebase, database column names use camelCase naming convention (e.g., tenantId, additionalFields, createdBy) as per their specification, not snake_case as typically expected in PostgreSQL.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:44-74
Timestamp: 2025-05-29T06:51:42.290Z
Learning: In eGov projects, hardcoded Kafka configurations (bootstrap servers, topic names) in application.properties files are expected and follow eGov standards, rather than using environment variable placeholders.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java:87-91
Timestamp: 2025-01-16T09:50:36.566Z
Learning: Email notification properties in HRMS service (kafka.topics.notification.email, notification.email.enabled, hrms.email.notification.implementation.partner, hrms.email.notification.website.link) are configured in both DevOps chart and application.properties, ensuring they are always present at startup.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/consumer/HrmsConsumer.java:35-45
Timestamp: 2025-01-16T11:41:16.610Z
Learning: In the HRMS service, a single Kafka listener is preferred to handle both employee data updates and email notifications, using the topic header to branch the logic. This approach was chosen for its simplicity and effectiveness in handling both event types together.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: core-services/beneficiary-idgen/src/main/resources/application.properties:4-6
Timestamp: 2025-06-17T07:08:22.938Z
Learning: In the eGovernments health-campaign-services project, database credentials in application.properties files are hardcoded as default/development values but are always overridden in production deployments via DevOps Helm charts, which is their standard deployment practice for externalizing secrets.
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/resources/application.properties:63-63
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The URL `https://unified-dev.digit.org` is the correct host for both `egov.project.factory.host` and `egov.facility.host` configurations.
health-services/project-factory/src/server/utils/microplanUtils.ts (3)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/src/server/validators/campaignValidators.ts (13)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java:448-449
Timestamp: 2025-01-22T10:07:27.833Z
Learning: In the health-campaign-services codebase, boundary codes in ExcelParser are pre-validated in the validateRows function before being used, which ensures they cannot be null or empty when accessed later in the code flow.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1419
File: docs/health-api-specs/contracts/registries/product.yml:0-0
Timestamp: 2025-02-24T07:06:49.114Z
Learning: The OpenAPI specification file at docs/health-api-specs/contracts/registries/product.yml should maintain the title "Product Registry" as it contains Product and ProductVariant related APIs.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository's ExcelParser.java, boundary code cell validation is comprehensively handled through validateRows() which includes:
1. validateTillBoundaryCode() - checks for null cells, BLANK cell type, and validates string values against regex patterns
2. validateAttributes() - validates cell types, boundary code existence in boundaryCodeList, and performs string value validation
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The `addTenantBoundaryItem` method in `BoundarySearchResponse.java` does not require thread safety measures as per devdatta-egov's guidance.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-06-26T17:13:14.997Z
Learning: The `addTenantBoundaryItem` method in `BoundarySearchResponse.java` does not require thread safety measures as per devdatta-egov's guidance.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: abishekTa-egov
PR: egovernments/health-campaign-services#1567
File: health-services/geopode-adapter/src/main/java/digit/config/ServiceConstants.java:32-57
Timestamp: 2025-05-28T11:03:54.258Z
Learning: The hierarchy definition in the geopode-adapter service doesn't need to be externalized or made dynamic because it's designed to work with hardcoded boundary-definition and will leverage MDMS values for actual data.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java:82-82
Timestamp: 2025-01-30T06:12:02.730Z
Learning: The getBoundaryCodeValue() method in PlanUtil requires a non-empty mappedValues map containing valid property mappings to prevent runtime exceptions.
health-services/project-factory/src/server/config/constants.ts (11)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/config/ErrorConstants.java:3-6
Timestamp: 2025-05-06T05:25:14.212Z
Learning: The ErrorConstants class in the health-campaign-services repository is accessed via dependency injection, so it needs to keep its @Component annotation.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/config/ServiceConstants.java:36-37
Timestamp: 2025-01-17T06:12:01.218Z
Learning: In ServiceConstants.java, error message constants should be kept together with their corresponding error code constants for better readability and maintainability, rather than grouping all codes separately from all messages.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/config/ServiceConstants.java:189-193
Timestamp: 2024-09-26T11:17:36.420Z
Learning: When reviewing error messages in `ServiceConstants.java`, avoid suggesting changes to make them more descriptive unless specifically requested.
Learnt from: kanishq-egov
PR: egovernments/health-campaign-services#847
File: health-services/libraries/health-services-models/src/main/java/org/egov/common/models/project/TaskStatus.java:6-12
Timestamp: 2024-10-08T20:11:07.773Z
Learning: The `TaskStatus` enum values are used for SMC, Bednet, and IRS campaigns in the health campaign services project.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MixedStrategyOperationLogic.java:19-29
Timestamp: 2025-01-22T10:07:11.992Z
Learning: The MDMS master data models in the health campaign services should maintain consistent property naming with the MDMS master definitions:
1. Boolean flags may use camelCase (e.g., "isFixedPost")
2. Other properties should use PascalCase (e.g., "RegistrationProcess", "DistributionProcess", "CategoriesNotAllowed")
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java:26-36
Timestamp: 2024-09-26T18:13:52.611Z
Learning: In this codebase, when creating resources via POST requests, HTTP status 202 Accepted is intentionally used as per the requirements.
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java:26-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: In this codebase, when creating resources via POST requests, HTTP status 202 Accepted is intentionally used as per the requirements.
health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (6)
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
health-services/project-factory/src/server/processFlowClasses/user-processClass.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/api/coreApis.ts (3)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/web/models/planFacility/PlanFacilitySearchRequest.java:24-27
Timestamp: 2025-01-17T06:16:55.255Z
Learning: The `RequestInfo` property in request DTOs should use PascalCase ("RequestInfo") to maintain consistency across all modules in the codebase, as this convention is used throughout the system and changing it would require UI changes.
health-services/project-factory/src/server/generateFlowClasses/boundary-generateClass.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/config/transFormConfig.ts (1)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
health-services/project-factory/src/server/api/genericApis.ts (8)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:103-105
Timestamp: 2025-01-16T08:16:47.695Z
Learning: When iterating through Excel sheet columns from right to left (last to first) to localize output columns that are appended at the end, breaking the loop upon encountering the first non-localized column is the correct approach as all columns to its left will also be non-localized.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java:68-72
Timestamp: 2025-04-29T08:38:24.868Z
Learning: In the CensusEnrichment class, the enrichBoundaryAncestralPath method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: kanishq-egov
PR: egovernments/health-campaign-services#838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-105
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The project type is currently used in both MDMS (Master Data Management System) and project additional details.
Learnt from: kanishq-egov
PR: egovernments/health-campaign-services#838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-105
Timestamp: 2024-08-02T09:10:43.693Z
Learning: The project type is currently used in both MDMS (Master Data Management System) and project additional details.
health-services/project-factory/src/server/utils/excelUtils.ts (7)
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:103-105
Timestamp: 2025-01-16T08:16:47.695Z
Learning: When iterating through Excel sheet columns from right to left (last to first) to localize output columns that are appended at the end, breaking the loop upon encountering the first non-localized column is the correct approach as all columns to its left will also be non-localized.
health-services/project-factory/src/server/utils/campaignUtils.ts (23)

<retrieved_learning>
Learnt from: nitish-egov
PR: #1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In health-services/project-factory/src/server/utils/campaignMappingUtils.ts, the processMapping function already includes validation for mappingObject.CampaignDetails.campaignDetails.boundaries before accessing it, so additional null checks are unnecessary.
</retrieved_learning>

<retrieved_learning>
Learnt from: jagankumar-egov
PR: #1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts file, the throwError function logs errors internally. Therefore, when catching errors and rethrowing using throwError, it's not necessary to add extra logger.error calls before invoking throwError.
</retrieved_learning>

<retrieved_learning>
Learnt from: devdatta-egov
PR: #784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the updateCampaignDetails method of the CampaignIntegrationUtil class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java:448-449
Timestamp: 2025-01-22T10:07:27.833Z
Learning: In the health-campaign-services codebase, boundary codes in ExcelParser are pre-validated in the validateRows function before being used, which ensures they cannot be null or empty when accessed later in the code flow.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository's ExcelParser.java, boundary code cell validation is comprehensively handled through validateRows() which includes:

  1. validateTillBoundaryCode() - checks for null cells, BLANK cell type, and validates string values against regex patterns
  2. validateAttributes() - validates cell types, boundary code existence in boundaryCodeList, and performs string value validation
    </retrieved_learning>

<retrieved_learning>
Learnt from: siddhant-nawale-egov
PR: #793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
</retrieved_learning>

<retrieved_learning>
Learnt from: siddhant-nawale-egov
PR: #793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:103-105
Timestamp: 2025-01-16T08:16:47.695Z
Learning: When iterating through Excel sheet columns from right to left (last to first) to localize output columns that are appended at the end, breaking the loop upon encountering the first non-localized column is the correct approach as all columns to its left will also be non-localized.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java:468-485
Timestamp: 2025-04-29T05:56:06.702Z
Learning: In the resource-generator module, workbook resources are intentionally not closed inside utility methods like convertWorkbookToXls because the workbook is used for further processing after these methods return. Resource cleanup is handled at a higher level in the processing chain.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java:82-82
Timestamp: 2025-01-30T06:12:02.730Z
Learning: The getBoundaryCodeValue() method in PlanUtil requires a non-empty mappedValues map containing valid property mappings to prevent runtime exceptions.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java:68-72
Timestamp: 2025-04-29T08:38:24.868Z
Learning: In the CensusEnrichment class, the enrichBoundaryAncestralPath method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-105
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The project type is currently used in both MDMS (Master Data Management System) and project additional details.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-105
Timestamp: 2024-08-02T09:10:43.693Z
Learning: The project type is currently used in both MDMS (Master Data Management System) and project additional details.
</retrieved_learning>

<retrieved_learning>
Learnt from: Saloni-eGov
PR: #906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:48-60
Timestamp: 2024-09-27T05:11:37.733Z
Learning: In this project, it's acceptable to keep the creation of objects like CampaignSearchCriteria within the current method for simplicity, even if extracting into a separate private method could improve readability.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-67
Timestamp: 2024-08-02T10:16:45.611Z
Learning: The project type JSON is currently stored in both the project model and MDMS. Once the transition to project models is complete, the logic will be updated accordingly.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-67
Timestamp: 2024-10-08T20:11:07.773Z
Learning: The project type JSON is currently stored in both the project model and MDMS. Once the transition to project models is complete, the logic will be updated accordingly.
</retrieved_learning>

<retrieved_learning>
Learnt from: devdatta-egov
PR: #784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-06-26T17:13:14.997Z
Learning: The addTenantBoundaryItem method in BoundarySearchResponse.java does not require thread safety measures as per devdatta-egov's guidance.
</retrieved_learning>

<retrieved_learning>
Learnt from: devdatta-egov
PR: #784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The addTenantBoundaryItem method in BoundarySearchResponse.java does not require thread safety measures as per devdatta-egov's guidance.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
</retrieved_learning>

health-services/project-factory/src/server/api/campaignApis.ts (10)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java:144-144
Timestamp: 2025-01-16T11:52:14.029Z
Learning: Changes to employeeService in core-services/egov-hrms should be handled by the HCM team rather than the health campaign services team.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java:448-449
Timestamp: 2025-01-22T10:07:27.833Z
Learning: In the health-campaign-services codebase, boundary codes in ExcelParser are pre-validated in the validateRows function before being used, which ensures they cannot be null or empty when accessed later in the code flow.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: health-services/libraries/health-services-models/src/main/java/org/egov/common/models/idgen/IDPoolGenerationRequest.java:34-37
Timestamp: 2025-05-29T08:34:07.853Z
Learning: When reviewing batch request APIs in health-services, ensure that list fields like batchRequestList have appropriate size validation (@Size annotation) to prevent performance issues from large batch operations. Typical limits should be reasonable for the use case (e.g., 1-100 items for batch requests).
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
health-services/project-factory/src/server/utils/genericUtils.ts (8)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MixedStrategyOperationLogic.java:19-29
Timestamp: 2025-01-22T10:07:11.992Z
Learning: The MDMS master data models in the health campaign services should maintain consistent property naming with the MDMS master definitions:
1. Boolean flags may use camelCase (e.g., "isFixedPost")
2. Other properties should use PascalCase (e.g., "RegistrationProcess", "DistributionProcess", "CategoriesNotAllowed")
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
🧬 Code Graph Analysis (13)
health-services/project-factory/src/server/utils/request.ts (1)
health-services/project-factory/src/server/utils/redisUtils.ts (2)
  • checkRedisConnection (108-108)
  • reconnectRedis (109-109)
health-services/project-factory/src/server/validators/genericValidator.ts (1)
health-services/project-factory/src/server/api/coreApis.ts (1)
  • searchBoundaryRelationshipData (305-305)
health-services/project-factory/src/server/index.ts (2)
health-services/project-factory/src/server/generateFlowClasses/generateFlowClassChecker.ts (1)
  • checkGenerateFlowClasses (9-48)
health-services/project-factory/src/server/processFlowClasses/processFlowClassChecker.ts (1)
  • checkProcessFlowClasses (9-48)
health-services/project-factory/src/server/utils/mailUtil.ts (8)
health-services/project-factory/src/server/utils/logger/index.ts (1)
  • logger (24-24)
health-services/project-factory/src/server/utils/genericUtils.ts (1)
  • getLocalizedMessagesHandlerViaLocale (1754-1754)
health-services/project-factory/src/server/models/index.ts (1)
  • MDMSModels (6-6)
health-services/project-factory/src/server/models/MDMS.d.ts (1)
  • MDMSv2RequestCriteria (142-144)
health-services/project-factory/src/server/api/coreApis.ts (1)
  • searchMDMSDataViaV2Api (305-305)
health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (1)
  • getFileUrl (729-742)
health-services/project-factory/src/server/utils/campaignUtils.ts (1)
  • getLocalizedName (4102-4102)
health-services/project-factory/src/server/kafka/Producer.ts (1)
  • produceModifiedMessages (112-112)
health-services/project-factory/src/server/controllers/index.ts (1)
health-services/project-factory/src/server/kafka/Listener.ts (1)
  • listener (26-55)
health-services/project-factory/src/server/utils/cryptUtils.ts (1)
health-services/project-factory/src/server/processFlowClasses/user-processClass.ts (1)
  • process (17-58)
health-services/project-factory/src/server/utils/generateUtils.ts (1)
health-services/project-factory/src/server/utils/genericUtils.ts (1)
  • replicateRequest (1739-1739)
health-services/project-factory/src/server/utils/redisUtils.ts (1)
health-services/project-factory/src/server/utils/logger/index.ts (1)
  • logger (24-24)
health-services/project-factory/src/server/utils/microplanUtils.ts (2)
health-services/project-factory/src/server/utils/campaignUtils.ts (1)
  • getLocalizedName (4102-4102)
health-services/project-factory/src/server/api/coreApis.ts (1)
  • searchMDMSDataViaV1Api (305-305)
health-services/project-factory/src/server/validators/campaignValidators.ts (9)
health-services/project-factory/src/server/utils/campaignUtils.ts (1)
  • getLocalizedName (4102-4102)
health-services/project-factory/src/server/utils/genericUtils.ts (2)
  • getLocalizedHeaders (1736-1736)
  • throwError (1707-1707)
health-services/project-factory/src/server/config/models/resourceDetailsSchema.ts (1)
  • ResourceDetails (21-21)
health-services/project-factory/src/server/utils/logger/index.ts (1)
  • logger (24-24)
health-services/project-factory/src/server/api/coreApis.ts (2)
  • fetchFileFromFilestore (305-305)
  • searchBoundaryRelationshipDefinition (305-305)
health-services/project-factory/src/server/service/campaignManageService.ts (1)
  • searchProjectTypeCampaignService (94-94)
health-services/project-factory/src/server/config/processTemplateConfigs.ts (1)
  • processTemplateConfigs (1-18)
health-services/project-factory/src/server/models/GenerateTemplateQuery.ts (1)
  • GenerateTemplateQuery (17-17)
health-services/project-factory/src/server/config/generationtTemplateConfigs.ts (1)
  • generationtTemplateConfigs (3-53)
health-services/project-factory/src/server/api/coreApis.ts (4)
health-services/project-factory/src/server/models/index.ts (2)
  • MDMSModels (6-6)
  • BoundaryModels (7-7)
health-services/project-factory/src/server/models/MDMS.d.ts (2)
  • MDMSv2RequestCriteria (142-144)
  • MDMSv2Response (45-47)
health-services/project-factory/src/server/utils/request.ts (2)
  • defaultheader (38-41)
  • httpRequest (227-227)
health-services/project-factory/src/server/models/Boundary.d.ts (1)
  • BoundaryHierarchyRelationshipResponse (68-71)
health-services/project-factory/src/server/config/transFormConfig.ts (4)
health-services/project-factory/src/server/utils/campaignUtils.ts (3)
  • createIdRequests (4112-4112)
  • createUniqueUserNameViaIdGen (4113-4113)
  • getBoundaryCodeAndBoundaryTypeMapping (4021-4029)
health-services/project-factory/src/server/utils/logger/index.ts (1)
  • logger (24-24)
health-services/project-factory/src/server/api/coreApis.ts (1)
  • searchBoundaryRelationshipData (305-305)
health-services/project-factory/src/server/api/campaignApis.ts (1)
  • generateUserPassword (1112-1144)
health-services/project-factory/src/server/api/campaignApis.ts (5)
health-services/project-factory/src/server/api/coreApis.ts (1)
  • defaultRequestInfo (7-18)
health-services/project-factory/src/server/utils/request.ts (1)
  • httpRequest (227-227)
health-services/project-factory/src/server/utils/genericUtils.ts (1)
  • throwError (1707-1707)
health-services/project-factory/src/server/utils/campaignUtils.ts (7)
  • validateUsernamesFormat (4031-4079)
  • getBoundaryOnWhichWeSplit (4111-4111)
  • checkIfSourceIsMicroplan (4110-4110)
  • getSchema (611-618)
  • getBoundaryCodeAndBoundaryTypeMapping (4021-4029)
  • createIdRequests (4112-4112)
  • createUniqueUserNameViaIdGen (4113-4113)
health-services/project-factory/src/server/config/constants.ts (1)
  • resourceDataStatuses (113-119)
🪛 Biome (1.9.4)
health-services/project-factory/src/server/generateFlowClasses/generateFlowClassChecker.ts

[error] 2-2: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 3-3: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 43-44: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

health-services/project-factory/src/server/utils/mailUtil.ts

[error] 33-33: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 52-52: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 55-55: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 109-109: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

health-services/project-factory/src/server/utils/cryptUtils.ts

[error] 1-1: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)

health-services/project-factory/src/server/processFlowClasses/processFlowClassChecker.ts

[error] 2-2: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 3-3: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 43-44: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

health-services/project-factory/src/server/app.ts

[error] 14-14: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)

health-services/project-factory/src/server/generateFlowClasses/user-generateClass.ts

[error] 11-206: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 36-36: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 39-39: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 40-40: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 84-84: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 124-124: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

health-services/project-factory/src/server/utils/campaignMappingUtils.ts

[error] 697-697: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 700-700: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 707-707: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 714-714: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 721-721: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 727-727: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 730-730: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

health-services/project-factory/src/server/utils/redisUtils.ts

[error] 10-10: Use Number.parseInt instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.parseInt instead.

(lint/style/useNumberNamespace)

health-services/project-factory/src/server/utils/sheetManageUtils.ts

[error] 10-10: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 14-14: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 181-181: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 206-206: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 250-250: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 266-266: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 107-107: Use Number.parseInt instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.parseInt instead.

(lint/style/useNumberNamespace)


[error] 139-139: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 359-359: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health-services/project-factory/src/server/generateFlowClasses/facility-generateClass.ts

[error] 8-187: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 18-18: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 20-20: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 22-22: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 23-23: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 51-51: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 91-91: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

health-services/project-factory/src/server/validators/campaignValidators.ts

[error] 667-667: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 655-655: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health-services/project-factory/src/server/processFlowClasses/user-processClass.ts

[error] 15-225: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 25-25: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 26-26: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 32-32: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 38-38: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 147-147: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 152-152: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 170-170: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 173-173: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 198-198: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 215-215: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

health-services/project-factory/src/server/api/coreApis.ts

[error] 37-37: This type annotation is trivially inferred from its initialization.

Safe fix: Remove the type annotation.

(lint/style/noInferrableTypes)

health-services/project-factory/src/server/generateFlowClasses/boundary-generateClass.ts

[error] 11-298: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 22-22: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 25-25: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 39-39: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 42-42: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 53-53: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 59-59: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 61-61: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 75-75: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 124-124: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)

health-services/project-factory/src/server/config/transFormConfig.ts

[error] 312-312: This let declares a variable that is only assigned once.

'result' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health-services/project-factory/src/server/api/genericApis.ts

[error] 507-516: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 1464-1464: This let declares a variable that is only assigned once.

'columns' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 1562-1562: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

health-services/project-factory/src/server/utils/excelUtils.ts

[error] 302-302: This type annotation is trivially inferred from its initialization.

Safe fix: Remove the type annotation.

(lint/style/noInferrableTypes)


[error] 302-302: This type annotation is trivially inferred from its initialization.

Safe fix: Remove the type annotation.

(lint/style/noInferrableTypes)


[error] 366-366: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 435-435: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

health-services/project-factory/src/server/utils/campaignUtils.ts

[error] 589-589: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 1438-1438: This let declares a variable that is only assigned once.

'level' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 3462-3462: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 4060-4060: Forbidden non-null assertion.

Unsafe fix: Replace with optional chain operator ?. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator

(lint/style/noNonNullAssertion)

health-services/project-factory/src/server/api/campaignApis.ts

[error] 465-465: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 466-466: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 547-547: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 787-787: This let declares a variable that is only assigned once.

'foundUsernames' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 885-885: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 1045-1046: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 1186-1186: This let declares a variable that is only assigned once.

'result' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 1187-1188: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 1190-1191: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 1707-1708: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health-services/project-factory/src/server/utils/genericUtils.ts

[error] 285-285: This let declares a variable that is only assigned once.

'queryConditions' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 286-286: This let declares a variable that is only assigned once.

'queryValues' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 995-995: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 1479-1479: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 1685-1685: This let declares a variable that is only assigned once.

'relatedData' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 1687-1687: This let declares a variable that is only assigned once.

'rows' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

🪛 Checkov (3.2.334)
build/maven/Dockerfile

[LOW] 1-26: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[LOW] 1-26: Ensure that a user for the container has been created

(CKV_DOCKER_3)

build/17/maven/Dockerfile

[LOW] 1-27: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[LOW] 1-27: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🔇 Additional comments (79)
health-services/project-factory/src/server/index.ts (1)

1-4: LGTM! Clean integration of static type checking.

The addition of static type checking at startup is a good practice. The functions are called synchronously before app initialization, which ensures type safety validation happens early in the startup sequence.

health-services/project-factory/src/server/generateFlowClasses/generateFlowClassChecker.ts (1)

9-48: Excellent static type checking implementation.

The TypeScript compiler API integration is well-implemented with proper error handling, clear messaging, and appropriate use of the existing tsconfig.json. The logic correctly filters files and handles both success and error cases.

build/maven/Dockerfile (1)

2-2: Base-image vendor mismatch may introduce runtime inconsistencies

The build stage uses maven:*-amazoncorretto-8-debian (glibc) while the runtime stage switches to openjdk:8-jdk-alpine (musl).
If any dependency bundles native libraries (e.g. Netty-TCNative, zstd-jni, snappy-jni) compiled against glibc, they will fail to load in the musl-based Alpine image.

Stick to the same vendor / libc family for both stages, e.g. amazoncorretto:8-alpine or openjdk:8-jdk for both.

Also applies to: 16-16

build/17/maven/Dockerfile (1)

1-1: Same vendor/libc divergence as JDK 8 image

The build image is Debian-based (amazoncorretto-17 ⇒ glibc) while runtime switches to Alpine/musl.
Ensure native libs are glibc-free or use amazoncorretto:17 for runtime to stay consistent.

Also applies to: 14-14

health-services/project-factory/src/server/utils/redisUtils.ts (2)

11-17: Verify that disabling Redis retries aligns with your reliability requirements.

The retry strategy returns null which completely disables automatic reconnection attempts. While the code now has explicit reconnection logic via reconnectRedis(), this means Redis won't automatically attempt to reconnect on connection loss. Ensure this behavior is intentional and that the manual reconnection approach provides sufficient reliability for your use case.


67-101: Well-implemented Redis connection resilience.

The addition of connection checks and automatic reconnection attempts before cache operations improves reliability. The enhanced logging with clear visual indicators will help with debugging connection issues.

health-services/project-factory/src/server/utils/request.ts (1)

79-83: Good integration of Redis reconnection logic.

The addition of reconnection attempts before Redis operations ensures cache functionality remains available even after connection losses. The double-check pattern provides an extra layer of verification.

health-services/project-factory/package.json (1)

13-13: Monitor memory usage to ensure the heap size increase is justified.

Increasing the heap size to 3GB suggests the application requires significant memory. While this may be necessary for processing large Excel files and complex data transformations, ensure this isn't masking memory leaks or inefficient algorithms.

Consider implementing memory monitoring to track actual usage patterns and identify potential optimization opportunities.

health-services/project-factory/src/server/controllers/index.ts (1)

4-4: Clean addition of the new sheet management controller.

The integration follows the established pattern and maintains consistency with existing controllers.

Also applies to: 11-11

health-services/project-factory/src/server/config/models/generateRequestSchema.ts (1)

14-22: Schema properly extended to support new resource types.

The addition of "facility" and "user" types aligns with the broader enhancements for Excel template generation and processing workflows mentioned in the PR summary.

health-services/project-factory/src/server/kafka/Producer.ts (1)

94-94: Clarify intention behind changing modifiedMessages to any

The signature was updated from modifiedMessages: any[] to modifiedMessages: any, which now allows objects, primitives or arrays across every call site. Please confirm this is intentional.

To preserve type safety while keeping flexibility, consider one of the following:

  • Use a generic signature:
    async function produceModifiedMessages<T>(message: T, topic: string): Promise<void> {  }
  • Define a specific payload interface (e.g. interface KafkaPayload { … }) and use:
    async function produceModifiedMessages(payload: KafkaPayload, topic: string): Promise<void> {  }
  • At minimum, tighten topic to string instead of any.

Location to review:

  • health-services/project-factory/src/server/kafka/Producer.ts:94
health-services/project-factory/src/server/validators/genericValidator.ts (2)

5-5: LGTM: Import updated for API refactoring.

The import change from getBoundaryRelationshipData to searchBoundaryRelationshipData is consistent with the API refactoring.


240-246: Remove commented code and confirm searchBoundaryRelationshipData signature

Before cleaning up, please verify that the new searchBoundaryRelationshipData API accepts the parameters you’re passing (tenantId, hierarchyType, includeChildren, includeParents, etc.) and that you’re not missing any required arguments or relying on implicit defaults. I couldn’t find its definition in the repo—please locate it (or the package that exports it) and confirm all callsites remain consistent.

Apply this diff to strip out the old, commented code:

--- a/health-services/project-factory/src/server/validators/genericValidator.ts
+++ b/health-services/project-factory/src/server/validators/genericValidator.ts
@@ -240,9 +240,6 @@ export const validateSomething = async (request: Request) => {
-    // const params = {
-    //     ...request?.query,
-    //     includeChildren: true
-    // };
-    // const boundaryData = await getBoundaryRelationshipData(request, params);
     const boundaryRelationshipResponse: any = await searchBoundaryRelationshipData(
       request?.query?.tenantId,
       request?.query?.hierarchyType,
@@
     const boundaryData = boundaryRelationshipResponse?.TenantBoundary?.[0]?.boundary;

Key callsites to cross-check for parameter consistency:

  • project-factory/src/server/api/genericApis.ts – called with five args (tenantId, hierarchyType, true, true, useCache)
  • project-factory/src/server/api/campaignApis.ts – called with three args (tenantId, hierarchyType, true)
  • project-factory/src/server/generateFlowClasses/* – all use five args (tenantId, hierarchyType, true, true, false)
  • project-factory/src/server/utils/microplanIntergration.ts – called with three args
  • project-factory/src/server/utils/campaignUtils.ts – sometimes with six args, including a root boundary code

Please locate the declaration of searchBoundaryRelationshipData (in this repo or its package), verify its parameters and defaults, and adjust these callsites if needed.

health-services/project-factory/src/server/validators/microplanValidators.ts (2)

18-18: LGTM: Phone number length validation made configurable.

Great improvement replacing the hardcoded length with config?.user?.phoneNumberLength. This makes the validation more flexible and maintainable.


23-23: LGTM: Error message updated to use configurable length.

The error message correctly uses the configurable phone number length dynamically, maintaining consistency with the validation logic.

health-services/project-factory/src/server/config/processTemplateConfigs.ts (1)

1-18: LGTM: Well-structured template processing configuration.

The new processTemplateConfigs is well-designed with:

  • Clear structure for user category templates
  • Appropriate use of localization keys for sheet names
  • Configurable locking options for processed files
  • Schema association for validation

The configuration follows good practices and integrates well with the broader template processing functionality.

health-services/project-factory/migration/main/V20250512172100__create_data_table.sql (1)

1-8: LGTM: Well-designed campaign data table structure.

The table structure is appropriate for campaign data storage:

  • Primary key on uniqueIdentifier ensures data integrity
  • NOT NULL constraints on essential fields (campaignNumber, type)
  • JSONB data column provides flexibility for campaign data
  • Additional columns support processing workflow tracking
  • Follows project naming conventions

The schema aligns well with the campaign data management functionality introduced in this PR.

health-services/project-factory/src/server/config/generationtTemplateConfigs.ts (1)

6-53: LGTM! Well-structured configuration with consistent patterns.

The configuration follows a consistent pattern across modules with clear sheet definitions and proper commenting.

health-services/project-factory/src/server/utils/transforms/localisationMessageConstructor.ts (1)

31-38: LGTM! Proper locale handling logic.

The locale splitting and reconstruction logic correctly preserves the suffix while allowing French and Portuguese prefix overrides.

health-services/project-factory/src/server/config/constants.ts (2)

42-43: LGTM! Proper validation error messages added.

The new validation error messages follow the established pattern and provide clear feedback for user validation scenarios.


121-131: LGTM! Well-structured status objects.

The new status objects resourceDetailsStatuses and dataRowStatuses follow consistent naming and structure patterns established in the codebase.

health-services/project-factory/src/server/config/models/resourceDetailsSchema.ts (2)

4-8: LGTM! Excellent helper function for consistent validation.

The requiredString helper function provides consistent error messages for all string validation scenarios (missing, wrong type, empty string).


10-21: LGTM! Well-structured schema with proper type inference.

The schema correctly defines required fields with appropriate validation and uses z.infer for type derivation, which is a best practice for maintaining type safety.

health-services/project-factory/src/server/models/GenerateTemplateQuery.ts (1)

1-18: LGTM! Well-structured validation schema.

The implementation provides comprehensive validation with clear error messages. Regarding the comment on line 16, while you're correct that the TypeScript interface can be omitted when using z.infer, keeping the explicit type export is still beneficial for:

  • Better IDE support and autocomplete
  • Documentation clarity when the type is used in other files
  • Consistency with TypeScript best practices
health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (1)

698-703: Good refactoring to expose utility functions.

Making getResourceFromResourceId and getFileUrl public is appropriate as they're now used by other modules (campaignMappingUtils.ts and mailUtil.ts). Both functions have proper error handling and clear responsibilities.

Also applies to: 729-742

health-services/project-factory/src/server/utils/campaignMappingUtils.ts (1)

372-372: Good fix for the getHierarchy function call.

Removing the extra argument aligns with the updated function signature.

health-services/project-factory/src/server/utils/mailUtil.ts (2)

10-122: Well-implemented email notification utility.

The implementation demonstrates good practices:

  • Comprehensive error handling
  • Detailed logging for debugging
  • Proper localization support
  • Clean separation of concerns
  • Good integration with MDMS and Kafka

The replacePlaceholders helper function is particularly elegant with its use of regex and nullish coalescing.


84-93: Clarify multiple file‐attachment handling before finalizing this change

Currently, in sendNotificationEmail (health-services/project-factory/src/server/utils/mailUtil.ts), you only use the first file ID from fileStoreIdMap to build accessLink and render the email body. The commented‐out block on lines 84–93 would instead generate an HTML link for every file:

// const fileUrls = await Promise.all(
//     Object.entries(fileStoreIdMap).map(async ([fileId, fileName]) => {
//         const url = await getFileUrl(fileId, tenantId);
//         logger.info(`Step 7: Fetched file URL for fileStoreId: ${fileId}`);
//         return `<a href="${url}">${fileName}</a>`;
//     })
// );
//
// const allFileUrls = fileUrls.join("<br/>");
// const fullBody = `${bodyLines.join("<br/><br/>")}<br/><br/>${allFileUrls}`;

Meanwhile, the final Kafka message already carries fileStoreId: fileStoreIdMap—implying your email‐sending consumer might handle attachments automatically.

Please clarify your intention so we can remove or reinstate this code appropriately:

  • Should the consumer attach all files and we can delete these commented lines?
  • Or do you want in‐body links for every file (in which case we should reintroduce/adapt this snippet or add a TODO)?
health-services/project-factory/src/server/utils/cryptUtils.ts (1)

3-11: Strong cryptographic implementation with proper parameters.

The cryptographic approach is well-implemented using industry-standard practices:

  • AES-256-GCM for authenticated encryption
  • PBKDF2 with SHA-512 and 100k iterations for key derivation
  • Random salt and IV generation per message
  • Proper parameter sizes (32-byte key, 12-byte IV, 16-byte salt)
health-services/project-factory/src/server/utils/generateUtils.ts (3)

70-70: Good approach to disable error throwing while retaining logging.

Commenting out the throwError call while keeping the error logging aligns with the codebase pattern where throwError logs internally. This change maintains error visibility without disrupting the flow.


78-78: Improved safety with optional chaining.

The addition of optional chaining (?.) for accessing nested properties prevents potential null pointer exceptions and makes the code more resilient.


103-117: Well-structured utility function for request building.

The buildGenerateRequest function provides a clean abstraction for creating generate requests with standardized parameters. It follows the same pattern used elsewhere in the codebase and improves code reusability.

health-services/project-factory/src/server/controllers/sheetManage/sheetManage.controller.ts (3)

34-58: Well-structured endpoint with comprehensive validation and error handling.

The generateData method follows excellent practices:

  • Proper input validation using Zod schema with detailed error messages
  • Extraction of user context (UUID, locale) from request
  • Comprehensive error handling with logging
  • Standardized response patterns using sendResponse and errorResponder
  • Clear separation of concerns by delegating to service layer

60-86: Consistent implementation pattern with proper validation.

The processData method maintains consistency with the generateData method by following the same validation and error handling patterns. The implementation correctly validates the request body structure and handles both success and error scenarios.


9-16: Clean controller structure with RESTful endpoints.

The controller class is well-organized with:

  • Clear path definition (/v2/data)
  • RESTful endpoint naming (_generate, _process)
  • Proper Express router setup
  • Clean constructor pattern
health-services/project-factory/src/server/service/sheetManageService.ts (2)

10-21: Well-structured service function with proper validation and type safety.

The generateDataService function demonstrates excellent practices:

  • Input validation using dedicated validators
  • Explicit type conversion to ensure string types
  • Deep cloning of configuration objects to prevent mutations
  • Proper default locale handling
  • Clean delegation to utility functions

23-29: Consistent service implementation with proper configuration handling.

The processDataService function follows the same excellent patterns as generateDataService:

  • Input validation before processing
  • Deep cloning of configuration objects
  • Proper parameter passing to utility functions
  • Consistent error handling approach
health-services/project-factory/src/server/config/createAndSearch.ts (3)

91-95: Logical addition of boundary code mapping for facility location tracking.

The new parsing logic for column "F" to map boundary code to address.locality.code provides a clear path for associating facilities with their geographic locations. This follows the established pattern for nested object mapping.


218-230: Well-integrated credential handling for user authentication.

The addition of UserName and Password columns (L and M) aligns perfectly with the new cryptographic utilities introduced in cryptUtils.ts. The mapping to user.userName and user.password follows the established schema structure.


238-241: Consistent column reference updates for template restructuring.

The updates to uniqueIdentifierColumn (I → P) and activeColumn (F → J) suggest a thoughtful reorganization of the Excel template structure. These changes maintain consistency with the new column additions while preserving the existing functionality.

health-services/project-factory/src/server/app.ts (1)

98-110: Server timeout configuration looks good

The async refactoring and timeout configurations are appropriate. The values (480s for general timeout, 90s for keep-alive, 120s for headers) provide good protection against slow clients and hanging connections.

health-services/project-factory/src/server/config/index.ts (1)

176-177: Verify performance impact of reduced unfroze limits

The unfroze limits have been significantly reduced. Ensure this doesn't negatively impact performance for large datasets.

Please verify that the reduced limits are sufficient for your use cases and don't cause performance issues with large Excel files.

health-services/project-factory/src/server/service/dataManageService.ts (3)

35-35: Good addition of locale support

Adding locale parameter to searchGeneratedResources ensures proper localization of retrieved data.


55-79: Well-implemented timestamp comparison logic

The logic for checking if source data was updated after generation is sound. This ensures users always get the latest data for boundary management.


82-92: Fix inconsistent indentation

The code block has inconsistent indentation and an extra closing brace.

-
-        // Send response with resource details
-        if (resourceDetails != null && responseData != null && responseData.length > 0) {
-            responseData[0].additionalDetails = {
-                ...(responseData[0].additionalDetails || {}),
-                ...(resourceDetails?.additionalDetails || {})
-            };
-        }
-
-
-        return responseData;
-    }
+    // Send response with resource details
+    if (resourceDetails != null && responseData != null && responseData.length > 0) {
+        responseData[0].additionalDetails = {
+            ...(responseData[0].additionalDetails || {}),
+            ...(resourceDetails?.additionalDetails || {})
+        };
+    }
+
+    return responseData;
+}
⛔ Skipped due to learnings
Learnt from: holashchand
PR: egovernments/health-campaign-services#1466
File: health-services/libraries/health-services-models/src/main/java/org/egov/common/models/service/AttributeValue.java:44-46
Timestamp: 2025-03-27T05:58:57.438Z
Learning: Code style in health-services-models should maintain consistency with the existing service-request service, including keeping blank lines that match the original code structure.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1466
File: health-services/libraries/health-services-models/src/main/java/org/egov/common/models/service/ServiceCriteria.java:42-44
Timestamp: 2025-03-27T05:59:20.332Z
Learning: In the health-campaign-services repository, extra blank lines in the service model classes (such as in ServiceCriteria.java) should be preserved for consistency with the existing service-request service implementation.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:244-245
Timestamp: 2025-01-16T08:00:17.932Z
Learning: In Java files, maintain consistent spacing with:
1. Single empty line between methods
2. Single empty line before the class closing brace
health-services/project-factory/src/server/utils/microplanUtils.ts (2)

397-398: Good addition of geospatial data

Adding latitude and longitude to additionalDetails enhances facility data with important location information.


481-493: Proper migration to explicit MDMS API

The refactoring to use searchMDMSDataViaV1Api with properly structured criteria is correct and follows the new MDMS integration pattern.

health-services/project-factory/src/server/api/coreApis.ts (3)

11-16: LGTM! Proper production authentication handling.

The conditional inclusion of authToken for production environments and the addition of default userInfo context are implemented correctly.


29-69: Excellent caching implementation and validation improvements.

The function now properly validates required fields, maintains backward compatibility, and implements caching with well-constructed cache keys.


200-241: Consistent caching implementation for boundary data.

The caching support is well-implemented with proper cache key construction that includes all relevant parameters.

health-services/project-factory/src/server/utils/sheetManageUtils.ts (1)

221-245: Well-structured error handling.

The error handling functions properly update status, capture error details, and persist to Kafka for both generate and process workflows.

health-services/project-factory/src/server/processFlowClasses/user-processClass.ts (1)

149-180: Excellent batch processing with error recovery.

The implementation properly handles batch failures, updates statuses, and ensures data consistency with appropriate wait times.

health-services/project-factory/src/server/generateFlowClasses/facility-generateClass.ts (2)

8-187: Consistent template class implementation.

The facility generation class follows the same pattern as other resource types, maintaining architectural consistency.


96-143: Well-implemented boundary structuring algorithm.

The tree construction and DFS traversal efficiently transform flat boundary data into a hierarchical structure with proper localization.

health-services/project-factory/src/server/validators/campaignValidators.ts (1)

1653-1662: Well-structured validation function.

Good use of code reuse by leveraging existing validation functions. The function is concise and follows the single responsibility principle.

health-services/project-factory/src/server/utils/excelUtils.ts (4)

69-78: LGTM!

The conditional validation logic is correctly implemented.


126-131: Good refactoring for improved modularity.

The function now accepts explicit parameters instead of extracting from request objects, which improves testability and reusability.


132-144: Well-implemented locale extraction function.

The function includes proper null checking and logging, making it robust for extracting locale metadata from workbooks.


403-408: Good defensive programming for safer calculations.

The use of Math.max(1, columnWidth - 10) prevents potential division by zero errors.

health-services/project-factory/src/server/api/genericApis.ts (3)

6-63: Good modularization with new exports.

The export of getJsonData and new imports align well with the enhanced functionality across the module.


439-441: Consistent implementation with enrichTemplateMetaData refactoring.

The code correctly uses getLocaleFromRequestInfo and passes explicit parameters to enrichTemplateMetaData, maintaining consistency with the refactored function signature.


668-696: Complex but necessary hierarchy processing logic.

The new hierarchy-based processing adds significant complexity but appears necessary for proper boundary code generation. Consider adding more inline comments to explain the logic flow, especially around the lastPresentHierarchyIndex calculation.

⛔ Skipped due to learnings
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: health-services/household/src/main/java/org/egov/household/household/member/validators/HmRelationshipTypeValidator.java:110-110
Timestamp: 2025-06-13T09:40:03.698Z
Learning: Reviewer preference: holashchand wants review feedback limited to significant issues and to ignore cosmetic or negligible concerns.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: core-services/beneficiary-idgen/src/main/java/org/egov/id/repository/IdTransactionLogRowMapper.java:36-42
Timestamp: 2025-06-17T10:30:47.684Z
Learning: When reviewing code changes that were previously suggested by CodeRabbit AI, avoid suggesting further "improvements" or alternative approaches to create suggestion cycles. Accept the implemented solution as appropriate if it was based on CodeRabbit's own recommendations.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java:68-72
Timestamp: 2025-04-29T08:38:24.868Z
Learning: In the CensusEnrichment class, the enrichBoundaryAncestralPath method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/census-service/src/main/java/digit/service/workflow/WorkflowService.java:245-247
Timestamp: 2025-05-08T05:31:48.038Z
Learning: In the Census service, the boundaryAncestralPath is enriched during census object creation, and is guaranteed to be non-null and non-empty when the getAssigneeForAutoAssignment method is called. If there's an issue during creation, the service throws an error before reaching this point.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository's ExcelParser.java, boundary code cell validation is comprehensively handled through validateRows() which includes:
1. validateTillBoundaryCode() - checks for null cells, BLANK cell type, and validates string values against regex patterns
2. validateAttributes() - validates cell types, boundary code existence in boundaryCodeList, and performs string value validation
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
health-services/project-factory/src/server/utils/genericUtils.ts (4)

729-757: LGTM! Good refactoring to use V1 API.

The refactoring to use searchMDMSDataViaV1Api is consistent with the broader API migration pattern in the codebase.


971-988: LGTM! Well-implemented multi-select column expansion.

The function correctly handles the expansion of headers for multi-select properties, maintaining the original order while inserting the multi-select columns.


1373-1376: LGTM! Good implementation of multi-language support.

The addition of French and Portuguese localization for boundary management is well-implemented with proper conditional checks.

Also applies to: 1415-1420


566-567: Also applies to: 572-573, 949-949, 996-996, 1094-1094, 1613-1613

health-services/project-factory/src/server/api/campaignApis.ts (4)

57-57: Good refactoring: Improved naming clarity.

The rename from createBatchRequest to searchBatchRequest better reflects the function's purpose of searching for individuals rather than creating batch requests.

Also applies to: 384-384


107-111: Good refactoring: Improved function independence.

Removing the request parameter dependency and using defaultRequestInfo makes this function more reusable and easier to test.


1259-1268: Good refactoring: Extracted address modification logic.

Extracting the facility address modification into a separate function improves code organization and reusability. The handling of comma-separated locality codes is appropriate.


1147-1175: Good improvement: Enhanced jurisdiction handling.

The changes improve robustness by:

  • Properly parsing comma-separated jurisdiction strings
  • Providing appropriate fallbacks when jurisdictions are not provided
  • Better type safety with explicit checks
health-services/project-factory/src/server/utils/campaignUtils.ts (9)

913-920: Verify the need for increased timeout.

The timeout for boundary data creation has been increased from 10 to 30 seconds. This significant increase suggests potential performance issues or race conditions.

Could you provide context on why this timeout increase is necessary? Consider documenting the reason in a comment or investigating if the underlying issue can be resolved instead of increasing the wait time.


1352-1374: Good performance optimization!

The refactored getChildParentMap function efficiently avoids expensive deep equality checks by using stringified keys. This is a smart optimization for large datasets.


4031-4080: Well-implemented username validation!

The function efficiently validates username format using regex and detects duplicates using a Map. The error messages are clear and include row numbers for easy debugging.


2375-2393: Good API migration approach!

The migration from getMDMSV1Data to searchMDMSDataViaV1Api with structured criteria objects improves code maintainability and follows the newer API patterns.


611-618: Clean schema fetching implementation!

The getSchema function provides a clear abstraction for fetching schemas based on resource type and source, improving code organization.


1459-1488: Excellent performance optimization!

The refactored prepareDataForExcel function uses Map for efficient lookups and clearly separates the data into hierarchy values, boundary code, and remaining values. This is much more performant than the previous implementation.


1376-1412: Smart optimization for boundary code extraction!

The function now efficiently stops processing once it reaches the boundary code column, avoiding unnecessary iterations. The localization support is properly integrated.


3914-3941: Good improvements to ID generation!

The function now uses consistent request info structure and provides clear error messages. The error handling properly propagates the original error details.


1804-1867: Remove unnecessary async declaration.

The populateBoundariesRecursively function is declared as async but doesn't contain any await statements.

-export async function populateBoundariesRecursively(
+export function populateBoundariesRecursively(

If this function might need async operations in the future, consider adding a comment explaining why it's kept async.

⛔ Skipped due to learnings
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java:68-72
Timestamp: 2025-04-29T08:38:24.868Z
Learning: In the CensusEnrichment class, the enrichBoundaryAncestralPath method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.

getCurrentDirectory: () => process.cwd(),
getNewLine: () => '\n'
});
console.error("❌ Type errors in processFlowClasses:\n" + formatted);
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Use template literal instead of string concatenation.

-console.error("❌ Type errors in processFlowClasses:\n" + formatted);
+console.error(`❌ Type errors in processFlowClasses:\n${formatted}`);
📝 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.

Suggested change
console.error("❌ Type errors in processFlowClasses:\n" + formatted);
console.error(`❌ Type errors in processFlowClasses:\n${formatted}`);
🧰 Tools
🪛 Biome (1.9.4)

[error] 43-44: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

🤖 Prompt for AI Agents
In
health-services/project-factory/src/server/processFlowClasses/processFlowClassChecker.ts
at line 43, replace the string concatenation in the console.error statement with
a template literal. Change the code to use backticks and embed the variable
formatted directly within the string for cleaner and more readable code.

Comment on lines +2 to +3
import * as path from "path";
import * as fs from "fs";
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Use Node.js import protocol for built-in modules.

Static analysis suggests using the node: protocol for Node.js built-in modules to make imports more explicit.

-import * as path from "path";
-import * as fs from "fs";
+import * as path from "node:path";
+import * as fs from "node:fs";
📝 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.

Suggested change
import * as path from "path";
import * as fs from "fs";
import * as path from "node:path";
import * as fs from "node:fs";
🧰 Tools
🪛 Biome (1.9.4)

[error] 2-2: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)


[error] 3-3: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)

🤖 Prompt for AI Agents
In
health-services/project-factory/src/server/processFlowClasses/processFlowClassChecker.ts
at lines 2 to 3, update the import statements for built-in Node.js modules to
use the 'node:' protocol. Replace 'import * as path from "path"' with 'import *
as path from "node:path"' and similarly replace 'import * as fs from "fs"' with
'import * as fs from "node:fs"' to make the imports explicit and compliant with
the Node.js import protocol.

Comment on lines +358 to +413
function mergeAndGetDynamicColumns(dynamicColumns: any, schema: any, localizationMap: any): any {
if (!dynamicColumns) dynamicColumns = {};

let maxOrderNumber = Number.MAX_SAFE_INTEGER;

const assignProps = (target: any, source: any, isMulti = false, index = 0, parentOrder = 0) => {
target.width ??= source.width ?? 40;
target.color ??= source.color;
target.adjustHeight ??= source.adjustHeight;
target.freezeColumnIfFilled ??= source.freezeColumnIfFilled;
target.showInProcessed ??= source.showInProcessed;
target.unFreezeColumnTillData ??= source.unFreezeColumnTillData;
target.freezeTillData ??= source.freezeTillData;
target.adjustHeight ??= source.adjustHeight;
target.wrapText ??= source.wrapText;


if (!isMulti) {
target.freezeColumn ??= source.freezeColumn;
target.hideColumn ??= source.hideColumn;
target.orderNumber ??= source.orderNumber ?? maxOrderNumber;
} else {
const order = parentOrder - 1 + (0.01 * index);
target.orderNumber ??= order;
}

maxOrderNumber = Math.min(maxOrderNumber, target.orderNumber);
};

for (const propertyKey in schema?.properties) {
const property = schema.properties[propertyKey];
const localizedKey = getLocalizedName(propertyKey, localizationMap);

// Process multiSelectDetails if any
if (property?.multiSelectDetails?.maxSelections) {
const max = property.multiSelectDetails.maxSelections;
const parentOrder = dynamicColumns[localizedKey]?.orderNumber ?? property.orderNumber ?? maxOrderNumber;

for (let i = 1; i <= max; i++) {
const multiKey = `${propertyKey}_MULTISELECT_${i}`;
const localizedMultiKey = getLocalizedName(multiKey, localizationMap);
dynamicColumns[localizedMultiKey] ??= {};
assignProps(dynamicColumns[localizedMultiKey], property, true, i, parentOrder);
}
}

// Process base column
dynamicColumns[localizedKey] ??= {};
assignProps(dynamicColumns[localizedKey], property);
}

// Return sorted by orderNumber
return Object.fromEntries(
Object.entries(dynamicColumns).sort(([, a]: any, [, b]: any) => a.orderNumber - b.orderNumber)
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid reassigning function parameters in mergeAndGetDynamicColumns.

Use a local variable instead of reassigning the parameter.

 function mergeAndGetDynamicColumns(dynamicColumns: any, schema: any, localizationMap: any): any {
-    if (!dynamicColumns) dynamicColumns = {};
+    const columns = dynamicColumns || {};

     let maxOrderNumber = Number.MAX_SAFE_INTEGER;

     const assignProps = (target: any, source: any, isMulti = false, index = 0, parentOrder = 0) => {
         // ... rest of the function
     };

     // Update all references to use 'columns' instead of 'dynamicColumns'
     for (const propertyKey in schema?.properties) {
         // ... 
-        const parentOrder = dynamicColumns[localizedKey]?.orderNumber ?? property.orderNumber ?? maxOrderNumber;
+        const parentOrder = columns[localizedKey]?.orderNumber ?? property.orderNumber ?? maxOrderNumber;
         // ... continue replacing dynamicColumns with columns
     }

     return Object.fromEntries(
-        Object.entries(dynamicColumns).sort(([, a]: any, [, b]: any) => a.orderNumber - b.orderNumber)
+        Object.entries(columns).sort(([, a]: any, [, b]: any) => a.orderNumber - b.orderNumber)
     );
 }
📝 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.

Suggested change
function mergeAndGetDynamicColumns(dynamicColumns: any, schema: any, localizationMap: any): any {
if (!dynamicColumns) dynamicColumns = {};
let maxOrderNumber = Number.MAX_SAFE_INTEGER;
const assignProps = (target: any, source: any, isMulti = false, index = 0, parentOrder = 0) => {
target.width ??= source.width ?? 40;
target.color ??= source.color;
target.adjustHeight ??= source.adjustHeight;
target.freezeColumnIfFilled ??= source.freezeColumnIfFilled;
target.showInProcessed ??= source.showInProcessed;
target.unFreezeColumnTillData ??= source.unFreezeColumnTillData;
target.freezeTillData ??= source.freezeTillData;
target.adjustHeight ??= source.adjustHeight;
target.wrapText ??= source.wrapText;
if (!isMulti) {
target.freezeColumn ??= source.freezeColumn;
target.hideColumn ??= source.hideColumn;
target.orderNumber ??= source.orderNumber ?? maxOrderNumber;
} else {
const order = parentOrder - 1 + (0.01 * index);
target.orderNumber ??= order;
}
maxOrderNumber = Math.min(maxOrderNumber, target.orderNumber);
};
for (const propertyKey in schema?.properties) {
const property = schema.properties[propertyKey];
const localizedKey = getLocalizedName(propertyKey, localizationMap);
// Process multiSelectDetails if any
if (property?.multiSelectDetails?.maxSelections) {
const max = property.multiSelectDetails.maxSelections;
const parentOrder = dynamicColumns[localizedKey]?.orderNumber ?? property.orderNumber ?? maxOrderNumber;
for (let i = 1; i <= max; i++) {
const multiKey = `${propertyKey}_MULTISELECT_${i}`;
const localizedMultiKey = getLocalizedName(multiKey, localizationMap);
dynamicColumns[localizedMultiKey] ??= {};
assignProps(dynamicColumns[localizedMultiKey], property, true, i, parentOrder);
}
}
// Process base column
dynamicColumns[localizedKey] ??= {};
assignProps(dynamicColumns[localizedKey], property);
}
// Return sorted by orderNumber
return Object.fromEntries(
Object.entries(dynamicColumns).sort(([, a]: any, [, b]: any) => a.orderNumber - b.orderNumber)
);
}
function mergeAndGetDynamicColumns(dynamicColumns: any, schema: any, localizationMap: any): any {
const columns = dynamicColumns || {};
let maxOrderNumber = Number.MAX_SAFE_INTEGER;
const assignProps = (target: any, source: any, isMulti = false, index = 0, parentOrder = 0) => {
target.width ??= source.width ?? 40;
target.color ??= source.color;
target.adjustHeight ??= source.adjustHeight;
target.freezeColumnIfFilled ??= source.freezeColumnIfFilled;
target.showInProcessed ??= source.showInProcessed;
target.unFreezeColumnTillData ??= source.unFreezeColumnTillData;
target.freezeTillData ??= source.freezeTillData;
target.adjustHeight ??= source.adjustHeight;
target.wrapText ??= source.wrapText;
if (!isMulti) {
target.freezeColumn ??= source.freezeColumn;
target.hideColumn ??= source.hideColumn;
target.orderNumber ??= source.orderNumber ?? maxOrderNumber;
} else {
const order = parentOrder - 1 + (0.01 * index);
target.orderNumber ??= order;
}
maxOrderNumber = Math.min(maxOrderNumber, target.orderNumber);
};
for (const propertyKey in schema?.properties) {
const property = schema.properties[propertyKey];
const localizedKey = getLocalizedName(propertyKey, localizationMap);
// Process multiSelectDetails if any
if (property?.multiSelectDetails?.maxSelections) {
const max = property.multiSelectDetails.maxSelections;
const parentOrder = columns[localizedKey]?.orderNumber ?? property.orderNumber ?? maxOrderNumber;
for (let i = 1; i <= max; i++) {
const multiKey = `${propertyKey}_MULTISELECT_${i}`;
const localizedMultiKey = getLocalizedName(multiKey, localizationMap);
columns[localizedMultiKey] ??= {};
assignProps(columns[localizedMultiKey], property, true, i, parentOrder);
}
}
// Process base column
columns[localizedKey] ??= {};
assignProps(columns[localizedKey], property);
}
// Return sorted by orderNumber
return Object.fromEntries(
Object.entries(columns).sort(([, a]: any, [, b]: any) => a.orderNumber - b.orderNumber)
);
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 359-359: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/sheetManageUtils.ts between
lines 358 and 413, the function mergeAndGetDynamicColumns reassigns the
parameter dynamicColumns directly, which is not recommended. To fix this, create
a new local variable initialized to dynamicColumns or an empty object if
dynamicColumns is falsy, and use this local variable throughout the function
instead of reassigning the parameter.

Comment on lines 15 to 225
export class TemplateClass {
// Static generate function
static async process(
resourceDetails: any,
wholeSheetData: any,
localizationMap: Record<string, string>
): Promise<SheetMap> {
logger.info("Processing file...");
logger.info(`ResourceDetails: ${JSON.stringify(resourceDetails)}`);

const reverseMap = this.getReverseLocalizationMap(localizationMap);
const campaign = await this.getCampaignDetails(resourceDetails);

const userSheetData = wholeSheetData[getLocalizedName("HCM_ADMIN_CONSOLE_USER_LIST", localizationMap)];
const mobileKey = getLocalizedName("HCM_ADMIN_CONSOLE_USER_PHONE_NUMBER", localizationMap);

const newUsers = await this.extractNewUsers(userSheetData, mobileKey, campaign.campaignNumber, resourceDetails, reverseMap);
await this.persistInBatches(newUsers, config.kafka.KAFKA_SAVE_SHEET_DATA_TOPIC);

const waitTime = Math.max(5000, newUsers.length * 8);
logger.info(`Waiting for ${waitTime} ms for persistence...`);
await new Promise((res) => setTimeout(res, waitTime));

await this.createUserFromTableData(resourceDetails, localizationMap);

const allCurrentUsers = await getRelatedDataWithCampaign(resourceDetails?.type, campaign.campaignNumber, dataRowStatuses.completed);
const allData = allCurrentUsers?.map((u: any) => {
const data : any = {};
for(const key of Object.keys(u?.data)) {
data[getLocalizedName(key, localizationMap)] = u?.data[key];
}
data["#status#"] = "CREATED";
data[getLocalizedName("UserName", localizationMap)] = decrypt(u?.data?.["UserName"]);
data[getLocalizedName("Password", localizationMap)] = decrypt(u?.data?.["Password"]);
return data;
});
const sheetMap : SheetMap = {};
sheetMap[getLocalizedName("HCM_ADMIN_CONSOLE_USER_LIST", localizationMap)] = {
data : allData,
dynamicColumns: null
};
logger.info(`SheetMap generated for template of type ${resourceDetails.type}.`);
return sheetMap;
}

private static getReverseLocalizationMap(localizationMap: Record<string, string>): Map<string, string> {
const reverse = new Map<string, string>();
Object.entries(localizationMap).forEach(([key, val]) => reverse.set(val, key));
return reverse;
}

private static async getCampaignDetails(resourceDetails: any): Promise<any> {
const response = await searchProjectTypeCampaignService({
tenantId: resourceDetails.tenantId,
ids: [resourceDetails?.campaignId],
});
const campaign = response?.CampaignDetails?.[0];
if (!campaign) throw new Error("Campaign not found");
return campaign;
}

private static async extractNewUsers(
sheetData: any[],
mobileKey: string,
campaignNumber: string,
resourceDetails: any,
reverseMap: Map<string, string>
): Promise<any[]> {
const userMap : any = Object.fromEntries(sheetData.map((row: any) => [row?.[mobileKey], row]).filter(([m]) => m));

const existing = await getRelatedDataWithCampaign(resourceDetails?.type, campaignNumber);
const existingMap : any = {};
for(const user of existing){
existingMap[user?.data?.[reverseMap.get(mobileKey) || mobileKey]] = user;
}

const newEntries = [];
for (const [mobile, row] of Object.entries(userMap)) {
if (existingMap?.[String(mobile)]) continue;
const data = Object.fromEntries(Object.entries(row as any).map(([k, v]) => [reverseMap.get(k) || k, v]));
newEntries.push({
campaignNumber,
data,
type: resourceDetails?.type,
uniqueIdentifier: mobile,
uniqueIdAfterProcess: null,
status: dataRowStatuses.pending
});
}
return newEntries;
}

private static async persistInBatches(users: any[], topic: string): Promise<void> {
const BATCH_SIZE = 100;
for (let i = 0; i < users.length; i += BATCH_SIZE) {
const batch = users.slice(i, i + BATCH_SIZE);
await produceModifiedMessages({ datas: batch }, topic);
}
}


static async createUserFromTableData(resourceDetails: any, localizationMap: Record<string, string>): Promise<any> {
logger.info("Fetching campaign details...");
const response = await searchProjectTypeCampaignService({
tenantId: resourceDetails.tenantId,
ids: [resourceDetails?.campaignId],
});

const campaign = response?.CampaignDetails?.[0];
if (!campaign) throw new Error("Campaign not found");

const campaignNumber = campaign?.campaignNumber;
const userUuid = campaign?.auditDetails?.createdBy;

const allCurrentUsers = await getRelatedDataWithCampaign("user", campaignNumber);
const usersToCreate = allCurrentUsers?.filter(
(user: any) => user?.status === dataRowStatuses.pending || user?.status === dataRowStatuses.failed
);

logger.info(`${usersToCreate?.length} users to create`);
const userRowDatas = usersToCreate?.map((u: any) => u?.data);

const transformConfig = { ...transformConfigs?.["employeeHrms"] };
transformConfig.metadata.tenantId = resourceDetails.tenantId;
transformConfig.metadata.hierarchy = resourceDetails.hierarchyType;

const transformer = new DataTransformer(transformConfig);

logger.info("Transforming user data...");
const transformedUsers = await transformer.transform(userRowDatas);
logger.info(`${transformedUsers.length} users transformed`);

const mobileToCampaignMap = this.buildMobileNumberToCampaignUserMap(allCurrentUsers);
const BATCH_SIZE = 100;
for (let i = 0; i < transformedUsers.length; i += BATCH_SIZE) {
const batch = transformedUsers.slice(i, i + BATCH_SIZE);
try {
const mobileToUserServiceMap = await this.createEmployeesAndGetServiceUuid(batch, userUuid);

const successfulUsers = [];
for (const user of batch) {
const mobile = String(user?.user?.mobileNumber);
const serviceUuid = mobileToUserServiceMap[mobile];
const existing = mobileToCampaignMap[mobile];
if (existing) {
existing.status = dataRowStatuses.completed;
existing.data["UserService Uuids"] = serviceUuid;
existing.data["UserName"] = encrypt(user?.user?.userName);
existing.data["Password"] = encrypt(user?.user?.password);
existing.uniqueIdAfterProcess = serviceUuid;
successfulUsers.push(existing);
}
}

logger.info(`Successfully created ${successfulUsers.length} users`);
await this.persistInBatches(successfulUsers, config.kafka.KAFKA_UPDATE_SHEET_DATA_TOPIC);
} catch (err) {
console.error("Error in batch creation:", err);
await this.handleBatchFailure(batch, usersToCreate, localizationMap);
throw new Error(`Error in user batch creation: ${err}`);
}
}
const waitTime = Math.max(5000, transformedUsers.length * 8);
logger.info(`Waiting for ${waitTime} ms for persistence of created users...`);
await new Promise((res) => setTimeout(res, waitTime));
}

private static buildMobileNumberToCampaignUserMap(users: any[]) {
const map: Record<string, any> = {};
for (const user of users) {
const mobile = String(user?.data?.["HCM_ADMIN_CONSOLE_USER_PHONE_NUMBER"]);
map[mobile] = user;
}
return map;
}


private static async handleBatchFailure(batch: any[], usersToCreate: any[], localizationMap: Record<string, string>) {
const phoneKey = getLocalizedName("HCM_ADMIN_CONSOLE_USER_PHONE_NUMBER", localizationMap);
const batchMobileSet = new Set(batch.map((u: any) => String(u?.user?.mobileNumber)));
const failedUsers = usersToCreate.filter((u: any) => batchMobileSet.has(String(u?.data?.[phoneKey])));
failedUsers.forEach(u => u.status = dataRowStatuses.failed);
logger.warn(`${failedUsers.length} users failed in batch`);
await this.persistInBatches(failedUsers, config.kafka.KAFKA_UPDATE_SHEET_DATA_TOPIC);
}



static async createEmployeesAndGetServiceUuid(users: any[], userUuid: string) {
const url = config.host.hrmsHost + config.paths.hrmsEmployeeCreate;
const RequestInfo : any = defaultRequestInfo?.RequestInfo;
RequestInfo.userInfo.uuid = userUuid;
const requestBody = {
RequestInfo,
Employees: users,
};

try {
const response = await httpRequest(url, requestBody);
const map: any = {};
for (const user of response?.Employees) {
map[user?.user?.mobileNumber] = user?.user?.userServiceUuid;
}
return map;
} catch (error: any) {
console.error("Employee creation API failed:", error);
throw new Error(error);
}
}

}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider the static class design pattern.

While this class contains only static methods, it appears to be part of a consistent template pattern across resource types (user, facility, boundary). The design is acceptable for maintaining consistency across dynamically loaded classes.

🧰 Tools
🪛 Biome (1.9.4)

[error] 15-225: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


[error] 25-25: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 26-26: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 31-31: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 32-32: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 38-38: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 147-147: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 152-152: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 170-170: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 173-173: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 198-198: Using this in a static context can be confusing.

this refers to the class.
Unsafe fix: Use the class name instead.

(lint/complexity/noThisInStatic)


[error] 215-215: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🤖 Prompt for AI Agents
In
health-services/project-factory/src/server/processFlowClasses/user-processClass.ts
from lines 15 to 225, the class uses only static methods which aligns with a
static class design pattern suitable for template consistency across resource
types. No changes are needed to the static method structure; maintain the
current static class design to ensure consistency and ease of dynamic loading
across different resource templates.

Comment on lines +214 to +217
const map: any = {};
for (const user of response?.Employees) {
map[user?.user?.mobileNumber] = user?.user?.userServiceUuid;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unsafe optional chaining in loop.

Add null check to prevent TypeError if response.Employees is undefined.

             const map: any = {};
-            for (const user of response?.Employees) {
+            for (const user of response?.Employees || []) {
                 map[user?.user?.mobileNumber] = user?.user?.userServiceUuid;
             }
📝 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.

Suggested change
const map: any = {};
for (const user of response?.Employees) {
map[user?.user?.mobileNumber] = user?.user?.userServiceUuid;
}
const map: any = {};
for (const user of response?.Employees || []) {
map[user?.user?.mobileNumber] = user?.user?.userServiceUuid;
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 215-215: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🤖 Prompt for AI Agents
In
health-services/project-factory/src/server/processFlowClasses/user-processClass.ts
around lines 214 to 217, the code uses optional chaining on response.Employees
without checking if response or Employees is defined, which can cause a
TypeError. Add a null check before the loop to ensure response and
response.Employees exist before iterating, preventing runtime errors.

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.

Review continued from previous batch...



static getReadMeData(readMeConfig: any, readMeColumnHeader: any, localizationMap: any) {
const dataArray = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unsafe optional chaining in loop.

Add null check to prevent TypeError.

-        for (const text of readMeConfig?.texts) {
+        for (const text of readMeConfig?.texts || []) {
📝 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.

Suggested change
const dataArray = [];
const dataArray = [];
for (const text of readMeConfig?.texts || []) {
🤖 Prompt for AI Agents
In
health-services/project-factory/src/server/generateFlowClasses/facility-generateClass.ts
at line 50, the code uses optional chaining unsafely within a loop, which can
cause a TypeError if the value is null or undefined. Add an explicit null or
undefined check before accessing properties or methods with optional chaining
inside the loop to ensure safety and prevent runtime errors.

Comment on lines +653 to 680
function validateForDuplicateRows(boundaryData: any[]) {
// Step 1: Trim strings in all rows
boundaryData = boundaryData.map(row =>
Object.fromEntries(
Object.entries(row).map(([key, value]) =>
[key, typeof value === "string" ? value.trim() : value]
)
Object.entries(row).map(([key, value]) =>
[key, typeof value === "string" ? value.trim() : value]
)
)
);
const uniqueRows = _.uniqWith(boundaryData, (obj1: any, obj2: any) => {
// Exclude '!row#number!' property when comparing objects
const filteredObj1 = _.omit(obj1, ['!row#number!']);
const filteredObj2 = _.omit(obj2, ['!row#number!']);
return _.isEqual(filteredObj1, filteredObj2);
});
const duplicateBoundaryRows = boundaryData.filter(e => !uniqueRows.includes(e));
const duplicateRowNumbers = duplicateBoundaryRows.map(obj => obj['!row#number!']);
const rowNumbersSeparatedWithCommas = duplicateRowNumbers.join(', ');
);
const seen = new Set<string>();
const duplicateRowNumbers: string[] = [];
for (const row of boundaryData) {
const rowNumber = row["!row#number!"];
const rowCopy = { ...row };
delete rowCopy["!row#number!"];
// Serialize row as a string (key), which is much faster than deep object comparison
const rowKey = JSON.stringify(rowCopy);
if (seen.has(rowKey)) {
duplicateRowNumbers.push(rowNumber);
} else {
seen.add(rowKey);
}
}
if (duplicateRowNumbers.length > 0) {
const rowNumbersSeparatedWithCommas = duplicateRowNumbers.join(', ');
throwError("COMMON", 400, "VALIDATION_ERROR", `Boundary Sheet has duplicate rows at rowNumber ${rowNumbersSeparatedWithCommas}`);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid reassigning the function parameter.

The static analysis correctly identifies that reassigning the boundaryData parameter can be confusing. Create a new variable instead.

-function validateForDuplicateRows(boundaryData: any[]) {
-    // Step 1: Trim strings in all rows
-    boundaryData = boundaryData.map(row =>
+function validateForDuplicateRows(boundaryData: any[]) {
+    // Step 1: Trim strings in all rows
+    const trimmedBoundaryData = boundaryData.map(row =>
         Object.fromEntries(
             Object.entries(row).map(([key, value]) =>
                 [key, typeof value === "string" ? value.trim() : value]
             )
         )
     );
     const seen = new Set<string>();
     const duplicateRowNumbers: string[] = [];
-    for (const row of boundaryData) {
+    for (const row of trimmedBoundaryData) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 667-667: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 655-655: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/validators/campaignValidators.ts
between lines 653 and 680, avoid reassigning the function parameter
boundaryData. Instead of modifying boundaryData directly, create a new variable
to hold the trimmed rows result and use that variable in the rest of the
function. This prevents confusion and maintains the immutability of the input
parameter.

Comment on lines +331 to +387
export function validateMultiSelect(
data: any[],
schemaProperties: Record<string, any>,
localizationMap: any
) {
if (!data?.length || !schemaProperties || !Object.keys(schemaProperties).length) return [];

const userSheet = getLocalizedName(createAndSearch?.user?.parseArrayConfig?.sheetName, localizationMap);
const errors: any[] = [];

data.forEach((item) => {
Object.entries(schemaProperties).forEach(([propertyKey, property]) => {
const minSelections = property?.multiSelectDetails?.minSelections || 0;
const maxSelections = property?.multiSelectDetails?.maxSelections || 0;
if (!minSelections || !maxSelections) return;

const mainPreFix = property?.name;
const valuesSet = new Set();
const duplicatesSet : any = new Set();

for (let i = 1; i <= maxSelections; i++) {
const key = getLocalizedName(`${mainPreFix}_MULTISELECT_${i}`, localizationMap);
const value = item[key];
if (value) {
if (!valuesSet.has(value)) {
valuesSet.add(value);
} else {
duplicatesSet.add(value);
}
}
}

// Collect all errors at once
const errorDetails = [];
if (duplicatesSet.size > 0) {
errorDetails.push(`Duplicate roles`);
}
const mainKey = getLocalizedName(property?.name, localizationMap);
const mainKeyValueArrayLength = item?.[mainKey]?.split(",")?.length || 0;
if (valuesSet.size < minSelections && mainKeyValueArrayLength < minSelections) {
errorDetails.push(`At least ${minSelections} ${getLocalizedName(property?.name, localizationMap)} should be selected.`);
}

if (errorDetails.length > 0) {
errors.push({
status: "INVALID",
rowNumber: item?.["!row#number!"],
sheetName: userSheet,
errorDetails: errorDetails.join(" "),
});
}
});
});

return errors;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make the duplicate error message more generic.

The error message "Duplicate roles" is hardcoded, but this function handles any multi-select field, not just roles. Consider making it more generic.

-errorDetails.push(`Duplicate roles`);   
+errorDetails.push(`Duplicate values found in ${getLocalizedName(property?.name, localizationMap)}`);   
📝 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.

Suggested change
export function validateMultiSelect(
data: any[],
schemaProperties: Record<string, any>,
localizationMap: any
) {
if (!data?.length || !schemaProperties || !Object.keys(schemaProperties).length) return [];
const userSheet = getLocalizedName(createAndSearch?.user?.parseArrayConfig?.sheetName, localizationMap);
const errors: any[] = [];
data.forEach((item) => {
Object.entries(schemaProperties).forEach(([propertyKey, property]) => {
const minSelections = property?.multiSelectDetails?.minSelections || 0;
const maxSelections = property?.multiSelectDetails?.maxSelections || 0;
if (!minSelections || !maxSelections) return;
const mainPreFix = property?.name;
const valuesSet = new Set();
const duplicatesSet : any = new Set();
for (let i = 1; i <= maxSelections; i++) {
const key = getLocalizedName(`${mainPreFix}_MULTISELECT_${i}`, localizationMap);
const value = item[key];
if (value) {
if (!valuesSet.has(value)) {
valuesSet.add(value);
} else {
duplicatesSet.add(value);
}
}
}
// Collect all errors at once
const errorDetails = [];
if (duplicatesSet.size > 0) {
errorDetails.push(`Duplicate roles`);
}
const mainKey = getLocalizedName(property?.name, localizationMap);
const mainKeyValueArrayLength = item?.[mainKey]?.split(",")?.length || 0;
if (valuesSet.size < minSelections && mainKeyValueArrayLength < minSelections) {
errorDetails.push(`At least ${minSelections} ${getLocalizedName(property?.name, localizationMap)} should be selected.`);
}
if (errorDetails.length > 0) {
errors.push({
status: "INVALID",
rowNumber: item?.["!row#number!"],
sheetName: userSheet,
errorDetails: errorDetails.join(" "),
});
}
});
});
return errors;
}
// Collect all errors at once
const errorDetails = [];
if (duplicatesSet.size > 0) {
- errorDetails.push(`Duplicate roles`);
+ errorDetails.push(`Duplicate values found in ${getLocalizedName(property?.name, localizationMap)}`);
}
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/validators/campaignValidators.ts
between lines 331 and 387, the duplicate error message "Duplicate roles" is
hardcoded, which is not appropriate since the function validates any
multi-select field. To fix this, replace the hardcoded string with a generic
message that dynamically references the current property name using
localizationMap, making the error message applicable to all multi-select fields.

Comment on lines +1595 to +1614
export async function validateResourceDetails(ResourceDetails : ResourceDetails) {
logger.info("validating resource details");
const type = ResourceDetails?.type;
const hierarchyType = ResourceDetails?.hierarchyType;
const campaignId = ResourceDetails?.campaignId;
const tenantId = ResourceDetails?.tenantId;
const fileStoreId = ResourceDetails?.fileStoreId;
validateTypeForProcess(type);
await validateHierarchyDefination(hierarchyType,tenantId);
await validateCampaignViaId(campaignId,tenantId);
try {
const fileResponse = await fetchFileFromFilestore(fileStoreId, tenantId);
if(!fileResponse){
throwError("CAMPAIGN", 400, "VALIDATION_ERROR", `file not found, check fileStoreId`);
}
} catch (error) {
throwError("CAMPAIGN", 400, "VALIDATION_ERROR", `file not found, check fileStoreId`);
}
logger.info("resource details validated");
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Improve error handling specificity in validateResourceDetails.

The catch block at lines 1610-1612 catches all errors but doesn't distinguish between different types of failures (network error, 404, etc.).

-    try {
-        const fileResponse = await fetchFileFromFilestore(fileStoreId, tenantId);
-        if(!fileResponse){
-            throwError("CAMPAIGN", 400, "VALIDATION_ERROR", `file not found, check fileStoreId`);
-        }
-    } catch (error) {
-        throwError("CAMPAIGN", 400, "VALIDATION_ERROR", `file not found, check fileStoreId`);
-    }
+    try {
+        const fileResponse = await fetchFileFromFilestore(fileStoreId, tenantId);
+        if(!fileResponse){
+            throwError("CAMPAIGN", 400, "FILE_NOT_FOUND", `File with id ${fileStoreId} not found`);
+        }
+    } catch (error: any) {
+        logger.error(`Error fetching file from filestore: ${error.message}`);
+        throwError("CAMPAIGN", 500, "FILE_FETCH_ERROR", `Failed to fetch file: ${error.message || 'Unknown error'}`);
+    }
📝 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.

Suggested change
export async function validateResourceDetails(ResourceDetails : ResourceDetails) {
logger.info("validating resource details");
const type = ResourceDetails?.type;
const hierarchyType = ResourceDetails?.hierarchyType;
const campaignId = ResourceDetails?.campaignId;
const tenantId = ResourceDetails?.tenantId;
const fileStoreId = ResourceDetails?.fileStoreId;
validateTypeForProcess(type);
await validateHierarchyDefination(hierarchyType,tenantId);
await validateCampaignViaId(campaignId,tenantId);
try {
const fileResponse = await fetchFileFromFilestore(fileStoreId, tenantId);
if(!fileResponse){
throwError("CAMPAIGN", 400, "VALIDATION_ERROR", `file not found, check fileStoreId`);
}
} catch (error) {
throwError("CAMPAIGN", 400, "VALIDATION_ERROR", `file not found, check fileStoreId`);
}
logger.info("resource details validated");
};
export async function validateResourceDetails(ResourceDetails: ResourceDetails) {
logger.info("validating resource details");
const type = ResourceDetails?.type;
const hierarchyType = ResourceDetails?.hierarchyType;
const campaignId = ResourceDetails?.campaignId;
const tenantId = ResourceDetails?.tenantId;
const fileStoreId = ResourceDetails?.fileStoreId;
validateTypeForProcess(type);
await validateHierarchyDefination(hierarchyType, tenantId);
await validateCampaignViaId(campaignId, tenantId);
try {
const fileResponse = await fetchFileFromFilestore(fileStoreId, tenantId);
if (!fileResponse) {
throwError("CAMPAIGN", 400, "FILE_NOT_FOUND", `File with id ${fileStoreId} not found`);
}
} catch (error: any) {
logger.error(`Error fetching file from filestore: ${error.message}`);
throwError("CAMPAIGN", 500, "FILE_FETCH_ERROR", `Failed to fetch file: ${error.message || 'Unknown error'}`);
}
logger.info("resource details validated");
};
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/validators/campaignValidators.ts
around lines 1595 to 1614, the catch block for fetchFileFromFilestore is too
generic and does not differentiate error types. Modify the catch block to
inspect the error object and handle different cases such as network errors or
file not found (404) specifically. Provide more detailed error messages or
rethrow unexpected errors to improve error handling clarity and debugging.

Comment on lines +310 to +342
private async transformBulkEmployee(data: any[], transformConfig: any): Promise<any> {
const idRequests = createIdRequests(data);
let result = await createUniqueUserNameViaIdGen(idRequests);
let curr = 0;
logger.info("Enriching boundary type in jurisdictions for employee create data.");
const boundaryRelationshipResponse = await searchBoundaryRelationshipData(transformConfig?.metadata?.tenantId, transformConfig?.metadata?.hierarchy, true);
if (!boundaryRelationshipResponse?.TenantBoundary?.[0]?.boundary) {
throw new Error("Boundary relationship search failed");
}
const boundaryCodeAndBoundaryTypeMapping = getBoundaryCodeAndBoundaryTypeMapping(boundaryRelationshipResponse?.TenantBoundary?.[0]?.boundary);
if (data?.length > 0) {
data.forEach(item => {
if (item?.jurisdictions?.length > 0) {
item?.jurisdictions?.forEach((jurisdiction: any) => {
jurisdiction.boundaryType = boundaryCodeAndBoundaryTypeMapping[jurisdiction.boundary];
})
}
if (config.user.userPasswordAutoGenerate) {
item.user.password = generateUserPassword();
}
else {
item.user.password = config.user.userDefaultPassword;
}
if(!item?.user?.userName || item?.user?.userName === "undefined" || item?.user?.userName.trim() === "")
{
item.user.userName = result?.idResponses?.[curr]?.id;
item.code = result?.idResponses?.[curr]?.id;
curr++;
}
});
}
return data;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Use const instead of let for the result variable.

The result variable is only assigned once and never reassigned.

-let result = await createUniqueUserNameViaIdGen(idRequests);
+const result = await createUniqueUserNameViaIdGen(idRequests);
🧰 Tools
🪛 Biome (1.9.4)

[error] 312-312: This let declares a variable that is only assigned once.

'result' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/config/transFormConfig.ts around
lines 310 to 342, the variable 'result' is declared with 'let' but is never
reassigned after its initial assignment. Change the declaration of 'result' from
'let' to 'const' to reflect that it is a constant value and improve code
clarity.

localizationMap?: { [key: string]: string }) {
const type = request?.body?.ResourceDetails?.type;
const tenantId = request?.body?.ResourceDetails?.tenantId;
const isUpdate = request?.body?.parentCampaignObject ? true : false;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Simplify boolean expression.

The ternary operator is unnecessary when the condition already evaluates to a boolean.

-  const isUpdate = request?.body?.parentCampaignObject ? true : false;
+  const isUpdate = !!request?.body?.parentCampaignObject;
📝 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.

Suggested change
const isUpdate = request?.body?.parentCampaignObject ? true : false;
const isUpdate = !!request?.body?.parentCampaignObject;
🧰 Tools
🪛 Biome (1.9.4)

[error] 589-589: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/campaignUtils.ts at line
589, simplify the boolean expression by removing the ternary operator. Replace
the current expression with a direct boolean evaluation of
request?.body?.parentCampaignObject without using "? true : false".

Comment on lines +739 to +741
const latLongColumnsList = config.values.latLongColumns
? config.values.latLongColumns.split(",").map((item: any) => item.trim()).filter(Boolean)
: [];
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider improving readability of column parsing.

The latitude/longitude columns parsing logic works but could be more readable.

-  const latLongColumnsList = config.values.latLongColumns
-    ? config.values.latLongColumns.split(",").map((item: any) => item.trim()).filter(Boolean)
-    : [];
+  const latLongColumnsList = config.values.latLongColumns
+    ? config.values.latLongColumns
+        .split(",")
+        .map((item: string) => item.trim())
+        .filter(Boolean)
+    : [];
📝 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.

Suggested change
const latLongColumnsList = config.values.latLongColumns
? config.values.latLongColumns.split(",").map((item: any) => item.trim()).filter(Boolean)
: [];
const latLongColumnsList = config.values.latLongColumns
? config.values.latLongColumns
.split(",")
.map((item: string) => item.trim())
.filter(Boolean)
: [];
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/campaignUtils.ts around
lines 739 to 741, the code parsing latitude/longitude columns is functional but
hard to read. Refactor the parsing logic by breaking it into multiple clear
steps or using descriptive variable names to improve readability. For example,
first check if latLongColumns exists, then split, trim, and filter in separate
lines or with clearer chaining to make the intent more understandable.

Comment on lines +334 to +343
// const foundUsernameColumn = findColumnByHeader("UserName", worksheet);
// const foundPasswordColumn = findColumnByHeader("Password", worksheet);

// if (foundUsernameColumn) {
// usernameColumn = foundUsernameColumn;
// }
// if (foundPasswordColumn) {
// passwordColumn = foundPasswordColumn;
// }

Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Remove commented out code.

The commented code for dynamically finding username and password columns should be removed if it's no longer needed. If this flexibility might be required in the future, consider adding a TODO comment explaining when it might be re-enabled.

-  // const foundUsernameColumn = findColumnByHeader("UserName", worksheet);
-  // const foundPasswordColumn = findColumnByHeader("Password", worksheet);
-
-  // if (foundUsernameColumn) {
-  //   usernameColumn = foundUsernameColumn;
-  // }
-  // if (foundPasswordColumn) {
-  //   passwordColumn = foundPasswordColumn;
-  // }
-
📝 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.

Suggested change
// const foundUsernameColumn = findColumnByHeader("UserName", worksheet);
// const foundPasswordColumn = findColumnByHeader("Password", worksheet);
// if (foundUsernameColumn) {
// usernameColumn = foundUsernameColumn;
// }
// if (foundPasswordColumn) {
// passwordColumn = foundPasswordColumn;
// }
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/campaignUtils.ts around
lines 334 to 343, remove the commented-out code that attempts to find username
and password columns dynamically, as it is no longer needed. If you think this
functionality might be useful later, replace the commented code with a clear
TODO comment explaining the potential future use and when it should be
re-enabled.

Comment on lines +3454 to +3458
const frenchLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, true, false,localizationMap);
const portugeseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);
await transformAndCreateLocalisation(frenchLocalizationMap, request, true, false);
await transformAndCreateLocalisation(portugeseLocalizationMap, request, false, true);
await transformAndCreateLocalisation(boundaryMap, request, false, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Good internationalization support with a minor typo.

The multi-language localization support is well-implemented. However, there's a typo in the variable name.

-  const portugeseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);
+  const portugueseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);

Also update the function call:

-  await transformAndCreateLocalisation(portugeseLocalizationMap, request, false, true);
+  await transformAndCreateLocalisation(portugueseLocalizationMap, request, false, 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.

Suggested change
const frenchLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, true, false,localizationMap);
const portugeseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);
await transformAndCreateLocalisation(frenchLocalizationMap, request, true, false);
await transformAndCreateLocalisation(portugeseLocalizationMap, request, false, true);
await transformAndCreateLocalisation(boundaryMap, request, false, false);
const frenchLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, true, false,localizationMap);
const portugueseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);
await transformAndCreateLocalisation(frenchLocalizationMap, request, true, false);
await transformAndCreateLocalisation(portugueseLocalizationMap, request, false, true);
await transformAndCreateLocalisation(boundaryMap, request, false, false);
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/campaignUtils.ts around
lines 3454 to 3458, there is a typo in the variable name
"portugeseLocalizationMap" which should be corrected to
"portugueseLocalizationMap". Update both the variable declaration and its usage
in the function call to use the correct spelling "portugueseLocalizationMap" to
maintain consistency and clarity.

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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
build/maven/Dockerfile (1)

12-18: Dependency-layer caching still missing (previous feedback)

Copying only pom.xml and running mvn dependency:go-offline in a separate
layer enables Docker-layer caching of Maven artifacts. The skipped line
(# 16) was exactly that optimisation. Re-adding it would speed up rebuilds
considerably.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f83b640 and 753dc2e.

📒 Files selected for processing (1)
  • build/maven/Dockerfile (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: shubhang-eGov
PR: egovernments/health-campaign-services#1387
File: health-services/referralmanagement/pom.xml:54-54
Timestamp: 2025-02-11T09:43:42.872Z
Learning: Version updates for health-services-models in referral management service require QA verification to ensure no breaking changes between versions.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: kanishq-egov
PR: egovernments/health-campaign-services#847
File: health-services/libraries/health-services-common/pom.xml:11-11
Timestamp: 2024-08-12T06:07:15.114Z
Learning: Not all services in the health campaign services project are required to move to newer versions like `1.0.17-dev-SNAPSHOT`, as per kanishq-egov's guidance.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: core-services/beneficiary-idgen/src/test/java/org/egov/id/service/IdGenerationServiceTest.java:20-28
Timestamp: 2025-06-17T10:11:37.370Z
Learning: In the health-campaign-services project, tests are handled at the dev level and comprehensive unit tests are added when needed in the future, rather than requiring full mock coverage for all dependencies immediately.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java:144-144
Timestamp: 2025-01-16T11:52:14.029Z
Learning: Changes to employeeService in core-services/egov-hrms should be handled by the HCM team rather than the health campaign services team.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: health-services/individual/src/main/java/org/egov/individual/service/IndividualService.java:158-166
Timestamp: 2025-06-17T08:53:38.146Z
Learning: The individual service in the health-campaign-services project is using Java 17.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
build/maven/Dockerfile (4)
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#902
File: health-services/plan-service/src/main/java/digit/service/validator/PlanConfigurationValidator.java:553-553
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The plan-service project is using Java 17.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/db/Dockerfile:1-9
Timestamp: 2025-05-29T07:17:56.555Z
Learning: The eGovernments (digit) platform has established standards for Dockerfiles that may differ from general Docker security best practices. When reviewing Dockerfiles in digit projects, respect their organizational standards rather than suggesting general security improvements like non-root users or health checks.
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#1546
File: .github/workflows/build.yaml:92-99
Timestamp: 2025-05-12T09:43:49.129Z
Learning: When reviewing GitHub Actions workflows with Docker builds, remind the user about properly configuring Docker layer caching by adding `cache-from: type=local,src=/tmp/.buildx-cache` and `cache-to: type=local,dest=/tmp/.buildx-cache,mode=max` to the docker/build-push-action step to optimize build performance.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: health-services/individual/src/main/java/org/egov/individual/service/EnrichmentService.java:3-3
Timestamp: 2025-05-29T07:22:24.845Z
Learning: The codebase uses wildcard imports (e.g., `import java.util.*;`) consistently throughout, and this style should be maintained rather than suggesting explicit imports.
🪛 Hadolint (2.12.0)
build/maven/Dockerfile

[warning] 9-9: Pin versions in apk add. Instead of apk add <package> use apk add <package>=<version>

(DL3018)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
build/maven/Dockerfile (1)

18-20: Confirm that running unit tests inside the image is intentional

The build stage now executes mvn package without -DskipTests, which will
slow CI and may fail when tests rely on services that are unavailable in the
Docker context. If this is accidental, restore -DskipTests; otherwise,
ignore this note.

Comment on lines 8 to 10
# Install Maven
RUN apk add --no-cache maven

Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Pin the maven package version (DL3018)

If you decide to keep the apk add route, pin the exact version to avoid
unexpected upgrades in future CI runs.

-RUN apk add --no-cache maven
+RUN apk add --no-cache maven=~3.9.6-r0
📝 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.

Suggested change
# Install Maven
RUN apk add --no-cache maven
# Install Maven
RUN apk add --no-cache maven=~3.9.6-r0
🧰 Tools
🪛 Hadolint (2.12.0)

[warning] 9-9: Pin versions in apk add. Instead of apk add <package> use apk add <package>=<version>

(DL3018)

🤖 Prompt for AI Agents
In build/maven/Dockerfile around lines 8 to 10, the apk add command installs the
maven package without specifying a version, which can lead to unexpected
upgrades. Modify the RUN apk add --no-cache maven line to pin the maven package
to a specific version by appending =<version> to the package name, ensuring
consistent builds and avoiding future upgrade issues.

Comment on lines 2 to 3
FROM egovio/amazoncorretto:17-alpine3.19 AS build
# FROM egovio/alpine-maven-builder-jdk-8:1-master-NA-6036091e AS build
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider switching to an official Maven + Corretto builder image

Rather than installing Maven manually, you can inherit directly from
maven:3.9.6-amazoncorretto-17-alpine (same as the new
build/17/maven/Dockerfile).
This keeps the Dockerfile shorter, guarantees a reproducible Maven version, and avoids an extra apk add layer.

-FROM egovio/amazoncorretto:17-alpine3.19 AS build
-# Install Maven
-RUN apk add --no-cache maven
+FROM maven:3.9.6-amazoncorretto-17-alpine AS build

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

🤖 Prompt for AI Agents
In build/maven/Dockerfile at lines 2 to 3, replace the base image from
egovio/amazoncorretto:17-alpine3.19 to the official
maven:3.9.6-amazoncorretto-17-alpine image. This change removes the need to
manually install Maven, shortens the Dockerfile, ensures a consistent Maven
version, and eliminates an extra apk add layer.

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.

Actionable comments posted: 8

🔭 Outside diff range comments (2)
health-services/project-factory/src/server/api/campaignApis.ts (1)

465-547: Fix variable declarations and use template literals.

The username validation logic is well-implemented, but there are some style improvements needed:

Apply this diff to modernize the code:

-var mobileNumbercount = 0;
-var userNameCount = 0;
+let mobileNumbercount = 0;
+let userNameCount = 0;
-logger.info("Invalid resources count : " + mobileNumbercount + userNameCount);
+logger.info(`Invalid resources count : ${mobileNumbercount + userNameCount}`);
health-services/project-factory/src/server/utils/campaignUtils.ts (1)

1-4131: Consider splitting this large file into smaller, focused modules.

This file is over 4000 lines long and handles many different responsibilities including campaign management, boundary processing, Excel operations, and more. Consider refactoring it into smaller, more focused modules for better maintainability and testability. For example:

  • campaignBoundaryUtils.ts for boundary-related functions
  • campaignExcelUtils.ts for Excel processing functions
  • campaignDataProcessing.ts for data transformation functions
  • campaignPersistence.ts for database/persistence operations
♻️ Duplicate comments (24)
health-services/project-factory/src/server/utils/campaignMappingUtils.ts (1)

697-731: Add proper error handling for email notification logic.

The email notification logic lacks error handling and could cause the entire campaign processing to fail if there's an issue with sending emails. This critical functionality should be wrapped in a try-catch block.

The string concatenation issues and missing error handling for email notification were already flagged in previous reviews. Please address those concerns by wrapping the email logic in a try-catch block and using template literals instead of string concatenation.

health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (2)

59-75: [Duplicate Comment] Remove commented-out fetchFileUrls function

This matches the previous feedback about removing unused commented-out code. The function should be entirely removed or replaced with a clear TODO comment if it's intended for future use.


309-309: [Duplicate Comment] Error suppression may hide critical failures

This matches the previous feedback about the commented-out throwError call potentially causing silent failures in child campaign generation. The error suppression should be addressed to prevent inconsistent campaign states.

health-services/project-factory/src/server/utils/microplanUtils.ts (1)

318-350: [Duplicate Comment] Consider extracting common pattern in coordinate functions

This matches the previous feedback about the duplicated logic between getLatitudeFromData and getLongitudeFromData functions. A generic helper function would reduce code duplication and improve maintainability.

health-services/project-factory/src/server/config/index.ts (1)

48-48: [Duplicate Comment] Consider making phone number length configurable

This matches the previous feedback about making the hardcoded phone number length configurable via environment variable for better regional adaptability.

health-services/project-factory/src/server/validators/campaignValidators.ts (2)

366-366: Make the duplicate error message more generic.

The error message "Duplicate roles" is hardcoded but this function handles any multi-select field, not just roles. Consider making it more generic.


1610-1612: Improve error handling specificity in validateResourceDetails.

The catch block catches all errors but doesn't distinguish between different types of failures (network error, 404, etc.).

health-services/project-factory/src/server/api/campaignApis.ts (3)

1043-1048: Simplify boolean expression.

The schema fetching refactoring looks good, but the ternary operator is unnecessary.

Apply this diff to simplify:

-    const isUpdate = request?.body?.parentCampaignObject ? true : false;
+    const isUpdate = !!request?.body?.parentCampaignObject;

1178-1212: Fix variable declarations in enrichEmployees.

The logic improvements for password and username handling are excellent. However, there are some variable declaration issues.

Apply this diff to modernize variable declarations:

-  let result = await createUniqueUserNameViaIdGen(idRequests);
-  var i = 0;
+  const result = await createUniqueUserNameViaIdGen(idRequests);
+  let i = 0;
-    var generatedPassword = user?.password;
+    let generatedPassword = user?.password;

1709-1710: Simplify boolean expression (duplicate issue).

Same unnecessary ternary operator as in line 1045.

Apply this diff:

-    const isUpdate = request?.body?.parentCampaignObject ? true : false;
+    const isUpdate = !!request?.body?.parentCampaignObject;
health-services/project-factory/src/server/utils/genericUtils.ts (5)

228-281: Use const for immutable variables.

Variables that are never reassigned should use const.


286-287: Use const for immutable variables.

Variables that are never reassigned should use const.


997-997: Simplify boolean assignment.

The ternary operator is unnecessary for boolean conversion.


1478-1485: Avoid reassigning function parameters.

Parameter reassignment can be confusing.


1682-1701: Fix variable declarations in database query function.

Use const for variables that aren't reassigned.

health-services/project-factory/src/server/utils/campaignUtils.ts (9)

589-589: Simplify boolean expression.

The ternary operator is unnecessary when the condition already evaluates to a boolean.

-  const isUpdate = request?.body?.parentCampaignObject ? true : false;
+  const isUpdate = !!request?.body?.parentCampaignObject;

739-741: Consider improving readability of column parsing.

The latitude/longitude columns parsing logic works but could be more readable.

-  const latLongColumnsList = config.values.latLongColumns
-    ? config.values.latLongColumns.split(",").map((item: any) => item.trim()).filter(Boolean)
-    : [];
+  const latLongColumnsList = config.values.latLongColumns
+    ? config.values.latLongColumns
+        .split(",")
+        .map((item: string) => item.trim())
+        .filter(Boolean)
+    : [];

1443-1443: Use const for non-reassigned variable.

The variable 'level' is never reassigned and should be declared with const.

-    for (let level of hierarchy) {
+    for (const level of hierarchy) {

3462-3465: Fix duplicate localization key and typo in variable name.

There's a duplicate localization key and a typo in the variable name 'portugeseLocalizationMap'.

-  const portugeseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);
+  const portugueseLocalizationMap = extractFrenchOrPortugeseLocalizationMap(boundaryDataForSheet, false, true,localizationMap);
   await transformAndCreateLocalisation(frenchLocalizationMap, request, true, false);
-  await transformAndCreateLocalisation(portugeseLocalizationMap, request, false, true);
+  await transformAndCreateLocalisation(portugueseLocalizationMap, request, false, true);

3480-3481: Fix duplicate localization key.

The same localization key is used twice, which appears to be an error. The second occurrence should likely be for Portuguese localization.

      getLocalizedName("HCM_ADMIN_CONSOLE_FRENCH_LOCALIZATION_MESSAGE",localizationMap),
-      getLocalizedName("HCM_ADMIN_CONSOLE_FRENCH_LOCALIZATION_MESSAGE",localizationMap),
+      getLocalizedName("HCM_ADMIN_CONSOLE_PORTUGUESE_LOCALIZATION_MESSAGE",localizationMap),

3470-3470: Replace var with const.

Use modern variable declarations instead of var.

-  var headers = [...modifiedHierarchy, config?.boundary?.boundaryCode];
+  const headers = [...modifiedHierarchy, config?.boundary?.boundaryCode];

4068-4068: Use optional chaining instead of non-null assertion.

Replace the non-null assertion with optional chaining for safer code.

-      usernameMap.get(username)!.push(rowNumber);
+      usernameMap.get(username)?.push(rowNumber);

604-604: Use logger instead of console.warn for consistency.

Replace console.warn with logger.warn to maintain consistent logging practices across the codebase.

-          console.warn(`Column with header "${columnName}" not found in worksheet.`);
+          logger.warn(`Column with header "${columnName}" not found in worksheet.`);

334-343: Remove commented out code.

The commented code for dynamically finding username and password columns should be removed if it's no longer needed. If this flexibility might be required in the future, consider adding a TODO comment explaining when it might be re-enabled.

-  // const foundUsernameColumn = findColumnByHeader("UserName", worksheet);
-  // const foundPasswordColumn = findColumnByHeader("Password", worksheet);
-
-  // if (foundUsernameColumn) {
-  //   usernameColumn = foundUsernameColumn;
-  // }
-  // if (foundPasswordColumn) {
-  //   passwordColumn = foundPasswordColumn;
-  // }
-
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 753dc2e and 82796e9.

📒 Files selected for processing (12)
  • health-services/project-factory/migration/migrate.sh (1 hunks)
  • health-services/project-factory/src/server/api/campaignApis.ts (25 hunks)
  • health-services/project-factory/src/server/config/index.ts (6 hunks)
  • health-services/project-factory/src/server/kafka/Producer.ts (1 hunks)
  • health-services/project-factory/src/server/utils/campaignMappingUtils.ts (3 hunks)
  • health-services/project-factory/src/server/utils/campaignUtils.ts (48 hunks)
  • health-services/project-factory/src/server/utils/db/index.ts (2 hunks)
  • health-services/project-factory/src/server/utils/genericUtils.ts (32 hunks)
  • health-services/project-factory/src/server/utils/microplanUtils.ts (7 hunks)
  • health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (6 hunks)
  • health-services/project-factory/src/server/utils/processTrackUtils.ts (2 hunks)
  • health-services/project-factory/src/server/validators/campaignValidators.ts (12 hunks)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
health-services/project-factory/src/server/utils/processTrackUtils.ts (2)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/migration/migrate.sh (3)
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-10-08T20:11:12.539Z
Learning: User kavi-egov has tested and confirmed that the shell script in `core-services/service-request/src/main/resources/db/migrate.sh` works without double quotes around variables, and prefers to keep it this way.
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-06-20T12:51:42.524Z
Learning: User kavi-egov has tested and confirmed that the shell script in `core-services/service-request/src/main/resources/db/migrate.sh` works without double quotes around variables, and prefers to keep it this way.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: health-services/individual/src/main/resources/db/migration/main/V20250616122000__populate_null_client_reference_id_individual_identifier.sql:2-19
Timestamp: 2025-06-17T10:19:50.672Z
Learning: For the migration file V20250616122000__populate_null_client_reference_id_individual_identifier.sql in health-services/individual, the batched loop approach was previously recommended by CodeRabbit to handle potential memory and timeout issues with large table updates. The current implementation uses a DO block with LOOP to update 1000 rows at a time.
health-services/project-factory/src/server/kafka/Producer.ts (3)
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/LOCALSETUP.md:0-0
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The note in the LOCALSETUP.md file regarding error handling with Kafka and other microservices has been updated to provide more detailed troubleshooting steps.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/LOCALSETUP.md:0-0
Timestamp: 2024-06-24T08:15:04.390Z
Learning: The note in the LOCALSETUP.md file regarding error handling with Kafka and other microservices has been updated to provide more detailed troubleshooting steps.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
health-services/project-factory/src/server/utils/microplanUtils.ts (7)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/java/digit/service/validator/PlanFacilityValidator.java:223-231
Timestamp: 2024-09-26T16:02:24.074Z
Learning: In PlanFacilityValidator, `rootTenantId` is used for retrieving configurations, while `planFacility.getTenantId()` is used for tenant-specific validations; they are intentionally different and serve different purposes.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/web/controllers/PlanFacilityController.java:24-34
Timestamp: 2024-09-26T11:15:18.213Z
Learning: In this codebase, when updating plan facilities, `HttpStatus.ACCEPTED` (202) is intentionally used in `PlanFacilityController` as per the requirements.
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/java/digit/web/models/PlanFacilityResponse.java:37-43
Timestamp: 2024-09-27T07:05:16.555Z
Learning: In the `PlanFacilityResponse` class, the `addPlanFacilityItem` method is intended to be called only with valid `PlanFacility` objects, so adding null checks for `planFacilityItem` is unnecessary.
health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (10)
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-10-08T20:11:07.772Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-09-26T10:51:08.515Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: core-services/beneficiary-idgen/src/test/java/org/egov/id/service/IdGenerationServiceTest.java:20-28
Timestamp: 2025-06-17T10:11:37.370Z
Learning: In the health-campaign-services project, tests are handled at the dev level and comprehensive unit tests are added when needed in the future, rather than requiring full mock coverage for all dependencies immediately.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/config/ServiceConstants.java:189-193
Timestamp: 2024-09-26T11:17:36.420Z
Learning: When reviewing error messages in `ServiceConstants.java`, avoid suggesting changes to make them more descriptive unless specifically requested.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
health-services/project-factory/src/server/utils/campaignMappingUtils.ts (10)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-10-08T20:11:07.772Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-09-26T10:51:08.515Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/config/ServiceConstants.java:189-193
Timestamp: 2024-09-26T11:17:36.420Z
Learning: When reviewing error messages in `ServiceConstants.java`, avoid suggesting changes to make them more descriptive unless specifically requested.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:48-60
Timestamp: 2024-09-27T05:11:37.733Z
Learning: In this project, it's acceptable to keep the creation of objects like `CampaignSearchCriteria` within the current method for simplicity, even if extracting into a separate private method could improve readability.
health-services/project-factory/src/server/config/index.ts (15)
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:76-83
Timestamp: 2025-05-29T06:53:25.851Z
Learning: In the health-campaign-services project, configuration properties should follow existing patterns throughout the codebase rather than using environment variable placeholders, to maintain consistency across the project.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/LOCALSETUP.md:0-0
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The note in the LOCALSETUP.md file regarding error handling with Kafka and other microservices has been updated to provide more detailed troubleshooting steps.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/LOCALSETUP.md:0-0
Timestamp: 2024-06-24T08:15:04.390Z
Learning: The note in the LOCALSETUP.md file regarding error handling with Kafka and other microservices has been updated to provide more detailed troubleshooting steps.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:3-14
Timestamp: 2025-05-29T06:50:59.173Z
Learning: The team prioritizes consistency across services over fixing individual formatting issues or typos. When properties like `spring.datasource.url= jdbc:...` (with leading space), `success=SUCCESSFULL` (with typo), or error codes like `IDSeqOverFlow` are consistent across multiple services, they should be kept as-is rather than "fixed" to maintain uniformity across the codebase.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/java/org/egov/id/config/RedissonProperties.java:6-16
Timestamp: 2025-05-29T06:52:37.823Z
Learning: In health-campaign-services repository, the team prefers camelCase for configuration property field names (e.g., connectionPoolSize, nettyThreads) instead of kebab-case to maintain code consistency, even for Spring Boot @ConfigurationProperties classes.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#978
File: health-services/plan-service/src/main/resources/application.properties:80-80
Timestamp: 2024-10-15T08:31:13.060Z
Learning: In the 'health-campaign-services' project, it's acceptable to keep the `role.map` property in single-line format in the `application.properties` file, and reformatting into multiple lines is not required.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:44-74
Timestamp: 2025-05-29T06:51:42.290Z
Learning: In eGov projects, hardcoded Kafka configurations (bootstrap servers, topic names) in application.properties files are expected and follow eGov standards, rather than using environment variable placeholders.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: core-services/beneficiary-idgen/src/main/resources/application.properties:4-6
Timestamp: 2025-06-17T07:08:22.938Z
Learning: In the eGovernments health-campaign-services project, database credentials in application.properties files are hardcoded as default/development values but are always overridden in production deployments via DevOps Helm charts, which is their standard deployment practice for externalizing secrets.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/db/migration/main/V20250322111348__DDL_id_generation_create_ddl.sql:1-12
Timestamp: 2025-05-29T07:06:41.314Z
Learning: In the egovernments/health-campaign-services codebase, database column names use camelCase naming convention (e.g., tenantId, additionalFields, createdBy) as per their specification, not snake_case as typically expected in PostgreSQL.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: core-services/egov-hrms/src/main/java/org/egov/hrms/repository/EmployeeQueryBuilder.java:107-111
Timestamp: 2025-06-17T07:03:29.537Z
Learning: The egov-hrms service has default values configured in application.properties for critical properties like pagination limits, which serve as fallbacks when environment variables are missing from deployment charts.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/config/PropertiesManager.java:87-91
Timestamp: 2025-01-16T09:50:36.566Z
Learning: Email notification properties in HRMS service (kafka.topics.notification.email, notification.email.enabled, hrms.email.notification.implementation.partner, hrms.email.notification.website.link) are configured in both DevOps chart and application.properties, ensuring they are always present at startup.
Learnt from: Taniya-eGov
PR: egovernments/health-campaign-services#914
File: health-services/plan-service/src/main/resources/application.properties:63-63
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The URL `https://unified-dev.digit.org` is the correct host for both `egov.project.factory.host` and `egov.facility.host` configurations.
health-services/project-factory/src/server/validators/campaignValidators.ts (18)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java:448-449
Timestamp: 2025-01-22T10:07:27.833Z
Learning: In the health-campaign-services codebase, boundary codes in ExcelParser are pre-validated in the validateRows function before being used, which ensures they cannot be null or empty when accessed later in the code flow.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository's ExcelParser.java, boundary code cell validation is comprehensively handled through validateRows() which includes:
1. validateTillBoundaryCode() - checks for null cells, BLANK cell type, and validates string values against regex patterns
2. validateAttributes() - validates cell types, boundary code existence in boundaryCodeList, and performs string value validation
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:498-499
Timestamp: 2024-12-04T11:51:01.303Z
Learning: In the `health-services/project-factory` codebase, the `throwError()` function already logs errors internally. Therefore, explicit error logging before calling `throwError()` is unnecessary.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: health-services/libraries/health-services-common/src/main/java/org/egov/common/utils/ValidatorUtils.java:46-48
Timestamp: 2025-06-17T10:06:27.377Z
Learning: In ValidatorUtils.java, the error message format for getErrorForInvalidEntity method should use "%s not valid %s" format, as this was previously requested in a CodeRabbit review to change from "%s is not valid %s".
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/config/ServiceConstants.java:189-193
Timestamp: 2024-09-26T11:17:36.420Z
Learning: When reviewing error messages in `ServiceConstants.java`, avoid suggesting changes to make them more descriptive unless specifically requested.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-10-08T20:11:07.772Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:34-46
Timestamp: 2024-09-26T10:51:08.515Z
Learning: When exceptions occur in `CampaignUtil.fetchCampaignData`, it's acceptable to catch all exceptions, log the error, and return the `campaignResponse`.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1419
File: docs/health-api-specs/contracts/registries/product.yml:0-0
Timestamp: 2025-02-24T07:06:49.114Z
Learning: The OpenAPI specification file at docs/health-api-specs/contracts/registries/product.yml should maintain the title "Product Registry" as it contains Product and ProductVariant related APIs.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The `addTenantBoundaryItem` method in `BoundarySearchResponse.java` does not require thread safety measures as per devdatta-egov's guidance.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-06-26T17:13:14.997Z
Learning: The `addTenantBoundaryItem` method in `BoundarySearchResponse.java` does not require thread safety measures as per devdatta-egov's guidance.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: abishekTa-egov
PR: egovernments/health-campaign-services#1567
File: health-services/geopode-adapter/src/main/java/digit/config/ServiceConstants.java:32-57
Timestamp: 2025-05-28T11:03:54.258Z
Learning: The hierarchy definition in the geopode-adapter service doesn't need to be externalized or made dynamic because it's designed to work with hardcoded boundary-definition and will leverage MDMS values for actual data.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java:82-82
Timestamp: 2025-01-30T06:12:02.730Z
Learning: The getBoundaryCodeValue() method in PlanUtil requires a non-empty mappedValues map containing valid property mappings to prevent runtime exceptions.
health-services/project-factory/src/server/utils/genericUtils.ts (8)
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: siddhant-nawale-egov
PR: egovernments/health-campaign-services#793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/web/models/mdmsV2/MixedStrategyOperationLogic.java:19-29
Timestamp: 2025-01-22T10:07:11.992Z
Learning: The MDMS master data models in the health campaign services should maintain consistent property naming with the MDMS master definitions:
1. Boolean flags may use camelCase (e.g., "isFixedPost")
2. Other properties should use PascalCase (e.g., "RegistrationProcess", "DistributionProcess", "CategoriesNotAllowed")
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
health-services/project-factory/src/server/api/campaignApis.ts (13)
Learnt from: nitish-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In `health-services/project-factory/src/server/utils/campaignMappingUtils.ts`, the `processMapping` function already includes validation for `mappingObject.CampaignDetails.campaignDetails.boundaries` before accessing it, so additional null checks are unnecessary.
Learnt from: jagankumar-egov
PR: egovernments/health-campaign-services#1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the `health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts` file, the `throwError` function logs errors internally. Therefore, when catching errors and rethrowing using `throwError`, it's not necessary to add extra `logger.error` calls before invoking `throwError`.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: core-services/egov-hrms/src/main/java/org/egov/hrms/service/EmployeeService.java:144-144
Timestamp: 2025-01-16T11:52:14.029Z
Learning: Changes to employeeService in core-services/egov-hrms should be handled by the HCM team rather than the health campaign services team.
Learnt from: devdatta-egov
PR: egovernments/health-campaign-services#784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the `updateCampaignDetails` method of the `CampaignIntegrationUtil` class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/kafka/ResourceEstimationConsumer.java:33-34
Timestamp: 2025-04-29T05:07:01.882Z
Learning: The codebase prefers using `Boolean.TRUE` over primitive `true` for consistency in the health-campaign-services project.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/resource-generator/src/main/java/org/egov/processor/service/DraftService.java:76-82
Timestamp: 2025-05-05T11:04:03.855Z
Learning: In the DraftService's createDraftPlans method, campaigns will always exist when performing campaign search, so null checks for campaign.getCampaign().get(0) are unnecessary.
Learnt from: Saloni-eGov
PR: egovernments/health-campaign-services#906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:48-60
Timestamp: 2024-09-27T05:11:37.733Z
Learning: In this project, it's acceptable to keep the creation of objects like `CampaignSearchCriteria` within the current method for simplicity, even if extracting into a separate private method could improve readability.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java:448-449
Timestamp: 2025-01-22T10:07:27.833Z
Learning: In the health-campaign-services codebase, boundary codes in ExcelParser are pre-validated in the validateRows function before being used, which ensures they cannot be null or empty when accessed later in the code flow.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: health-services/libraries/health-services-models/src/main/java/org/egov/common/models/idgen/IDPoolGenerationRequest.java:34-37
Timestamp: 2025-05-29T08:34:07.853Z
Learning: When reviewing batch request APIs in health-services, ensure that list fields like batchRequestList have appropriate size validation (@Size annotation) to prevent performance issues from large batch operations. Typical limits should be reasonable for the use case (e.g., 1-100 items for batch requests).
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
health-services/project-factory/src/server/utils/campaignUtils.ts (32)

<retrieved_learning>
Learnt from: nitish-egov
PR: #1082
File: health-services/project-factory/src/server/utils/campaignMappingUtils.ts:640-646
Timestamp: 2024-12-04T12:30:22.889Z
Learning: In health-services/project-factory/src/server/utils/campaignMappingUtils.ts, the processMapping function already includes validation for mappingObject.CampaignDetails.campaignDetails.boundaries before accessing it, so additional null checks are unnecessary.
</retrieved_learning>

<retrieved_learning>
Learnt from: jagankumar-egov
PR: #1082
File: health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts:464-465
Timestamp: 2024-12-04T11:51:07.331Z
Learning: In the health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts file, the throwError function logs errors internally. Therefore, when catching errors and rethrowing using throwError, it's not necessary to add extra logger.error calls before invoking throwError.
</retrieved_learning>

<retrieved_learning>
Learnt from: devdatta-egov
PR: #784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/util/CampaignIntegrationUtil.java:73-89
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The error message in the updateCampaignDetails method of the CampaignIntegrationUtil class should be descriptive to aid in debugging, as confirmed by devdatta-egov.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1340
File: health-services/plan-service/src/main/java/digit/web/models/PlanSearchCriteria.java:46-50
Timestamp: 2025-01-22T09:59:37.847Z
Learning: In the health-campaign-services project, fields that get their values from MDMS should be kept as strings rather than enums to maintain flexibility, as MDMS values can be modified without requiring code changes.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint /egov-mdms-service/v1/_search in the following files, and updating them is not required:

  • health-services/referralmanagement/src/main/resources/application.properties
  • health-services/transformer/src/main/resources/application.properties
  • health-services/stock/src/main/resources/application.properties
  • health-services/resource-estimation-service/src/main/resources/application.properties
  • health-services/individual/src/main/resources/application.properties
  • health-services/product/src/main/resources/application.properties
  • health-services/project/src/main/resources/application.properties
  • health-services/household/src/main/resources/application.properties
  • health-services/facility/src/main/resources/application.properties
  • core-services/pgr-services/src/main/resources/application.properties
  • core-services/egov-hrms/src/main/resources/application.properties
  • core-services/dashboard-analytics/src/main/resources/application.properties
    </retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1533
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:69-86
Timestamp: 2025-05-05T11:46:06.216Z
Learning: In the health-campaign-services codebase, boundary codes are validated against the boundary service before being used in enrichment methods like PlanFacilityEnricher.enrichJurisdictionMapping, guaranteeing that boundary search responses will always contain valid data and making null checks unnecessary.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/EnrichmentUtil.java:147-148
Timestamp: 2025-01-22T09:58:20.727Z
Learning: In the health-campaign-services codebase, null checks for maps containing additional details are preferred at the point of consumption rather than at the point of population.
</retrieved_learning>

<retrieved_learning>
Learnt from: Sreejit-K
PR: #1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:76-83
Timestamp: 2025-05-29T06:53:25.851Z
Learning: In the health-campaign-services project, configuration properties should follow existing patterns throughout the codebase rather than using environment variable placeholders, to maintain consistency across the project.
</retrieved_learning>

<retrieved_learning>
Learnt from: Saloni-eGov
PR: #906
File: health-services/plan-service/src/main/java/digit/config/ServiceConstants.java:189-193
Timestamp: 2024-09-26T11:17:36.420Z
Learning: When reviewing error messages in ServiceConstants.java, avoid suggesting changes to make them more descriptive unless specifically requested.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/plan-service/src/main/java/digit/kafka/ResourceEstimationConsumer.java:33-34
Timestamp: 2025-04-29T05:07:01.882Z
Learning: The codebase prefers using Boolean.TRUE over primitive true for consistency in the health-campaign-services project.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1533
File: health-services/resource-generator/src/main/java/org/egov/processor/service/DraftService.java:76-82
Timestamp: 2025-05-05T11:04:03.855Z
Learning: In the DraftService's createDraftPlans method, campaigns will always exist when performing campaign search, so null checks for campaign.getCampaign().get(0) are unnecessary.
</retrieved_learning>

<retrieved_learning>
Learnt from: holashchand
PR: #1599
File: health-services/libraries/health-services-models/CHANGELOG.md:9-10
Timestamp: 2025-06-13T09:07:10.882Z
Learning: Changelog markdown files in this repository intentionally omit blank lines around headings and lists; markdownlint spacing nitpicks (MD022, MD032) should be ignored in future reviews.
</retrieved_learning>

<retrieved_learning>
Learnt from: Sreejit-K
PR: #1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:3-14
Timestamp: 2025-05-29T06:50:59.173Z
Learning: The team prioritizes consistency across services over fixing individual formatting issues or typos. When properties like spring.datasource.url= jdbc:... (with leading space), success=SUCCESSFULL (with typo), or error codes like IDSeqOverFlow are consistent across multiple services, they should be kept as-is rather than "fixed" to maintain uniformity across the codebase.
</retrieved_learning>

<retrieved_learning>
Learnt from: Sreejit-K
PR: #1419
File: docs/health-api-specs/contracts/registries/household.yml:540-554
Timestamp: 2025-02-24T08:29:54.544Z
Learning: In the health-campaign-services repository, trailing spaces in YAML files are acceptable and should not be flagged as issues during code review.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository, boundary code cell validation is handled in ExcelParser.java through the validateRows() method, which validates cells through validateTillBoundaryCode() and validateAttributes() methods.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:206-211
Timestamp: 2025-01-16T08:40:43.544Z
Learning: In the health-campaign-services repository's ExcelParser.java, boundary code cell validation is comprehensively handled through validateRows() which includes:

  1. validateTillBoundaryCode() - checks for null cells, BLANK cell type, and validates string values against regex patterns
  2. validateAttributes() - validates cell types, boundary code existence in boundaryCodeList, and performs string value validation
    </retrieved_learning>

<retrieved_learning>
Learnt from: siddhant-nawale-egov
PR: #793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-06-20T13:45:49.139Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
</retrieved_learning>

<retrieved_learning>
Learnt from: siddhant-nawale-egov
PR: #793
File: frontend/micro-ui/web/micro-ui-internals/packages/modules/hcm-microplanning/src/utils/excelUtils.js:18-36
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The excelUtils.js file contains several functions for selectively freezing and unfreezing cells, including unfreezeColumnsByHeader, freezeSheetValues, freezeCellsWithData, and performUnfreezeCells.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/service/ExcelParser.java:448-449
Timestamp: 2025-01-22T10:07:27.833Z
Learning: In the health-campaign-services codebase, boundary codes in ExcelParser are pre-validated in the validateRows function before being used, which ensures they cannot be null or empty when accessed later in the code flow.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:103-105
Timestamp: 2025-01-16T08:16:47.695Z
Learning: When iterating through Excel sheet columns from right to left (last to first) to localize output columns that are appended at the end, breaking the loop upon encountering the first non-localized column is the correct approach as all columns to its left will also be non-localized.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/resource-generator/src/main/java/org/egov/processor/util/ParsingUtil.java:468-485
Timestamp: 2025-04-29T05:56:06.702Z
Learning: In the resource-generator module, workbook resources are intentionally not closed inside utility methods like convertWorkbookToXls because the workbook is used for further processing after these methods return. Resource cleanup is handled at a higher level in the processing chain.
</retrieved_learning>

<retrieved_learning>
Learnt from: Priyanka-eGov
PR: #1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/CalculationUtil.java:82-82
Timestamp: 2025-01-30T06:12:02.730Z
Learning: The getBoundaryCodeValue() method in PlanUtil requires a non-empty mappedValues map containing valid property mappings to prevent runtime exceptions.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/census-service/src/main/java/digit/service/enrichment/CensusEnrichment.java:68-72
Timestamp: 2025-04-29T08:38:24.868Z
Learning: In the CensusEnrichment class, the enrichBoundaryAncestralPath method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-105
Timestamp: 2024-10-08T20:11:12.539Z
Learning: The project type is currently used in both MDMS (Master Data Management System) and project additional details.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-105
Timestamp: 2024-08-02T09:10:43.693Z
Learning: The project type is currently used in both MDMS (Master Data Management System) and project additional details.
</retrieved_learning>

<retrieved_learning>
Learnt from: Saloni-eGov
PR: #906
File: health-services/plan-service/src/main/java/digit/util/CampaignUtil.java:48-60
Timestamp: 2024-09-27T05:11:37.733Z
Learning: In this project, it's acceptable to keep the creation of objects like CampaignSearchCriteria within the current method for simplicity, even if extracting into a separate private method could improve readability.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-67
Timestamp: 2024-08-02T10:16:45.611Z
Learning: The project type JSON is currently stored in both the project model and MDMS. Once the transition to project models is complete, the logic will be updated accordingly.
</retrieved_learning>

<retrieved_learning>
Learnt from: kanishq-egov
PR: #838
File: health-services/referralmanagement/src/main/java/org/egov/referralmanagement/service/MasterDataService.java:53-67
Timestamp: 2024-10-08T20:11:07.773Z
Learning: The project type JSON is currently stored in both the project model and MDMS. Once the transition to project models is complete, the logic will be updated accordingly.
</retrieved_learning>

<retrieved_learning>
Learnt from: devdatta-egov
PR: #784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-06-26T17:13:14.997Z
Learning: The addTenantBoundaryItem method in BoundarySearchResponse.java does not require thread safety measures as per devdatta-egov's guidance.
</retrieved_learning>

<retrieved_learning>
Learnt from: devdatta-egov
PR: #784
File: health-services/resource-estimation-service/src/main/java/org/egov/processor/web/models/boundary/BoundarySearchResponse.java:28-43
Timestamp: 2024-10-08T20:11:07.772Z
Learning: The addTenantBoundaryItem method in BoundarySearchResponse.java does not require thread safety measures as per devdatta-egov's guidance.
</retrieved_learning>

<retrieved_learning>
Learnt from: tanishi-egov
PR: #1526
File: health-services/plan-service/src/main/java/digit/service/enrichment/PlanFacilityEnricher.java:81-86
Timestamp: 2025-04-29T10:50:41.452Z
Learning: In the PlanFacilityEnricher class, the enrichJurisdictionMapping method only processes the first child (index 0) because the boundary search API returns only one boundary at each hierarchy level in this specific context.
</retrieved_learning>

🧬 Code Graph Analysis (5)
health-services/project-factory/src/server/utils/processTrackUtils.ts (1)
health-services/project-factory/src/server/utils/db/index.ts (1)
  • getTableName (34-44)
health-services/project-factory/src/server/utils/microplanUtils.ts (3)
health-services/project-factory/src/server/utils/campaignUtils.ts (1)
  • getLocalizedName (4110-4110)
health-services/project-factory/src/server/kafka/Producer.ts (1)
  • produceModifiedMessages (117-117)
health-services/project-factory/src/server/api/coreApis.ts (1)
  • searchMDMSDataViaV1Api (305-305)
health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (1)
health-services/project-factory/src/server/kafka/Producer.ts (1)
  • produceModifiedMessages (117-117)
health-services/project-factory/src/server/utils/campaignMappingUtils.ts (7)
health-services/project-factory/src/server/api/campaignApis.ts (1)
  • getHierarchy (2039-2039)
health-services/project-factory/src/server/kafka/Producer.ts (1)
  • produceModifiedMessages (117-117)
health-services/project-factory/src/server/utils/processTrackUtils.ts (1)
  • persistTrack (224-224)
health-services/project-factory/src/server/config/constants.ts (2)
  • processTrackTypes (141-155)
  • processTrackStatuses (169-174)
health-services/project-factory/src/server/utils/logger/index.ts (1)
  • logger (24-24)
health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (1)
  • getResourceFromResourceId (698-703)
health-services/project-factory/src/server/utils/mailUtil.ts (1)
  • sendNotificationEmail (10-118)
health-services/project-factory/src/server/validators/campaignValidators.ts (12)
health-services/project-factory/src/server/utils/campaignUtils.ts (1)
  • getLocalizedName (4110-4110)
health-services/project-factory/src/server/api/campaignApis.ts (1)
  • getHierarchy (2039-2039)
health-services/project-factory/src/server/utils/genericUtils.ts (2)
  • getLocalizedHeaders (1738-1738)
  • throwError (1709-1709)
health-services/project-factory/src/server/api/genericApis.ts (1)
  • getSheetData (1577-1577)
health-services/project-factory/src/server/kafka/Producer.ts (1)
  • produceModifiedMessages (117-117)
health-services/project-factory/src/server/config/models/resourceDetailsSchema.ts (1)
  • ResourceDetails (21-21)
health-services/project-factory/src/server/utils/logger/index.ts (1)
  • logger (24-24)
health-services/project-factory/src/server/api/coreApis.ts (2)
  • fetchFileFromFilestore (305-305)
  • searchBoundaryRelationshipDefinition (305-305)
health-services/project-factory/src/server/service/campaignManageService.ts (1)
  • searchProjectTypeCampaignService (94-94)
health-services/project-factory/src/server/config/processTemplateConfigs.ts (1)
  • processTemplateConfigs (1-18)
health-services/project-factory/src/server/models/GenerateTemplateQuery.ts (1)
  • GenerateTemplateQuery (17-17)
health-services/project-factory/src/server/config/generationtTemplateConfigs.ts (1)
  • generationtTemplateConfigs (3-53)
🪛 Shellcheck (0.10.0)
health-services/project-factory/migration/migrate.sh

[error] 7-7: The shebang must be on the first line. Delete blanks and move comments.

(SC1128)

🪛 Biome (1.9.4)
health-services/project-factory/src/server/kafka/Producer.ts

[error] 99-99: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health-services/project-factory/src/server/utils/campaignMappingUtils.ts

[error] 697-697: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 700-700: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 707-707: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 714-714: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 721-721: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 727-727: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 730-730: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

health-services/project-factory/src/server/config/index.ts

[error] 18-18: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health-services/project-factory/src/server/validators/campaignValidators.ts

[error] 667-667: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 655-655: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

health-services/project-factory/src/server/utils/genericUtils.ts

[error] 286-286: This let declares a variable that is only assigned once.

'queryConditions' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 287-287: This let declares a variable that is only assigned once.

'queryValues' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 402-402: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 403-403: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 997-997: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 1481-1481: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 1687-1687: This let declares a variable that is only assigned once.

'relatedData' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 1689-1689: This let declares a variable that is only assigned once.

'rows' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

health-services/project-factory/src/server/api/campaignApis.ts

[error] 465-465: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 466-466: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 547-547: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 787-787: This let declares a variable that is only assigned once.

'foundUsernames' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 885-885: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)


[error] 1045-1046: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 1186-1186: This let declares a variable that is only assigned once.

'result' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 1187-1188: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 1190-1191: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 1709-1710: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

health-services/project-factory/src/server/utils/campaignUtils.ts

[error] 589-589: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 1443-1443: This let declares a variable that is only assigned once.

'level' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)


[error] 3470-3470: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 4068-4068: Forbidden non-null assertion.

Unsafe fix: Replace with optional chain operator ?. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator

(lint/style/noNonNullAssertion)

🔇 Additional comments (40)
health-services/project-factory/migration/migrate.sh (1)

7-28: LGTM! Multi-schema migration approach is well-implemented.

The loop-based approach to handle multiple schemas is correct and aligns with the broader multi-tenant support changes in this PR. The use of tr for portability and the schema URL construction logic are appropriate.

health-services/project-factory/src/server/utils/processTrackUtils.ts (2)

4-4: Good addition of dynamic table naming support.

The import of getTableName aligns with the new database utility functions introduced in this PR.


13-13: Correct implementation of dynamic table naming.

Using getTableName with the default tenant ID is the right approach for supporting both central and non-central environments.

health-services/project-factory/src/server/kafka/Producer.ts (1)

94-94: Good addition of tenant-aware topic naming.

The tenantId parameter with default value supports the new multi-tenant architecture introduced in this PR.

health-services/project-factory/src/server/utils/db/index.ts (2)

34-44: Excellent implementation of dynamic table naming.

The getTableName function correctly handles both central and non-central environments, supporting the multi-tenant architecture introduced in this PR. The tenant parsing logic and schema resolution are well-implemented.


47-50: Good helper function for schema name resolution.

The getDBSchemaName function appropriately handles the "egov" to "public" mapping and defaults to "public" for empty schemas.

health-services/project-factory/src/server/utils/campaignMappingUtils.ts (2)

372-372: Good fix for getHierarchy function call.

Removing the extra parameter aligns with the function signature changes in other parts of the codebase.


694-694: Correct addition of tenantId parameter.

Adding the tenantId parameter to produceModifiedMessages is consistent with the multi-tenant Kafka topic naming introduced in this PR.

health-services/project-factory/src/server/utils/onGoingCampaignUpdateUtils.ts (2)

652-652: LGTM: Tenant ID inclusion in Kafka message production

The addition of mappingObject?.CampaignDetails?.tenantId to the produceModifiedMessages call aligns with the broader pattern of tenant-aware messaging seen across the codebase. This supports multi-tenant functionality properly.


698-698: LGTM: Function exports enable external usage

Exporting getResourceFromResourceId and getFileUrl functions makes them available for use in other modules, which is consistent with their usage in campaignMappingUtils.ts for resource detail retrieval and notification workflows.

Also applies to: 729-729

health-services/project-factory/src/server/utils/microplanUtils.ts (6)

6-6: LGTM: API migration to new MDMS functions

The import updates correctly reflect the migration from deprecated callMdmsData to the new searchMDMSDataViaV1Api and searchMDMSDataViaV2Api functions, which is consistent with similar changes across the codebase.

Also applies to: 10-10


286-286: LGTM: Function signature enhancement for geospatial data

The addition of latLongColumnsList parameter to changeCreateDataForMicroplan enables the function to handle latitude and longitude extraction, supporting enhanced geospatial data processing.


299-306: LGTM: Geospatial data extraction integration

The coordinate extraction logic properly integrates with the helper functions to extract latitude and longitude values from row data, with appropriate null checks before assignment.


366-366: LGTM: Tenant-aware Kafka message production

The addition of request?.body?.ResourceDetails?.tenantId to the produceModifiedMessages call maintains consistency with the tenant-aware messaging pattern implemented across the codebase.


397-398: LGTM: Geospatial data inclusion in facility objects

The addition of latitude and longitude to the additionalDetails with proper null coalescing (?? null) ensures that geospatial data is included when available while maintaining consistent object structure.


481-493: LGTM: MDMS API migration with proper structure

The refactoring correctly migrates from the deprecated callMdmsData to searchMDMSDataViaV1Api with the proper MdmsCriteria structure that matches the API requirements.

health-services/project-factory/src/server/config/index.ts (6)

15-15: LGTM: Formatting improvements enhance readability

The consistent spacing after colons and addition of trailing commas improve code readability and maintainability.

Also applies to: 17-17, 40-41, 129-130, 167-168, 187-187


25-25: LGTM: Central instance detection configuration

The addition of isEnvironmentCentralInstance property enables the application to behave differently based on the deployment environment, which is useful for multi-tenant configurations.


69-72: LGTM: New Kafka topic configurations

The addition of KAFKA_SAVE_SHEET_DATA_TOPIC, KAFKA_UPDATE_SHEET_DATA_TOPIC, and KAFKA_NOTIFICATION_EMAIL_TOPIC environment variables supports the new messaging flows for sheet data management and email notifications.


77-77: LGTM: Database schema configuration

The addition of DB_SCHEMA property enables flexible database schema configuration, which is useful for multi-tenant deployments.


83-86: LGTM: Simplified database table names

The simplified table names as string literals improve readability and are consistent with the schema being handled elsewhere in the configuration.


172-173: LGTM: Reduced default values for unfroze configuration

The reduction of default values from "10000" to "5000" for unfrozeTillRow and from "50" to "26" for unfrozeTillColumn likely improves performance by reducing the scope of unfrozen cells in Excel processing.

health-services/project-factory/src/server/validators/campaignValidators.ts (7)

218-230: Great improvement making phone number length configurable!

The change from hardcoded value to config?.user?.phoneNumberLength improves maintainability and allows different deployments to have different phone number requirements.


512-512: Good refactoring to simplify getHierarchy calls.

Removing the redundant request parameter from getHierarchy calls is consistent with the broader refactoring mentioned in the AI summary.

Also applies to: 636-636, 1341-1341


810-810: Good defensive programming with explicit string conversion.

Converting the boundary column value to string before splitting prevents potential runtime errors if the value is not already a string.


1229-1241: Excellent addition of null safety checks!

The optional chaining and existence check for additionalDetails?.retryCycle prevents potential runtime errors. Good defensive programming practice.


1591-1592: Good practice using error code constants.

Replacing the hardcoded error message with VALIDATION_ERROR_ACTIVE_ROW improves maintainability and enables localization.


1616-1651: Well-structured validation helper functions!

The three validation functions (validateHierarchyDefination, validateCampaignViaId, validateTypeForProcess) follow consistent patterns and provide clear error messages.


1653-1662: Excellent code reuse in validateGenerateQuery!

The function effectively reuses existing validation helpers (validateHierarchyDefination, validateCampaignViaId) promoting DRY principles.

health-services/project-factory/src/server/api/campaignApis.ts (5)

107-111: LGTM! Good use of centralized request info.

The change to use defaultRequestInfo instead of constructing RequestInfo from the request body improves consistency across the codebase.


384-385: Good function rename for clarity.

The rename from createBatchRequest to searchBatchRequest better reflects the function's purpose of searching for individuals rather than creating them.


1147-1175: LGTM! Robust jurisdiction handling.

The improved jurisdiction enrichment logic properly handles:

  • String parsing with trimming
  • Graceful handling of non-string values
  • Sensible defaults when no jurisdictions are provided

1259-1268: Good abstraction for facility address processing.

The modifyFacilityAddress function properly:

  • Cleans locality codes by taking only the first comma-separated value
  • Ensures address has the correct tenantId
  • Provides a safe fallback with empty address object

1539-1541: LGTM! Proper tenant scoping for Kafka messages.

Adding tenantId to Kafka message production ensures proper message routing and multi-tenancy support.

Also applies to: 1557-1561

health-services/project-factory/src/server/utils/genericUtils.ts (6)

401-467: Multi-tenancy support properly implemented.

Good work adding tenantId to all produceModifiedMessages calls and updating API usage to match the new patterns.


731-759: Well-structured MDMS API migration.

Good refactoring to use searchMDMSDataViaV1Api and improve parameter specificity by accepting tenantId and type directly.


813-878: Enhanced dropdown handling with improved debugging.

Excellent improvements to the dropdown handling with comprehensive logging and proper null checks.


973-990: Clean implementation of multi-select column expansion.

Good approach to handle multi-select columns by expanding headers based on maxSelections configuration.


1494-1498: Clean locale-based localization handler.

Good addition for flexible localization retrieval by accepting locale directly.


1375-1422: Excellent multi-language localization support.

Good implementation of French and Portuguese translations with region-based locale handling. The integration with boundary data processing is clean and well-structured.

Comment on lines +96 to +100
if(config.isEnvironmentCentralInstance) {
// If tenantId has no ".", default to tenantId itself
const firstTenantPartAfterSplit = tenantId.includes(".") ? tenantId.split(".")[0] : tenantId;
topic = `${firstTenantPartAfterSplit}-${topic}`;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix parameter reassignment issue.

The topic parameter reassignment is flagged by static analysis. Use a local variable instead for better code clarity.

Apply this fix:

-        if(config.isEnvironmentCentralInstance) {
-            // If tenantId has no ".", default to tenantId itself
-            const firstTenantPartAfterSplit = tenantId.includes(".") ? tenantId.split(".")[0] : tenantId;
-            topic = `${firstTenantPartAfterSplit}-${topic}`;
-        }
+        let finalTopic = topic;
+        if(config.isEnvironmentCentralInstance) {
+            // If tenantId has no ".", default to tenantId itself
+            const firstTenantPartAfterSplit = tenantId.includes(".") ? tenantId.split(".")[0] : tenantId;
+            finalTopic = `${firstTenantPartAfterSplit}-${topic}`;
+        }

Then update the subsequent usage to use finalTopic instead of topic.

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

🧰 Tools
🪛 Biome (1.9.4)

[error] 99-99: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/kafka/Producer.ts around lines 96
to 100, the code reassigns the parameter 'topic', which is flagged by static
analysis. To fix this, create a new local variable, for example 'finalTopic',
assign the modified topic value to it instead of reassigning 'topic', and update
all subsequent uses in this scope to use 'finalTopic' instead of 'topic'.

cacheTime: 300,
retryUntilResourceCreationComplete:process.env.RETRY_TILL_RESOURCE_CREATION_COMPLETES || 100,
retryUntilResourceCreationComplete: process.env.RETRY_TILL_RESOURCE_CREATION_COMPLETES || 100,
isProduction: process.env ? true : false,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unnecessary ternary operator

The static analysis tool correctly identifies an unnecessary ternary operator. The expression can be simplified.

-isProduction: process.env ? true : false,
+isProduction: !!process.env.NODE_ENV,

Or if you intend to check for production environment:

-isProduction: process.env ? true : false,
+isProduction: process.env.NODE_ENV === "production",
📝 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.

Suggested change
isProduction: process.env ? true : false,
isProduction: process.env.NODE_ENV === "production",
🧰 Tools
🪛 Biome (1.9.4)

[error] 18-18: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/config/index.ts at line 18, the
ternary operator used to set isProduction is unnecessary because process.env is
always defined in Node.js. Simplify the expression by directly assigning a
boolean value that correctly reflects the production environment, such as
checking if process.env.NODE_ENV equals 'production'.

Comment on lines +777 to +831
async function getEmployeesBasedOnUserName(dataToCreate: any[], request: any) {
const searchBody = {
RequestInfo: request?.body?.RequestInfo,
};

// const tenantId = request?.body?.ResourceDetails?.tenantId;
const searchUrl = config.host.hrmsHost + config.paths.hrmsEmployeeSearch;
logger.info(`Waiting for 10 seconds`);
// await new Promise((resolve) => setTimeout(resolve, 10000));
const chunkSize = 50;
let foundUsernames = new Set<string>(); // ✅ Initialize resultSet properly

for (let i = 0; i < dataToCreate.length; i += chunkSize) {
const chunk = dataToCreate.slice(i, i + chunkSize);
const userNames = chunk.map((data: any) => data?.code).filter(Boolean); // ✅ Now an array, not a string


const params = {
tenantId: 'mz',
limit: 51,
offset: 0,
codes: userNames.join(","), // ✅ Convert array to comma-separated string
};

try {
const response = await httpRequest(
searchUrl,
searchBody,
params,
undefined,
undefined,
undefined,
undefined,
true
);
if (response?.Employees?.length) {
response.Employees.forEach((emp: any) => {
if (emp?.code) foundUsernames.add(emp.code); // ✅ Add only valid codes
});
}
} catch (error: any) {
console.log(error);
throwError(
"COMMON",
500,
"INTERNAL_SERVER_ERROR",
error.message ||
"Some internal error occurred while searching employees"
);
}
}

return foundUsernames;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix hardcoded tenant ID and use const for immutable variable.

The implementation has some issues that need to be addressed:

Apply this diff to fix the issues:

-  // await new Promise((resolve) => setTimeout(resolve, 10000));
   const chunkSize = 50;
-  let foundUsernames = new Set<string>(); // ✅ Initialize resultSet properly
+  const foundUsernames = new Set<string>(); // ✅ Initialize resultSet properly
     const params = {
-      tenantId: 'mz',
+      tenantId: request?.body?.ResourceDetails?.tenantId,
       limit: 51,
       offset: 0,
       codes: userNames.join(","), // ✅ Convert array to comma-separated string
     };

The hardcoded tenant ID 'mz' should use the actual tenant ID from the request to ensure proper multi-tenancy support.

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

Suggested change
async function getEmployeesBasedOnUserName(dataToCreate: any[], request: any) {
const searchBody = {
RequestInfo: request?.body?.RequestInfo,
};
// const tenantId = request?.body?.ResourceDetails?.tenantId;
const searchUrl = config.host.hrmsHost + config.paths.hrmsEmployeeSearch;
logger.info(`Waiting for 10 seconds`);
// await new Promise((resolve) => setTimeout(resolve, 10000));
const chunkSize = 50;
let foundUsernames = new Set<string>(); // ✅ Initialize resultSet properly
for (let i = 0; i < dataToCreate.length; i += chunkSize) {
const chunk = dataToCreate.slice(i, i + chunkSize);
const userNames = chunk.map((data: any) => data?.code).filter(Boolean); // ✅ Now an array, not a string
const params = {
tenantId: 'mz',
limit: 51,
offset: 0,
codes: userNames.join(","), // ✅ Convert array to comma-separated string
};
try {
const response = await httpRequest(
searchUrl,
searchBody,
params,
undefined,
undefined,
undefined,
undefined,
true
);
if (response?.Employees?.length) {
response.Employees.forEach((emp: any) => {
if (emp?.code) foundUsernames.add(emp.code); // ✅ Add only valid codes
});
}
} catch (error: any) {
console.log(error);
throwError(
"COMMON",
500,
"INTERNAL_SERVER_ERROR",
error.message ||
"Some internal error occurred while searching employees"
);
}
}
return foundUsernames;
}
async function getEmployeesBasedOnUserName(dataToCreate: any[], request: any) {
const searchBody = {
RequestInfo: request?.body?.RequestInfo,
};
// const tenantId = request?.body?.ResourceDetails?.tenantId;
const searchUrl = config.host.hrmsHost + config.paths.hrmsEmployeeSearch;
logger.info(`Waiting for 10 seconds`);
const chunkSize = 50;
const foundUsernames = new Set<string>(); // ✅ Initialize resultSet properly
for (let i = 0; i < dataToCreate.length; i += chunkSize) {
const chunk = dataToCreate.slice(i, i + chunkSize);
const userNames = chunk.map((data: any) => data?.code).filter(Boolean); // ✅ Now an array, not a string
const params = {
tenantId: request?.body?.ResourceDetails?.tenantId,
limit: 51,
offset: 0,
codes: userNames.join(","), // ✅ Convert array to comma-separated string
};
try {
const response = await httpRequest(
searchUrl,
searchBody,
params,
undefined,
undefined,
undefined,
undefined,
true
);
if (response?.Employees?.length) {
response.Employees.forEach((emp: any) => {
if (emp?.code) foundUsernames.add(emp.code); // ✅ Add only valid codes
});
}
} catch (error: any) {
console.log(error);
throwError(
"COMMON",
500,
"INTERNAL_SERVER_ERROR",
error.message ||
"Some internal error occurred while searching employees"
);
}
}
return foundUsernames;
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 787-787: This let declares a variable that is only assigned once.

'foundUsernames' is never reassigned.

Safe fix: Use const instead.

(lint/style/useConst)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/api/campaignApis.ts around lines
777 to 831, the tenant ID is hardcoded as 'mz', which breaks multi-tenancy
support. Replace the hardcoded tenant ID with the actual tenant ID extracted
from the request object, such as from request.body.ResourceDetails.tenantId.
Also, declare this tenant ID as a const variable to indicate immutability and
improve code clarity.

Comment on lines +876 to +889
properties: any,
localizationMap?: { [key: string]: string }
) {
try {
validateEmptyActive(dataFromSheet, request?.body?.ResourceDetails?.type, localizationMap);
const errorsRelatedToUserName :any = validateUsernamesFormat(dataFromSheet,localizationMap)
const errorsRelatedToMultiSelect:any = validateMultiSelect(dataFromSheet, properties, localizationMap);
const allErrors = [...errorsRelatedToUserName, ...errorsRelatedToMultiSelect];
request.body.sheetErrorDetails = request?.body?.sheetErrorDetails
? [...request?.body?.sheetErrorDetails, ...allErrors]
: allErrors;
if(request?.body?.sheetErrorDetails?.length){
request.body.ResourceDetails.status = resourceDataStatuses.invalid
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix unsafe optional chaining usage.

The validation additions look good, but there's a potential runtime error:

At line 885, the optional chaining with spread operator can throw an error. Apply this fix:

-    request.body.sheetErrorDetails = request?.body?.sheetErrorDetails
-      ? [...request?.body?.sheetErrorDetails, ...allErrors]
+    request.body.sheetErrorDetails = request.body?.sheetErrorDetails
+      ? [...request.body.sheetErrorDetails, ...allErrors]
       : allErrors;

The optional chaining on request?.body is unnecessary here since we're already accessing request.body.sheetErrorDetails in the assignment.

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

Suggested change
properties: any,
localizationMap?: { [key: string]: string }
) {
try {
validateEmptyActive(dataFromSheet, request?.body?.ResourceDetails?.type, localizationMap);
const errorsRelatedToUserName :any = validateUsernamesFormat(dataFromSheet,localizationMap)
const errorsRelatedToMultiSelect:any = validateMultiSelect(dataFromSheet, properties, localizationMap);
const allErrors = [...errorsRelatedToUserName, ...errorsRelatedToMultiSelect];
request.body.sheetErrorDetails = request?.body?.sheetErrorDetails
? [...request?.body?.sheetErrorDetails, ...allErrors]
: allErrors;
if(request?.body?.sheetErrorDetails?.length){
request.body.ResourceDetails.status = resourceDataStatuses.invalid
}
properties: any,
localizationMap?: { [key: string]: string }
) {
try {
validateEmptyActive(dataFromSheet, request?.body?.ResourceDetails?.type, localizationMap);
const errorsRelatedToUserName: any = validateUsernamesFormat(dataFromSheet, localizationMap);
const errorsRelatedToMultiSelect: any = validateMultiSelect(dataFromSheet, properties, localizationMap);
const allErrors = [...errorsRelatedToUserName, ...errorsRelatedToMultiSelect];
request.body.sheetErrorDetails = request.body?.sheetErrorDetails
? [...request.body.sheetErrorDetails, ...allErrors]
: allErrors;
if (request?.body?.sheetErrorDetails?.length) {
request.body.ResourceDetails.status = resourceDataStatuses.invalid;
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 885-885: Unsafe usage of optional chaining.

If it short-circuits with 'undefined' the evaluation will throw TypeError here:

(lint/correctness/noUnsafeOptionalChaining)

🤖 Prompt for AI Agents
In health-services/project-factory/src/server/api/campaignApis.ts around lines
876 to 889, the use of optional chaining with the spread operator on
request?.body?.sheetErrorDetails can cause a runtime error. Since request.body
is already accessed directly, remove the optional chaining from
request?.body?.sheetErrorDetails and use request.body.sheetErrorDetails
consistently to safely spread the array or assign allErrors without risking
undefined errors.

async function searchAllGeneratedResources(searchQuery: any, locale: any) {
try {
const { type, tenantId, hierarchyType, id, status, campaignId } = searchQuery;
let queryString = `SELECT * FROM ${config?.DB_CONFIG.DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME} WHERE `;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use multi-tenant table name handling for consistency.

The function uses a hardcoded table name while searchGeneratedResources uses getTableName for multi-tenant support. Apply the same pattern here:

-    let queryString = `SELECT * FROM ${config?.DB_CONFIG.DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME} WHERE `;
+    const tableName = getTableName(config?.DB_CONFIG.DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME, tenantId);
+    let queryString = `SELECT * FROM ${tableName} WHERE `;
📝 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.

Suggested change
let queryString = `SELECT * FROM ${config?.DB_CONFIG.DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME} WHERE `;
const tableName = getTableName(config?.DB_CONFIG.DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME, tenantId);
let queryString = `SELECT * FROM ${tableName} WHERE `;
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/genericUtils.ts at line 285,
replace the hardcoded table name with a call to getTableName to ensure
multi-tenant table name handling is consistent with the searchGeneratedResources
function. This involves using getTableName with the appropriate parameters
instead of directly accessing DB_GENERATED_RESOURCE_DETAILS_TABLE_NAME from the
config.

Comment on lines +1534 to +1565
function extractFrenchOrPortugeseLocalizationMap(
boundaryData: any[][],
isFrench: boolean,
isPortugese: boolean,
localizationMap: any
): Map<{ key: string; value: string }, string> {
const resultMap = new Map<{ key: string; value: string }, string>();

boundaryData.forEach(row => {
const boundaryCodeObj = row.find(obj => obj.key === getLocalizedName(config?.boundary?.boundaryCode, localizationMap));
const boundaryCode = boundaryCodeObj?.value;

if (!boundaryCode) return;

if (isFrench) {
const frenchMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_FRENCH_LOCALIZATION_MESSAGE", localizationMap));
resultMap.set({
key: "french",
value: frenchMessageObj?.value || ""
}, boundaryCode);
} else if (isPortugese) {
const portugeseMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_PORTUGESE_LOCALIZATION_MESSAGE", localizationMap));
resultMap.set({
key: "portugese",
value: portugeseMessageObj?.value || ""
}, boundaryCode);
}
});

return resultMap;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential issue with Map object keys.

Using objects as Map keys can be problematic since JavaScript uses reference equality. Consider using string keys instead:

-function extractFrenchOrPortugeseLocalizationMap(
+function extractFrenchOrPortugeseLocalizationMap(
   boundaryData: any[][],
   isFrench: boolean,
   isPortugese: boolean,
   localizationMap: any
-): Map<{ key: string; value: string }, string> {
-  const resultMap = new Map<{ key: string; value: string }, string>();
+): Map<string, string> {
+  const resultMap = new Map<string, string>();

   boundaryData.forEach(row => {
     const boundaryCodeObj = row.find(obj => obj.key === getLocalizedName(config?.boundary?.boundaryCode, localizationMap));
     const boundaryCode = boundaryCodeObj?.value;

     if (!boundaryCode) return;

     if (isFrench) {
       const frenchMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_FRENCH_LOCALIZATION_MESSAGE", localizationMap));
-      resultMap.set({
-        key: "french",
-        value: frenchMessageObj?.value || ""
-      }, boundaryCode);
+      resultMap.set(boundaryCode, frenchMessageObj?.value || "");
     } else if (isPortugese) {
       const portugeseMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_PORTUGESE_LOCALIZATION_MESSAGE", localizationMap));
-      resultMap.set({
-        key: "portugese",
-        value: portugeseMessageObj?.value || ""
-      }, boundaryCode);
+      resultMap.set(boundaryCode, portugeseMessageObj?.value || "");
     }
   });

   return resultMap;
}
📝 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.

Suggested change
function extractFrenchOrPortugeseLocalizationMap(
boundaryData: any[][],
isFrench: boolean,
isPortugese: boolean,
localizationMap: any
): Map<{ key: string; value: string }, string> {
const resultMap = new Map<{ key: string; value: string }, string>();
boundaryData.forEach(row => {
const boundaryCodeObj = row.find(obj => obj.key === getLocalizedName(config?.boundary?.boundaryCode, localizationMap));
const boundaryCode = boundaryCodeObj?.value;
if (!boundaryCode) return;
if (isFrench) {
const frenchMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_FRENCH_LOCALIZATION_MESSAGE", localizationMap));
resultMap.set({
key: "french",
value: frenchMessageObj?.value || ""
}, boundaryCode);
} else if (isPortugese) {
const portugeseMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_PORTUGESE_LOCALIZATION_MESSAGE", localizationMap));
resultMap.set({
key: "portugese",
value: portugeseMessageObj?.value || ""
}, boundaryCode);
}
});
return resultMap;
}
function extractFrenchOrPortugeseLocalizationMap(
boundaryData: any[][],
isFrench: boolean,
isPortugese: boolean,
localizationMap: any
): Map<string, string> {
const resultMap = new Map<string, string>();
boundaryData.forEach(row => {
const boundaryCodeObj = row.find(obj => obj.key === getLocalizedName(config?.boundary?.boundaryCode, localizationMap));
const boundaryCode = boundaryCodeObj?.value;
if (!boundaryCode) return;
if (isFrench) {
const frenchMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_FRENCH_LOCALIZATION_MESSAGE", localizationMap));
resultMap.set(boundaryCode, frenchMessageObj?.value || "");
} else if (isPortugese) {
const portugeseMessageObj = row.find(obj => obj.key === getLocalizedName("HCM_ADMIN_CONSOLE_PORTUGESE_LOCALIZATION_MESSAGE", localizationMap));
resultMap.set(boundaryCode, portugeseMessageObj?.value || "");
}
});
return resultMap;
}
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/genericUtils.ts around lines
1534 to 1565, the function uses objects as keys in a Map, which causes issues
because JavaScript compares object keys by reference, not by value. To fix this,
replace the object keys with unique string keys that combine the key and value
properties, ensuring consistent and reliable Map key comparisons.

Comment on lines +915 to +920
logger.info("Timeout of 30 sec after boundary data creation");
await callGenerate(
newRequestBoundary,
request?.body?.ResourceDetails?.type
);
}, 10000);
}, 30000);
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider making timeout values configurable.

The hardcoded timeout of 30 seconds should be configurable to allow flexibility in different environments.

-      logger.info("Timeout of 30 sec after boundary data creation");
+      const timeoutMs = config?.boundary?.creationTimeout || 30000;
+      logger.info(`Timeout of ${timeoutMs/1000} sec after boundary data creation`);
       await callGenerate(
         newRequestBoundary,
         request?.body?.ResourceDetails?.type
       );
-    }, 30000);
+    }, timeoutMs);
📝 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.

Suggested change
logger.info("Timeout of 30 sec after boundary data creation");
await callGenerate(
newRequestBoundary,
request?.body?.ResourceDetails?.type
);
}, 10000);
}, 30000);
const timeoutMs = config?.boundary?.creationTimeout || 30000;
logger.info(`Timeout of ${timeoutMs/1000} sec after boundary data creation`);
await callGenerate(
newRequestBoundary,
request?.body?.ResourceDetails?.type
);
}, timeoutMs);
🤖 Prompt for AI Agents
In health-services/project-factory/src/server/utils/campaignUtils.ts around
lines 915 to 920, the timeout value of 30000 milliseconds is hardcoded. Refactor
the code to replace this hardcoded timeout with a configurable parameter, such
as reading the timeout value from a configuration file or environment variable,
to allow flexibility across different environments.

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.

Actionable comments posted: 5

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9027632 and 17aa304.

📒 Files selected for processing (2)
  • .github/workflows/buildProjectFactory.yml (1 hunks)
  • build/build-config.yml (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
build/build-config.yml (4)
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:76-83
Timestamp: 2025-05-29T06:53:25.851Z
Learning: In the health-campaign-services project, configuration properties should follow existing patterns throughout the codebase rather than using environment variable placeholders, to maintain consistency across the project.
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#934
File: health-services/plan-service/src/main/resources/application.properties:54-54
Timestamp: 2024-10-03T10:08:20.045Z
Learning: In the 'health-campaign-services' project, it is acceptable to keep the old MDMS endpoint `/egov-mdms-service/v1/_search` in the following files, and updating them is not required:

- `health-services/referralmanagement/src/main/resources/application.properties`
- `health-services/transformer/src/main/resources/application.properties`
- `health-services/stock/src/main/resources/application.properties`
- `health-services/resource-estimation-service/src/main/resources/application.properties`
- `health-services/individual/src/main/resources/application.properties`
- `health-services/product/src/main/resources/application.properties`
- `health-services/project/src/main/resources/application.properties`
- `health-services/household/src/main/resources/application.properties`
- `health-services/facility/src/main/resources/application.properties`
- `core-services/pgr-services/src/main/resources/application.properties`
- `core-services/egov-hrms/src/main/resources/application.properties`
- `core-services/dashboard-analytics/src/main/resources/application.properties`
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#1546
File: .github/workflows/build.yaml:92-99
Timestamp: 2025-05-12T09:43:49.129Z
Learning: When reviewing GitHub Actions workflows with Docker builds, remind the user about properly configuring Docker layer caching by adding `cache-from: type=local,src=/tmp/.buildx-cache` and `cache-to: type=local,dest=/tmp/.buildx-cache,mode=max` to the docker/build-push-action step to optimize build performance.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1599
File: health-services/household/src/main/resources/household-persister.yml:176-189
Timestamp: 2025-06-13T08:53:48.057Z
Learning: The file health-services/household/src/main/resources/household-persister.yml (and similar persister YAMLs in that module) are intended for development use only and do not impact production deployments.
.github/workflows/buildProjectFactory.yml (1)
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#1546
File: .github/workflows/build.yaml:92-99
Timestamp: 2025-05-12T09:43:49.129Z
Learning: When reviewing GitHub Actions workflows with Docker builds, remind the user about properly configuring Docker layer caching by adding `cache-from: type=local,src=/tmp/.buildx-cache` and `cache-to: type=local,dest=/tmp/.buildx-cache,mode=max` to the docker/build-push-action step to optimize build performance.
🪛 YAMLlint (1.37.1)
build/build-config.yml

[warning] 337-337: missing starting space in comment

(comments)


[warning] 337-337: comment not indented like content

(comments-indentation)

.github/workflows/buildProjectFactory.yml

[warning] 3-3: truthy value should be one of [false, true]

(truthy)


[error] 21-21: too many spaces after colon

(colons)

🪛 actionlint (1.7.7)
.github/workflows/buildProjectFactory.yml

25-25: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


50-50: the runner of "docker/setup-buildx-action@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


53-53: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


61-61: the runner of "docker/login-action@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (2)
build/build-config.yml (1)

342-345: ✅ Dockerfile existence verified

The Dockerfiles at health-services/project-factory/Dockerfile and health-services/project-factory/migration/Dockerfile have been confirmed to exist. This build matrix configuration is safe to merge.

.github/workflows/buildProjectFactory.yml (1)

66-95: Image-tag logic can still collide on re-runs.

If the same commit is rebuilt (e.g., manual re-run) the tag ${BRANCH}-${COMMIT_HASH} already exists and the push will fail.
Common patterns:

  • Append the GitHub run number (${{ github.run_number }}).
  • Or use --push --provenance=false --sbom=false with --push --pull=true and --provenance=true to allow overwrites.

At minimum, add --provenance=false or a unique suffix to avoid flakiness.

image-name: microplan-ui


#Utilities
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Insert a space after the # to silence YAML-lint.

#Utilities should be # Utilities (same for other section headers, but this line is the only new one in the diff).

-#Utilities
+# Utilities
📝 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.

Suggested change
#Utilities
# Utilities
🧰 Tools
🪛 YAMLlint (1.37.1)

[warning] 337-337: missing starting space in comment

(comments)


[warning] 337-337: comment not indented like content

(comments-indentation)

🤖 Prompt for AI Agents
In build/build-config.yml at line 337, add a space after the '#' in the comment
'#Utilities' to make it '# Utilities'. This change will silence YAML-lint
warnings related to comment formatting.

Comment on lines +34 to +48
- name: Determine Dockerfile path from build-config.yml
id: pick_dockerfile
run: |
SERVICE="project-factory"
DEFAULT_DOCKERFILE="build/maven/Dockerfile"
DF=$(yq eval ".config[].build[] | select(.\"image-name\" == \"${SERVICE}\") | .dockerfile // \"\"" build/build-config.yml)
if [ -z "$DF" ] || [ "$DF" = "null" ]; then
echo "No dockerfile entry found for \"$SERVICE\" in build-config.yml; using default"
DF="$DEFAULT_DOCKERFILE"
else
echo "Found dockerfile \"$DF\" for service \"$SERVICE\"."
fi
echo "dockerfile_path=$DF" >> "$GITHUB_OUTPUT"
echo "DOCKERFILE_PATH=$DF" >> "$GITHUB_ENV"
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Protect against multiple matches in the yq query.

yq will output all matching dockerfile paths; if more than one exists the variable will contain newlines and the script will choke.
Safer:

DF=$(yq eval -o=json '.config[].build[] | select(."image-name"=="'"${SERVICE}"'") | .dockerfile // ""' build/build-config.yml | jq -r '.[0]')

(or simply head -n1 the current output).
Also quote $DF in the echo to preserve spaces.

🤖 Prompt for AI Agents
In .github/workflows/buildProjectFactory.yml lines 34 to 48, the yq command may
return multiple dockerfile paths causing the script to fail due to newlines in
the variable. Modify the yq command to output JSON and pipe it to jq to select
only the first match, or alternatively pipe the current output to head -n1 to
pick the first line. Also, ensure that the variable $DF is quoted in the echo
statements to correctly handle any spaces in the dockerfile path.

Comment on lines +20 to +21
docker_image: ${{ steps.save_docker_image.outputs.docker_image }}
db_image: ${{ steps.save_db_image.outputs.db_image }}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Trim excess spaces to satisfy YAML linters.

YAML-lint flags “too many spaces after colon”. One space is enough:

-      db_image:     ${{ steps.save_db_image.outputs.db_image }}
+      db_image: ${{ steps.save_db_image.outputs.db_image }}
📝 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.

Suggested change
docker_image: ${{ steps.save_docker_image.outputs.docker_image }}
db_image: ${{ steps.save_db_image.outputs.db_image }}
docker_image: ${{ steps.save_docker_image.outputs.docker_image }}
db_image: ${{ steps.save_db_image.outputs.db_image }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 21-21: too many spaces after colon

(colons)

🤖 Prompt for AI Agents
In .github/workflows/buildProjectFactory.yml at lines 20 to 21, the YAML keys
have extra spaces after the colon which causes linter warnings. Remove the extra
spaces so that there is only one space after each colon, ensuring proper YAML
formatting and passing the linter checks.

Comment on lines +50 to +59
uses: docker/setup-buildx-action@v2

- name: Cache Docker Layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-project-factory-${{ github.ref_name }}
restore-keys: |
${{ runner.os }}-buildx-
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Cache step is restored but never consumed by buildx.

Add cache-from and cache-to flags to the two docker/build-push-action steps to actually leverage the restored layers (matches the team convention noted in earlier PR #1546).

-          push: true
+          push: true
+          cache-from: type=local,src=/tmp/.buildx-cache
+          cache-to: type=local,dest=/tmp/.buildx-cache,mode=max

Apply the same diff to the DB image step.

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

🧰 Tools
🪛 actionlint (1.7.7)

50-50: the runner of "docker/setup-buildx-action@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


53-53: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/buildProjectFactory.yml around lines 50 to 59, the Docker
cache restored by the actions/cache step is not being used by the
docker/build-push-action steps. To fix this, add the cache-from and cache-to
flags to both docker/build-push-action steps, referencing the same cache path
(/tmp/.buildx-cache) and key, so that buildx can leverage the cached layers.
Apply the same changes to the DB image build step to maintain consistency with
team conventions.

Comment on lines +24 to +26
- name: Checkout Code
uses: actions/checkout@v3

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Bump actions/checkout to v4 (v3 is already deprecated).

Same applies to other core actions later in the file.
Ref:

-uses: actions/checkout@v3
+uses: actions/checkout@v4

Repeat for:

  • docker/setup-buildx-action (v3)
  • actions/cache (v4)
  • docker/login-action (v3)
📝 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.

Suggested change
- name: Checkout Code
uses: actions/checkout@v3
- name: Checkout Code
uses: actions/checkout@v4
🧰 Tools
🪛 actionlint (1.7.7)

25-25: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/buildProjectFactory.yml around lines 24 to 26, the
actions/checkout is using the deprecated v3 version. Update the version to v4
for actions/checkout and similarly update docker/setup-buildx-action to v4,
actions/cache to v4, and docker/login-action to v4 wherever they appear later in
the file to use the latest supported versions.

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.

Actionable comments posted: 2

♻️ Duplicate comments (1)
health-services/project-factory/migration/migrate.sh (1)

1-8: Shebang must be the very first line – remove the commented duplicate and blank lines

The script still violates SC1128: the executable shebang is at line 7, preceded by a commented-out shebang and blank lines. Many shells ignore the shebang unless it is literally the first bytes in the file; this can break executions that invoke the script directly.

-# #!/bin/sh
-
-
-#!/bin/sh
+#!/bin/sh

This also removes the obsolete commented shebang to avoid confusion.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17aa304 and d8fa497.

📒 Files selected for processing (1)
  • health-services/project-factory/migration/migrate.sh (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
health-services/project-factory/migration/migrate.sh (3)
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-10-08T20:11:12.539Z
Learning: User kavi-egov has tested and confirmed that the shell script in `core-services/service-request/src/main/resources/db/migrate.sh` works without double quotes around variables, and prefers to keep it this way.
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-06-20T12:51:42.524Z
Learning: User kavi-egov has tested and confirmed that the shell script in `core-services/service-request/src/main/resources/db/migrate.sh` works without double quotes around variables, and prefers to keep it this way.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: health-services/individual/src/main/resources/db/migration/main/V20250616122000__populate_null_client_reference_id_individual_identifier.sql:2-19
Timestamp: 2025-06-17T10:19:50.672Z
Learning: For the migration file V20250616122000__populate_null_client_reference_id_individual_identifier.sql in health-services/individual, the batched loop approach was previously recommended by CodeRabbit to handle potential memory and timeout issues with large table updates. The current implementation uses a DO block with LOOP to update 1000 rows at a time.
🪛 Shellcheck (0.10.0)
health-services/project-factory/migration/migrate.sh

[error] 7-7: The shebang must be on the first line. Delete blanks and move comments.

(SC1128)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: build

Comment on lines +9 to +10
# Print the base DB URL
baseurl="$DB_URL"
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Enable fail-fast behaviour for safer migrations

Consider aborting on the first error and treating unset variables as failures:

 baseurl="$DB_URL"
+set -euo pipefail

This prevents partial migrations or silent mis-substitutions in CI/CD pipelines.

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

Suggested change
# Print the base DB URL
baseurl="$DB_URL"
# Print the base DB URL
baseurl="$DB_URL"
set -euo pipefail
🤖 Prompt for AI Agents
In health-services/project-factory/migration/migrate.sh around lines 9 to 10,
the script currently does not fail immediately on errors or unset variables,
which can lead to unsafe migrations. Add "set -euo pipefail" at the beginning of
the script to enable fail-fast behavior and treat unset variables as errors.
This ensures the script aborts on the first failure or unset variable,
preventing partial migrations or silent errors.

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.

Actionable comments posted: 2

♻️ Duplicate comments (2)
health-services/project-factory/migration/migrate.sh (2)

1-3: Add fail-fast flags right after the shebang
set -euo pipefail makes the script abort on the first error, on use of an unset var, or on a failed pipe – crucial for migrations. This was already pointed out in an earlier review but is still missing.

 #!/bin/sh
+# fail fast on any error / unset variable
+set -euo pipefail

14-16: Robustly split SCHEMA_NAME – avoid word-splitting pitfalls
Using echo … | tr ',' ' ' drops empty items and misbehaves with spaces or globs in schema names. Prefer an IFS-based split that preserves values verbatim (previously suggested).

-# Loop through comma-separated schemas
-for schemaname in $(echo "$schemas" | tr ',' ' ')
+# Loop through comma-separated schemas
+IFS=',' read -r -a schema_arr <<EOF
+$schemas
+EOF
+for schemaname in "${schema_arr[@]}"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8fa497 and f737733.

📒 Files selected for processing (1)
  • health-services/project-factory/migration/migrate.sh (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Priyanka-eGov
PR: egovernments/health-campaign-services#1340
File: health-services/resource-generator/src/main/java/org/egov/processor/util/OutputEstimationGenerationUtil.java:50-70
Timestamp: 2025-01-22T11:10:43.217Z
Learning: In the health-campaign-services repository, workbook validation in Excel processing is handled at the entry point in ExcelParser.java through try-with-resources and exception handling (FileNotFoundException, InvalidFormatException, IOException).
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1533
File: health-services/plan-service/CHANGELOG.md:4-6
Timestamp: 2025-05-07T05:57:17.673Z
Learning: The audit log viewing enhancements (HCMPRE-2497), functionality to download drafts before freezing microplans (HCMPRE-2492), and addition of new columns (HCMPRE-2493) are implemented in the resource-generator service, not in the plan-service.
health-services/project-factory/migration/migrate.sh (7)
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-10-08T20:11:12.539Z
Learning: User kavi-egov has tested and confirmed that the shell script in `core-services/service-request/src/main/resources/db/migrate.sh` works without double quotes around variables, and prefers to keep it this way.
Learnt from: kavi-egov
PR: egovernments/health-campaign-services#791
File: core-services/service-request/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-06-20T12:51:42.524Z
Learning: User kavi-egov has tested and confirmed that the shell script in `core-services/service-request/src/main/resources/db/migrate.sh` works without double quotes around variables, and prefers to keep it this way.
Learnt from: holashchand
PR: egovernments/health-campaign-services#1607
File: health-services/individual/src/main/resources/db/migration/main/V20250616122000__populate_null_client_reference_id_individual_identifier.sql:2-19
Timestamp: 2025-06-17T10:19:50.672Z
Learning: For the migration file V20250616122000__populate_null_client_reference_id_individual_identifier.sql in health-services/individual, the batched loop approach was previously recommended by CodeRabbit to handle potential memory and timeout issues with large table updates. The current implementation uses a DO block with LOOP to update 1000 rows at a time.
Learnt from: Sreejit-K
PR: egovernments/health-campaign-services#1577
File: core-services/beneficiary-idgen/src/main/resources/application.properties:3-14
Timestamp: 2025-05-29T06:50:59.173Z
Learning: The team prioritizes consistency across services over fixing individual formatting issues or typos. When properties like `spring.datasource.url= jdbc:...` (with leading space), `success=SUCCESSFULL` (with typo), or error codes like `IDSeqOverFlow` are consistent across multiple services, they should be kept as-is rather than "fixed" to maintain uniformity across the codebase.
Learnt from: tanishi-egov
PR: egovernments/health-campaign-services#1337
File: health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java:229-230
Timestamp: 2025-01-16T12:10:20.764Z
Learning: Database schema modifications should be avoided in code reviews. The team prefers to handle schema changes through dedicated database migration processes rather than as part of feature PRs.
Learnt from: palak-egov
PR: egovernments/health-campaign-services#899
File: health-services/plan-service/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-09-27T06:41:35.748Z
Learning: In this codebase, it's acceptable to not enclose shell script variables in double quotes.
Learnt from: palak-egov
PR: egovernments/health-campaign-services#899
File: health-services/plan-service/src/main/resources/db/migrate.sh:3-3
Timestamp: 2024-10-08T20:11:07.772Z
Learning: In this codebase, it's acceptable to not enclose shell script variables in double quotes.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: build

Comment on lines 7 to 9
# Append schema param to URL
schemasetter="?currentSchema="

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Handle existing query parameters in DB_URL
If DB_URL already contains a ?, appending another ?currentSchema= yields an invalid JDBC URL. Switch to &currentSchema= when a ? is present.

-schemasetter="?currentSchema="
+# Default query separator
+schemasetter="?currentSchema="
+# If base URL already has query params, use '&'
+case $baseurl in
+  *\?*) schemasetter="&currentSchema=" ;;
+esac

Also applies to: 18-18

🤖 Prompt for AI Agents
In health-services/project-factory/migration/migrate.sh at lines 7-9 and line
18, the script appends the schema parameter using "?currentSchema=" without
checking if DB_URL already contains query parameters. Modify the code to check
if DB_URL includes a "?" character; if it does, use "&currentSchema=" instead of
"?currentSchema=" to correctly append the parameter and avoid invalid JDBC URLs.

Comment on lines +21 to +29

# Run Flyway migrate
flyway -url="$fullurl" \
-table="$SCHEMA_TABLE" \
-user="$FLYWAY_USER" \
-password="$FLYWAY_PASSWORD" \
-locations="$FLYWAY_LOCATIONS" \
-baselineOnMigrate=true \
-outOfOrder=true \
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Optional: run flyway repair before each migrate
If previous runs left the metadata table in an inconsistent state, flyway repair cleans it up. Executing it per-schema before migrate makes the loop idempotent.

-    # Run Flyway migrate
-    flyway -url="$fullurl" \
+    # Repair then migrate
+    flyway -url="$fullurl" \
+           -table="$SCHEMA_TABLE" \
+           -user="$FLYWAY_USER" \
+           -password="$FLYWAY_PASSWORD" \
+           -locations="$FLYWAY_LOCATIONS" \
+           repair
+    flyway -url="$fullurl" \
            -table="$SCHEMA_TABLE" \
            -user="$FLYWAY_USER" \
            -password="$FLYWAY_PASSWORD" \
            -locations="$FLYWAY_LOCATIONS" \
            -baselineOnMigrate=true \
            -outOfOrder=true \
            migrate
📝 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.

Suggested change
# Run Flyway migrate
flyway -url="$fullurl" \
-table="$SCHEMA_TABLE" \
-user="$FLYWAY_USER" \
-password="$FLYWAY_PASSWORD" \
-locations="$FLYWAY_LOCATIONS" \
-baselineOnMigrate=true \
-outOfOrder=true \
migrate
# Repair then migrate
flyway -url="$fullurl" \
-table="$SCHEMA_TABLE" \
-user="$FLYWAY_USER" \
-password="$FLYWAY_PASSWORD" \
-locations="$FLYWAY_LOCATIONS" \
repair
flyway -url="$fullurl" \
-table="$SCHEMA_TABLE" \
-user="$FLYWAY_USER" \
-password="$FLYWAY_PASSWORD" \
-locations="$FLYWAY_LOCATIONS" \
-baselineOnMigrate=true \
-outOfOrder=true \
migrate
🤖 Prompt for AI Agents
In health-services/project-factory/migration/migrate.sh around lines 21 to 29,
add a command to run `flyway repair` with the same connection parameters before
the `flyway migrate` command. This will clean up any inconsistent metadata state
and make the migration loop idempotent. Ensure the repair command uses the same
variables for URL, table, user, password, and locations as the migrate command.

@jagankumar-egov jagankumar-egov changed the title Final console v0.4 HCM Console :: Project Factory changes Jul 14, 2025
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.

5 participants