Skip to content

Vb/release 3.8.2 nikshay reapply#295

Open
vishwab1 wants to merge 97 commits into
release-3.8.2from
vb/release-3.8.2-nikshay-reapply
Open

Vb/release 3.8.2 nikshay reapply#295
vishwab1 wants to merge 97 commits into
release-3.8.2from
vb/release-3.8.2-nikshay-reapply

Conversation

@vishwab1

Copy link
Copy Markdown
Member

📋 Description

JIRA ID:

Please provide a summary of the change and the motivation behind it. Include relevant context and details.


✅ Type of Change

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

ℹ️ Additional Information

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

Zapper9982 and others added 30 commits July 21, 2026 19:21
…strict is null

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ames

- StopTBGeneralExamination: rewrite with BRD-correct fields (pallorId+pallor
  string pairs, pulseRate, randomBloodSugar, oedema, beneficiaryRegID,
  keyPopulationRiskFactorIds, hivStatusId — no more boolean clinical signs)
- StopTBRegistration: add villageId + villageName from i_bendemographics.districtBranchID
- StopTBRegistrationDto: add villageId + villageName for worklist requests
- StopTBRegistrationRepo: scope registrar worklist by psmId + villageId
- BenFlowStatusRepo: scope nurse worklist by psmId + villageId
- StopTBGeneralExaminationRepo: rename findByBeneficiaryRegID
- StopTBServiceImpl: extract village from demographics on registration,
  set on both tb_stoptb_registration and i_ben_flow_outreach flow record,
  fix all BRD field names throughout, add toJsonString for array fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…trar worklist and add beneficiary details endpoint

- getRegistrarWorklist now queries i_ben_flow_outreach by villageID + visitCategory instead of tb_stoptb_registration
- add getRegistrarWorklist query to BenFlowStatusRepo
- add getBeneficiaryDetails endpoint that proxies TM-API quickSearchNew and merges otherFields into flat response object

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…etails

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ckSearchNew

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n getBeneficiaryData style

- saveRegistration: forward full payload to TM-API without stripping Stop TB/anthropometry
  fields — they land in ExtraFields via checkExtraFields; enrich BenFlowStatus with benName,
  dob, gender, phone, district extracted from registration payload
- getRegistrarWorklist: returns getBeneficiaryData-style response — BenFlowStatus fields +
  db_identity detail (community, education, fatherName, motherName) + otherFields parsed for
  anthropometry and Stop TB details (personFrom, caseFindingType, tuId, weight, height, bmi, temp)
- getNurseWorklist: same rich response + generalExamination, tbScreening, generalOpd attached
  if already saved (null if not yet captured)
- Remove getRegistration and getBeneficiaryDetails endpoints — worklist covers both
- Add otherFields (ExtraFields column) mapping to RMNCHMBeneficiarydetail entity
- BenFlowStatusRepo worklist queries scoped to psmId + villageId only (visitCategory column
  not guaranteed to exist in i_ben_flow_outreach table)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n Stop TB worklist

getDetailByBenRegID queries i_beneficiarydetails.beneficiaryRegID which is unpopulated;
correct path is i_beneficiarymapping → BenDetailsId → i_beneficiarydetails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tch AMRIT standard format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add providerServiceMapID to GetBenRequestHandler for Stop TB filtering
- Add getAddressesByBenRegIds repo query to fetch addresses by benRegId list
- Add Stop TB path in getBenData: filter by providerServiceMapID+villageID via BenFlowStatus
- Parse i_beneficiarydetails.ExtraFields to include anthropometry (weight/height/bmi/temperatureValue) in response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…alias

- Replace subquery with JOIN to fix Hibernate 6 multi-valued binding error
- Add setVillageId setter as alias for villageID in GetBenRequestHandler

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…6 IN binding issue

JPQL IN with collection param throws multi-valued binding error in Hibernate 6 — native query bypasses this.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…te IN binding issue

