Segnalare ai pazienti le modifiche delle cartelle cliniche HL7 FHIR utilizzando le App per la logica e Azure Cosmos DBNotifying patients of HL7 FHIR health care record changes using Logic Apps and Azure Cosmos DB

Howard Edidin, Azure MVP, è stato recentemente contattato da un'organizzazione del settore di sanitario che desiderava aggiungere una nuova funzionalità al proprio portale dei pazienti.Azure MVP Howard Edidin was recently contacted by a healthcare organization that wanted to add new functionality to their patient portal. L'organizzazione aveva bisogno di inviare notifiche ai pazienti in caso di aggiornamenti ai loro record sanitari. I pazienti dovevano anche essere in grado di iscriversi a tali aggiornamenti.They needed to send notifications to patients when their health record was updated, and they needed patients to be able to subscribe to these updates.

Questo articolo illustra la soluzione di notifica del feed delle modifiche creata per questa organizzazione sanitaria usando Azure Cosmos DB, le App per la logica e il bus di servizio.This article walks through the change feed notification solution created for this healthcare organization using Azure Cosmos DB, Logic Apps, and Service Bus.

Requisiti del progettoProject requirements

  • I provider inviano documenti HL7 Consolidated-Clinical Document Architecture (C-CDA) in formato XML.Providers send HL7 Consolidated-Clinical Document Architecture (C-CDA) documents in XML format. I documenti C-CDA comprendono sostanzialmente ogni tipo di documento clinico, incluse informazioni familiari e registri immunologici, oltre a documenti amministrati, finanziari e su flussi di lavoro.C-CDA documents encompass just about every type of clinical document, including clinical documents such as family histories and immunization records, as well as administrative, workflow, and financial documents.
  • I documenti C-CDA vengono convertiti in risorse HL7 FHIR in formato JSON.C-CDA documents are converted to HL7 FHIR Resources in JSON format.
  • I documenti di risorse FHIR modificati vengono inviati via e-mail in formato JSON.Modified FHIR resource documents are sent by email in JSON format.

Flusso di lavoro della soluzioneSolution workflow

A livello generale, il progetto richiedeva i seguenti passaggi del flusso di lavoro:At a high level, the project required the following workflow steps:

  1. Convertire documenti C-CDA in risorse FHIR.Convert C-CDA documents to FHIR resources.
  2. Eseguire un trigger ricorrente per il polling di risorse FHIR modificate.Perform recurring trigger polling for modified FHIR resources.
  3. Chiamare un'app personalizzata, FhirNotificationApi, per connettersi ad Azure Cosmos DB ed eseguire query in merito a documenti nuovi o modificati.Call a custom app, FhirNotificationApi, to connect to Azure Cosmos DB and query for new or modified documents.
  4. Salvare la risposta nella coda del bus di servizio.Save the response to to the Service Bus queue.
  5. Effettuare il polling per i nuovi messaggi nella coda del bus di servizio.Poll for new messages in the Service Bus queue.
  6. Inviare notifiche e-mail ai pazienti.Send email notifications to patients.

Architettura della soluzioneSolution architecture

Questa soluzione richiede tre App per la logica per soddisfare i requisiti precedenti e completare il flusso di lavoro della soluzione.This solution requires three Logic Apps to meet the above requirements and complete the solution workflow. Le tre App per la logica sono:The three logic apps are:

  1. App HL7-FHIR-Mapping: riceve il documento HL7 C-CDA, lo trasforma nella risorsa FHIR e lo salva in Azure Cosmos DB.HL7-FHIR-Mapping app: Receives the HL7 C-CDA document, transforms it to the FHIR Resource, then saves it to Azure Cosmos DB.
  2. App EHR: esegue una query nel repository FHIR di Azure Cosmos DB e salva la risposta in una coda del bus di servizio.EHR app: Queries the Azure Cosmos DB FHIR repository and saves the response to a Service Bus queue. Questa App per la logica usa un'app per le API per recuperare i documenti nuovi e modificati.This logic app uses an API app to retrieve new and changed documents.
  3. App per le notifiche sul processo: invia una notifica e-mail contenente i documenti della risorsa FHIR.Process notification app: Sends an email notification with the FHIR resource documents in the body.

Le tre App per la logica usate in questa soluzione per la sanità HL7 FHIR

I servizi di Azure usati nella soluzioneAzure services used in the solution

API DocumentDB di Azure Cosmos DBAzure Cosmos DB DocumentDB API

