Skip to content

BAH-4917 | Add. Nurse Acknowledgement of Physician Instructions — backend changes - #341

Open
vvkpd wants to merge 6 commits into
Bahmni:masterfrom
cureinternational:BAH-4917-nurse-acknowledgement
Open

BAH-4917 | Add. Nurse Acknowledgement of Physician Instructions — backend changes#341
vvkpd wants to merge 6 commits into
Bahmni:masterfrom
cureinternational:BAH-4917-nurse-acknowledgement

Conversation

@vvkpd

@vvkpd vvkpd commented Aug 4, 2026

Copy link
Copy Markdown

Summary

Backend changes in bahmni-core required for the Nurse Acknowledgement of Physician Instructions workflow. This PR covers four stories:

  1. Batch Observations API (HIVE-105551) — new endpoint to fetch multiple observations in a single request, used to load care instructions in the IPD dashboard
  2. Previous UUID on Observations (HIVE-114116) — include the previous observation UUID in the response so the frontend can detect edited instructions and highlight them
  3. Surgery Order Creation and Linkage (HIVE-113267) — pre-save command that creates an order when an operative report form is saved and stamps the orderUuid on all care instruction observations in that form, enabling full traceability: Surgery → Order → Observation → Task
  4. Refactor Surgery Order to Pre-save (HIVE-107135) — replaces the post-save approach with a pre-save command; removes OT module compile dependency from bahmni-core (OT module now owns surgery order creation)

Changes

HIVE-105551 — Batch Observations API

  • New REST endpoint to fetch observations in batch by visit/encounter

HIVE-114116 — Previous UUID for Observations

  • BahmniObservation contract extended with previousObsUuid field
  • Allows frontend to track edits across observation versions

HIVE-113267 — Create Order and Link Tasks for Surgery

  • SurgeryOrderPostSaveCommandImpl: creates a Surgery/General order on operative report save
  • Links orderUuid to all care instruction observations in the same form submission
  • Surgery selection concept UUID configurable via global property bahmnicore.order.surgerySelectionConceptUuid
  • Groups observations by form using formFieldPath prefix to correctly scope order linkage per form

HIVE-107135 — Refactor to Pre-save Approach

  • Replaces SurgeryOrderPostSaveCommandImpl (post-save) with SurgeryObsOrderLinkPreSaveCommandImpl (pre-save)
  • Removes SurgeryObsOrderLinkDao — no longer needed
  • Removes operationtheater-api compile dependency from bahmni-emr-api
  • Removes require_module for operationtheater from config.xml
  • Removes Surgery/General Order type Liquibase changesets (moved to OT module)

Related PRs (CURE fork)

Testing

End-to-end linkage can be verified on DB:

SET @patient_uuid = 'enter-patient-uuid-here';

SELECT
    obs.uuid            AS obs_uuid,
    cn.name             AS obs_concept,
    o.uuid              AS order_uuid,
    ot.name             AS order_type,
    sa.uuid             AS surgical_appointment
FROM obs
    JOIN person pr      ON pr.person_id = obs.person_id AND pr.uuid = @patient_uuid
    LEFT JOIN orders o  ON o.order_id = obs.order_id AND o.voided = 0
    LEFT JOIN order_type ot ON ot.order_type_id = o.order_type_id
    LEFT JOIN surgical_appointment sa ON sa.order_id = o.order_id AND sa.voided = 0
    LEFT JOIN concept_name cn ON cn.concept_id = obs.concept_id
        AND cn.concept_name_type = 'FULLY_SPECIFIED' AND cn.voided = 0
WHERE obs.voided = 0
ORDER BY obs.date_created DESC
LIMIT 20;

Summary by CodeRabbit

  • New Features

    • Added batch retrieval of observations across multiple visits, with initial, latest, and default scopes.
    • Added optional filtering of observations associated with orders.
    • Automatically links surgery-related observations to their corresponding orders.
    • Preserves previous observation versions during processing.
    • Added support for storing and retrieving surgical appointment observations.
  • Documentation

    • Added a comprehensive contributor and development guide.

