Skip to content

Commit 28cb300

Browse files
authored
Merge pull request #134 from mcode/dev
Dev
2 parents cd018c5 + d32b27c commit 28cb300

5 files changed

Lines changed: 113 additions & 22 deletions

File tree

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ a) `REACT_APP_LAUNCH_URL=http://example.com PORT=6000 npm start` or b) by specif
2020

2121
Following are a list of modifiable paths:
2222

23-
| URI Name | Default |
24-
| --------------- | ------------------------------------------ |
25-
| AUTH_SERVER_URI | `http://localhost:8090` |
26-
| HTTPS_CERT_PATH | `server.cert` |
27-
| HTTPS_KEY_PATH | `server.key` |
28-
| LOGGING_LEVEL | `debug` |
29-
| MONGO_DB_NAME | `remsadmin` |
30-
| MONGO_URL | `mongodb://rems-user:pass@127.0.0.1:27017` |
31-
| PORT | `8090` |
32-
| RESOURCE_SERVER | `http://localhost:8090` |
33-
| SMART_ENDPOINT | `http://localhost:4040/launch` |
34-
| USE_HTTPS | `false` |
35-
| VSAC_API_KEY | `changeMe` |
36-
| WHITELIST | `http://localhost, http://localhost:3005` |
23+
| URI Name | Default | Description |
24+
| --------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------|
25+
| AUTH_SERVER_URI | `http://localhost:8090` | The base url of the auth server, currently set to the base url of this app. |
26+
| HTTPS_CERT_PATH | `server.cert` | Path to a certificate for encryption, allowing HTTPS. Unnecessary if using HTTP. |
27+
| HTTPS_KEY_PATH | `server.key` | Path to a key for encryption, allowing HTTPS. Unnecessary if using HTTP. |
28+
| LOGGING_LEVEL | `debug` | Amount to output in the log, can be changed to verbose, info, warn, or error. |
29+
| MONGO_DB_NAME | `remsadmin` | Name of the database table being used. Should be changed if not using the Mongo instructions below. |
30+
| MONGO_URL | `mongodb://rems-user:pass@127.0.0.1:27017` | URL for the connection to the database, should be changed if not using the Mongo instructions below. |
31+
| PORT | `8090` | Port that this server should run on, change if there are conflicts with port usage. |
32+
| RESOURCE_SERVER | `http://localhost:8090` | Base URL of this server, should match with port. |
33+
| SMART_ENDPOINT | `http://localhost:4040/launch` | Launch URL of associated SMART app, should be changed if not using the REMS Smart App. |
34+
| USE_HTTPS | `false` | Change to true to enable HTTPS. Ensure that HTTPS_CERT_PATH and HTTPS_KEY_PATH are valid. |
35+
| VSAC_API_KEY | `changeMe` | Replace with VSAC API key for pulling down ValueSets. Request an API Key from the [VSAC website](https://vsac.nlm.nih.gov/) |
36+
| WHITELIST | `http://localhost, http://localhost:3005` | List of valid URLs for CORS. Should include any URLs the server accesses for resources. |
3737

3838
## Running the Mongo DB instance
3939

src/cards/Card.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ interface Source {
55
url: URL;
66
icon?: URL;
77
}
8-
interface Action {
8+
export interface Action {
99
type: string;
1010
description: string;
1111
resource?: Resource | string;
1212
}
13-
interface Suggestion {
13+
export interface Suggestion {
1414
label: string;
1515
uuid?: string;
1616
actions: Action[];

src/cds-library/CRD-DTR/IPledge/R4/resources/Questionnaire-R4-IPledge.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@
415415
},
416416
{
417417
"linkId": "6.11",
418-
"text": "10. I will not give blood while taking isotretinoin or for 1 moth after I stop taking isotretinoin. I understand that if someone who is pregnant gets my donated blood, their baby may be exposed to isotretinoin and may be born with serious birth defects.",
418+
"text": "10. I will not give blood while taking isotretinoin or for 1 month after I stop taking isotretinoin. I understand that if someone who is pregnant gets my donated blood, their baby may be exposed to isotretinoin and may be born with serious birth defects.",
419419
"type": "boolean",
420420
"required": true
421421
},

src/hooks/hookResources.ts

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
import { MedicationRequest, Coding, FhirResource, Identifier } from 'fhir/r4';
2-
import Card, { Link } from '../cards/Card';
1+
import {
2+
MedicationRequest,
3+
Coding,
4+
FhirResource,
5+
Identifier,
6+
Task,
7+
Questionnaire,
8+
Patient
9+
} from 'fhir/r4';
10+
import Card, { Link, Suggestion, Action } from '../cards/Card';
311
import {
412
HookPrefetch,
513
OrderSignPrefetch,
@@ -17,6 +25,16 @@ type HandleCallback = (
1725
contextRequest: FhirResource | undefined,
1826
patient: FhirResource | undefined
1927
) => Promise<void>;
28+
29+
interface Requirement {
30+
name: string;
31+
description: string;
32+
stakeholderType: string;
33+
createNewCase: boolean;
34+
resourceId: string;
35+
requiredToDispense: boolean;
36+
appContext?: string;
37+
}
2038
export interface CardRule {
2139
links: Link[];
2240
summary?: string;
@@ -364,6 +382,9 @@ export async function handleCardOrder(
364382
card.addLink(
365383
createSmartLink(requirement.name, requirement.appContext, contextRequest)
366384
);
385+
if (patient && patient.resourceType === 'Patient') {
386+
createQuestionnaireSuggestion(card, requirement, patient);
387+
}
367388
smartLinkCount++;
368389
}
369390
}
@@ -372,6 +393,9 @@ export async function handleCardOrder(
372393
card.addLink(
373394
createSmartLink(requirement.name, requirement.appContext, contextRequest)
374395
);
396+
if (patient && patient.resourceType === 'Patient') {
397+
createQuestionnaireSuggestion(card, requirement, patient);
398+
}
375399
smartLinkCount++;
376400
}
377401
} else {
@@ -380,6 +404,9 @@ export async function handleCardOrder(
380404
card.addLink(
381405
createSmartLink(requirement.name, requirement.appContext, contextRequest)
382406
);
407+
if (patient && patient.resourceType === 'Patient') {
408+
createQuestionnaireSuggestion(card, requirement, patient);
409+
}
383410
smartLinkCount++;
384411
}
385412
}
@@ -421,14 +448,14 @@ export async function handleCard(
421448
// verify ids
422449
if (
423450
patient?.id &&
424-
patient.id.replace('Patient/', '') !== context.patientId.replace('Patient/', '')
451+
patient.id.replace('Patient/', '') !== context.patientId?.replace('Patient/', '')
425452
) {
426453
res.json(buildErrorCard('Context patientId does not match prefetch Patient ID'));
427454
return;
428455
}
429456
if (
430457
practitioner?.id &&
431-
practitioner.id.replace('Practitioner/', '') !== context.userId.replace('Practitioner/', '')
458+
practitioner.id.replace('Practitioner/', '') !== context.userId?.replace('Practitioner/', '')
432459
) {
433460
res.json(buildErrorCard('Context userId does not match prefetch Practitioner ID'));
434461
return;
@@ -463,3 +490,67 @@ export function handleHook(
463490
res.json(buildErrorCard('Unknown Error'));
464491
}
465492
}
493+
494+
export function createQuestionnaireSuggestion(
495+
card: Card,
496+
requirement: Requirement,
497+
patient: Patient
498+
) {
499+
if (requirement.appContext && requirement.appContext.includes('=')) {
500+
const qArr = requirement.appContext.split('='); // break up into parts
501+
let qUrl = null;
502+
for (let i = 0; i < qArr.length; i++) {
503+
if (qArr[i].toLowerCase() === 'questionnaire') {
504+
if (i + 1 < qArr.length) {
505+
// not at end of array
506+
qUrl = qArr[i + 1];
507+
}
508+
}
509+
}
510+
if (qUrl) {
511+
const action: Action = {
512+
type: 'create',
513+
description: `Create task for "completion of ${requirement.name} Questionnaire`,
514+
resource: createQuestionnaireCompletionTask(requirement.name, qUrl, patient)
515+
};
516+
const suggestion: Suggestion = {
517+
label: `Add "Completion of ${requirement.name} Questionnaire" to task list`,
518+
actions: [action]
519+
};
520+
card.addSuggestion(suggestion);
521+
}
522+
}
523+
}
524+
export function createQuestionnaireCompletionTask(
525+
questionnaireTitle: string,
526+
questionnaireUrl: string,
527+
patient: Patient
528+
) {
529+
const taskResource: Task = {
530+
resourceType: 'Task',
531+
status: 'ready',
532+
intent: 'order',
533+
code: {
534+
coding: [
535+
{
536+
system: 'http://hl7.org/fhir/uv/sdc/CodeSystem/temp',
537+
code: 'complete-questionnaire'
538+
}
539+
]
540+
},
541+
description: `Complete ${questionnaireTitle} Questionnaire`,
542+
for: {
543+
reference: `${patient.resourceType}/${patient.id}`
544+
},
545+
authoredOn: `${new Date(Date.now()).toISOString()}`,
546+
input: [
547+
{
548+
type: {
549+
text: 'questionnaire'
550+
},
551+
valueCanonical: `${questionnaireUrl}`
552+
}
553+
]
554+
};
555+
return taskResource;
556+
}

src/rems-cds-hooks

0 commit comments

Comments
 (0)