Skip to content

Latest commit

 

History

History
242 lines (221 loc) · 8.46 KB

USAGE.md

File metadata and controls

242 lines (221 loc) · 8.46 KB

Usage

Require blue-button and blue-button-record

var bb = require("@amida-tech/blue-button");
var bbr = require("@amida-tech/blue-button-record");

blue-button-record assumes MongoDB is already running. Connect to the database

bbr.connectDatabase('localhost', function(err) {
  if (err) throw err;
}

Read a ccd file and convert it to JSON. An example file exists in this repository

var fs = require('fs');
var path = require('path');
var filepath  = 'test/artifacts/standard/CCD_demo1.xml';
var xmlString = fs.readFileSync(filepath, 'utf-8');
var result = bb.parseString(xmlString);
var ccdJSON = result.data;

Persist the file as a source of patient data. Various properties is the responsibility the caller

var fileInfo = {
    name: 'CCD_demo1.xml',
    type: 'text/xml'
};
var fileId;
bbr.saveSource('patientKey', xmlString, fileInfo, 'ccda', function(err, id) {
    fileId = id;
});

After source is persisted it can also be updated

var updateInfo = {
    'metadata.parsed': new Date(),
    'metadata.archived': new Date()
};
bbr.updateSource('patientKey', fileId, updateInfo, function(err) {
    if (err) {throw err;}
});

For simplicity we will only use this fileId in usage documentation as if it has several types of data. Methods are provided to access patient data source records as a list or individually

bbr.getSourceList('patientKey', function(err, results) {
    console.log(results.length);
});

bbr.getSource('patientKey', fileId, function(err, filename, content) {
    console.log(filename);
});

bbr.sourceCount('patientKey', function(err, count) {
    console.log(count);
});

You can persist all the blue-button sections together

bbr.saveAllSections('patientKey', ccdJSON, fileId, function(err) {
    if (err) {throw err;}
});

or individually

bbr.saveSection('allergies', 'patientKey', ccdJSON.allergies, fileId, function(err) {
    if (err) {throw err;}
});

Note that persisting blue-button-data always requires a source (fileId above). By default all sections supported by blue-button are also supported by blue-button-record.

You can get all sections of the Master Health Record

bbr.getAllSections('patientKey',function(err, result) {
    console.log(result.allergies[0].allergen.name);
    console.log(result.procedures[0].procedure.name);
});

or get any section individually

var id;
var allergies;
bbr.getSection('allergies', 'patientKey', function(err, result) {
    console.log(result[0].allergen.name);
    id = result[0]._id;
    allergies = result;
});

In addition to blue-button data, each entry also includes metadata and property _id which you can later use to update or access

bbr.updateEntry('allergies', 'patientKey', id, fileId, {severity: 'Severe'}, function(err) {
    if (err) {throw err;}
});

var allergy;
bbr.getEntry('allergies', 'patientKey', id, function(err, result) {
    console.log(result.severity);
    allergy = result;
});

You can clean up metadata and other non blue-button data

var allergiesBBOnly = bbr.cleanSection(allergies);
console.log(allergiesBBOnly[0]._id);
console.log(allergiesBBOnly[0].allergen.name);

which makes allergiesBBOnly comparable to ccdJSON.allergies.

If you find an existing entry of Master Health Record in a new source, you can register the source as such

bbr.duplicateEntry('allergies', 'patientKey', id, fileId, function(err) {
  if (err) throw err;
});

Metadata property for each entry provides both the source of the data and the Merge History

  bbr.getEntry('allergies', 'patientKey', id, function(err, entry) {
      var attribution = entry.metadata.attribution;
      console.log(attribution[0].merge_reason);     // 'new'
      console.log(attribution[0].record.filename);
      console.log(attribution[1].merge_reason);     // 'update'
      console.log(attribution[1].record.filename);
      console.log(attribution[2].merge_reason);     // 'duplicate'
      console.log(attribution[2].record.filename);
  });        

Whole Merge History for a section is available

bbr.getMerges('allergies', 'patientKey', 'allergen severity', 'filename uploadDate', function(err, mergeList) {
    var explMerge = mergeList[0];
    console.log(explMerge.merge_reason);
    console.log(explMerge.entry.allergen.name);
    console.log(explMerge.entry.severity);
    console.log(explMerge.record.filename);
    console.log(explMerge.record.uploadDate);
});        

You can count Merge History entries with various conditions

 bbr.mergeCount('allergies', 'patientKey', {}, function(err, count) {
    console.log(count);
 });   
 
bbr.mergeCount('allergies', 'patientKey', {merge_reason: 'new'}, function(err, count) {
    console.log(count);
});    

bbr.mergeCount('allergies', 'patientKey', {merge_reason: 'duplicate'}, function(err, count) {
    console.log(count);
});        

blue-button-record also stores Match List; entries which cannot immediately become part of the Master Health Record since they are similar enough to existing entries but not identical to become duplicates. In addition to blue-button health data, blue-button-record requires a pointer to an existing Master Health Record entry and match information to persist partial entries

var partialAllergy = {
            partial_entry: ccdJSON.allergies[0],
            partial_matches: [{
                match_entry: id,
                match_object: {
                    diff: {
                        severity: 'new'
                    },
                    percent: 80,
                    subelements: []
                }
            }]
        };

Here match information is assumed to have three fields: diff, subelements, and percent. The match fields are application specific and are not validated.

Match List entries are persisted as sections

// for simplicity use the same here, these would be different in reality
var partialAllergies = [partialAllergy, partialAllergy];
bbr.saveMatches('allergies', 'patientKey', partialAllergies, fileId, function(err) {
    if (err) {throw err;}       
});

Match List is available as a list

bbr.getMatches('allergies', 'patientKey', 'allergen severity', function(err, result) {
    console.log(result[0].matches[0].match_entry.observation.severity.code.name);
    console.log(result[0].entry.observation.allergen.name);
    console.log(result[0].entry.observation.severity.code.name);
    console.log(result[0].matches[0].match_object.diff.severity);
    console.log(result[0].matches[0].match_object.percent);
    matchId0 = result[0]._id;
    matchId1 = result[1]._id;
});

Individual Match List entry access is also available and will return the full blue-button data both for the Master Health Record enty and the Match List entry

bbr.getMatch('allergies', 'patientKey', matchId0, function(err, result) {
     console.log(result.matches[0].match_entry.observation.allergen.name);
     console.log(result.matches[0].match_entry.observation.status.name);
     console.log(result.matches[0].match_entry.observation.allergen.name);
     console.log(result.matches[0].match_entry.observation.status.name);
     console.log(result.matches[0].match_object.diff.severity);
     console.log(result.matches[0].match_object.percent);
});   

Only count of matches can be accessed instead of full list

bbr.matchCount('allergies', 'patientKey', {}, function(err, count) {
    console.log(count);
});   

bbr.matchCount('allergies', 'patientKey', {percent: 90}, function(err, count) {
    console.log(count);
});   

Match List entries can be canceled with application specific reasons such as 'ignored' or 'merged'

bbr.cancelMatch('allergies', 'patientKey', matchId0, 'ignored', function(err, count) {
  console.log(count);
});

bbr.cancelMatch('allergies', 'patientKey', matchId0, 'merged', function(err, count) {
  console.log(count);
});

or they can be accepted and become part of the Master Health Record.

bbr.acceptMatch('allergies', 'patientKey', matchId1, 'added', function(err) {
    if (err) {throw err;}
});   

When the session ends, you disconnect from the database

bbr.disconnect(function(err) {
    if (err) {throw err;}
});