Repository navigation
Conversation
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>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
drtechie
approved these changes
Oct 29, 2026
drtechie
added a commit
that referenced
this pull request
Nov 2, 2026
* fix(user): append village ID into villageName so duplicate names are 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> * chore: bump version to 3.8.4 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * trace: add diagnostic logging to getBeneficiaryData for count-mismatch 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> * fix: order duplicate-row lookups in getBeneficiaryData so .get(0) is 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> * Revert "trace: add diagnostic logging to getBeneficiaryData for count-mismatch investigation" This reverts commit 911e2be. * Dropping duplicate columns in table tb_stoptb_general_examination * Adding migration applier and removing column migration file * feat: add four new columns to TB screening form * feat: add dynamic form migrator and contact tracing migration * feat: change the flw-api version to 3.9.1 * feat: update Stop TB service implementation * feat: add dynamic form migrator with new form version creation * feat: refactored code * feat: changed flw-api version to 3.12.0 * chore: bump pom version to 3.9.1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * feat: stop-584 dynamic form backward compatibility changes * fix(diagnostic): stop the poll scheduler from nulling vanSerialNo pollOnce saved a stale copy of the order loaded before createAndPushOrder's updateVanSerialNo() ran, writing vanSerialNo back to NULL. MMU sync keys tb_diagnostic_order by vanSerialNo, so those rows could never sync and the Stop TB sync group stayed partial. - refill vanSerialNo after the scheduler's save in pollOnce - mark vanSerialNo updatable=false on the diagnostic entities so entity saves can no longer overwrite it (updateVanSerialNo still sets it) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(diagnostic): stamp vanSerialNo right after the order is first saved Fill vanSerialNo before the (possibly slow) EMR Lite push instead of only after it, so a crash or restart mid-push can't leave the order without its sync key. Same value (= id); no change to status, push or response. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: stop-542 extra fields consumer changes * Revert "feat: stop-542 extra fields consumer changes" This reverts commit 50dc8ba. * feat: stop-542 extra fields consumer changes * feat(stoptb): save OPD prescription to standard tables and dispense stock Same endpoint stoptb/nurse/generalOpd/save. When the app sends the new fields (submissionId, chiefComplaints[], prescription.drugs[] with drugID and qtyPrescribed) the save writes t_benchiefcomplaint, t_prescription, t_prescribeddrug, t_patientissue and t_itemstockexit and reduces t_itemstockentry from the van's store, like TM and Inventory-API. One transaction: insufficient stock rejects the whole submit. submissionId makes retries safe. Old payload behaves as before. The configured stoptb.van.id is the source of truth; a different vanID from the app is rejected. Parking place and store are read from m_van. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(stoptb): close dispensing gaps found in review - Always use stoptb.van.id; a vanID sent by the app is ignored (logged). - Reduced batch gets Processed='N' so the new quantity uploads to central; removed chief complaints are re-sent the same way. - Batches with no expiry date are usable, as in v_drugforprescription. - Drug must be mapped to the store on its own service line, same join as the drug list, so the save accepts exactly what the list shows. - Patient name, age and gender filled on t_patientissue for the Inventory dispense screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): General OPD on AMRIT standard tables only - New payload (chiefComplaints[] / prescription.drugs[]) no longer writes tb_stoptb_general_opd; complaints, prescription and dispensing live only in t_benchiefcomplaint, t_prescription, t_prescribeddrug, t_patientissue, t_itemstockexit. - generalOpd/getAll reads the standard tables first and falls back to tb_stoptb_general_opd only for older visits that exist only there. Response fields and formats are unchanged for the app. - Old app payload keeps its current behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): calculate tablet/capsule quantity when the app sends none qtyPrescribed from the app is used as is. When it is missing, for tablets and capsules (MMU's prescription screen asks quantity only for other forms) it is doses per day x days from frequency and duration; Single/Stat dose = 1, Once in a Week = 1 per 7 days. SOS or other forms without a quantity are rejected. The calculated value is saved in t_prescribeddrug.QtyPrescribed and dispensed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(stoptb): OPD save validations from final review - chiefComplaintID is required for each chief complaint (getAll and reports identify standard-table records by it). - prescription.instruction is saved in t_prescription even when no drug is given, as MMU does for the visit instruction. - providerServiceMapID and createdBy give a clear error when missing instead of a database error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): default quantity 1 for non-tablet medicines when the app sends none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): getAll drugs list with form; SOS quantity default - generalOpd/getAll returns a "drugs" list per record (drugID, drugName, itemFormID, drugForm, dose, frequency, duration, durationUnit, qtyPrescribed, instructions) from t_prescribeddrug, so a saved prescription can be shown with form and quantity. Existing fields are unchanged; old free-text records return an empty list. - SOS tablets/capsules without a quantity: 1 per day of duration (1 when no duration) instead of rejecting the save. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * updated version to 3.9.2 * Removing gpsLatitude and gpsLongitude, and setting values into latitude and longitude * Adding locking for multiple order creation * Adding locking for multiple order creation * fix(stoptb): fill missing service line on the day's visit 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> * Adding locking for multiple order creation * fix(stoptb): MMU dose-based quantity; no batch re-upload after dispense - 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> * fix(stoptb): send the batch's new stock to central after an OPD dispense 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> * feat(stoptb): save OPD prescription to standard tables and dispense stock Same endpoint stoptb/nurse/generalOpd/save. When the app sends the new fields (submissionId, chiefComplaints[], prescription.drugs[] with drugID and qtyPrescribed) the save writes t_benchiefcomplaint, t_prescription, t_prescribeddrug, t_patientissue and t_itemstockexit and reduces t_itemstockentry from the van's store, like TM and Inventory-API. One transaction: insufficient stock rejects the whole submit. submissionId makes retries safe. Old payload behaves as before. The configured stoptb.van.id is the source of truth; a different vanID from the app is rejected. Parking place and store are read from m_van. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(stoptb): close dispensing gaps found in review - Always use stoptb.van.id; a vanID sent by the app is ignored (logged). - Reduced batch gets Processed='N' so the new quantity uploads to central; removed chief complaints are re-sent the same way. - Batches with no expiry date are usable, as in v_drugforprescription. - Drug must be mapped to the store on its own service line, same join as the drug list, so the save accepts exactly what the list shows. - Patient name, age and gender filled on t_patientissue for the Inventory dispense screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): General OPD on AMRIT standard tables only - New payload (chiefComplaints[] / prescription.drugs[]) no longer writes tb_stoptb_general_opd; complaints, prescription and dispensing live only in t_benchiefcomplaint, t_prescription, t_prescribeddrug, t_patientissue, t_itemstockexit. - generalOpd/getAll reads the standard tables first and falls back to tb_stoptb_general_opd only for older visits that exist only there. Response fields and formats are unchanged for the app. - Old app payload keeps its current behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): calculate tablet/capsule quantity when the app sends none qtyPrescribed from the app is used as is. When it is missing, for tablets and capsules (MMU's prescription screen asks quantity only for other forms) it is doses per day x days from frequency and duration; Single/Stat dose = 1, Once in a Week = 1 per 7 days. SOS or other forms without a quantity are rejected. The calculated value is saved in t_prescribeddrug.QtyPrescribed and dispensed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(stoptb): OPD save validations from final review - chiefComplaintID is required for each chief complaint (getAll and reports identify standard-table records by it). - prescription.instruction is saved in t_prescription even when no drug is given, as MMU does for the visit instruction. - providerServiceMapID and createdBy give a clear error when missing instead of a database error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): default quantity 1 for non-tablet medicines when the app sends none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(stoptb): getAll drugs list with form; SOS quantity default - generalOpd/getAll returns a "drugs" list per record (drugID, drugName, itemFormID, drugForm, dose, frequency, duration, durationUnit, qtyPrescribed, instructions) from t_prescribeddrug, so a saved prescription can be shown with form and quantity. Existing fields are unchanged; old free-text records return an empty list. - SOS tablets/capsules without a quantity: 1 per day of duration (1 when no duration) instead of rejecting the save. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Dropping duplicate columns in table tb_stoptb_general_examination * Adding migration applier and removing column migration file * feat: add dynamic form migrator and contact tracing migration * feat: change the flw-api version to 3.9.1 * feat: update Stop TB service implementation * feat: add dynamic form migrator with new form version creation * feat: refactored code * feat: changed flw-api version to 3.12.0 * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * Updated the device integration according to updated workflow * feat: stop-584 dynamic form backward compatibility changes * feat: stop-542 extra fields consumer changes * Revert "feat: stop-542 extra fields consumer changes" This reverts commit 50dc8ba. * feat: stop-542 extra fields consumer changes * fix(stoptb): fill missing service line on the day's visit 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> * Removing gpsLatitude and gpsLongitude, and setting values into latitude and longitude * Adding locking for multiple order creation * Adding locking for multiple order creation * fix(stoptb): MMU dose-based quantity; no batch re-upload after dispense - 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> * fix(stoptb): send the batch's new stock to central after an OPD dispense 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> * Changes for STOP-711 * Making changes for STOP-735 * feat(stoptb): /stoptb/sync/changes feed on the hub change log 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> * feat(stoptb): let the app choose which record types the changes feed returns Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(stoptb): treat t_prescription as a source of the OPD record 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> * fix(stoptb): bound beneficiaries per feed page and bind tokens to record 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> * docs(stoptb): the change log now comes from AMRIT-DB main migrations V132 / V32 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Efficency on Stoptbapp (#394) * 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> * fix(stoptb): never move the feed past a change whose transaction is still 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> * fix(diagnostics): polls that change nothing don't rewrite the order or 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> * feat(stoptb): send a beneficiary's older records when they come into 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> * feat(stoptb): changes feed only serves the user's own villages, all of 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> * fix(diagnostic): don't treat a failed result update as a lost race 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> * feat(stoptb): save OPD prescription without dispensing by default (#395) 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> --------- Co-authored-by: vishwab1 <vishwanath@navadhiti.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Co-authored-by: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Co-authored-by: chetansaroya <chetan.saroya@unthinkable.co> Co-authored-by: Mithun James <1007084+drtechie@users.noreply.github.com>
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.
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.
📋 Description
JIRA ID:
Please provide a summary of the change and the motivation behind it. Include relevant context and details.
✅ Type of Change
ℹ️ Additional Information
Please describe how the changes were tested, and include any relevant screenshots, logs, or other information that provides additional context.