Associating data with the correct encounter


Continuing the discussion from O3: What should be the UX of a non-provider user?:

@ibacher brought up some good points in the above thread that relate to something I’ve wanted to discuss around this topic but it fell off my radar, which relates to how we associate Orders (or any e Encounter data, really) with an appropriate Encounter if that data is not collected in a standard “form”.

It’s always felt like the wrong approach to me that the Order Entry application is configured with a certain Encounter Type, and will always create (or try to use) an Encounter of this type when it is used to place an Order. I don’t think this was ever really intended as “correct” behavior, rather my sense is that this was hacked in because Orders need an Encounter and there is no other standard mechanism for associating Orders with the “active” Encounter.

Does it make sense to add core API support for something like a current “EncounterContext” along with a current “VisitContext”, which would allow a Provider to start an Encounter for a Patient at a particular point in time, and then any subsequent Encounter-level data entered for that Provider for that Patient (until that EncounterContext is “closed” and/or a new “EncounterContext” is started, or other rules) would be associated with that Encounter?

If a Provider sees a Patient for their “NCD Initial” Encounter, and during the course of that Encounter the provider enters a bunch of data, don’t we want all of this data to be associated with a single Encounter of type “NCD Initial”, regardless of whether that data is collected on a questionnaire (form) or in an order basket widget? Right now it seems that the Encounters collected are based on what is convenient and easy to model in a UI with multiple, independently-designed components, rather than what is correct from a clinical interaction.

Thoughts - @ibacher / @burke ? Doesn’t Bahmni have some sort of mechanism to achieve this via a custom REST endpoint (encounterTransaction)? @mksd / @angshuonline ?

1 Like

Bahmni does have notion of Encounter/Visit context.

  • During a consultation (OPD/IPD) - there is just single encounter created, irrespective of what the practitioner entered. So, no diff encounter for obs and orders or diagnosis.
  • Unless specified Bahmni tries to detect the encounter type based on location and encounter type mapping we keep (e.g. maybe OP-1 is usually for GPs, and OP-2 is for Cardiology etc). We also recommend that implementations use generic ones - e.g. OP Consultation etc.
  • There are places where type is defined - e.g. registration creating encounter type REG, IP admission creating ADMISSION enc type.
  • You can always pass on the encounter type (thats what the REG and ADMISSION does).

Bahmni uses the encounterTransaction (a layer over EMR API) to resolve encounter type.

Bahmni also identifies existing encounter. It has a concept called “encounter session” which is defined in terms of practitioner+location+encounter-type+time-period. So when a POST to encounterTransaction API is called (without an encounter uuid), it tries to find an encounter matching the above session criteria - if not creates a new one. If the encounter is within the session, it will update/append the same encounter. The time-period is configurable - if you always want to create a new encounter, keep the period really short.

Yes, something like this or what @angshuonline outlined as Bahmni’s behaviour would be far better than what we’re doing right now. It would be ideal if OMRS Encounters actually corresponded to clinical encounters rather than “some point where we needed to save some data”.

I’d be interested in discussing this on a TAC at some point, as pursing something like this would have broad benefits but also broad implications.

1 Like

We discussed this on this week’s TAC call (@mseaton, @mogoodrich, @ibacher, @jwnasambu, and myself).

  • The vision for the OpenMRS Encounter is to represent a clinical encounter (a point-in-time interaction between patient & healthcare system) that may include any combination of form data, orders, notes, encounter diagnoses, problem list changes, allergy changes.
    • This means Encounters (and encounter types) should groups data into clinically relevant transactions (i.e., logical groupings that are useful/meaningful for clinical users reviewing the longitudinal record).
  • We’re devolving toward an approach where frontend apps are submitting their data to a new encounter, making application/technical groupings instead of clinically relevant groupings of data. For example, a provider seeing a patient in clinic, collecting some observations, writing a note, and writing some orders would expect all of these data to appear within a single encounter and not, for example, have orders placed in a separate encounter.
  • Currently, our API doesn’t help the frontend application determine whether it should associate data with an existing encounter or create a new encounter.
  • Per @angshuonline, Bahmni has tackled this problem by introducing its “Encounter session” as a mechanism to direct all data for the same provider+patient+location+encounter type within a configurable time period to the same encounter.

