From da9bd5b5b277105f48870e9207d4c1e8fc9137c8 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 07:14:45 -0400 Subject: [PATCH 01/10] update rems admin to work with auth number to case number migration --- src/fhir/guidanceResponseUtilities.ts | 3 +++ src/lib/etasu.ts | 5 ++++- src/services/guidanceresponse.service.ts | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/fhir/guidanceResponseUtilities.ts b/src/fhir/guidanceResponseUtilities.ts index b6806e1..f99d189 100644 --- a/src/fhir/guidanceResponseUtilities.ts +++ b/src/fhir/guidanceResponseUtilities.ts @@ -29,6 +29,7 @@ export class GuidanceResponseUtilities { RemsCase, | 'drugName' | 'auth_number' + | 'case_number' | 'status' | 'drugCode' | 'patientFirstName' @@ -79,6 +80,7 @@ export class GuidanceResponseUtilities { } }); outputParameters.parameter?.push({ name: 'auth_number', valueString: etasu?.auth_number }); + outputParameters.parameter?.push({ name: 'case_number', valueString: etasu?.case_number }); return outputParameters; } @@ -87,6 +89,7 @@ export class GuidanceResponseUtilities { RemsCase, | 'drugName' | 'auth_number' + | 'case_number' | 'status' | 'drugCode' | 'patientFirstName' diff --git a/src/lib/etasu.ts b/src/lib/etasu.ts index 8922b5b..e1c28f2 100644 --- a/src/lib/etasu.ts +++ b/src/lib/etasu.ts @@ -34,7 +34,7 @@ router.get('/met/:caseId', async (req: Request, res: Response) => { }); router.get('/met/auth/:authNumber', async (req: Request, res: Response) => { - console.log('get etasu by authnumber: ' + req.params.authNumber); + console.log('get etasu by authNumber: ' + req.params.authNumber); res.send(await remsCaseCollection.findOne({ auth_number: req.params.authNumber })); }); @@ -46,6 +46,7 @@ export const getCaseInfo = async ( | 'status' | 'drugName' | 'auth_number' + | 'case_number' | 'drugCode' | 'patientFirstName' | 'patientLastName' @@ -67,6 +68,7 @@ export const getCaseInfo = async ( | 'status' | 'drugName' | 'auth_number' + | 'case_number' | 'drugCode' | 'patientFirstName' | 'patientLastName' @@ -76,6 +78,7 @@ export const getCaseInfo = async ( status: 'Approved', drugName: drug?.name, auth_number: remsCaseSearchDict.auth_number || '', + case_number: remsCaseSearchDict.case_number || '', drugCode: drug?.code, patientFirstName: remsCaseSearchDict.patientFirstName || '', patientLastName: remsCaseSearchDict.patientLastName || '', diff --git a/src/services/guidanceresponse.service.ts b/src/services/guidanceresponse.service.ts index de37ed9..6aff51b 100644 --- a/src/services/guidanceresponse.service.ts +++ b/src/services/guidanceresponse.service.ts @@ -59,6 +59,8 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { let patient: Patient | undefined; let medication: Medication | MedicationRequest | undefined; let authNumber: string | undefined; + let caseNumber: string | undefined; + parameters?.parameter?.forEach(param => { if (param?.name === 'patient' && param?.resource?.resourceType === 'Patient') { @@ -71,12 +73,15 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { medication = param.resource; } else if (param?.name === 'authNumber') { authNumber = param.valueString; + } else if (param?.name === 'caseNumber') { + caseNumber = param.valueString; } }); let etasu: Pick< RemsCase, | 'drugName' + | 'case_number' | 'auth_number' | 'status' | 'drugCode' @@ -94,7 +99,15 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { const medicationSearchDict = {}; etasu = await getCaseInfo(remsCaseSearchDict, medicationSearchDict); - } else { + } else if (caseNumber) { + const remsCaseSearchDict = { + case_number: caseNumber + }; + + const medicationSearchDict = {}; + + etasu = await getCaseInfo(remsCaseSearchDict, medicationSearchDict); + }else { const drugCode = getMedicationCode(medication); // grab the patient demographics from the Patient resource in the parameters From 1cb7c717a342aed67021876d2b1d13301b086ff6 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 10:36:49 -0400 Subject: [PATCH 02/10] remove case number from output params --- src/fhir/guidanceResponseUtilities.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fhir/guidanceResponseUtilities.ts b/src/fhir/guidanceResponseUtilities.ts index f99d189..2961e49 100644 --- a/src/fhir/guidanceResponseUtilities.ts +++ b/src/fhir/guidanceResponseUtilities.ts @@ -80,7 +80,6 @@ export class GuidanceResponseUtilities { } }); outputParameters.parameter?.push({ name: 'auth_number', valueString: etasu?.auth_number }); - outputParameters.parameter?.push({ name: 'case_number', valueString: etasu?.case_number }); return outputParameters; } From cbff94f7b4a5cbdfd9bab1bb0f5c54442c3ac518 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 10:52:23 -0400 Subject: [PATCH 03/10] put back case number - handle in pims --- src/fhir/guidanceResponseUtilities.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fhir/guidanceResponseUtilities.ts b/src/fhir/guidanceResponseUtilities.ts index 2961e49..f99d189 100644 --- a/src/fhir/guidanceResponseUtilities.ts +++ b/src/fhir/guidanceResponseUtilities.ts @@ -80,6 +80,7 @@ export class GuidanceResponseUtilities { } }); outputParameters.parameter?.push({ name: 'auth_number', valueString: etasu?.auth_number }); + outputParameters.parameter?.push({ name: 'case_number', valueString: etasu?.case_number }); return outputParameters; } From 4954be719cd18c7536fe4c34992a3ede7a180d77 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 11:16:24 -0400 Subject: [PATCH 04/10] formatting --- src/services/guidanceresponse.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/guidanceresponse.service.ts b/src/services/guidanceresponse.service.ts index 6aff51b..6d022f9 100644 --- a/src/services/guidanceresponse.service.ts +++ b/src/services/guidanceresponse.service.ts @@ -107,7 +107,7 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { const medicationSearchDict = {}; etasu = await getCaseInfo(remsCaseSearchDict, medicationSearchDict); - }else { + } else { const drugCode = getMedicationCode(medication); // grab the patient demographics from the Patient resource in the parameters From 875d4ae44e374d820d6ab4d1085e16723b9df700 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 11:23:45 -0400 Subject: [PATCH 05/10] run prettier --- src/hooks/hookResources.ts | 5 ++--- src/server.ts | 1 - src/services/guidanceresponse.service.ts | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hooks/hookResources.ts b/src/hooks/hookResources.ts index deaccad..0194a5c 100644 --- a/src/hooks/hookResources.ts +++ b/src/hooks/hookResources.ts @@ -855,9 +855,8 @@ export function createQuestionnaireCompletionTask( } ] }, - valueString: `${requirement.appContext}&order=${JSON.stringify(request)}&coverage=${ - request?.insurance?.[0].reference - }` + valueString: `${requirement.appContext}&order=${JSON.stringify(request)}&coverage=${request + ?.insurance?.[0].reference}` } ] }; diff --git a/src/server.ts b/src/server.ts index ff5fd52..b5ad26b 100644 --- a/src/server.ts +++ b/src/server.ts @@ -18,7 +18,6 @@ import bodyParserXml from 'body-parser-xml'; const logger = container.get('application'); - const initialize = (config: any) => { //const logLevel = _.get(config, 'logging.level'); return new REMSServer(config.fhirServerConfig) diff --git a/src/services/guidanceresponse.service.ts b/src/services/guidanceresponse.service.ts index 6d022f9..728fa08 100644 --- a/src/services/guidanceresponse.service.ts +++ b/src/services/guidanceresponse.service.ts @@ -61,7 +61,6 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { let authNumber: string | undefined; let caseNumber: string | undefined; - parameters?.parameter?.forEach(param => { if (param?.name === 'patient' && param?.resource?.resourceType === 'Patient') { patient = param.resource; From 6a95944e52efcff73fab878d096ad92f44c3eeec Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 11:31:12 -0400 Subject: [PATCH 06/10] run eslint --- frontend/vite.config.ts | 2 +- src/hooks/hookResources.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index ca9ba31..12f4f80 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ base: '', plugins: [react()], preview: { - allowedHosts: ['.mitre.org', '.us-east-1.elb.amazonaws.com'], + allowedHosts: ['.mitre.org', '.us-east-1.elb.amazonaws.com'] }, define: { 'process.env': process.env diff --git a/src/hooks/hookResources.ts b/src/hooks/hookResources.ts index 0194a5c..deaccad 100644 --- a/src/hooks/hookResources.ts +++ b/src/hooks/hookResources.ts @@ -855,8 +855,9 @@ export function createQuestionnaireCompletionTask( } ] }, - valueString: `${requirement.appContext}&order=${JSON.stringify(request)}&coverage=${request - ?.insurance?.[0].reference}` + valueString: `${requirement.appContext}&order=${JSON.stringify(request)}&coverage=${ + request?.insurance?.[0].reference + }` } ] }; From 2561dc58a2eba0561ce17a2119f79f295f1a30d3 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 11:51:46 -0400 Subject: [PATCH 07/10] update ci/cd --- .github/workflows/ci-workflow.yml | 7 +++++-- .github/workflows/docker-cd-dev.yml | 1 + .github/workflows/docker-cd.yml | 1 + .github/workflows/docker-ci.yml | 1 + .github/workflows/docker-tag-cd.yml | 3 ++- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index fe97a70..36037bf 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -7,12 +7,15 @@ jobs: name: Check tsc, lint, and prettier runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - name: Checkout Repository uses: actions/checkout@v3 with: submodules: true - node-version: '14.x' + clean: true + + - uses: actions/setup-node@v1 + with: + node-version: "18.x" - run: npm install - run: npm run lint diff --git a/.github/workflows/docker-cd-dev.yml b/.github/workflows/docker-cd-dev.yml index 809f164..fe2bb5e 100644 --- a/.github/workflows/docker-cd-dev.yml +++ b/.github/workflows/docker-cd-dev.yml @@ -14,6 +14,7 @@ jobs: uses: actions/checkout@v3 with: submodules: true + clean: true - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2 diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 78a22ed..858a0c1 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -14,6 +14,7 @@ jobs: uses: actions/checkout@v3 with: submodules: true + clean: true - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2 diff --git a/.github/workflows/docker-ci.yml b/.github/workflows/docker-ci.yml index 5edae1d..36f1abe 100644 --- a/.github/workflows/docker-ci.yml +++ b/.github/workflows/docker-ci.yml @@ -15,6 +15,7 @@ jobs: uses: actions/checkout@v3 with: submodules: true + clean: true - name: Test Server Docker image Builds run: docker build . \ No newline at end of file diff --git a/.github/workflows/docker-tag-cd.yml b/.github/workflows/docker-tag-cd.yml index 0287fe9..e565595 100644 --- a/.github/workflows/docker-tag-cd.yml +++ b/.github/workflows/docker-tag-cd.yml @@ -14,7 +14,8 @@ jobs: uses: actions/checkout@v3 with: submodules: true - + clean: true + - name: Setup Docker Buildx uses: docker/setup-buildx-action@v2 From b4408c498c8474761dbc93147d4f7efa3e2d68de Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 12:03:14 -0400 Subject: [PATCH 08/10] remove all instances of auth number --- README.md | 2 +- frontend/src/views/DataViews/CaseCollection.tsx | 3 --- src/fhir/guidanceResponseUtilities.ts | 3 --- src/fhir/models.ts | 2 -- src/lib/etasu.ts | 11 ----------- src/services/guidanceresponse.service.ts | 14 +------------- 6 files changed, 2 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 84cdb6b..777d9ad 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ The FHIR server built into the REMS Admin can be queried for the questionnaire p - Input requires a parameter containing the following: - `patient` - Patient FHIR Resource, must include `medication` with `patient` - `medication` - Medication or MedicationRequest FHIR Resource, must include `patient` with `medication` - - `authNumber` - String containing the REMS Authorization Number, may be sent without `patient` or `medication` + - `caseNumber` - String containing the REMS Case Number, may be sent without `patient` or `medication` - Returns a GuidanceResponse within a Parameter with the status - Contains Nested GuidanceResponse resources for each ETASU requirement with their status - `/4_0_0/Questionnaire/\/$questionnaire-package` - The endpoint for the FHIR Operation used for retrieving the Questionnaire package for a given form diff --git a/frontend/src/views/DataViews/CaseCollection.tsx b/frontend/src/views/DataViews/CaseCollection.tsx index 0c7e496..5589d5b 100644 --- a/frontend/src/views/DataViews/CaseCollection.tsx +++ b/frontend/src/views/DataViews/CaseCollection.tsx @@ -21,7 +21,6 @@ import FormPopup from '../FormPopup'; export type RemsCase = { case_number?: string; - auth_number?: string; patientFirstName?: string; patientLastName?: string; patientDOB?: string; @@ -162,7 +161,6 @@ const CaseCollection = (props: { refresh: boolean }) => { Patient DOB Status Dispense Status - Authorization Number Met Requirements Delete @@ -180,7 +178,6 @@ const CaseCollection = (props: { refresh: boolean }) => { {row.patientDOB} {row.status} {row.dispenseStatus} - {row.auth_number} {metReq} ( const remsCaseCollectionSchema = new Schema({ case_number: { type: String }, - auth_number: { type: String }, status: { type: String }, dispenseStatus: { type: String }, drugName: { type: String }, diff --git a/src/lib/etasu.ts b/src/lib/etasu.ts index e1c28f2..e66ac42 100644 --- a/src/lib/etasu.ts +++ b/src/lib/etasu.ts @@ -33,11 +33,6 @@ router.get('/met/:caseId', async (req: Request, res: Response) => { res.send(await remsCaseCollection.findOne({ case_number: req.params.caseId })); }); -router.get('/met/auth/:authNumber', async (req: Request, res: Response) => { - console.log('get etasu by authNumber: ' + req.params.authNumber); - res.send(await remsCaseCollection.findOne({ auth_number: req.params.authNumber })); -}); - export const getCaseInfo = async ( remsCaseSearchDict: FilterQuery, medicationSearchDict: FilterQuery @@ -45,7 +40,6 @@ export const getCaseInfo = async ( RemsCase, | 'status' | 'drugName' - | 'auth_number' | 'case_number' | 'drugCode' | 'patientFirstName' @@ -67,7 +61,6 @@ export const getCaseInfo = async ( RemsCase, | 'status' | 'drugName' - | 'auth_number' | 'case_number' | 'drugCode' | 'patientFirstName' @@ -77,7 +70,6 @@ export const getCaseInfo = async ( > = { status: 'Approved', drugName: drug?.name, - auth_number: remsCaseSearchDict.auth_number || '', case_number: remsCaseSearchDict.case_number || '', drugCode: drug?.code, patientFirstName: remsCaseSearchDict.patientFirstName || '', @@ -233,7 +225,6 @@ const createMetRequirementAndNewCase = async ( const remsRequest: Pick< RemsCase, | 'case_number' - | 'auth_number' | 'status' | 'dispenseStatus' | 'drugName' @@ -244,7 +235,6 @@ const createMetRequirementAndNewCase = async ( | 'metRequirements' > = { case_number: case_number, - auth_number: '', status: remsRequestCompletedStatus, dispenseStatus: dispenseStatusDefault, drugName: drug?.name, @@ -393,7 +383,6 @@ const createMetRequirementAndUpdateCase = async ( if (!foundUncompleted && remsRequestToUpdate?.status === 'Pending') { remsRequestToUpdate.status = 'Approved'; - remsRequestToUpdate.auth_number = uid(); await remsRequestToUpdate.save(); } } diff --git a/src/services/guidanceresponse.service.ts b/src/services/guidanceresponse.service.ts index 728fa08..c2739e5 100644 --- a/src/services/guidanceresponse.service.ts +++ b/src/services/guidanceresponse.service.ts @@ -58,7 +58,6 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { const parameters: Parameters = args?.resource; let patient: Patient | undefined; let medication: Medication | MedicationRequest | undefined; - let authNumber: string | undefined; let caseNumber: string | undefined; parameters?.parameter?.forEach(param => { @@ -70,8 +69,6 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { param.resource?.resourceType === 'MedicationRequest') ) { medication = param.resource; - } else if (param?.name === 'authNumber') { - authNumber = param.valueString; } else if (param?.name === 'caseNumber') { caseNumber = param.valueString; } @@ -81,7 +78,6 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { RemsCase, | 'drugName' | 'case_number' - | 'auth_number' | 'status' | 'drugCode' | 'patientFirstName' @@ -90,15 +86,7 @@ module.exports.remsEtasu = async (args: any, context: any, logger: any) => { | 'metRequirements' > | null; - if (authNumber) { - const remsCaseSearchDict = { - auth_number: authNumber - }; - - const medicationSearchDict = {}; - - etasu = await getCaseInfo(remsCaseSearchDict, medicationSearchDict); - } else if (caseNumber) { + if (caseNumber) { const remsCaseSearchDict = { case_number: caseNumber }; From 8c893962a26018501335b24ffa1c2275158231c7 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 12:12:09 -0400 Subject: [PATCH 09/10] fix tests? --- test/server.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/server.test.ts b/test/server.test.ts index 8b57a17..f96340e 100644 --- a/test/server.test.ts +++ b/test/server.test.ts @@ -25,7 +25,7 @@ describe('REMSServer class', () => { const set = sinon.spy(server.app, 'set'); const use = sinon.spy(server.app, 'use'); - server.configureMiddleware(); + server.configureMiddleware({}); expect(set.callCount).to.equal(6); expect(set.getCall(4).args[0]).to.equal('showStackError'); expect(set.getCall(4).args[1]).to.be.true; @@ -87,20 +87,20 @@ describe('REMSServer class', () => { }); it('should be able to prepopulate data without error', async () => { - expect(await metRequirementsCollection.count({})).to.equal(0); - expect(await medicationCollection.count({})).to.equal(0); + expect(await metRequirementsCollection.countDocuments({})).to.equal(0); + expect(await medicationCollection.countDocuments({})).to.equal(0); await FhirUtilities.populateDB(); - expect(await metRequirementsCollection.count({})).to.not.equal(0); - expect(await medicationCollection.count({})).to.not.equal(0); + expect(await metRequirementsCollection.countDocuments({})).to.not.equal(0); + expect(await medicationCollection.countDocuments({})).to.not.equal(0); await FhirUtilities.populateDB(); }); it('should be able to load artifacts from filesystem', async () => { - expect(await LibraryModel.count({})).to.equal(0); - expect(await QuestionnaireModel.count({})).to.equal(0); + expect(await LibraryModel.countDocuments({})).to.equal(0); + expect(await QuestionnaireModel.countDocuments({})).to.equal(0); await FhirUtilities.loadResources('./test/fixtures/cds-library'); - expect(await LibraryModel.count({})).to.not.equal(0); - expect(await QuestionnaireModel.count({})).to.not.equal(0); + expect(await LibraryModel.countDocuments({})).to.not.equal(0); + expect(await QuestionnaireModel.countDocuments({})).to.not.equal(0); await FhirUtilities.loadResources('./test/fixtures/cds-library'); }); }); From 57ba2814954dc3745659b82f468fa5524c59bfe1 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Fri, 13 Jun 2025 12:25:39 -0400 Subject: [PATCH 10/10] test dependency --- .github/workflows/ci-workflow.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 36037bf..c7d51a3 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -22,6 +22,7 @@ jobs: - run: npm run prettier env: CI: true + test: name: Test on node ${{ matrix.node-version }} and ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -32,12 +33,24 @@ jobs: steps: - uses: actions/checkout@v1 + - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} + + - name: Install OpenSSL 1.1 on Ubuntu + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y libssl1.1 || { + # Fallback for newer Ubuntu versions + wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb + sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb + } + - run: npm install - run: git submodule update --init - run: npm test env: - CI: true + CI: true \ No newline at end of file