Replace bulk native query with per-row findByBenRegIdFromMapping + getAddressById calls
— same pattern as existing FLW code, avoids Object[] mapping error from native SELECT *.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…vailable, tuId, tuName) to getBeneficiaryData response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s in worklist response

- occupation read from i_beneficiarydetails (already stored by Identity-API)
- economicStatus and residentialArea promoted to top-level in registration payload so Identity-API saves them in ExtraFields; read back in worklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, residentialArea to worklist response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…icStatus, residentialArea to worklist response"

This reverts commit 3695522.
…ensure ExtraFields storage

Identity-API ignores unknown processing of economicStatus/residentialArea to DB columns silently;
using tbEconomicStatus/tbResidentialArea as keys ensures they land in ExtraFields and are returned in worklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ryDetails object

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s (not tb-prefixed keys)

Mobile sends these as top-level fields to TM-API; Identity-API saves them in ExtraFields as-is

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e flow

- Add StopTBDiagnostics entity, repo, service, and controller (save/get/getAll)
- Add village-scoped getAll (villageID optional) to GeneralExamination, TBScreening, GeneralOpd, Diagnostics via BenFlowStatus subquery
- Fix TBScreening visitDate to accept user-provided date; preserve on update (not editable once submitted)
- Fix referralToHWCNeeded to trust mobile-computed value instead of server recalculating
- Fix chiefComplaint to support multi-select (JSON array)
- Add Yes/No boolean ID counterpart fields to TBScreening (14 fields), GeneralExamination (referralToHWCNeededId), Registration (isMobileAvailableId), and Diagnostics (6 fields)
- Add getTimestamp helper to StopTBServiceImpl

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
generalExamination, tbScreening, generalOpd, and diagnostics save
endpoints now take List<Map> instead of a single Map, allowing bulk
save in one request. Each item is processed within the same transaction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
vishwab1 and others added 29 commits July 21, 2026 22:52
…tead of userId

Nurse and Counsellor are different logins hitting the same
/tb/suspected/getAll and /tb/confirmed/getAll endpoints, but both queries
filtered by the calling user's own userId. So a Counsellor pulling data
after a Nurse creates a Suspected/Confirmed record saw none of it - only
rows tied to their own login.

Adds an optional providerServiceMapID(+villageID)-scoped query path on
both endpoints, joined through the already-populated BenFlowStatus table
(same pattern as StopTBDiagnosticsRepo), so any role at the same
facility/village sees the same worklist. The old userId-based path is
kept as the fallback when the new fields aren't sent, so already-deployed
app builds are unaffected.
visitDate isn't the right dimension for a facility worklist - an
unresolved Suspected case from months ago is still actionable, and
filtering it out by date would hide it from the Counsellor, working
against the visibility fix in the previous commit. Also matches
StopTBDiagnosticsRepo's facility-scoped query, which never date-filters.
Old ashaId-based fallback path is untouched and still date-filters as
before.
…iaryRegID

TBSuspected.benId / TBConfirmedCase.benId store the person-level
beneficiary_id (e.g. 907797933607), not beneficiaryRegID (e.g. 35137) -
confirmed by querying i_ben_flow_outreach directly. The facility-scoped
query added in the previous two commits joined against
BenFlowStatus.beneficiaryRegID, so it never matched anything and always
returned empty. Switched the join to BenFlowStatus.beneficiaryID, which
is the correct corresponding column.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Enforced mandatory validation for "Reason for Refusal in section e in file TbCounsellingFormSeeder

* Added counselled flag to confirmed cases response, indicating whether a beneficiary has completed the TB Counselling form. Implemented using a single bulk query to avoid N+1 lookups against FormResponse.

* Align `/complete` and `/submitBulk` form response editing behavior

* Updated `/complete` to resolve `FormResponse` using `beneficiaryId` and `formUuid` from the request body, removing the dependency on `responseId` as a query parameter.
* Updated `/submitBulk` section editing to match `/complete` behavior by performing in-place `SectionResponse` upserts and per-question delete-and-reinsert operations, instead of deleting and recreating the entire section.

