Skip to content

Commit

Permalink
Merge pull request #10 from mcode/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
smalho01 authored Dec 4, 2023
2 parents 7abfd4a + 0e921c0 commit 9d175cc
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 16 deletions.
4 changes: 4 additions & 0 deletions prefetch/PrefetchHydrator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Hook, HookPrefetch, TypedRequestBody } from '../resources/HookTypes';
import { ServicePrefetch } from '../resources/CdsService';
import { FhirResource } from 'fhir/r4';

function jsonPath(json: any, path: string) {
// Use a regular expression to find array accessors in the form of "[i]"
const arrayRegex = /\[(\d+)\]/g;
Expand All @@ -27,6 +28,7 @@ function jsonPath(json: any, path: string) {
return obj[key];
}, json);
}

function replaceTokens(str: string, json: Hook): string {
// Use a regular expression to find tokens in the form of "{{token}}"
const tokenRegex = /{{([\w.]+)}}/g;
Expand All @@ -47,6 +49,7 @@ function replaceTokens(str: string, json: Hook): string {
// Return the modified string
return str;
}

function resolveToken(
token: string,
callback: (token: string, req: TypedRequestBody) => Promise<any>,
Expand All @@ -55,6 +58,7 @@ function resolveToken(
const fulfilledToken = replaceTokens(token, hook);
return callback(fulfilledToken, { body: hook });
}

function hydrate(
callback: (token: string, req: TypedRequestBody) => Promise<any>,
template: ServicePrefetch,
Expand Down
18 changes: 9 additions & 9 deletions prefetch/exampleHookService.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"id": "rems-order-sign",
"hook": "order-sign",
"title": "REMS Requirement Lookup",
"description": "REMS Requirement Lookup",
"prefetch": {
"patient": "Patient/{{context.patientId}}",
"practitioner": "Practitioner/{{context.userId}}"
}
}
"id": "rems-order-sign",
"hook": "order-sign",
"title": "REMS Requirement Lookup",
"description": "REMS Requirement Lookup",
"prefetch": {
"patient": "Patient/{{context.patientId}}",
"practitioner": "Practitioner/{{context.userId}}"
}
}
23 changes: 23 additions & 0 deletions resources/CdsHook.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Client from 'fhirclient/lib/Client';
import { Hook, HookContext, SupportedHooks } from './HookTypes';
import { v4 } from 'uuid';
export default abstract class CdsHook {
Expand All @@ -9,4 +10,26 @@ export default abstract class CdsHook {
}
abstract generate(): Hook;
abstract generateContext(): HookContext;
fillAuth(client: Client, hook: Hook) {
if (client.state?.tokenResponse) {
const tokenResponse = client.state.tokenResponse;
if (
tokenResponse.access_token &&
tokenResponse.token_type &&
tokenResponse.expires_in &&
tokenResponse.scope &&
client.state.clientId
) {
hook.fhirAuthorization = {
access_token: tokenResponse.access_token,
token_type: tokenResponse.token_type,
expires_in: tokenResponse.expires_in,
scope: tokenResponse.scope,
subject: client.state.clientId
};
}
}
hook.fhirServer = new URL(client.state.serverUrl);
return hook;
}
}
25 changes: 23 additions & 2 deletions resources/HookTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { Bundle, FhirResource, Patient, Practitioner } from 'fhir/r4';

export enum SupportedHooks {
ORDER_SIGN = 'order-sign',
ORDER_SELECT = 'order-select'
ORDER_SELECT = 'order-select',
PATIENT_VIEW = 'patient-view'
}

export interface FhirAuthorization {
access_token: string;
token_type: 'Bearer';
token_type: 'Bearer' | 'bearer';
expires_in: number;
scope: string;
subject: string;
Expand All @@ -30,6 +31,13 @@ export interface OrderSelectPrefetch extends HookPrefetch {
practitioner?: Practitioner;
patient?: Patient;
}

export interface PatientViewPrefetch extends HookPrefetch {
practitioner?: Practitioner;
patient?: Patient;
medicationRequests?: Bundle;
}

export interface Hook {
hook: SupportedHooks;
hookInstance: string;
Expand All @@ -55,6 +63,14 @@ export interface OrderSelectContext extends HookContext {
selections: string[];
draftOrders: Bundle;
}

// https://cds-hooks.org/hooks/patient-view/#context
export interface PatientViewContext extends HookContext {
userId: string;
patientId: string;
encounterId?: string;
}

// https://cds-hooks.hl7.org/1.0/#calling-a-cds-service
export interface OrderSignHook extends Hook {
context: OrderSignContext;
Expand All @@ -66,6 +82,11 @@ export interface OrderSelectHook extends Hook {
prefetch?: OrderSelectPrefetch;
}

export interface PatientViewHook extends Hook {
context: PatientViewContext;
prefetch?: PatientViewPrefetch;
}

export interface Coding {
/**
* The code for what is being represented
Expand Down
12 changes: 9 additions & 3 deletions resources/OrderSelect.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Bundle } from 'fhir/r4';
import CdsHook from './CdsHook';
import { OrderSelectContext, OrderSelectHook, SupportedHooks } from './HookTypes';
import Client from 'fhirclient/lib/Client';

export default class OrderSelect extends CdsHook {
patientId: string;
Expand All @@ -9,20 +10,25 @@ export default class OrderSelect extends CdsHook {
selections: string[];

constructor(patientId: string, userId: string, draftOrders: Bundle, selections: string[]) {
super(SupportedHooks.ORDER_SIGN);
super(SupportedHooks.ORDER_SELECT);
this.patientId = patientId;
this.userId = userId;
this.draftOrders = draftOrders;
this.selections = selections;
}

generate(): OrderSelectHook {
return {
generate(client?: Client): OrderSelectHook {
const baseHook: OrderSelectHook = {
hook: this.hookType,
hookInstance: this.hookInstance,
context: this.generateContext(),
prefetch: {}
};
if (client) {
this.fillAuth(client, baseHook);
}

return baseHook;
}
generateContext(): OrderSelectContext {
return {
Expand Down
10 changes: 8 additions & 2 deletions resources/OrderSign.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Bundle } from 'fhir/r4';
import CdsHook from './CdsHook';
import { OrderSignContext, OrderSignHook, SupportedHooks } from './HookTypes';
import Client from 'fhirclient/lib/Client';

export default class OrderSign extends CdsHook {
patientId: string;
Expand All @@ -14,13 +15,18 @@ export default class OrderSign extends CdsHook {
this.draftOrders = draftOrders;
}

generate(): OrderSignHook {
return {
generate(client?: Client): OrderSignHook {
const baseHook: OrderSignHook = {
hook: this.hookType,
hookInstance: this.hookInstance,
context: this.generateContext(),
prefetch: {}
};
if (client) {
this.fillAuth(client, baseHook);
}

return baseHook;
}
generateContext(): OrderSignContext {
return {
Expand Down
28 changes: 28 additions & 0 deletions resources/PatientView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import CdsHook from './CdsHook';
import { PatientViewContext, PatientViewHook, SupportedHooks } from './HookTypes';

export default class PatientView extends CdsHook {
patientId: string;
userId: string;

constructor(patientId: string, userId: string) {
super(SupportedHooks.PATIENT_VIEW);
this.patientId = patientId;
this.userId = userId;
}

generate(): PatientViewHook {
return {
hook: this.hookType,
hookInstance: this.hookInstance,
context: this.generateContext(),
prefetch: {}
};
}
generateContext(): PatientViewContext {
return {
userId: this.userId,
patientId: this.patientId
};
}
}

0 comments on commit 9d175cc

Please sign in to comment.