adding all clients.

This commit is contained in:
Jason Kulatunga 2022-10-05 23:51:59 -07:00
parent 7f8e592f6a
commit c8ffe73057
11 changed files with 308 additions and 9 deletions

View File

@ -0,0 +1,40 @@
import {SourceType} from '../models/database/types';
import {Source} from '../models/database/source';
import {IClient} from './interface';
import {AetnaClient} from './fhir/aetna_client';
import {BlueButtonClient} from './fhir/bluebutton_client';
import {CareEvolutionClient} from './fhir/careevolution_client';
import {CernerClient} from './fhir/cerner_client';
import {AthenaClient} from './fhir/athena_client';
import {CignaClient} from './fhir/cigna_client';
import {EpicClient} from './fhir/epic_client';
import {HealthITClient} from './fhir/healthit_client';
import {LogicaClient} from './fhir/logica_client';
export function NewClient(sourceType: SourceType, source: Source): IClient {
switch(sourceType) {
case SourceType.Aetna:
return new AetnaClient(source)
case SourceType.Athena:
return new AthenaClient(source)
case SourceType.BlueButtonMedicare:
return new BlueButtonClient(source)
case SourceType.CareEvolution:
return new CareEvolutionClient(source)
case SourceType.Cerner:
return new CernerClient(source)
case SourceType.Cigna:
return new CignaClient(source)
case SourceType.Epic:
return new EpicClient(source)
case SourceType.HealthIT:
return new HealthITClient(source)
case SourceType.Logica:
return new LogicaClient(source)
// case SourceType.Manual:
// return new ManualClient(source)
default:
throw new Error(`Unknown Source Type: ${sourceType}`)
}
}

View File

@ -0,0 +1,23 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class AetnaClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
}
/**
* Aetna overrides the SyncAll function because Patient-everything operation uses a non-standard endpoint
* @param db
* @constructor
*/
async SyncAll(db: IDatabaseRepository): Promise<string[]> {
const bundle = await this.GetResourceBundlePaginated("Patient")
const wrappedResourceModels = await this.ProcessBundle(bundle)
//todo, create the resources in dependency order
return await db.CreateResources(wrappedResourceModels)
}
}

View File

@ -0,0 +1,42 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class AthenaClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
}
/**
* Athena overrides the SyncAll function because Patient-everything operation is not available.
* @param db
* @constructor
*/
async SyncAll(db: IDatabaseRepository): Promise<string[]> {
const supportedResources: string[] = [
"AllergyIntolerance",
//"Binary",
"CarePlan",
"CareTeam",
"Condition",
"Device",
"DiagnosticReport",
"DocumentReference",
"Encounter",
"Goal",
"Immunization",
//"Location",
//"Medication",
//"MedicationRequest",
"Observation",
//"Organization",
//"Patient",
//"Practitioner",
"Procedure",
//"Provenance",
]
return this.SyncAllByResourceName(db, supportedResources)
}
}

View File

@ -56,10 +56,7 @@ export class FHIR401Client extends BaseClient implements IClient {
try {
let bundle = await this.GetResourceBundlePaginated(`${resourceType}?patient=${this.source.patient}`)
let wrappedResourceModels = await this.ProcessBundle(bundle)
for(let apiModel of wrappedResourceModels){
await db.CreateResource(apiModel)
}
await db.CreateResources(wrappedResourceModels)
}
catch (e) {
console.error(`An error occurred while processing ${resourceType} bundle ${this.source.patient}`)
@ -132,17 +129,13 @@ export class FHIR401Client extends BaseClient implements IClient {
})
}
/////////////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////////////
/**
* Retrieve a resource bundle. While "next" link is present in response, continue to request urls and append BundleEntries
* @param relativeResourcePath
* @constructor
* @private
*/
private async GetResourceBundlePaginated(relativeResourcePath: string): Promise<IResourceBundleRaw> {
protected async GetResourceBundlePaginated(relativeResourcePath: string): Promise<IResourceBundleRaw> {
// https://www.hl7.org/fhir/patient-operation-everything.html
const bundle = await this.GetRequest(relativeResourcePath) as IResourceBundleRaw
@ -181,4 +174,8 @@ export class FHIR401Client extends BaseClient implements IClient {
return bundle
}
/////////////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////////////
}

View File

@ -0,0 +1,24 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class BlueButtonClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
}
/**
* BlueButton overrides the SyncAll function because Patient-everything operation is not available.
* @param db
* @constructor
*/
async SyncAll(db: IDatabaseRepository): Promise<string[]> {
const supportedResources: string[] = [
"ExplanationOfBenefit",
"Coverage",
]
return this.SyncAllByResourceName(db, supportedResources)
}
}