* Add van/sync tracking fields (vanID, parkingPlaceID, vanSerialNo, processed, syncedDate, syncedBy, syncFailureReason) to domain entities for offline mobile data collection support

* feat(dynamic-form): add Hindi localization fields and completed beneficiaries endpoint

- Added `sectionName_hindi`, `questionText_hindi`, and `optionValue_hindi` fields to the FormSection, SectionQuestion, and QuestionOption entities to support Hindi localization.
- Added `GET /dynamicForm/response/getCompletedBeneficiaries?formType=` endpoint to return beneficiary IDs with `COMPLETE` status for the specified form type.

* feat(dynamic-form): add Hindi localization fields and completed beneficiaries endpoint

- Added `sectionName_hindi`, `questionText_hindi`, and `optionValue_hindi` fields to the FormSection, SectionQuestion, and QuestionOption entities to support Hindi localization.
- Added `GET /dynamicForm/response/getCompletedBeneficiaries?formType=` endpoint to return beneficiary IDs with `COMPLETE` status for the specified form type.

* feat(beneficiary): expose GPS coordinates in getBeneficiaryData response

Add gpsLatitude, gpsLongitude, digipin, gpsTimestamp, and isGpsUnavailable
fields to RMNCHBeneficiaryDetailsRmnch and RMNCHHouseHoldDetails entities,
mapping to the columns written by Identity-API's /syncDataToAmrit endpoint.

Enable serializeNulls on the Gson builder in BeneficiaryServiceImpl so GPS
keys are always present in householdDetails and beneficiaryDetails — null
for web-registered records, real values for mobile-registered ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

* Revert "Committed 82b00ccf with only the three files:"

This reverts commit 3040a08077d82d27dfd86f29f0fbdd4dc094ec56.

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

* Updated isMandatory field in Section C, so changed in TbCounsellingFormSeeder

* Add optional villageId and providerServiceMapId filters to getCompletedBeneficiaries

* Removing section f from seeder

* Removing already existing check in /complete api

* Add a CHECKBOX question type and a TB_COUNSELLING_V2 seeder with a GENERAL_INFO consent gate ahead of the counselling sections.

* Seed single-checkbox questions for Sections A-D and point the Counselled lookup at TB_COUNSELLING_V2 instead of the retired V1 form

* Mark form/section status REFUSED when TB2_GI_Q1=NO on /complete, split getCompletedBeneficiaries into completed/refused lists, and extract FormResponseStatus enum

* Resolved conflicts

* fix(stoptb): getBeneficiaryData reads anthropometry/vitals from standard tables

- getBeneficiaryData now reads height/weight/bmi from t_phy_anthropometry
  and temperature/pulse/BP/RBS from t_phy_vitals (latest row per beneficiary)
- Fallback to otherFields if exam not yet saved for the beneficiary
- Stop TB specific fields (personFrom, caseFindingType etc.) still from otherFields
- Add findByBeneficiaryRegIDOrderByCreatedDateDesc and findByBenVisitID
  to BenAnthropometryRepo and BenPhysicalVitalRepo
- Add StopTB_Future_Roadmap.md for future HWC integration and edit support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compile): rename variable 'a' to 'anthro' to avoid conflict with outer loop variable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): set CreatedDate on t_benvisitdetail insert to prevent NOT NULL constraint violation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(anc-pnc): guard CreatedDate on BenVisitDetail insert for ANC and PNC flows

If mobile does not send createdDate, ModelMapper leaves it null and MySQL
rejects the insert with NOT NULL constraint. Set server timestamp as fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docker): set TZ=Asia/Kolkata to prevent UTC/IST date mismatch

Without explicit timezone, Docker defaults to UTC. This causes LocalDate.now()
in getOrCreateVisitForToday() to use UTC date, so evening IST registrations
appear as next-day July 1 in DB and visit lookups fail after UTC midnight.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): handle ISO 8601 Z suffix in parseDob to fix beneficiary age display

