Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .eslintignore
Empty file.
14 changes: 14 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": [
"prettier"
],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "single", { "avoidEscape": true }],

}
}
36 changes: 36 additions & 0 deletions .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Lint and Test

on: [push, pull_request]

jobs:
lint:
name: Check tsc, lint, and prettier
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- run: npm install
- run: npm run lint
- run: npm run prettier
env:
CI: true
test:
name: Test on node ${{ matrix.node-version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [12]

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
env:
CI: true
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "none",
"arrowParens": "avoid",
"endOfLine": "auto",
"printWidth": 100,
"tabWidth": 2,
"singleQuote": true
}
21 changes: 15 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "REMS Administrator",
"name": "rems-administrator",
"version": "1.0.0",
"description": "A starter project emphasizing best practices for creating CDS Services",
"main": "main.js",
Expand All @@ -14,8 +14,11 @@
"scripts": {
"develop": "node src/scripts/nodemon.js",
"start": "node src/scripts/serve.js",
"test": "jest",
"prettier": "prettier \"src/**/*.js\" --write",
"test": "jest --maxWorkers=4 --coverage --detectOpenHandles",
"lint": "eslint \"**/*.{js,ts}\"",
"lint:fix": "eslint \"**/*.{js,ts}\" --quiet --fix",
"prettier": "prettier --check \"**/*.{js,ts}\"",
"prettier:fix": "prettier --write \"**/*.{js,ts}\"",
"changelog": "conventional-changelog -p angular -s -i CHANGELOG.md"
},
"repository": {
Expand Down Expand Up @@ -51,8 +54,14 @@
"winston-daily-rotate-file": "^4.2.1"
},
"devDependencies": {
"eslint": "^7.0.0",
"jest": "^26.0.1",
"prettier": "^2.0.5"
"prettier": "^2.0.5",
"eslint": "^8.5.0",
"eslint-config-prettier": "^6.10.1",
"jest": "^27.4.5",
"jest-extended": "^1.2.0",
"json-diff": "^0.9.0",
"ts-jest": "^27.1.2",
"ts-node": "^9.1.1",
"typescript": "^4.8.4"
}
}
6 changes: 3 additions & 3 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module.exports = {
server: {
port: 8090,
discoveryEndpoint: '/cds-services',
discoveryEndpoint: '/cds-services'
},

logging: {
level: 'info',
},
level: 'info'
}
};
60 changes: 32 additions & 28 deletions src/hooks/rems.hook.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { kebabCase } = require("lodash");
const { kebabCase } = require('lodash');

const definition = {
hook: 'order-sign',
Expand All @@ -7,34 +7,34 @@ const definition = {
id: 'rems-order-sign',
prefetch: {
patient: 'Patient/{{context.patientId}}',
request:'MedicationRequest?_id={{context.draftOrders.MedicationRequest.id}}',
request: 'MedicationRequest?_id={{context.draftOrders.MedicationRequest.id}}',
practitioner: 'Practitioner/{{context.userId}}'
},
}
};

const sourceLabel = "MCODE REMS Administrator Prototype";
const sourceUrl = "https://github.com/mcode/REMS";
const sourceLabel = 'MCODE REMS Administrator Prototype';
const sourceUrl = 'https://github.com/mcode/REMS';

function buildErrorCard(reason) {
console.log(reason);
let cards = {
cards: [
{
summary: "Bad Request",
summary: 'Bad Request',
detail: reason,
source: {
label: sourceLabel,
url: sourceUrl
},
indicator: 'warning',
},
],
indicator: 'warning'
}
]
};
return cards;
};
}