Next steps could be:

  • Develop a consensus on how we would like encounter assignment to work
  • Describe/document the vision/approach
  • Make sure our product owners (e.g., @grace, @dennis, etc.) are well informed & supportive
  • Make necessary changes to backend
  • Share with frontend developers to get new code created and existing code refactored to properly add data to encounters without having to invent arbitrary encounter types based on technical transaction.

In it’s simplest form this could be something like:


In reality, we will need to handle cases where the appropriate encounter is ambiguous and cannot be determined without user input and, because not all types of data are appropriate for all types of encounters, we should probably be working toward a future where the EMR is aware of an active/open encounter and prevents users from working within multiple encounters simultaneously within the same tab.

Perhaps this would be a good topic for a TAC call with broader participation?

@mseaton and I continued brainstorming this on this week’s TAC call. In general, we agree that OpenMRS would benefit from recognizing an “Encounter session”. Below are some rough notes from the conversation.

Encounter Session

  • An encounter session would be specific to user & patient.
  • The frontend could include an optional encounter within
  • Ideally, encounter session would be introduced in the Platform to centralize business logic, simplify frontend logic, and to allow it to evolve toward support for draft encounters.

Encounter Session API ideas

  • Create a new encounter session for patient.
    • This would include user, patient, and encounter type.
    • Might throw an exception if an encounter session already exists.
  • What encounter sessions exist for patient?
    • Optionally scoped to current user ± encounter type.
  • Close/delete encounter session
    • Allows a client to abort/cancel an encounter session.

What changes for an app/esm developer?

  • When creating data for an encounter (e.g., orders, obs, notes, etc.), an application would check for an active encounter session (e.g., within the application’s session context) and, if found, default to adding data to that encounter.
  • When storing data outside of an encounter session, first look for an existing encounter session and, if one doesn’t exist, create one.
  • Eventually, we’d like for apps to be able to query the backend for an encounter types appropriate for their features (e.g., which encounter types allow for orders? Or does a given encounter type support orders?).

Note: there are related conversations in the OpenMRS3 Slack channel.

1 Like

I’ve deleted my earlier post as I missed some of the earlier conversation which addressed some of my comments.

I still think there is an over-emphasis on how to store the data rather than how to get the data. There are multiple consumers of this data not only clinicians, i.e. M&E, managers, etc. I also think that it doesn’t fully account for the cases where a lot of infomration is collected by different users during the same episode of care. A common workflow for us would for an outreach worker, a nurse and a clinician and possibly a social worker to enter data. All of this collected data should be viewable across these user types.

I think the goal is to establish some way the api can help get all the “relevant” data that the user may be looking for. The devs behind frontend modules ideally wouldn’t be the ones having to come up with clever api calls to get the “right” data.

So some ideas:

  1. Leverage the use of visits to support “relating” data across encounters. It seem slike this was the original purpose of visits: anticipate that it may not be obvious temporally for when one encounter begins and ends, encourage the use of many encounters (but not too many) and build up a api that say, let’s you get all the conditions associated with a visit. It’s not clear to me how you enforce this but perhpas strict enforcement is not the right approach. I suspect that if we build out useful apis at the visit level, devs/implementers will start to use the visit following best practices.

2… Use the Bahmni approach above. I think this helps solve the problem of how to limit too many encounters from being created. I don’t think it should govern how we link relevant data across encounters, as it seems too strict to me and seems focused on the point-of-care user instead of other personas. However, it’s likely I don’t understand the full extent of the bahmni approach and it may be the exact right way of choosing how to “store” data. I would be interested to undersand better how it helps “get” the right data for different persona types.

  1. Create one encounter and try to use clever logic to figure out when it starts and ends and let that drive the “GET” apis. As I discuss above, I don’t really think this is the right way to approach linking data together. It could be one way of doing so but I think we should build out the api’s to make this easier as well.

Lastly, when it comes to create an API to get data, I think it’s better to have more than less. Changing the data model is something that requires a lot of consideration and should be done very carefully. I think adding on an api (or simply making it easier for users to come up with clever ways of efficiently and performantly getting) should have a lower barrier and it should be easier to get good ideas into core or at least some sort of module that is widely shared.


The goal isn’t just about how the data are stored, it’s how they are grouped into encounter and the fact that how they are grouped is directly related to how clients will get/see the data.