Timestamp.valueOf() throws on "yyyy-MM-dd HH:mm:ss.SSSZ" format because the
trailing Z is not a valid nanosecond value. Strip Z before parsing so mobile
DOB like "1987-07-01T00:00:00.000Z" is correctly stored in i_ben_flow_outreach.ben_dob.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): fallback to i_ben_flow_outreach.ben_dob when i_beneficiarydetails.dob is null

Identity-API mapper (@mapping source=dto.dob) is commented out, causing dob to be
null for all mobile registrations. Fall back to ben_dob from i_ben_flow_outreach
so getBeneficiaryData returns correct DOB and mobile shows correct age.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use saveAndFlush to prevent FK violation in t_benchiefcomplaint

save() leaves VisitCode UPDATE pending in JPA session — t_benchiefcomplaint
INSERT runs before the UPDATE reaches DB, causing FK constraint failure and
full transaction rollback. saveAndFlush forces the UPDATE to DB immediately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): compute age from benDetailsRMNCH_OBJ.dob instead of benDetailsOBJ.dob

benDetailsOBJ.dob (i_beneficiarydetails) is null for Stop TB mobile
registrations, which is why c22b3fd added a fallback that fills
benDetailsRMNCH_OBJ.dob from i_ben_flow_outreach. The age calculation
block still read the original, still-null benDetailsOBJ.dob, so dob
came back correct but age/ageFull stayed 0/"". Point it at the
already-corrected benDetailsRMNCH_OBJ.dob instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(stoptb): scope Suspected/Confirmed getAll by facility+village instead of userId

Nurse and Counsellor are different logins hitting the same
/tb/suspected/getAll and /tb/confirmed/getAll endpoints, but both queries
filtered by the calling user's own userId. So a Counsellor pulling data
after a Nurse creates a Suspected/Confirmed record saw none of it - only
rows tied to their own login.

Adds an optional providerServiceMapID(+villageID)-scoped query path on
both endpoints, joined through the already-populated BenFlowStatus table
(same pattern as StopTBDiagnosticsRepo), so any role at the same
facility/village sees the same worklist. The old userId-based path is
kept as the fallback when the new fields aren't sent, so already-deployed
app builds are unaffected.

* fix(stoptb): drop date filter from facility-scoped Suspected query

visitDate isn't the right dimension for a facility worklist - an
unresolved Suspected case from months ago is still actionable, and
filtering it out by date would hide it from the Counsellor, working
against the visibility fix in the previous commit. Also matches
StopTBDiagnosticsRepo's facility-scoped query, which never date-filters.
Old ashaId-based fallback path is untouched and still date-filters as
before.

* fix(stoptb): join facility-scoped query on beneficiaryID, not beneficiaryRegID

TBSuspected.benId / TBConfirmedCase.benId store the person-level
beneficiary_id (e.g. 907797933607), not beneficiaryRegID (e.g. 35137) -
confirmed by querying i_ben_flow_outreach directly. The facility-scoped
query added in the previous two commits joined against
BenFlowStatus.beneficiaryRegID, so it never matched anything and always
returned empty. Switched the join to BenFlowStatus.beneficiaryID, which
is the correct corresponding column.

* Added counselled flag to confirmed cases response, indicating whether a beneficiary has completed the TB Counselling form. Implemented using a single bulk query to avoid N+1 lookups against FormResponse.

* Revert "Committed 82b00ccf with only the three files:"

This reverts commit 3040a08077d82d27dfd86f29f0fbdd4dc094ec56.

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

---------

Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: vishwab1 <vishwanath@navadhiti.com>
…port left over from PR #269 merge

The duplicate interface method was a compile error that cascaded into
hundreds of unrelated Lombok symbol errors across the module.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Enforced mandatory validation for "Reason for Refusal in section e in file TbCounsellingFormSeeder

* Added counselled flag to confirmed cases response, indicating whether a beneficiary has completed the TB Counselling form. Implemented using a single bulk query to avoid N+1 lookups against FormResponse.

* Align `/complete` and `/submitBulk` form response editing behavior

* Updated `/complete` to resolve `FormResponse` using `beneficiaryId` and `formUuid` from the request body, removing the dependency on `responseId` as a query parameter.
* Updated `/submitBulk` section editing to match `/complete` behavior by performing in-place `SectionResponse` upserts and per-question delete-and-reinsert operations, instead of deleting and recreating the entire section.

* Add van/sync tracking fields (vanID, parkingPlaceID, vanSerialNo, processed, syncedDate, syncedBy, syncFailureReason) to domain entities for offline mobile data collection support

* feat(dynamic-form): add Hindi localization fields and completed beneficiaries endpoint

- Added `sectionName_hindi`, `questionText_hindi`, and `optionValue_hindi` fields to the FormSection, SectionQuestion, and QuestionOption entities to support Hindi localization.
- Added `GET /dynamicForm/response/getCompletedBeneficiaries?formType=` endpoint to return beneficiary IDs with `COMPLETE` status for the specified form type.

* feat(dynamic-form): add Hindi localization fields and completed beneficiaries endpoint

- Added `sectionName_hindi`, `questionText_hindi`, and `optionValue_hindi` fields to the FormSection, SectionQuestion, and QuestionOption entities to support Hindi localization.
- Added `GET /dynamicForm/response/getCompletedBeneficiaries?formType=` endpoint to return beneficiary IDs with `COMPLETE` status for the specified form type.

* feat(beneficiary): expose GPS coordinates in getBeneficiaryData response

Add gpsLatitude, gpsLongitude, digipin, gpsTimestamp, and isGpsUnavailable
fields to RMNCHBeneficiaryDetailsRmnch and RMNCHHouseHoldDetails entities,
mapping to the columns written by Identity-API's /syncDataToAmrit endpoint.

Enable serializeNulls on the Gson builder in BeneficiaryServiceImpl so GPS
keys are always present in householdDetails and beneficiaryDetails — null
for web-registered records, real values for mobile-registered ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

* Revert "Committed 82b00ccf with only the three files:"

This reverts commit 3040a08077d82d27dfd86f29f0fbdd4dc094ec56.

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

# Conflicts:
#	src/main/java/com/iemr/flw/domain/identity/RMNCHMBeneficiaryaddress.java

* Updated isMandatory field in Section C, so changed in TbCounsellingFormSeeder

* Add optional villageId and providerServiceMapId filters to getCompletedBeneficiaries

* Removing section f from seeder

* Removing already existing check in /complete api

* Add a CHECKBOX question type and a TB_COUNSELLING_V2 seeder with a GENERAL_INFO consent gate ahead of the counselling sections.

* Seed single-checkbox questions for Sections A-D and point the Counselled lookup at TB_COUNSELLING_V2 instead of the retired V1 form

* Mark form/section status REFUSED when TB2_GI_Q1=NO on /complete, split getCompletedBeneficiaries into completed/refused lists, and extract FormResponseStatus enum

* Resolved conflicts

* fix(stoptb): getBeneficiaryData reads anthropometry/vitals from standard tables

- getBeneficiaryData now reads height/weight/bmi from t_phy_anthropometry
  and temperature/pulse/BP/RBS from t_phy_vitals (latest row per beneficiary)
- Fallback to otherFields if exam not yet saved for the beneficiary
- Stop TB specific fields (personFrom, caseFindingType etc.) still from otherFields
- Add findByBeneficiaryRegIDOrderByCreatedDateDesc and findByBenVisitID
  to BenAnthropometryRepo and BenPhysicalVitalRepo
- Add StopTB_Future_Roadmap.md for future HWC integration and edit support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compile): rename variable 'a' to 'anthro' to avoid conflict with outer loop variable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): set CreatedDate on t_benvisitdetail insert to prevent NOT NULL constraint violation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(anc-pnc): guard CreatedDate on BenVisitDetail insert for ANC and PNC flows

If mobile does not send createdDate, ModelMapper leaves it null and MySQL
rejects the insert with NOT NULL constraint. Set server timestamp as fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docker): set TZ=Asia/Kolkata to prevent UTC/IST date mismatch

Without explicit timezone, Docker defaults to UTC. This causes LocalDate.now()
in getOrCreateVisitForToday() to use UTC date, so evening IST registrations
appear as next-day July 1 in DB and visit lookups fail after UTC midnight.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): handle ISO 8601 Z suffix in parseDob to fix beneficiary age display

Timestamp.valueOf() throws on "yyyy-MM-dd HH:mm:ss.SSSZ" format because the
trailing Z is not a valid nanosecond value. Strip Z before parsing so mobile
DOB like "1987-07-01T00:00:00.000Z" is correctly stored in i_ben_flow_outreach.ben_dob.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): fallback to i_ben_flow_outreach.ben_dob when i_beneficiarydetails.dob is null

Identity-API mapper (@mapping source=dto.dob) is commented out, causing dob to be
null for all mobile registrations. Fall back to ben_dob from i_ben_flow_outreach
so getBeneficiaryData returns correct DOB and mobile shows correct age.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use saveAndFlush to prevent FK violation in t_benchiefcomplaint

save() leaves VisitCode UPDATE pending in JPA session — t_benchiefcomplaint
INSERT runs before the UPDATE reaches DB, causing FK constraint failure and
full transaction rollback. saveAndFlush forces the UPDATE to DB immediately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(stoptb): compute age from benDetailsRMNCH_OBJ.dob instead of benDetailsOBJ.dob

benDetailsOBJ.dob (i_beneficiarydetails) is null for Stop TB mobile
registrations, which is why c22b3fd added a fallback that fills
benDetailsRMNCH_OBJ.dob from i_ben_flow_outreach. The age calculation
block still read the original, still-null benDetailsOBJ.dob, so dob
came back correct but age/ageFull stayed 0/"". Point it at the
already-corrected benDetailsRMNCH_OBJ.dob instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(stoptb): scope Suspected/Confirmed getAll by facility+village instead of userId

Nurse and Counsellor are different logins hitting the same
/tb/suspected/getAll and /tb/confirmed/getAll endpoints, but both queries
filtered by the calling user's own userId. So a Counsellor pulling data
after a Nurse creates a Suspected/Confirmed record saw none of it - only
rows tied to their own login.

Adds an optional providerServiceMapID(+villageID)-scoped query path on
both endpoints, joined through the already-populated BenFlowStatus table
(same pattern as StopTBDiagnosticsRepo), so any role at the same
facility/village sees the same worklist. The old userId-based path is
kept as the fallback when the new fields aren't sent, so already-deployed
app builds are unaffected.

* fix(stoptb): drop date filter from facility-scoped Suspected query

visitDate isn't the right dimension for a facility worklist - an
unresolved Suspected case from months ago is still actionable, and
filtering it out by date would hide it from the Counsellor, working
against the visibility fix in the previous commit. Also matches
StopTBDiagnosticsRepo's facility-scoped query, which never date-filters.
Old ashaId-based fallback path is untouched and still date-filters as
before.

* fix(stoptb): join facility-scoped query on beneficiaryID, not beneficiaryRegID

TBSuspected.benId / TBConfirmedCase.benId store the person-level
beneficiary_id (e.g. 907797933607), not beneficiaryRegID (e.g. 35137) -
confirmed by querying i_ben_flow_outreach directly. The facility-scoped
query added in the previous two commits joined against
BenFlowStatus.beneficiaryRegID, so it never matched anything and always
returned empty. Switched the join to BenFlowStatus.beneficiaryID, which
is the correct corresponding column.