View File

@ -0,0 +1,12 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
export class CareEvolutionClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
//CareEvolution API requires the following Accept header for every request
this.headers["Accept"] = "application/json+fhir"
}
}

View File

@ -0,0 +1,47 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class CernerClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
//Cerner API requires the following Accept header for every request
this.headers["Accept"] = "application/json+fhir"
}
/**
* Cerner overrides the SyncAll function because Patient-everything operation is not available.
* @param db
* @constructor
*/
async SyncAll(db: IDatabaseRepository): Promise<string[]> {
const supportedResources: string[] = [
"AllergyIntolerance",
"CarePlan",
"CareTeam",
"Condition",
"Consent",
"Device",
"Encounter",
"FamilyMemberHistory",
"Goal",
"Immunization",
"InsurancePlan",
"MedicationRequest",
"NutritionOrder",
"Observation",
"Person",
"Procedure",
"Provenance",
"Questionnaire",
"QuestionnaireResponse",
"RelatedPerson",
"Schedule",
"ServiceRequest",
"Slot",
]
return this.SyncAllByResourceName(db, supportedResources)
}
}

View File

@ -0,0 +1,10 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
export class CignaClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
}
}

View File

@ -0,0 +1,47 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class EpicClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
//Epic API requires the following Accept header for every request
this.headers["Accept"] = "application/json+fhir"
}
/**
* Epic overrides the SyncAll function because Patient-everything operation is not available.
* @param db
* @constructor
*/
async SyncAll(db: IDatabaseRepository): Promise<string[]> {
const supportedResources: string[] = [
"AllergyIntolerance",
"CarePlan",
"CareTeam",
"Condition",
"Consent",
"Device",
"Encounter",
"FamilyMemberHistory",
"Goal",
"Immunization",
"InsurancePlan",
"MedicationRequest",
"NutritionOrder",
"Observation",
"Person",
"Procedure",
"Provenance",
"Questionnaire",
"QuestionnaireResponse",
"RelatedPerson",
"Schedule",
"ServiceRequest",
"Slot",
]
return this.SyncAllByResourceName(db, supportedResources)
}
}

View File

@ -0,0 +1,47 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class HealthITClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
//HealthIT API requires the following Accept header for every request
this.headers["Accept"] = "application/json+fhir"
}
/**
* HealthIT overrides the SyncAll function because Patient-everything operation is not available.
* @param db
* @constructor
*/
async SyncAll(db: IDatabaseRepository): Promise<string[]> {
const supportedResources: string[] = [
"AllergyIntolerance",
"CarePlan",
"CareTeam",
"Condition",
"Consent",
"Device",
"Encounter",
"FamilyMemberHistory",
"Goal",
"Immunization",
"InsurancePlan",
"MedicationRequest",
"NutritionOrder",
"Observation",
"Person",
"Procedure",
"Provenance",
"Questionnaire",
"QuestionnaireResponse",
"RelatedPerson",
"Schedule",
"ServiceRequest",
"Slot",
]
return this.SyncAllByResourceName(db, supportedResources)
}
}

View File

@ -0,0 +1,10 @@
import {IClient} from '../interface';
import {FHIR401Client} from './base/fhir401_r4_client';
import {Source} from '../../models/database/source';
import {IDatabaseRepository} from '../../database/interface';
export class LogicaClient extends FHIR401Client implements IClient {
constructor(source: Source) {
super(source);
}
}