Repository navigation
Merge to main release 3.12.0 - #397
Merged
Merged
Conversation
…distinguishable Two different villages can legitimately share the same name (confirmed live: Nikshay village IDs 275135 and 275136 are both named "Sanapindapadar", under two different facilities in Boriguma block, Koraput). The mobile app's post-login village dropdown displays only villageName, so a user has no way to tell which entry is which - selecting the wrong one loads zero HH records for that village, since worklists filter by villageID, not by name. getUserDetail now appends the ID into each name segment, e.g. "Sanapindapadar,Sanapindapadar" + "275135,275136" becomes "Sanapindapadar (275135),Sanapindapadar (275136)". villageId and the response shape (two parallel comma-separated strings) are unchanged. Verified this requires zero mobile app changes: the village dropdown (ServiceLocationViewModel -> BindingUtils.setSpinnerItems) is a plain ArrayAdapter that displays villageName verbatim, and selection is by array position + villageId, not by matching name text. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Duplicate village fix
…h investigation Adds temporary [TRACE getBeneficiaryData] log lines to trace which caller/device is hitting the Stop TB worklist endpoint, how many pages/rows it gets back, and the household/non-household split actually sent to the client per call: - Controller: log real caller username (from JWT) + providerServiceMapID/ villageID/pageNo per request, instead of the previous useless default toString() of the request DTO. - Service: log totalCount/totalPage/addressIds per Stop TB page fetch. - Service: warn when getByAddressID() or getDetailsByRegID() return more than one row for a single address/beneficiary (both do .get(0) with no ORDER BY) — logs the distinct houseoldId values seen among duplicates, to confirm whether duplicate detail rows actually carry conflicting household links in production (not reproduced on the .198 demo DB, where duplicates found were exact clones with identical houseoldId). - Service: log a per-call summary of household-linked vs non-household counts in the response, for direct comparison against what each device's Home screen shows. Intended to be deployed to UAT StopTB and removed once the root cause of Nurse vs Registrar count mismatches (Achuthapuram, village 5821) is confirmed from real traffic. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…deterministic and correct BenAddressId (i_beneficiarymapping.getByAddressID) and BenRegId (i_beneficiarydetails_rmnch.getDetailsByRegID) can both have more than one matching row, but the queries had no ORDER BY and the calling code in BeneficiaryServiceImpl just takes .get(0) — whichever row MySQL happened to return first, not necessarily the correct one. Confirmed live against the UAT StopTB database (Achuthapuram, village 5821): 36+ address IDs are shared between an old test-account registration and a real one, and some beneficiaries have duplicate detail rows where only the newer one has the household link recorded. Picking an arbitrary row instead of the latest one is why the Nurse and Registrar apps showed different Household/Non-Household counts for the same village. - getByAddressID: ORDER BY benMapId DESC, same "latest wins" convention already used in findByBenRegIdFromMapping (a5e5734). - getDetailsByRegID: ORDER BY beneficiaryDetails_RmnchId DESC. Verified locally against the real UAT DB: household/non-household split now matches the true numbers (computed from i_ben_flow_outreach, the actual source getBeneficiaryData's village worklist is built from) within a 1-record margin from an unrelated, pre-existing "mapping not available" skip. Does not touch the underlying duplicate rows themselves — those still need a data cleanup decision (which record to keep) separately from this code fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-mismatch investigation" This reverts commit 911e2be.
fix: order duplicate-row lookups in getBeneficiaryData
…elds feat: add four new columns to TB screening form
… feature/delete-duplicate-columns-general-examination
…lumns-general-examination Feature/delete duplicate columns general examination
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore: bump pom version to 3.9.1
…updated-device-intgeration Feature/workflow updated device intgeration
…updated-device-intgeration Feature/workflow updated device intgeration
TB suspected / confirmed / diagnostic saves create the visit with ProviderServiceMapID null. When one of them syncs before TB screening or OPD, the visit keeps null and getAll (filters by psm) skips it. A later save that has a service line now fills it in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Quantity for tablets uses the dose like MMU (Half Tab 0.5, One Tab 1, One & Half Tab 1.5, Two Tabs 2 per intake), rounded up. No dose sent = one tablet, so today's results are unchanged. - Dispense no longer marks the stock batch Processed='N'. Central gets the stock-out rows (standard MMU); re-sending a batch could insert a duplicate batch on central. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dispensed batch is marked Processed='N' again so the next upload updates central's copy (matched by VanSerialNo + store, now kept by central MMU-API). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…TOP-710 # Conflicts: # src/main/java/com/iemr/flw/service/impl/DiagnosticOrderServiceImpl.java # src/main/java/com/iemr/flw/service/impl/DiagnosticPollSchedulerService.java
Feature/stop 710
…tegration-updatd-workflow Making changes for STOP-735
One endpoint replaces the 15+ getAll calls a STOP-TB pull makes. With no token it pages
through everything in the requested villages (keyset, type by type, beneficiaries first);
after that it returns only records with t_sync_change_log lines after the tablet's token,
in their current state, deduplicated, with deletes. Tokens carry the hub's server_uuid,
so a token from another hub or older than the log's retention starts a fresh snapshot.
Records keep the exact JSON each existing endpoint returns, via by-id variants of the
existing builders (beneficiary, screening, examination, OPD, diagnostics, suspected,
confirmed, form responses, diagnostic orders), so the app reuses its parsers.
The feed is served only where the change log exists and every source table has its
triggers (checked on the hub); elsewhere it answers {supported:false} and the app keeps
the full pull. StopTBSyncCoverageTest fails when a mapped table is neither synced nor
listed as deliberately not synced.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The OPD record's notes come from the visit's latest t_prescription instruction. A remarks-only save writes only that table, so without it in the list the change log missed the edit and tablets kept the old note. Paired with the t_prescription trigger in the AMRIT-DB hub migration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ord types - A page carries at most 25 beneficiary records. Each costs several identity lookups and a FHIR call, so 200-500 per page could outlast the tablet's HTTP timeout. In a snapshot the token resumes after the last one sent; in a delta the row list stops before the one over the cap and the token resumes from the last row kept, so nothing is skipped. - Tokens carry the set of record types they were issued for. A request for a different set starts a new snapshot instead of missing the newly requested types' existing records. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…V132 / V32 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* perf(worklist): batch per-page lookups in getBeneficiaryData Load mapping, details, account, image, address, contact, beneficiary ID, rmnch, born-birth, household, flow, anthropometry, vitals and user lookups once per page instead of once per beneficiary. Read ABHA from m_benhealthidmapping/t_healthid directly instead of calling FHIR-API per beneficiary. Falls back to the existing per-row queries if the batch load fails or a single-result lookup finds more than one row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(worklist): page size 50 and per-page timing log door-to-door-page-size 10 -> 50 so a village pull needs 5x fewer requests. Log one [WORKLIST-TIMING] line per Stop TB village worklist page with the time spent in count, ids, address, prefetch, build and JSON. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(worklist): index-only count and page query; per-request timing log Count village flow rows without the mapping join, and page with a deferred join so OFFSET skips on idx_flow_psm_village_reg only and just the page's rows are joined to the mapping. Ties on registrationDate are ordered by ben_flow_id so a page boundary cannot skip or repeat a beneficiary. An in-range page with no mapped rows returns an empty page instead of "No record found". Add ApiTimingFilter: one [API-TIMING] line per request with method, path, status and time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(stoptb): faster TB suspected and Stop TB getAll responses TB suspected getAll looked up the full user detail (role + facility queries) for every confirmed row only to read the state for the incentive check; look it up once per user. The incentive rules and calls are unchanged. Stop TB general exam, screening, OPD and diagnostics getAll built the JSON text, parsed it back and wrote it again; build the tree once via OutputResponse.setResponse(JsonElement). Load those rows read-only. Responses are byte-identical to before (Stop TB getAlls and the FLW app worklist/suspected paths compared on the 3307 test DB). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(stoptb): one-query diagnostic status summary; leaner suspected and OPD lists Diagnostic status summary read each beneficiary's latest order five times, once per status bucket; read beneficiaryId + status once and bucket in Java with the same status groups (case-insensitive, like the database comparison). Bucket contents are unchanged; order inside a bucket was never fixed by the query. TB suspected getAll copies the DTO fields directly instead of ModelMapper per row, and its village subquery hints idx_flow_psm_village_reg (MySQL ignores the hint where that index is absent). Standard OPD records for a village start from the village's beneficiaries instead of every visit of the PSM; the same visits match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(stoptb): keep TB suspected speed-up on the Stop TB village path only Restore IncentiveLogicService/IncentiveLogicImpl to their original code and run the FLW (ashaId) path of TB suspected getAll exactly as before. The Stop TB village path reads each user's state once and calls the unchanged incentiveForTbSuspected only for CG users, the only state where it acts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(worklist): restore original village count and page queries The index-only count also counted flow rows that have no i_beneficiarymapping row (423 on the reference DB, mostly PSM 1725), so villages with such rows got extra or empty pages and a fully unmapped village got an empty success instead of "No record found". Put countVillageWorklist, getVillageWorklistAddressIds and the empty-page handling back to the release-3.12.0 behaviour. The batch loader, page size and timing logs stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…till open The safe point was the newest log line older than 5 s. seq is taken at insert, not at commit, so a transaction open longer than that could commit a lower seq after the feed had moved past it, and tablets would miss the change. The safe point is now below the oldest open transaction (information_schema.innodb_trx), minus the same 5 s margin; without the PROCESS privilege it falls back to the fixed lag and logs a warning once. Reproduced on MySQL 8.0: with A open holding seq 5 and B committed at seq 6, the old rule returned 6 (skipping 5); the new one returns 0 until A commits, then 6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r result Every pending order was saved on every poll (every ~35 s): processed reset to 'N' so MMU re-uploaded it, and the change-log trigger re-sent it to every tablet. Now, when the vendor reports the same status, error, provider order id and result fields, only last_polled_at (and the retry count) is updated; a repeated poll error is recorded the same way. Real changes are saved as before. Pairs with AMRIT-DB V134 (PSMRI/AMRIT-DB#227). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…scope AMRIT-DB V134 logs flow-table scope changes (new flow row, village / service / deleted change) with op 'S'. When a delta page has such a line for a beneficiary, the feed now also sends that beneficiary's existing records of every requested type: they were logged before the beneficiary was in the tablet's villages, so they never passed the scope check and the token had already moved past them. Each type's query for this is derived from its snapshot query (village scope swapped for the given BenRegIds, paging dropped); StopTBSyncTypeTest checks every one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f them by default - The feed reads the user from the JwtToken header (required) and their services and villages from every active m_userservicerolemapping row. A service or village the user isn't mapped to is rejected; no villageIds means all of the user's villages for that service. Cached 5 minutes per user. - Tokens carry a hash of the service and village list, so a different scope starts a new snapshot instead of continuing from another scope's position. - getUserDetail no longer takes whichever mapping row came first: it uses the STOP-TB (Nikshay) row when there is one, merges villages across all rows for that service, and fails clearly when the user has no mapping instead of IndexOutOfBounds. UserSyncScopeTest covers merging, defaults and rejection; SyncTokenTest the new token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
processResult caught every DataIntegrityViolationException on the result save as a lost insert race and went on to mark the order COMPLETED. When the save of an existing result failed (V134 trigger NULL row_pk), the order completed with its result still PENDING. Only a first insert can race; rethrow otherwise so the order is left as it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inventory is not part of this release, so the Stop TB OPD save no longer checks the camp store or stock, writes no patient issue and leaves stock unchanged. Drugs from the app's own list are saved as sent (DrugID, name, form, frequency, duration, instructions); quantity is worked out when the app sends 0. A new save for the visit replaces its earlier prescription, so an edit or retry leaves one copy. The existing dispensing path is kept behind stoptb.dispense.enabled (default false, no config needed) for the release that brings inventory. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
feat(stoptb): /stoptb/sync/changes feed on the hub change log
Merging releae-3.12.0 to main
…-3.12.0 # Conflicts: # pom.xml # src/main/environment/common_example.properties # src/main/java/com/iemr/flw/domain/identity/RMNCHBeneficiaryDetailsRmnch.java # src/main/java/com/iemr/flw/domain/iemr/TBScreening.java # src/main/java/com/iemr/flw/repo/iemr/UserServiceRoleRepo.java # src/main/java/com/iemr/flw/service/TBConfirmedCaseService.java # src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java # src/main/java/com/iemr/flw/service/impl/DiagnosticOrderServiceImpl.java # src/main/java/com/iemr/flw/service/impl/TBConfirmedCaseServiceImpl.java # src/main/java/com/iemr/flw/service/impl/UserServiceImpl.java
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
drtechie
approved these changes
Nov 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merging 3.12.0 branch into main branch