We are aiming for orders, observation, form data, notes, allergy & problem list changes, etc. organized within clinical instead of technical transactions – i.e., closer to the left than the right example (note, the idea is all the same data are being collected in both examples, the only difference is how those data are organized into encounters):

While Bahmni’s time-window approach to encounter sessions is a decent workaround for lack of explicit encounter sessions and could work as a short-term mitigation, inferring appropriate encounters by time will inappropriately group data in some cases (e.g., the same user completing two encounters back-to-back for the same patient ending up with those encounters merged) and inappropriate split data across encounters in other cases (e.g., data entered by a nurse and doctor placed in separate encounters instead of contributing to a single encounter).

Essentially everything related to the patient’s time is put under a single encounter. Does this mean we will deprecate visits? Also, how does this work in the inpatient setting - single encounter for the the entire admission? One useful thing about the multiple encounter approach was that it was relatively easy to get grouped data. I think we still will need to a lot of effort to make it easy to get the right data.

Also, another question occurred to me: are we removing form_id from the data encounter data model? In the above, presumably you can have multiple forms per encounter. Where does the form_id get stored ? a new table form_encounter_map?

The goal isn’t to group by time; rather, to group by clinical transaction. If you see a patient returning to your HIV clinic, ideally all the notes, orders, form data (observations), etc. you gather as you see them at that point in time would go into a single clinical encounter (instead of into separate Form, Notes, and Orders encounters).

For example, if the patient sees a dietitian while waiting on you in your clinic,

  • if your site decided to have dietary forms an optional part of return visit encounters, the dietitian would add to your same “Adult HIV Return” encounter.
  • if your site prefers to have “Dietary Encounter” as a distinct encounter type, the dietitian would create a separate encounter and any data generated by the dietitian would go into that separate encounter (even it took place concurrently).

We discussed the issue of associating data with the correct encounter on today’s OpenMRS 3 Product & Design Session. Here’s a recording for those interested:

The fundamental issue is that OpenMRS was originally used for data entry of encounters after they had happened, where all data for a clinical encounter was captured on paper and then transcribed into OpenMRS in a single transaction. As implementations evolved to more point of care (direct entry), workarounds have been made to coerce data into clinical transactions, but these have varied by application (e.g., Bahmni came up with the “encounter session” to direct all data generated by a single user for a single patient within a pre-defined time window into the same encounter). Now, in OpenMRS 3, we are running into this issue again, where separate parts of the application generating data (orders, forms, notes, etc.), for lack of being given an encounter context, are creating their own encounter (i.e., using encounters as technical transactions instead of the intended clinical transactions).

One step in the right direction would be to introduce an encounter context within the application a refactor modules to fetch the current encounter from this context before creating their own encounter.

But when/how does an encounter context get set? And how is the user informed of the encounter context?

We didn’t have time to answer these questions today. Here are some initial thoughts:

  • If the encounter context was introduced within the workspace (e.g., encounter type ± date when editing an existing encounter), then any work in the workspace would apply to that encounter. Any work (e.g., form, note, orders) would be associated with that encounter. Trying to change the encounter (e.g., edit data within a prior encounter) when there is unsaved work in the workspace would force the user to save or abandon their unfinished work before proceeding.

  • Eventually, we’d like to have support for draft encounters, where orders, observations/forms, and notes could be entered into the application and edited as needed until submitted (“signed”). An encounter context within the workspace would fit well into this model (i.e., all work in the workspace is “draft” until signed).

  • Ultimately, we could avoid confusing users with encounter selection if we flipped from the current approach of “create data (form, orders, notes, etc.) then figure out encounter type” to “choose an encounter type then create appropriate data for that encounter type.” If encounter types were enhanced to include which functions (e.g., orders, notes, forms, etc.) were required vs. optional and could be optionally associated with user roles or care context (inpatient vs. outpatient), then we could present a user with a set of encounter type-based actions to take for a patient (e.g., enter a return HIV encounter, write admission orders, write a consult note, etc.) tailored to the user & patient’s context and we could help users complete the steps needed for that workflow. For example, the system could know a note is required and orders optional when the user is completing a return HIV encounter and any of three forms can be completed and orders are not allowed when performing a case management encounter.