* Added counselled flag to confirmed cases response, indicating whether a beneficiary has completed the TB Counselling form. Implemented using a single bulk query to avoid N+1 lookups against FormResponse.

* Revert "Committed 82b00ccf with only the three files:"

This reverts commit 3040a08077d82d27dfd86f29f0fbdd4dc094ec56.

* Committed 82b00ccf with only the three files:
  - BeneficiaryServiceImpl.java — serializeNulls() + GPS fallback from address
  - RMNCHBeneficiaryDetailsRmnch.java — gpsLatitude, gpsLongitude, digipin, gpsTimestamp, isGpsUnavailable fields
  - RMNCHHouseHoldDetails.java — gpsLatitude, gpsLongitude fields

* feat(beneficiary): expose GPS coordinates in getBeneficiaryData response

Add gpsLatitude, gpsLongitude, digipin, gpsTimestamp, and isGpsUnavailable
fields to RMNCHBeneficiaryDetailsRmnch and RMNCHHouseHoldDetails entities,
mapping to the columns written by Identity-API's /syncDataToAmrit endpoint.

Enable serializeNulls on the Gson builder in BeneficiaryServiceImpl so GPS
keys are always present in householdDetails and beneficiaryDetails — null
for web-registered records, real values for mobile-registered ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Changing working of checkbox as of radio button

---------

Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: vishwab1 <vishwanath@navadhiti.com>
…ning

Adds a mandatory Risk Factors section (Key Population/Risk Factors
multi-select + HIV Status) to nurse TB Screening, matching the new
form requirement, and removes it from General Examination where it
previously lived.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per updated requirement, these fields should be captured on both
General Examination and TB Screening, not moved exclusively to TB
Screening. Restores keyPopulationRiskFactorIds/Factors and
hivStatusId/hivStatus on StopTBGeneralExamination (save + response
map), on top of the earlier commit that added them to TBScreening.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
new Gson() excludes any key whose value is null by default, so
fields like hivStatus/keyPopulationRiskFactor* that were saved as
NULL never appeared in GET/GETALL responses at all. Switch to a
shared Gson instance built with serializeNulls() across all 16
StopTBController response sites.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ning

Adds a mandatory Risk Factors section (Key Population/Risk Factors
multi-select + HIV Status) to nurse TB Screening, matching the new
form requirement, and removes it from General Examination where it
previously lived.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per updated requirement, these fields should be captured on both
General Examination and TB Screening, not moved exclusively to TB
Screening. Restores keyPopulationRiskFactorIds/Factors and
hivStatusId/hivStatus on StopTBGeneralExamination (save + response
map), on top of the earlier commit that added them to TBScreening.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
benRegId has no unique constraint on i_beneficiarymapping, so
findByBenRegIdFromMapping's single-result query threw
IncorrectResultSizeDataAccessException whenever a beneficiary had
more than one mapping row, crashing the Stop TB registrar worklist
refresh. Return the list ordered by benMapId DESC and use the latest
mapping instead of assuming uniqueness.
…roller

getBeneficiaryData request/response System.out.println calls logged full
beneficiary details (name, address, health ID) to stdout unconditionally.
Without local exception handling, an unhandled error in saveVhndForm/
saveVhncForm/savePhcForm/saveAhdForm/saveDewormingForm now falls through
to GlobalExceptionHandler's catch-all, which returns a different response
shape (ApiResponse) than this controller's existing status/statusCode/
message convention, breaking existing clients. Wrap each in the same
try/catch pattern already used by getVillageLevelFormData.
Verified against the actual mobile app source (STOP-TB-App release-1.1
AmritApiService.kt) and ADMIN-UI web client — none of these are called:

- /stoptb/registration/save — mobile registers directly against TM-API's
  registrarBeneficaryRegistrationNew; TM-API creates BenFlowStatus itself
  via its own isMobile-flag branch when the request doesn't carry
  isMobile=true (confirmed in TM-API's RegistrarServiceImpl)
- /stoptb/registrar/worklist, /stoptb/nurse/worklist — explicitly
  commented out in the app's network layer
- /stoptb/nurse/submit — no reference at all
- /stoptb/nurse/{generalExamination,tbScreening,generalOpd,diagnostics}/get
  (singular) — only the /getAll variants are used

Also removes the now-fully-orphaned StopTBRegistration entity/DTO/repo
(the registration table itself was already replaced by BenFlowStatus in
an earlier commit) and StopTBServiceImpl helper methods that only existed
to support the removed saveRegistration path.
findByBenRegIdFromMapping's return type was changed from a single object
to List<RMNCHMBeneficiarymapping> by an earlier Stop TB commit (fixing an
IncorrectResultSizeDataAccessException when a beneficiary has more than
one mapping row), but this caller was never updated to match — a
pre-existing oversight in the original commit, surfaced by the build check.
dynamic_form_schema.sql and alter_tb_screening_risk_factors_hiv_status.sql
are dropped from the codebase — the underlying DB schema changes they
describe are still required (documented in stoptb_schema_changes.sql),
they will just be run directly against the DB instead of being tracked
as files in this repo.
- getUserDetail: additive Nikshay TU/Facility fields via a new base-table
  query, bypassing the shared v_userservicerolemapping view entirely so
  other service lines' reads are provably unaffected.
- New NikshayLocationDerivationService: auto-derives a beneficiary's
  Nikshay TU/Facility/Village from their existing village (i_ben_flow_outreach),
  no new input needed from the mobile app.
- TBSuspected/StopTBDiagnostics: snapshot nikshayTUID/FacilityID/VillageID
  at save time, wired into both save paths.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Keep the Nikshay TU/Facility lookup in getUserDetail (user-level, both
old and new users handled gracefully) but remove the per-case snapshot
on TBSuspected/StopTBDiagnostics — not needed there. Deletes the now-
orphaned NikshayLocationDerivationService and NikshayVillageFacilityMapping
(entity + repo), which existed only to serve that snapshot.
NikshayTUID/NikshayFacilityID on m_userservicerolemapping are now TEXT
columns holding a comma-joined list of IDs per row. The old equality
join (nt.NikshayTUID = usrm.NikshayTUID) silently matched only the
first ID in the list, since MySQL casts "12,45" to 12 for numeric
comparison, and dropped the rest without erroring. Switch to
FIND_IN_SET so every ID in the list resolves to its name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
getDistrictByBlockId(userRole.getBlockId()) joins the raw BlockId
against m_districtblock/m_district - correct for other servicelines,
where BlockId genuinely is an AMRIT block ID. Stop TB's BlockId holds
the first selected Nikshay TU's ID instead, so this join resolves to
whatever AMRIT district happens to share that same numeric ID by
coincidence, not real data - feeding a wrong district into the mobile
app's login/session response for Stop TB workers.

Fetch the Nikshay scope first so Stop TB users can be detected and
skip the district-by-block patch entirely for them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Stop TB never sets WorkingLocationID, so workingDistrictId/Name (derived
from it, used by every other serviceline) always come back null - and
the earlier fallback (resolving district via BlockId) was correctly
disabled for Stop TB since BlockId holds a Nikshay TU ID, not a real
AMRIT block, and would resolve to a coincidentally-matching wrong
district.

DistrictID already sits directly on the mapping row for Stop TB (no
work-location indirection layer to go through), so getNikshayLocationScope
now also returns it, resolved via a join against Nikshay's own district
table (safe - same ID space, unlike AMRIT's m_district). getUserDetail
uses this to populate workingDistrictId/Name for Stop TB users directly,
instead of leaving them null. This is what the mobile app's own village
selection screen falls back to Block's name for, when District comes back
null - so this fixes that screen showing the wrong value too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b4664370-8b87-4b7e-84be-9c7ca1307d96

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

❤️ Share

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

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.

4 participants