vvkpd and others added 4 commits August 4, 2026 16:25
* Vivek | added claude.md file

* Vivek | HIVE-105551 | Add batch observations API endpoint
… for obs (#37)

* Avni|Hive-114116| Updated bahmni observation to include previous uuid for obs

* Avni|Hive-114116| Remove cross encounter conditions
…ions (#36)

* HIVE-113267: Vivek: Create order and link tasks for surgery related instructions

- Add SurgeryOrderPostSaveCommandImpl: creates Surgery or General Order per encounter form submission, links obs via HQL bulk update, updates surgical_appointment.order_id
- Add SurgicalBlockObsHandler: handles Complex obs for Select Surgery concept
- Seed Surgery Order and General Order types via Liquibase
- Add operationtheater-api as provided dependency
- Declare operationtheater as required module in config.xml

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Fix order linkage correctness for multi-surgery and multi-form encounters

- Surgery Order lookup now keyed on surgicalAppointmentUuid via OT service (not encounter):
  same surgical appointment reuses its Surgery Order across multiple operative reports;
  different surgical appointments in the same encounter each get their own Surgery Order
- Category detection (Surgery vs General) reads from currentEncounter.getObs() with
  order IS NULL — avoids picking up Select Surgery obs from a previous form on the same encounter
- linkAllObsToOrder and linkUnlinkedObsToOrder both use AND o.order IS NULL to prevent
  overwriting obs already linked to a different order on the same encounter
- Remove dead code: findSurgicalAppointmentUuid(BahmniObservation) and isSelectSurgeryObs
- Add findExistingOrderForSurgicalAppointment using OT service for appointment-level lookup
- Tests updated and new scenario added: different surgical appointment on same encounter
  creates its own Surgery Order without reusing the existing one

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Address review comments on order creation and obs linkage

- Extract HQL obs-order linkage to SurgeryObsOrderLinkDao (bahmni-emr-api layer)
- Merge duplicate linkAllObsToOrder/linkUnlinkedObsToOrder into single assignOrderToUnlinkedObs
- Add null guard on concept and careSetting lookups in createOrder
- Remove unused ProviderService dependency
- Move operationtheater-api version to parent pom property
- Fix Liquibase UUID portability: replace UUID() with fixed literals
- Fix Liquibase changeset IDs to descriptive names
- Rename SUPPORTED_VIEWS to supportedViews in SurgicalBlockObsHandler

Open items pending tech lead discussion:
- require_module operationtheater in config.xml (cross-module integration decision)
- Wrong concept used for General Order (needs dedicated concept or config)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Make surgery selection concept configurable via global property

- Add global property bahmnicore.order.surgerySelectionConcept (default: Select Surgery)
  seeded via Liquibase — deployments with a different concept name can override via admin UI
- Replace hardcoded SELECT_SURGERY_CONCEPT_NAME with GP lookup in SurgeryOrderPostSaveCommandImpl
- Inject AdministrationService via constructor

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Use UUID GP for surgery selection concept with name fallback

- GP bahmnicore.order.surgerySelectionConceptUuid (UUID-based, locale-safe)
- Falls back to concept name lookup if GP not configured
- Seeding of GP held — to be done via cure-bahmni-emr when concept UUID is known
- Both Surgery and General Orders use same concept (Select Surgery) — acceptable
  since no concept class constraints on our order types (DB placeholder only)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Remove name fallback from getSurgerySelectionConcept

GP not configured → return null → order creation skipped gracefully.
Seeding of bahmnicore.order.surgerySelectionConceptUuid held — to be done
via cure-bahmni-emr once concept UUID is confirmed.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Setup GitHub Packages repository for openmrs-module-operationtheater in bahmni-core

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ve OT dependency from bahmni-core (#43)

* HIVE-113267: Vivek: Refactor surgery order to pre-save approach and remove OT dependency from bahmni-core

- Replace SurgeryOrderPostSaveCommandImpl (post-save, creates orders) with
  SurgeryObsOrderLinkPreSaveCommandImpl (pre-save, sets orderUuid on obs DTOs)
- Remove SurgeryObsOrderLinkDao and impl; no longer needed with pre-save approach
- Remove operationtheater-api compile dependency from bahmni-emr-api pom.xml
- Remove require_module for operationtheater from config.xml
- Remove Surgery Order and General Order type liquibase changesets (moved to OT module)
- Open point: filter only configured care instruction obs (pending tech lead discussion)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Stamp orderUuid per form using formFieldPath prefix grouping

- Group obs by form using formFieldPath prefix (e.g. "ENT Operative Report.1"
  from "ENT Operative Report.1/1-0") — formNamespace is always "Bahmni" for all
  forms so cannot be used for grouping
- Only obs in the same form as the Select Surgery obs get orderUuid stamped
- Non-surgical forms (no Select Surgery obs) remain unlinked
- Multiple operative forms in same encounter each get their own orderUuid

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Fix corrupted constant names in SurgeryObsOrderLinkPreSaveCommandImplTest

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* HIVE-113267: Vivek: Remove surgeryOrderPostSaveCommandImpl from Spring constructor-arg list

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 61eacf52-9ab9-4a90-8e23-ea5c378a411b

📥 Commits

Reviewing files that changed from the base of the PR and between 6fc2c3a and 07862b8.

📒 Files selected for processing (1)
  • bahmnicore-omod/src/main/resources/config.xml

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

Changes

Observation workflows

Layer / File(s) Summary
Previous-version observation mapping
bahmni-emr-api/src/main/java/.../contract/BahmniObservation.java, bahmni-emr-api/src/main/java/.../mapper/OMRSObsToBahmniObsMapper.java, bahmni-emr-api/src/test/java/.../mapper/OMRSObsToBahmniObsMapperTest.java
BahmniObservation stores previousVersionUuid. The mapper copies it from OpenMRS observations. Tests cover present and absent values.
Surgery order linking
bahmni-emr-api/src/main/java/.../command/impl/SurgeryObsOrderLinkPreSaveCommandImpl.java, bahmni-emr-api/src/test/java/.../command/impl/SurgeryObsOrderLinkPreSaveCommandImplTest.java, bahmnicore-omod/src/main/resources/config.xml
A pre-save command reads the configured surgery concept and links eligible observations and nested group members to selected surgery orders. Tests cover forms, existing links, voided observations, missing selections, and configuration.
Surgical block complex observation handling
bahmnicore-api/src/main/java/.../obs/handler/SurgicalBlockObsHandler.java, bahmnicore-api/src/main/resources/moduleApplicationContext.xml
The handler preserves surgical block values during save and reconstructs ComplexData during retrieval. Spring configuration registers the handler.
Batch observation retrieval
bahmnicore-omod/src/main/java/.../web/contract/*, bahmnicore-omod/src/main/java/.../web/v1_0/controller/display/controls/BahmniObservationsController.java, bahmnicore-omod/src/test/java/.../BahmniObservationsControllerTest.java
A POST /batch endpoint retrieves observations for multiple visits by scope and returns grouped responses. Tests cover ordering, scopes, defaults, and empty requests.

Repository guidance

Layer / File(s) Summary
Contributor guidance and formatting
CLAUDE.md, pom.xml
CLAUDE.md documents repository development workflows. The JaCoCo version line has trailing whitespace removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 07862

The PR is merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant BahmniObservationsController
  participant VisitService
  participant ObservationService
  Client->>BahmniObservationsController: POST /batch with visit UUIDs and scope
  BahmniObservationsController->>VisitService: resolve each visit
  BahmniObservationsController->>ObservationService: retrieve observations by scope
  ObservationService-->>BahmniObservationsController: observations
  BahmniObservationsController-->>Client: VisitObservationsResponse list
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 6 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the BAH-4917 workflow and states that the pull request adds backend changes. This matches the primary objective of supporting Nurse Acknowledgement of Physician Instructio…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title clearly identifies the BAH-4917 workflow and states that the pull request adds backend changes. This matches the primary objective of supporting Nurse Acknowledgement of Physician Instructions.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 6 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java (1)

7-8: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add Javadoc for the new public APIs.

  • bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java#L7-L8: Document request fields, default order filtering, and supported scopes.
  • bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/VisitObservationsResponse.java#L7-L8: Document response grouping and nullability expectations.
  • bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java#L88-L90: Document endpoint input, scope behavior, and response semantics.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java`
around lines 7 - 8, **Summary:** Add Javadoc to the new request, response, and
controller APIs. In
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java:7-8,
document the request fields, default order filtering, and supported scopes; in
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/VisitObservationsResponse.java:7-8,
document response grouping and nullability; and in
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java:88-90,
document endpoint inputs, scope behavior, and response semantics.

Source: Coding guidelines

bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/SurgicalBlockObsHandler.java (1)

12-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Javadoc to the public handler API.

Add Javadoc to SurgicalBlockObsHandler, saveObs, getObs, and getSupportedViews. Document the surgical appointment UUID format, save behavior, and supported views.

As per coding guidelines, public APIs in **/src/main/java/**/*.java require Javadoc.

Also applies to: 21-25, 28-39, 42-45

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/SurgicalBlockObsHandler.java`
around lines 12 - 13, Add Javadoc to the public class SurgicalBlockObsHandler
and its methods saveObs, getObs, and getSupportedViews. Document the surgical
appointment UUID format, save behavior, and the views supported by
getSupportedViews, following the project’s JavaDoc conventions without changing
implementation behavior.

Source: Coding guidelines

bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java (1)

445-452: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the new response property.

Add Javadoc that defines the predecessor relationship and the null behavior. The getter and fluent setter are public contract APIs.

Proposed Javadoc
+    /**
+     * Gets the UUID of the direct previous observation version.
+     *
+     * `@return` the previous version UUID, or {`@code` null} when no previous version exists
+     */
     public String getPreviousVersionUuid() {
         return previousVersionUuid;
     }

+    /**
+     * Sets the UUID of the direct previous observation version.
+     *
+     * `@param` previousVersionUuid the previous version UUID
+     * `@return` this observation
+     */
     public BahmniObservation setPreviousVersionUuid(String previousVersionUuid) {

As per coding guidelines, "Add Javadoc to public APIs."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java`
around lines 445 - 452, Add Javadoc to the public getPreviousVersionUuid()
getter and setPreviousVersionUuid(String) fluent setter, documenting that
previousVersionUuid identifies the predecessor observation version and is null
when no predecessor exists.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/SurgeryObsOrderLinkPreSaveCommandImpl.java`:
- Around line 49-53: Update groupObsByForm so observations whose extracted form
name is blank are not added to the grouped map, preventing unrelated unscoped
observations from sharing a list. Preserve grouping for nonblank form names, and
add a regression test covering a blank formFieldPath to verify orderUuid is not
propagated between unscoped observations.

In
`@bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java`:
- Around line 72-74: Move the previous-version UUID assignment out of
OMRSObsToBahmniObsMapper.map(...) and into ETObsToBahmniObsMapper so it runs for
every recursively mapped observation, including group members. Preserve the
existing UUID source from obs.getPreviousVersion().getUuid() and add coverage
for a nested observation with a previousVersion that verifies
previousVersionUuid is populated.

In `@CLAUDE.md`:
- Around line 193-195: Update the “Pull requests” guidance in CLAUDE.md to state
that pull requests are required for merging to CURE-Product-Master instead of
master, while preserving the existing branch naming guidance.

---

Nitpick comments:
In
`@bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java`:
- Around line 445-452: Add Javadoc to the public getPreviousVersionUuid() getter
and setPreviousVersionUuid(String) fluent setter, documenting that
previousVersionUuid identifies the predecessor observation version and is null
when no predecessor exists.

In
`@bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/SurgicalBlockObsHandler.java`:
- Around line 12-13: Add Javadoc to the public class SurgicalBlockObsHandler and
its methods saveObs, getObs, and getSupportedViews. Document the surgical
appointment UUID format, save behavior, and the views supported by
getSupportedViews, following the project’s JavaDoc conventions without changing
implementation behavior.

In
`@bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java`:
- Around line 7-8: **Summary:** Add Javadoc to the new request, response, and
controller APIs. In
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java:7-8,
document the request fields, default order filtering, and supported scopes; in
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/VisitObservationsResponse.java:7-8,
document response grouping and nullability; and in
bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java:88-90,
document endpoint inputs, scope behavior, and response semantics.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 85fcd758-d274-4f0b-adfd-a38d86a24d9d

📥 Commits

Reviewing files that changed from the base of the PR and between 90c3ed7 and ecdb1f2.

📒 Files selected for processing (13)
  • CLAUDE.md
  • bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/SurgeryObsOrderLinkPreSaveCommandImpl.java
  • bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java
  • bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java
  • bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/SurgeryObsOrderLinkPreSaveCommandImplTest.java
  • bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapperTest.java
  • bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/obs/handler/SurgicalBlockObsHandler.java
  • bahmnicore-api/src/main/resources/moduleApplicationContext.xml
  • bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/BahmniObservationsBatchRequest.java
  • bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/contract/VisitObservationsResponse.java
  • bahmnicore-omod/src/main/java/org/bahmni/module/bahmnicore/web/v1_0/controller/display/controls/BahmniObservationsController.java
  • bahmnicore-omod/src/test/java/org/bahmni/module/bahmnicore/web/v1_0/controller/BahmniObservationsControllerTest.java
  • pom.xml

Comment on lines +49 to +53
private Map<String, List<BahmniObservation>> groupObsByForm(Collection<BahmniObservation> observations) {
Map<String, List<BahmniObservation>> result = new LinkedHashMap<>();
for (BahmniObservation obs : observations) {
result.computeIfAbsent(extractFormName(obs.getFormFieldPath()), k -> new ArrayList<>()).add(obs);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not group observations with no form identity.

extractFormName returns "" for a blank formFieldPath. The map then combines every unscoped observation into one list. If one unscoped observation contains the surgery-selection value, the command stamps its orderUuid onto every other unscoped observation.

Skip blank form names, or use a key that cannot combine unrelated observations. Add a regression test with a blank formFieldPath.

Proposed fix
     private Map<String, List<BahmniObservation>> groupObsByForm(Collection<BahmniObservation> observations) {
         Map<String, List<BahmniObservation>> result = new LinkedHashMap<>();
         for (BahmniObservation obs : observations) {
-            result.computeIfAbsent(extractFormName(obs.getFormFieldPath()), k -> new ArrayList<>()).add(obs);
+            String formName = extractFormName(obs.getFormFieldPath());
+            if (StringUtils.isBlank(formName)) {
+                continue;
+            }
+            result.computeIfAbsent(formName, k -> new ArrayList<>()).add(obs);
         }
         return result;
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/command/impl/SurgeryObsOrderLinkPreSaveCommandImpl.java`
around lines 49 - 53, Update groupObsByForm so observations whose extracted form
name is blank are not added to the grouped map, preventing unrelated unscoped
observations from sharing a list. Preserve grouping for nonblank form names, and
add a regression test covering a blank formFieldPath to verify orderUuid is not
propagated between unscoped observations.

Comment on lines +72 to +74
if (obs.getPreviousVersion() != null) {
bahmniObservation.setPreviousVersionUuid(obs.getPreviousVersion().getUuid());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

et_mapper="$(fd -a '^ETObsToBahmniObsMapper\.java$' | head -n 1)"
test_file="bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapperTest.java"

test -n "$et_mapper"
ast-grep outline "$et_mapper" --items all
rg -n -C 6 \
  -e 'getGroupMembers' \
  -e 'setGroupMembers' \
  -e 'previousVersion' \
  -e 'setPreviousVersionUuid' \
  "$et_mapper" "$test_file"

Repository: Bahmni/bahmni-core

Length of output: 12504


🏁 Script executed:

#!/bin/bash
set -euo pipefail

omrs_mapper="bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java"
et_mapper="bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/ETObsToBahmniObsMapper.java"
contract="bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/contract/BahmniObservation.java"
test_file="bahmni-emr-api/src/test/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapperTest.java"

for f in "$omrs_mapper" "$et_mapper" "$contract" "$test_file"; do
  echo "===== ${f#$(pwd)/} ====="
  wc -l "$f"
done

echo "===== OMRS mapper relevant lines ====="
sed -n '1,120p' "$omrs_mapper" | cat -n

echo "===== ET mapper relevant lines ====="
sed -n '1,110p' "$et_mapper" | cat -n

echo "===== contract previous version / group members lines ====="
rg -n -C 4 'previousVersion|groupMembers|setPreviousVersionUuid' "$contract"

echo "===== tests relevant previous version group member lines ====="
rg -n -C 5 'previousVersion|getPreviousVersion|setPreviousVersionUuid|previousVersionUuid|parentObs|withGroupMembers' "$test_file"

echo "===== repository all references to previousVersionUuid in mapper source/contract/tests ====="
rg -n -C 3 'previousVersionUuid' bahmni-emr-api/src/main/java bahmni-emr-api/src/test/java

Repository: Bahmni/bahmni-core

Length of output: 24033


Propagate previous-version UUID for group-member observations.

OMRSObsToBahmniObsMapper.map(...) maps to ETObsToBahmniObsMapper recursively through group members, but previousVersionUuid is only set on the root BahmniObservation. A nested Obs with previousVersion therefore omits previousVersionUuid. Move this assignment into ETObsToBahmniObsMapper at each recursive mapping, and add a nested-observation coverage case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bahmni-emr-api/src/main/java/org/openmrs/module/bahmniemrapi/encountertransaction/mapper/OMRSObsToBahmniObsMapper.java`
around lines 72 - 74, Move the previous-version UUID assignment out of
OMRSObsToBahmniObsMapper.map(...) and into ETObsToBahmniObsMapper so it runs for
every recursively mapped observation, including group members. Preserve the
existing UUID source from obs.getPreviousVersion().getUuid() and add coverage
for a nested observation with a previousVersion that verifies
previousVersionUuid is populated.

Comment thread CLAUDE.md
Comment on lines +193 to +195
- **Main development branch**: `CURE-Product-Master`
- **Feature branches**: Named after Hive/JIRA tickets (e.g., `draft-form`, `Hive-106849`)
- **Pull requests**: Required for merging to master

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the exact main development branch name.

Line 9 identifies CURE-Product-Master as the main development branch. Line 195 refers to master. Replace master with CURE-Product-Master to prevent contributors from using the wrong merge target.

Based on learnings, pull requests are required for merging to CURE-Product-Master.

Proposed documentation fix
-- **Pull requests**: Required for merging to master
+- **Pull requests**: Required for merging to `CURE-Product-Master`
📝 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
- **Main development branch**: `CURE-Product-Master`
- **Feature branches**: Named after Hive/JIRA tickets (e.g., `draft-form`, `Hive-106849`)
- **Pull requests**: Required for merging to master
- **Main development branch**: `CURE-Product-Master`
- **Feature branches**: Named after Hive/JIRA tickets (e.g., `draft-form`, `Hive-106849`)
- **Pull requests**: Required for merging to `CURE-Product-Master`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` around lines 193 - 195, Update the “Pull requests” guidance in
CLAUDE.md to state that pull requests are required for merging to
CURE-Product-Master instead of master, while preserving the existing branch
naming guidance.

Source: Learnings

vvkpd and others added 2 commits August 4, 2026 17:14
SurgeryObsOrderLinkPreSaveCommandImpl implements EncounterDataPreSaveCommand
which does not extend BeanPostProcessor, so postProcessBeforeInitialization
and postProcessAfterInitialization cannot be annotated with @OverRide.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…obal property

Registers the GP key in config.xml so it appears in the admin UI and
is documented alongside the module. The value (concept UUID) is left
empty — implementers set it via the config repo by providing the UUID
of their 'Select Surgery' concept.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants