Seeking Community Input: Multi-Facilities Server Instances

In this talk post and in the squad call last week, we discussed multi-facilities server instances, ex: one OpenMRS server used by multiple hospitals that are operationally independent from each other. The way we model the the location hierarchy might look like this (Location tags are in parentheses):

Hospital A (Visit Location)
|- Inpatient Department A (Queue Location)
  |- Ward A1 (Login Location) 
  |- Ward A2 (Login Location)
|- Outpatient Department A (Queue Location)
|- Triage A (Login Location)
|- Pharmacy A (Login Location)

Hospital B (Visit Location)
|- Inpatient Department B (Queue Location)
  |- Ward B1 (Login Location)
  |- Ward B2 (Login Location)
|- Outpatient Department B (Queue Location)
|- Triage B (Login Location)
|- Pharmacy B (Login Location)

Some distributions, like the Refapp (populated with the default data in dev3 / test3) and PIH, use the Visit Location tag to denote such “top-level” locations. When a user logs into a Login Location under Hospital A (ex: Triage A), they should only see data (for patients, visits, prescriptions, queues, appointments, etc…) that are created within Hospital A (i.e. either Hospital A or its sub-locations). Currently, this is done / considered in an ad-hoc, non-standard manner in some apps:

  • In the dispensing app, we have a search bar for prescriptions. In a multi-facilities server, we can configure locationBehavior.restrictToVisitLocationDescendants to true, do make the search bar only return prescriptions made in a sub-location of the login session location’s closet ancestor location tagged as Visit Location. For example, if the user is logged into Triage A, the closest ancestor location that is tagged as Visit Location is Hospital A, and the user can search for prescriptions made in all locations under Hospital A.
  • In the Service Queues app, a similar pattern is being proposed (also enabled via config) . When the user is logged into a Login Location under Hospital A, the app’s Location dropdown filter should only show Queue Locations under Hospital A, and should only see queue entries that are made under Hospital A.

Some open questions for the community:

  • Should we standardize on having a top-level location tag, so that when a user logs in to a location under a top-level location, they can only see data under that top-level Location?
    • Should we standardize on calling this top-level location tag Visit Location? If not, we can allow this tag to be configurable.
  • Are there any other solutions the community has come up with that solves the multi-facilities pattern differently?
  • If we do standardize on having a top-level location tag, should we standardize this “only see data within a top-level location” behavior across all apps as default, and eliminate configurations like locationBehavior.restrictToVisitLocationDescendants within the dispensing app?

cc @PIH, @METS, @ibacher , @dennis , @slubwama, @ujjawalprabhat, (feel free to cc additional people)

1 Like

One approach comes from the system developed by Regenstrief, which was the original model that OpenMRS was based on. In that design, a patient is not treated as a 1:1 representation of a person. Instead, the patient table includes an organization reference, and each patient record represents a person’s registration within a specific organization.

As a result, a single person can have one or more entries in the patient table—one for each organization where they are registered. The system then presents data from all organizations visible to the current user as a single, unified patient record.

This approach is arguably more robust because it explicitly models organizational membership. However, adopting it in OpenMRS would require significant changes because the codebase has long assumed a 1:1 relationship between person and patient.

Thanks @chibongho !

And thanks @burke … I don’t think I ever knew that history, but, yeah, I feel like that ship has sailed (having two patient records for the same actual person in the system) long ago… :slight_smile:

Also, in our case, it’s not different organizations. It’s different facilities within the PIH “network”.

I think the pattern @chibongho lays out above makes sense, albeit I’m thinking of it more about a way to organize patient data rather than strictly restrict access to patient data (though I realize that we at PIH may need the strictly all “restrict access” in the not-so-distant further).

For instance, in the examples above a Pharmacist at Facility A really only cares about orders coming into to their facility, and a clinician at Facility B really only cares about service queues at their facility. (But when digging down into the record of one of the patients the are serving they’d likely want all clinical data for that patient across facilities).

So to answer some of the specific questions:

  • We went with “Visit Location”, but in hindsight, something like “Facility Location” might be clearer–so maybe make this configurable
  • I think we could have a standard about “only see data within a top level location” but I don’t know if it’s necessary and we’d need to careful about it, because, in my option, this isn’t about strictly restriction clinical data based on facility but more about in certain views not showing data that is less irrelevant to user (ie the ED Queue at Hospital B is not something that a doctor in Hospital A wants/needs in their primary workflow, like a Pharmacist at Hospital A does not need to see a list of orders pending at Hospital B)

Hope that makes some sense!

Take care,

Mark