Skip to content

Commit

Permalink
Metriport initial integration (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
Orta21 authored May 15, 2023
1 parent 71647cb commit 3fd1cbc
Show file tree
Hide file tree
Showing 47 changed files with 1,504 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ dist/*
# projections file to easily jump to/from test file
.projections.json

# Jetbrains ide
# Jetbrains ide
.idea
26 changes: 26 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
spec: '@yarnpkg/plugin-interactive-tools'

yarnPath: .yarn/releases/yarn-3.4.1.cjs
32 changes: 17 additions & 15 deletions extensions/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
// import { AvaAi } from './avaAi'
import { Awell } from './awell'
import { CalDotCom } from './calDotCom'
import { Healthie } from './healthie'
import { HelloWorld } from './hello-world'
import { Twilio } from './twilio'
import { Cloudinary } from './cloudinary'
import { DropboxSign } from './dropboxSign'
import { Elation } from './elation'
import { MessageBird } from './messagebird'
import { MathExtension } from './math'
import { Mailgun } from './mailgun'
import { Formsort } from './formsort'
// import { AvaAi } from './avaAi'
import { Healthie } from './healthie'
import { HelloWorld } from './hello-world'
import { Mailchimp } from './mailchimp'
import { Cloudinary } from './cloudinary'
import { Mailgun } from './mailgun'
import { MathExtension } from './math'
import { MessageBird } from './messagebird'
import { Metriport } from './metriport'
import { Twilio } from './twilio'

export const extensions = [
// AvaAi, Best to disable this until we cleared out data privacy & HIPAA with OpenAI
Awell,
Cloudinary,
HelloWorld,
Healthie,
Twilio,
CalDotCom,
Cloudinary,
DropboxSign,
Elation,
Mailgun,
MessageBird,
MathExtension,
Formsort,
Healthie,
HelloWorld,
Mailchimp,
Mailgun,
MathExtension,
MessageBird,
Metriport,
Twilio,
]
1 change: 1 addition & 0 deletions extensions/metriport/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Metriport changelog
3 changes: 3 additions & 0 deletions extensions/metriport/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Metriport extension

(TBD requires more info)
28 changes: 28 additions & 0 deletions extensions/metriport/actions/document/fields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { FieldType, type Field } from '../../../../lib/types'

export const listFields = {
patientId: {
id: 'patientId',
label: 'Patient ID',
description: 'The ID of the Patient for which to list their available Documents',
type: FieldType.STRING,
required: true,
},
facilityId: {
id: 'facilityId',
label: 'Facility ID',
description: 'The ID of the Facility where the patient is receiving care',
type: FieldType.STRING,
required: true,
},
} satisfies Record<string, Field>

export const getUrlFields = {
fileName: {
id: 'fileName',
label: 'File Name',
description: 'The file name of the document',
type: FieldType.STRING,
required: true,
},
} satisfies Record<string, Field>
46 changes: 46 additions & 0 deletions extensions/metriport/actions/document/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { type Action, type DataPointDefinition } from '../../../../lib/types'
import { Category } from '../../../../lib/types/marketplace'
import { type settings } from '../../settings'
import { createMetriportApi } from '../../client'
import { handleErrorMessage } from '../../shared/errorHandler'
import { listFields } from './fields'
import { startQuerySchema } from './validation'

const dataPoints = {
patientId: {
key: 'patientId',
valueType: 'string',
},
} satisfies Record<string, DataPointDefinition>

export const queryDocs: Action<
typeof listFields,
typeof settings,
keyof typeof dataPoints
> = {
key: 'listDocs',
category: Category.EHR_INTEGRATIONS,
title: 'List Documents',
description:
'Triggers a document query for the specified patient across HIEs.',
fields: listFields,
previewable: true,
dataPoints,
onActivityCreated: async (payload, onComplete, onError): Promise<void> => {
try {
const { patientId, facilityId } = startQuerySchema.parse(payload.fields)

const api = createMetriportApi(payload.settings)

await api.startDocumentQuery(patientId, facilityId)

await onComplete({
data_points: {
patientId: String(patientId),
},
})
} catch (err) {
await handleErrorMessage(err, onError)
}
},
}
46 changes: 46 additions & 0 deletions extensions/metriport/actions/document/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { type Action, type DataPointDefinition } from '../../../../lib/types'
import { Category } from '../../../../lib/types/marketplace'
import { type settings } from '../../settings'
import { createMetriportApi } from '../../client'
import { handleErrorMessage } from '../../shared/errorHandler'
import { listFields } from './fields'
import { startQuerySchema } from './validation'

const dataPoints = {
patientId: {
key: 'patientId',
valueType: 'string',
},
} satisfies Record<string, DataPointDefinition>

export const queryDocs: Action<
typeof listFields,
typeof settings,
keyof typeof dataPoints
> = {
key: 'queryDocs',
category: Category.EHR_INTEGRATIONS,
title: 'Start Document Query',
description:
'Triggers a document query for the specified patient across HIEs.',
fields: listFields,
previewable: true,
dataPoints,
onActivityCreated: async (payload, onComplete, onError): Promise<void> => {
try {
const { patientId, facilityId } = startQuerySchema.parse(payload.fields)

const api = createMetriportApi(payload.settings)

await api.startDocumentQuery(patientId, facilityId)

await onComplete({
data_points: {
patientId: String(patientId),
},
})
} catch (err) {
await handleErrorMessage(err, onError)
}
},
}
10 changes: 10 additions & 0 deletions extensions/metriport/actions/document/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { z } from 'zod'

export const startQuerySchema = z.object({
patientId: z
.string({ errorMap: () => ({ message: 'Missing patientId' }) })
.min(1),
facilityId: z
.string({ errorMap: () => ({ message: 'Missing facilityId' }) })
.min(1),
})
54 changes: 54 additions & 0 deletions extensions/metriport/actions/facility/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { type Action } from '../../../../lib/types'
import { Category } from '../../../../lib/types/marketplace'
import { type settings } from '../../settings'
import { createMetriportApi } from '../../client'
import { handleErrorMessage } from '../../shared/errorHandler'
import { facilityFields } from './fields'
import { facilityIdDataPoint } from './dataPoints'
import { facilityCreateSchema } from './validation'

export const createFacility: Action<
typeof facilityFields,
typeof settings,
keyof typeof facilityIdDataPoint
> = {
key: 'createFacility',
category: Category.EHR_INTEGRATIONS,
title: 'Create Facility',
description:
'Creates a Facility in Metriport where your patients receive care.',
fields: facilityFields,
previewable: true,
dataPoints: facilityIdDataPoint,
onActivityCreated: async (payload, onComplete, onError): Promise<void> => {
try {
const facility = facilityCreateSchema.parse(payload.fields)

const metriportFacility = {
name: facility.name,
npi: facility.npi,
tin: facility.tin,
address: {
addressLine1: facility.addressLine1,
addressLine2: facility.addressLine2,
city: facility.city,
state: facility.state,
zip: facility.zip,
country: facility.country,
},
}

const api = createMetriportApi(payload.settings)

const { id } = await api.createFacility(metriportFacility)

await onComplete({
data_points: {
facilityId: String(id),
},
})
} catch (err) {
await handleErrorMessage(err, onError)
}
},
}
29 changes: 29 additions & 0 deletions extensions/metriport/actions/facility/dataPoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { type DataPointDefinition } from '../../../../lib/types'
import { address } from '../../shared/dataPoints'

export const facilityIdDataPoint = {
facilityId: {
key: 'facilityId',
valueType: 'string',
},
} satisfies Record<string, DataPointDefinition>

export const facilityDataPoints = {
name: {
key: 'name',
valueType: 'string',
},
npi: {
key: 'npi',
valueType: 'string',
},
active: {
key: 'active',
valueType: 'boolean',
},
tin: {
key: 'tin',
valueType: 'string',
},
...address,
} satisfies Record<string, DataPointDefinition>
Loading

0 comments on commit 3fd1cbc

Please sign in to comment.