const handler = (req, res) => {
console.log("REMS order-sign hook")
console.log('REMS order-sign hook');
try {
const context = req.body.context;
const contextRequest = context.draftOrders.entry[0];
Expand All @@ -44,27 +44,32 @@ const handler = (req, res) => {
const practitioner = prefetch.practitioner;
const npi = practitioner.identifier[0].value;

console.log(" MedicationRequest: " + prefetchRequest.id);
console.log(" Practitioner: " + practitioner.id + " NPI: " + npi);
console.log(" Patient: " + patient.id);
console.log(' MedicationRequest: ' + prefetchRequest.id);
console.log(' Practitioner: ' + practitioner.id + ' NPI: ' + npi);
console.log(' Patient: ' + patient.id);

// verify a MedicationRequest was sent
if (contextRequest.resourceType !== "MedicationRequest") {
res.json(buildErrorCard("DraftOrders does not contain a MedicationRequest"));
if (contextRequest.resourceType !== 'MedicationRequest') {
res.json(buildErrorCard('DraftOrders does not contain a MedicationRequest'));
return;
}

// verify ids
if (patient.id.replace('Patient/','') !== context.patientId.replace('Patient/','')) {
res.json(buildErrorCard("Context patientId does not match prefetch Patient ID"));
if (patient.id.replace('Patient/', '') !== context.patientId.replace('Patient/', '')) {
res.json(buildErrorCard('Context patientId does not match prefetch Patient ID'));
return;
}
if (practitioner.id.replace('Practitioner/','') !== context.userId.replace('Practitioner/','')) {
res.json(buildErrorCard("Context userId does not match prefetch Practitioner ID"));
if (
practitioner.id.replace('Practitioner/', '') !== context.userId.replace('Practitioner/', '')
) {
res.json(buildErrorCard('Context userId does not match prefetch Practitioner ID'));
return;
}
if (prefetchRequest.id.replace('MedicationRequest/','') !== contextRequest.id.replace('MedicationRequest/','')) {
res.json(buildErrorCard("Context draftOrder does not match prefetch MedicationRequest ID"));
if (
prefetchRequest.id.replace('MedicationRequest/', '') !==
contextRequest.id.replace('MedicationRequest/', '')
) {
res.json(buildErrorCard('Context draftOrder does not match prefetch MedicationRequest ID'));
return;
}

Expand All @@ -77,17 +82,16 @@ const handler = (req, res) => {
detail: `Detail: ${text}`,
source: {
label: sourceLabel,
url: sourceUrl,
url: sourceUrl
},
indicator: 'info',
},
],
indicator: 'info'
}
]
};
res.json(cards);

} catch (error) {
console.log(error);
res.json(buildErrorCard("Unknown Error"));
res.json(buildErrorCard('Unknown Error'));
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/hooks/rems.hook.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ describe('hook: test rems', () => {
id: 'rems-order-sign',
prefetch: {
patient: 'Patient/{{context.patientId}}',
request:'MedicationRequest?_id={{context.draftOrders.MedicationRequest.id}}',
request: 'MedicationRequest?_id={{context.draftOrders.MedicationRequest.id}}',
practitioner: 'Practitioner/{{context.userId}}'
},
}
};
expect(getREMSHook).toHaveProperty('definition');
expect(getREMSHook).toHaveProperty('handler');
Expand Down
6 changes: 3 additions & 3 deletions src/lib/winston.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ let applicationTransports = [];
let transportConsole = new transports.Console({
level: logging.level,
timestamp: true,
colorize: true,
colorize: true
});

applicationTransports.push(transportConsole);
Expand All @@ -25,7 +25,7 @@ if (logging.directory) {
datePattern: 'YYYY-MM-DD-HH',
level: logging.level,
zippedArchive: true,
maxSize: '20m',
maxSize: '20m'
});

applicationTransports.push(transportDailyFile);
Expand All @@ -34,7 +34,7 @@ if (logging.directory) {
// Add a default application logger
container.add('application', {
format: format.combine(format.timestamp(), format.logstash()),
transports: applicationTransports,
transports: applicationTransports
});

/**
Expand Down
4 changes: 2 additions & 2 deletions src/lib/winston.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ describe('Logger Class', () => {
jest.mock('../config', () => ({
logging: {
level: 'debug',
directory: 'logs',
},
directory: 'logs'
}
}));

const config = require('../config');
Expand Down
3 changes: 1 addition & 2 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ module.exports = async function main() {
// Build our server
logger.info('Initializing REMS Administrator');

const app = initialize(config)
.registerService(remsService);
const app = initialize(config).registerService(remsService);

const { server: serverConfig } = config;

Expand Down
2 changes: 1 addition & 1 deletion src/scripts/develop.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ nodemon({
ext: 'js json',
verbose: true,
watch: ['src/**/*.json', 'src/**/*.js'],
ignore: ['node_modules'],
ignore: ['node_modules']
});

nodemon
Expand Down
8 changes: 3 additions & 5 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const _ = require('lodash');

let logger = container.get('application');

const initialize = (config) => {
const initialize = config => {
const logLevel = _.get(config, 'logging.level');
return new REMSServer().configureLogstream(logLevel).configureMiddleware();
};
Expand Down Expand Up @@ -54,7 +54,7 @@ class REMSServer {
log
? log
: morgan('combined', {
stream: { write: (message) => logger[level](message) },
stream: { write: message => logger[level](message) }
})
);

Expand All @@ -81,9 +81,7 @@ class REMSServer {
listen({ port, discoveryEndpoint = '/cds-services' }, callback) {
this.app.get(discoveryEndpoint, (req, res) => res.json({ services: this.services }));
this.app.get('/', (req, res) => res.send('Welcome to the REMS Administrator'));
this.app.listen(port, callback);

return this;
return this.app.listen(port, callback);
}
}

Expand Down
Loading