Interesting. If there are three implementers (that we know of from this thread) all doing work-arounds to accomplish a similar use case, does that constitute the need to modify the EMR API as part of the core community efforts (edited because I was misunderstood here, sorry about that)?
@janflowers EMR API is a module, and it’s not a platform module
@mogoodrich, from the top of your head, is expanding EMR API in the direction of supporting concurrent active visits -if configured to do so- a reasonable development or a complete game changer for that module?
@janflowers, @jdick, @gschmidt, and @mksd, do we think that modeling this requirement out as multiple overlapping visits is the right way to model this, or is it what groups have chosen because it’s a workaround in lieu of a more correct design?
In terms of configuration and control, I would love for us to have some more formalized configuration constructs that allow us to represent valid combinations of Programs, Encounter Types, Forms, Patient Identifiers, Visit Types, Attributes, etc and to build workflows and UI/UX around these. We certainly have done this ourselves, though using older, hackier mechanisms. Still, I’m not sure that overlapping visits that contain a subset of encounters is the best model.
Some possible alternative ideas to consider with the existing data model:
- Store 1-N visit attributes on a single visit (eg. Reason For Visit), and check those to determine what types of encounters are allowed within that visit.
- Store 1-N observations on 1-N encounters within a single Visit (eg Reason for Visit). Check those observations to determine what can/should happen within that Visit.
I assume you don’t have this use case, but let’s say you have a Vitals encounter that is independent of program. You can’t have 1 encounter connected to 2 visits. So how do you represent that this Vitals encounter is part of both your HIV visit and your NCD visit? Even if this doesn’t happen today, is this plausibly something you’d want to support in the future (eg. in an Integrated Care Clinic?)
@mksd, I don’t know the answer but am curious to hear from @paul, @burke and @darius around their thoughts/recollection of whether validating was deliberately kept out of core and put in emrapi to keep this option open, or if there were other intents.
I’d have to look to refresh my memory in more detail, but, to clarify, I probably should have used different terminology… I don’t think that EMR-API necessarily enforces a single encounter, but if you use the methods it provides it ensures a single visit at one time. It’s the core apps module that expects a single visit at any one time, and, if perhaps you end up with multiple active visits it can end up stack trace if you try to open the visit dashboard… we’d need to identify the places where this occurs and fix this up… but there’s also is likely a question in some of these cases of what is exactly supposed to happen (from a UI perspective, among other things) if a patient has two active visits…
Take care, Mark
Clever, but not the intended use of these objects.
Yeah, I don’t know how you would prevent 1-to-many simultaneous visits within the data model. But the concepts of visit and encounter were initially an attempt to describe “real life” clinical settings. IE, a person can often times interact (have an encounter with) multiple health workers during a specific visit (contiguous period of time where a person goes to a location ).
So, at some level the data model has to be opinionated about such things… and this was the choice we made (and validated against HL7 v2’s conventions) when we built the data model back in 2004-2005.
This comment relates to this:
I’m just the old codger to this conversation, but when we conceived OpenMRS, we believed pretty strongly in conventions… ie, the data model was meant to support clinical care in as much detail as possible to avoid drift in how people stored data. In this thread, we’ve seen a couple of examples of that drift, which is kinda hard to totally avoid.
I wonder if we’ve lost sight of the definitions of the objects, or maybe not made it clear to implementers what the conventions were?
There’s lots of pages out there like this one that I think do a pretty good job of distinguishing visits from encounters. What role do we have as a community to help make those conventions known, and more importantly, what should we do to support cases where implementations become stuck once those conventions are misunderstood or broken?
That help you understand my perspective?
I always had the same mental model as Paul, that a visit was meant to represent a contiguous block of time that the patient is interacting with the care system, in a single physical or virtual location.
I would consider it invalid to have overlapping visits at the same location.
I did assume we’d someday have to support overlapping visits at distinct locations in the location hierarchy, if it happens that one OpenMRS database is storing data for multiple care providers. But these seem like corner cases.
- patient does a “phone visit” teleconsultation with an external doctor while they’re in the middle of a clinic visit
- patient is in a hospital visit, and they are taken to some independently-run and administered specialty clinic on the same campus (and for some political reason this doesn’t count as a discharge from the hospital).
IIRC the emrapi module supports having multiple visits as long as the locations of those visits are in distinct areas of the location hierarchy. (But it’s been years since I looked at that.)
But those examples are really supposed to be the 1% use case, not the common case.
For the described use case (cross-program care with a single real-life visit to the facility) I agree with Mike’s suggested approach, i.e. use visit attributes to indicate what care the patient is supposed to have. This can drive the UI too. Encounters will be the record of what actually happened.
So coming back to this conversation because it’s still unclear to me how to accomplish what the implementer needs to track. Here’s the story they are solving:
- patient comes into the clinic and is part of the program A. While the patient is there, they also go and see a provider in program B, and then afterwards, returns to a provider in program A.
Right now, from what I understand when using EMR API, you can start a visit for the patient as part of program A, but then you would have to end the visit and start a new visit for that patient to be seen in program B, and then end a start a new visit to go back to program A. That doesn’t seem correct since it technically is all the same visit - but just across service areas. Instead: We’d like to be able to have a visit, and encounters for the programs they are involved in during that visit.
Is the only way to accomplish that to do the start/end visit pathway - and run up 3 visits instead of the actual single visit they do? Or is this the same story other implementers are trying to accomplish with these workarounds you all have wrote out here? If it’s the same or similar - shouldn’t we look at what @mseaton suggested and find a better design that allows some configuration? @paul since this is actually an enforcement from EMR API, does this still fit the data model that was selected or is this too far of ‘creative use’ like you mentioned to @gschmidt?
@janflowers EMR-API enforces that a patient has one active visit at one time, but it does not enforce that there is a one-to-one mapping between programs and visits… I believe that some implementations have standardized a one-to-one mapping between programs and visit types and use visit types to control what forms are available, so if a patient is seen for multiple programs within a single actual “visit” they would need to create two or more visits… but that it nothing that is enforced (or implemented) in the core Ref App modules.
Take care, Mark
So are you saying that because the program and visit type is mapped, that they must end the visit and start a new one to change programs? Is this something in the EMR API that is enforced? Or is this something custom configured/created?
@janflowers I think we should attempt to not have multiple concurrent visits and rather achieve what @mseaton suggested above: multiple concurrent encounters within the same visit (one per program, perhaps also some that are transverse… etc).
Something custom configured/created… there’s no relationship between programs and visits in EMR-API or Core (as far as I can remember).
What @mksd says is what we do at PIH… a patient might have an HIV encounter and an NCD encounter within a single visit. Encounters have a single point-in-time and there can be as many as you want within a visit.
Take care, Mark
I totally agree, but wasn’t sure we could accomplish that with the use of EMR-API. You would know better than I would on that front…?
Yes, this is not a limitation of the EMR API module, it must be custom code for that implementation.
If someone is locked into having program:visit mappings, then one possible workaround would be to configure the location hierarchy such that there are parallel visit locations for different programs. E.g.
Hospital X / \ HIV Program TB Program Locations* Locations* * = tagged as Visit Location /|\ /|\ HIV Rooms TB Rooms
This is obviously hacky, and would require two visits (one for HIV one for TB), but that’s unavoidable if someone is locked into using visit types to control program-specific UIs. The visits would be allowed to overlap in time because neither visit location has the other as an ancestor. (At least, if I remember the code correctly. There’s also a chance that EMR API allows this, but Core Apps breaks, but that would be a quick and desired fix.)
Exactly. (Also, fwiw, Encounters are at point in time, with a single encounter_datetime, so thinking of encounters as concurrent isn’t exactly correct… though you can have as many encounters as you want with the same encounter_datetime)
I would hope that this could be avoided…
Take care, Mark
Can you model it as follows?
Hospital X | Visit / \ HIV Program TB Program / | \ / | \ Encounters Encounters
If this is possible, can the encounter be automatically assigned to the correct program based on either the form that is used or the location of the encounter? The real goal here is to be able to have analysis of care given under each program, even though a patient may utilize care from multiple programs during a single visit.
@mksd I’m not sure if a patient would ever have multiple concurrent encounters unless they were doing telemedicine or remote monitoring in some way? At least not physically. So we should be able to do a single visit with multiple encounters. The question here would be how to tie it to the appropriate program since my understanding from the dialogue across the thread above is that Visit is hierarchically underneath Programs.
Yes this is will not happen, I also forgot that an encounter was not recording its own duration. As Mark said:
Encounters have a single point-in-time
There will be multiple encounters happening during the same visit, some associated to a program, some to another program, some to no programs at all.
That’s what we want to achieve, certainly. The entity patient-program has a location member (see here), but that doesn’t mean that every encounter that occurred at that location belongs to that program though…
I don’t know how we know that the data recorded during a given encounter is associated to a program or another, or none. One could argue to look at the patient, and see in which program he/she was enrolled at the datetime of the encounter, but again, a patient might be enrolled in multiple programs at the same time…
@janflowers taking a step back, it’s hard to answer your question because I’m assuming that the implementer has some (self-inflicted) constraint that is limiting them, and I assume it’s that they are using Visit Type to drive a program-based UI. In that speculative scenario I suggested a hacky workaround which would allow them to record 2 visits instead of 3 (for what’s really 1 visit).
But none of these limitations come from the shared OpenMRS model, and in the EMR API module. They both allow you to record what you’re trying to record in a straightforward way, i.e. you have a visit, and it can include both an HIV followup encounter and a Diabetes followup encounter.
In the OpenMRS data model (and in EMR API) visits and encounters are not linked to a Programs. Often an encounter type would be named to be part of a program, and someone might write their reports as if it belongs, but that’s outside the OpenMRS data model. Likewise someone might write a custom UI that ties a Visit Type to forms/screen for a particular program. But again, that would be in their custom code, not in OpenMRS core or EMR API.
As far as OpenMRS goes, sort of. You can have a Visit a the Hospital level, and you can have encounters from 2 programs in it. But “HIV Program” and “TB Program” are not actually part of the same logical hierarchy, so OpenMRS wouldn’t represent those nodes.
Whether or not EMR API currently supports it, Visits can definitely overlap. For example, a stable hospitalized patient may be taken to an outpatient clinic during their hospitalization to avoid missing an outpatient appointment, resulting in an outpatient visit coincident with an inpatient visit. Also, visit boundaries can be fuzzy (e.g., steps to close the visit may be deferred until the end of the day). Patients traveling a long way to a clinic may very likely arrange multiple visits on the same day for convenience and we cannot guarantee each preceding visit will be closed before the next begins. I think it would be fair to say two visits for the same type of visit in the same care setting would not overlap.
As far as automatically assigning encounter to visits, our intent was to support this auto-assignment in a manner that could be adapted to meet local needs, since the logic for automatically assigning encounters to a visit is not universal. Ideally, this algorithm would be isolated (not spread throughout multiple parts of the codebase) and would respond with an array of possible visits – i.e., in the happy path, you’d get back one visit, but if the algorithm lacked the information to decide between 2 or more open visits, it could handle the ambiguity by passing the list of candidates and forcing the client to pick amongst them.
OpenMRS Visit-Encounter Model
For OpenMRS, we came up with this model:
Encounter is an interaction between patient and healthcare system at a point in time.
Visit represents an event that can include one or more encounters and occurs over a span of time. Typically, an outpatient clinic visit or an inpatient hospitalization.
Episode of Care is a collection of encounters and/or visits that belong to a logical grouping and may span across visits. This could be all visits/encounters relating to a pregnancy or a course of TB treatment.
Program was created to represent a care program (like HIV Treatment Program or TB Treatment Program) or a study protocol. It might seem similar to an Episode of Care; however, there are distinct differences: patient are enrolled in a Program, may have a program-specific identifiers, go through states of a program, etc. Episode of Care is just a logical grouping that does not involve enrollments or states. If we had implemented Episodes of Care, they would have likely linked either to a condition or program as the “topic” for the episode of care. As it stands, if/when we want to implements Episodes of Care, we’ll be better off aligning with FHIR’s
|Episode of Care||EpisodeOfCare|