-
Notifications
You must be signed in to change notification settings - Fork 36
System Overview
The Buendia application software consists of these components, described in detail in later sections:
- OpenMRS server: an open-source medical records system that is designed for extensibility, data uniformity, and ease of data collection
- Buendia server module: an OpenMRS module used to provide a custom REST interface to OpenMRS data
- Buendia Android client: Android application for recording and viewing patient records
There may be more than one client, but there should be only one server. Clients communicate with the Buendia module via REST API calls (see the Buendia REST API Spec for details).
OpenMRS is an open-source medical record system written in Java. It is designed to be modular, allowing developers to deploy and manage "modules" that add additional functionality. It runs in a Java servlet container (this project uses Tomcat) and stores its data in a relational database (this project uses MySQL).
In the database, there is a SQL table for patients, a table for providers (i.e. clinicians), and so on. The schema is quite complex, with about 100 tables; however, the patient health data, of all different types, is primarily kept one big table of observations. For example, the fact that a particular patient's temperature was 37.3 degrees C at 10:00 am would be stored as an observation with temperature as the concept, 37.3 as the value, and 10:00 am as the timestamp.
All concepts are numerically coded and generally come from a standard concept dictionary (for example, MVP/CIEL, which is the basis of the Buendia concept dictionary). In MVP/CIEL, the concept patient's temperature in degrees Celsius is represented by the code 5088, which would be consistent across all systems using MVP/CIEL even if the word "temperature" is displayed in different ways or different languages. Each concept has a unique id (UUID), a datatype (for temperature, the datatype is "numeric"), and can have relationships to other concepts (e.g. "nosebleed" might be a specialization of a "bleeding" concept).
Using OpenMRS means that Buendia is built on top of a community standard and provides the benefits of standard concept dictionaries, extensibility, and built-in ODK integration for ease of data entry.
This project avoids modifications to the OpenMRS core code; instead, all the necessary custom functionality is provided by the Buendia server module, a few new concepts in the database (some of which have been incorporated back into the standard MVP/CIEL dictionary), and special cases for certain forms.
OpenMRS allows you to define a collection of forms for entering patient data; each form is made of fields that are associated with concepts, and the fields can be grouped into sections. For example, a form could contain a numeric entry field for the patient's temperature. There is an existing XForms module that can emit form definitions in XForm format, which is the format used by Open Data Kit (ODK).
The Buendia client uses ODK to display these forms on the client device and accept submitted data. In addition to forms for data entry, there is also a special-purpose form object that defines the how patient data is displayed. Specifically, it gives the order and layout of items on the patient chart, specifying each item in terms of its concept ID, the label, and formatting parameters for the value.
The Buendia server module (sometimes called an "omod") can be found in the buendia
repo under openmrs/omod
. The module defines a custom REST API that provides a layer of abstraction between OpenMRS and clients. Although OpenMRS already has a REST API, we designed a custom REST API for this project with the following motivations:
- The existing OpenMRS REST API operates on individual objects at the level of OpenMRS's data model, whereas we sometimes need to perform several of these smaller operations in a single transaction. For example, adding a new clinician to the system consists of adding a Person, a PersonName, a User, and a Provider at the OpenMRS level, but the client should be able to make all that happen with a single API call.
- The backend could potentially be moved from OpenMRS to another system, maintaining the same or a similar API.
- Using a custom API allows us to work around bugs and limitations in OpenMRS and perform additional handling such as custom preprocessing of submitted ODK forms.
- Using a custom API reduces our sensitivity to OpenMRS updates (the API can remain stable while OpenMRS changes).
The Buendia Android client is an Android app (in the client repository) that provides a human interface to view and edit patient records. The human interface is designed with Ebola treatment centers in mind, so it contains large touch targets, large text, and a limited need to type in information, which makes the app usable while wearing PPE (personal protective equipment).
The Android client complements the extensibility of the Buendia server by embedding a customized, library version of ODK, which is normally standalone. This gives the client the capability to load ODK forms defined on the OpenMRS server and display forms with customizations we have made to improve visibility and usability.
See the Client Overview for more about the Android client.
For proper operation, the client needs to be configured with a server URL as well as username and password to authenticate REST API calls.
The server is considered the single source of truth for data; clients keep a local copy of the patient data and periodically sync their copy with the server's copy by querying the server. The local copy on the client includes all existing patients and observations [Note 1].
Reading or querying data for display in the client UI is always done by querying the client's local copy, not the server. Thus, all patient attributes and observations are available offline.
Also, the local copy is disposable; any client can be wiped at will, and the next time the app starts it will pull all the data from the server again.
However, writing data (such as editing a patient or adding an observation) is always done by posting to the server directly. If the server reports success, the client then applies an equivalent update to its local copy. When the server cannot be reached, all editing actions simply fail with an error message.
For example, when a patient is added in a particular instance of the client app:
- The client makes a REST API call to the patient creation endpoint in the Buendia Server module.
- The server validates the data and accepts or rejects the new patient.
- If the request was successful, the client adds the new patient to its local database.
- Other clients will then pick up the new patient when they do their next sync (scheduled every 5 minutes).
- If the request was unsuccessful, the client displays an error message and does not save the new patient.
This general procedure applies for all communication between the clients and the server: clients always wait on the server to return successful responses (HTTP response codes 200 or 201) before updating local data, and data is never directly transferred from client to client.
As explained above, the client has a local copy of all the data, so all of the following operations work offline:
- View the list of users and their names
- Log in as a particular user
- View the list of locations
- View the list of all patients or patients in any location
- Filter the list of patients by name, location, pregnancy, or age
- Search for patients by name or ID
- View an individual patient's chart, including patient attributes (e.g. name, age, location), the complete history of all observations, and all treatment orders for the patient
All of the following operations require writing data to the server and do not work offline:
- Add a user
- Add a patient
- Change a patient's location
- Edit a patient's name, age, or sex
- Add observations for a patient
- Add lab test results for a patient
- Add treatment orders for a patient
- Mark a treatment as given
- To limit resource usage on the client, we had planned to sync only "active" patient records to the client; some number of days after a patient is discharged their record would become "inactive" and remain archived on the server but not copied down to clients. This flag is not currently implemented; all clients receive a copy of all the data for all patients. This is manageable up to about 1000 patients; as the number of patients grows significantly past 1000, the client becomes quite slow.
About the software
System Overview
Client Application
Server Application
Server Platform
Development practices
GitHub Usage
Java Style
Testing
Releases
For field users and testers
Software Install and Configuration
Upon Receiving Your Gear
Setting Up a Tablet
Setting Up a Server
Setting Up an Access Point
Reference Configuration