Azure Cosmos DB è il repository per le risorse FHIR come illustrato nella figura seguente.Azure Cosmos DB is the repository for the FHIR resources as shown in the following figure.

Account di Azure Cosmos DB utilizzato in questa esercitazione per la soluzione HL7 FHIR del settore sanitario

App per la logicaLogic Apps

Le App per la logica gestiscono il processo del flusso di lavoro.Logic Apps handle the workflow process. Gli screenshot seguenti mostrano le App per la logica create per questa soluzione.The following screenshots show the Logic apps created for this solution.

  1. App HL7-FHIR-Mapping: riceve il documento HL7 C-CDA e lo trasforma in una risorsa FHIR usando Enterprise Integration Pack per App per la logica.HL7-FHIR-Mapping app: Receive the HL7 C-CDA document and transform it to an FHIR resource using the Enterprise Integration Pack for Logic Apps. Enterprise Integration Pack gestisce il mapping da C-CDA alle risorse FHIR.The Enterprise Integration Pack handles the mapping from the C-CDA to FHIR resources.

    L'App per la logica usata per ricevere record sanitari HL7 FHIR

  2. App EHR: esegue una query nel repository FHIR di Azure Cosmos DB e salva la risposta in una coda del bus di servizio.EHR app: Query the Azure Cosmos DB FHIR repository and save the response to a Service Bus queue. Il codice per l'app GetNewOrModifiedFHIRDocuments è indicato di seguito.The code for the GetNewOrModifiedFHIRDocuments app is below.

    App per la logica utilizzata per eseguire query in Azure Cosmos DB

  3. App per le notifiche sul processo: invia una notifica e-mail contenente i documenti della risorsa FHIR.Process notification app: Send an email notification with the FHIR resource documents in the body.

    L'App per la logica per inviare e-mail ai pazienti contenenti la risorsa HL7 FHIR

Bus di servizioService Bus

La figura seguente mostra la coda di pazienti.The following figure shows the patients queue. Il valore della proprietà Tag viene usato per l'oggetto dell'email.The Tag property value is used for the email subject.

La coda del bus di servizio usata in questa esercitazione HL7 FHIR

App per le APIAPI app

Un'app per le API si connette ad Azure Cosmos DB ed esegue query per documenti FHIR nuovi o modificati in base al tipo di risorsa.An API app connects to Azure Cosmos DB and queries for new or modified FHIR documents By resource type. Questa applicazione dispone di un controller, FhirNotificationApi con una unica operazione GetNewOrModifiedFhirDocuments, vedere l'origine di app per le API.This app has one controller, FhirNotificationApi with a one operation GetNewOrModifiedFhirDocuments, see source for API app.

Viene utilizzata la classe CreateDocumentChangeFeedQuery dell'API DocumentDB .NET di Azure Cosmos DB.We are using the CreateDocumentChangeFeedQuery class from the Azure Cosmos DB DocumentDB .NET API. Per altre informazioni, vedere l'articolo sul feed delle modifiche.For more information, see the change feed article.

Operazione GetNewOrModifiedFhirDocumentsGetNewOrModifiedFhirDocuments operation

InputInputs

  • DatabaseIdDatabaseId
  • CollectionIdCollectionId
  • Nome del tipo di risorsa HL7 FHIRHL7 FHIR Resource Type name
  • Valore booleano: Avvia dall'inizioBoolean: Start from Beginning
  • Int: Numero di documenti restituitiInt: Number of documents returned

OutputsOutputs

  • Operazione riuscita: Codice di stato: 200, Risposta: Elenco di documenti (matrice JSON)Success: Status Code: 200, Response: List of Documents (JSON Array)
  • Errore: Codice di stato: 404, Risposta: "No Documents found for 'resource name' Resource Type" (Nessun documento trovato per il tipo di risorsa "nome risorsa")Failure: Status Code: 404, Response: "No Documents found for 'resource name' Resource Type"

