
Hello. My name is Andrey, I work in a company that creates IT solutions in the field of medicine. We use Clojure as the main development language, as well as (depending on the project / module) Python, Javascript, Go, C, C #, Rust, Objective-C, etc.
An important place in our technology stack is occupied by the international standard
FHIR (Fast Healthcare Interoperability Resources), which defines the format of storage / exchange / provision of medical information in electronic form and includes the
RESTful API specification of
the client-server interaction.
')
Some time ago I started a pet-project of an application that visualizes the contents of the resources of an arbitrary FHIR server and allows you to perform basic CRUD operations. In KDPV there is a screenshot of the page for editing the element of the Patient type resource.
Under the cat a small description and a link to the online demo - you can feel the real live FHIR server, poke buttons, view / create / edit various resources and even try to trigger the same effect! )
A couple of words about FHIR
I will not rewrite the description of the standard here, those who wish can learn all the details at the link above, read other materials on various resources, as well as ask questions and join the discussion in the
FHIR chat . I will give only a general idea: the central concept is a resource, resources are divided into types and groups, each type has its own structure of fields, the values of which can be primitive or composite types and references to other resources. Fields can be required or optional, contain one value or a collection of values. For example, the
Patient resource has fields of a primitive type: date of birth / gender / ..., composite type: name / address / ...., links to the organization and list of attending physicians, etc.
For each resource, the history of its changes is stored as a list of states with dates of their relevance and the version number of the object. The RESTful API allows you to request metadata about the composition and structure of resources supported by this FHIR server, a list of any type of resource elements with extensive filtering capabilities by the values of individual parameters, including dependent resources, limit the result output to the values of the listed fields, sort the query result by complex criteria, and etc. There are also methods for supporting CRUD at the resource element level - creating / updating with structure validation and the presence of required fields, deleting the element. There are API methods for viewing the change history both at the element level and at the resource type level.
In a typical application, the use of this universal API is abstracted by a thick layer of business logic of a particular client. For example, when a patient's visit to a doctor is scheduled, data on the number of his health insurance and its duration, the history of previous visits, information on the balance of patient's settlements with the clinic, etc., data on the schedule of the selected doctor and available hours for admission, etc. are requested. .P. And all this is presented in a convenient form on the screen of the workplace of the recording officer. Or the automatic task scheduler periodically, according to a predetermined schedule, starts a process requesting a list of upcoming upcoming visits and automatically sending patients sms with the text of reminders or notifications according to predefined templates.
But I got the idea to make a universal visualization of the contents of the FHIR server resources, and so a project called ...
FHIR-face
The application allows you to connect to any FHIR-server and to view the contents of the resources and basic CRUD. One of the difficulties of such a universal approach is that different servers can have different versions of the FHIR standard, not fully implement it, have deviations in the list, composition and structure of resources and API, and also have additional functionality that is not included in the specification . But if this server allows you to request metadata about the composition and structure of supported resources, you can add its support in this project.
The interface of the project is imho intuitive. The server address is selected via the address bar parameter, but
hapi.fhir.org is selected by default in the current demo version. From the start page, the composition and structure of resources is loaded, and it is proposed to select a specific type of resource to view its contents. When a resource type is selected, a request is made for a limited number of its elements, which are output to a table with columns: an identifier, a conditional user representation (if available) and a size in characters of string serialization. Works full-text search on the contents of the resource. When you click on a row in a table or on a button to create a new item, you are redirected to the content page of the resource item.
At the top of the item page there are buttons for complete convolution / sweep of hierarchical content and a button for changing the style of presentation of details. The content of the item is a list of details. Each prop has a name, type, brief description and value. A circle filled with black to the left of the attribute indicates that this attribute is present in the resource (even if its value is not selected - in this case, the element has this attribute, but it has an empty value), an empty circle means the absence of this attribute in the element, but the presence in the list details of the structure of this type of resource. Any props can be added / removed from the item by clicking the mouse on the icon of the circle to the left of the name. Details, not listed in the structure of the resource type, but available in the element are highlighted in purple.
The values of primitive types are represented by the corresponding typed widgets - date, time, number, string, etc. The icon to the right of the string details switches the text input / editing mode - with or without newlines. When editing, the widget is automatically resized depending on its content. When you start filling out the form, all text fields longer than 50 characters are represented by textArea widgets with line breaks. Link widgets are represented by the type of the link resource and value; when a value is selected, full-text search by the content of the link resource works.
Details of composite types can be minimized with a highlight of the number of possible and filled subordinate details or expanded - with a demonstration of the contents. When you click on the name / type / description of the requisite, a full deep convolution / content scan is triggered; when you click on the highlight, the number of fields is the scanning of the details of the next level. Collection requisites (with an arbitrary number of values) have an
+ icon to the right of the attribute description - to add new values to the collection. Convolution / unwrapping of a collection item (if it in turn is a composite type value) is performed by clicking on the rightmost part of the frame bounding the collection item. When you click on the cross in the upper right corner of the frame, the collection element is deleted.
This interface allows you to edit the contents of any resource. At the bottom of the page there is a button to save the resource in the edited state. When a resource is written, the FHIR server validates its contents and, if there are errors, does not write the resource, but returns a list of validation errors. In this case, the text of these errors is displayed in red below the save button. The structure of the object of validation errors is determined by the implementation of the server, so a variant of its universal textual representation was chosen. In the absence of errors, the resource element is written and redirected back to the list of elements page.
And finally, the promised links:
Online demo projectGithub of the project - a cat is not an exhibition scarecrow, but a live worker, therefore there are commented sections, scaffolding and other elements necessary for construction and installation works, wear helmets)