Origine per l'app per le APISource for the API app


    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web.Http;
    using Microsoft.Azure.Documents;
    using Microsoft.Azure.Documents.Client;
    using Swashbuckle.Swagger.Annotations;
    using TRex.Metadata;

    namespace FhirNotificationApi.Controllers
    {
        /// <summary>
        ///     FHIR Resource Type Controller
        /// </summary>
        /// <seealso cref="System.Web.Http.ApiController" />
        public class FhirResourceTypeController : ApiController
        {
            /// <summary>
            ///     Gets the new or modified FHIR documents from Last Run Date 
            ///     or create date of the collection
            /// </summary>
            /// <param name="databaseId"></param>
            /// <param name="collectionId"></param>
            /// <param name="resourceType"></param>
            /// <param name="startfromBeginning"></param>
            /// <param name="maximumItemCount">-1 returns all (default)</param>
            /// <returns></returns>
            [Metadata("Get New or Modified FHIR Documents",
                "Query for new or modifed FHIR Documents By Resource Type " +
                "from Last Run Date or Begining of Collection creation"
            )]
            [SwaggerResponse(HttpStatusCode.OK, type: typeof(Task<dynamic>))]
            [SwaggerResponse(HttpStatusCode.NotFound, "No New or Modifed Documents found")]
            [SwaggerOperation("GetNewOrModifiedFHIRDocuments")]
            public async Task<dynamic> GetNewOrModifiedFhirDocuments(
                [Metadata("Database Id", "Database Id")] string databaseId,
                [Metadata("Collection Id", "Collection Id")] string collectionId,
                [Metadata("Resource Type", "FHIR resource type name")] string resourceType,
                [Metadata("Start from Beginning ", "Change Feed Option")] bool startfromBeginning,
                [Metadata("Maximum Item Count", "Number of documents returned. '-1 returns all' (default)")] int maximumItemCount = -1
            )
            {
                var collectionLink = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);

                var context = new DocumentDbContext();  

                var docs = new List<dynamic>();

                var partitionKeyRanges = new List<PartitionKeyRange>();
                FeedResponse<PartitionKeyRange> pkRangesResponse;

                do
                {
                    pkRangesResponse = await context.Client.ReadPartitionKeyRangeFeedAsync(collectionLink);
                    partitionKeyRanges.AddRange(pkRangesResponse);
                } while (pkRangesResponse.ResponseContinuation != null);

                foreach (var pkRange in partitionKeyRanges)
                {
                    var changeFeedOptions = new ChangeFeedOptions
                    {
                        StartFromBeginning = startfromBeginning,
                        RequestContinuation = null,
                        MaxItemCount = maximumItemCount,
                        PartitionKeyRangeId = pkRange.Id
                    };

                    using (var query = context.Client.CreateDocumentChangeFeedQuery(collectionLink, changeFeedOptions))
                    {
                        do
                        {
                            if (query != null)
                            {
                                var results = await query.ExecuteNextAsync<dynamic>().ConfigureAwait(false);
                                if (results.Count > 0)
                                    docs.AddRange(results.Where(doc => doc.resourceType == resourceType));
                            }
                            else
                            {
                                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
                            }
                        } while (query.HasMoreResults);
                    }
                }
                if (docs.Count > 0)
                    return docs;
                var msg = new StringContent("No documents found for " + resourceType + " Resource");
                var response = new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.NotFound,
                    Content = msg
                };
                return response;
            }
        }
    }

Test di FhirNotificationApiTesting the FhirNotificationApi

Nell'immagine seguente viene illustrato l'uso di Swagger per testare FhirNotificationApi.The following image demonstrates how swagger was used to to test the FhirNotificationApi.

Il file Swagger utilizzato per testare l'app per le API

Dashboard del portale di AzureAzure portal dashboard

L'immagine seguente mostra tutti i servizi di Azure per questa soluzione in esecuzione nel portale di Azure.The following image shows all of the Azure services for this solution running in the Azure portal.

Il portale di Azure con tutti i servizi usati in questa esercitazione HL7 FHIR

RiepilogoSummary

  • Si è appreso che Azure Cosmos DB dispone di supporto nativo per le notifiche per documenti nuovi o modificati, con notevole facilità d'uso.You have learned that Azure Cosmos DB has native suppport for notifications for new or modifed documents and how easy it is to use.
  • Sfruttando le App per la logica è possibile creare flussi di lavoro senza scrivere codice.By leveraging Logic Apps, you can create workflows without writing any code.
  • Uso delle code del bus di servizio di Azure per gestire la distribuzione dei documenti HL7 FHIR.Using Azure Service Bus Queues to handle the distribution for the HL7 FHIR documents.

Passaggi successiviNext steps

Per altre informazioni su Azure Cosmos DB, vedere la relativa home page.For more information about Azure Cosmos DB, see the Azure Cosmos DB home page. Per altre informazioni sulle App per la logica, vedere App per la logica.For more informaiton about Logic Apps, see Logic Apps.