From d7c87977b436722037a170ff1e8fd44be6975ecb Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Thu, 19 Feb 2026 10:17:22 -0500 Subject: [PATCH 1/5] pims bug fix --- backend/env.json | 2 +- backend/package-lock.json | 15 +++++++++++++++ backend/src/lib/pharmacyConfig.js | 22 +++++++++++++--------- backend/src/server.ts | 4 ++-- frontend/package-lock.json | 7 ++++--- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/backend/env.json b/backend/env.json index 18462d2..fb0b270 100644 --- a/backend/env.json +++ b/backend/env.json @@ -57,7 +57,7 @@ }, "INTERMEDIARY_URL": { "type": "string", - "default": "http://localhost:8090/ncpdp/script" + "default": "http://localhost:3003" }, "EHR_NCPDP_URL": { "type": "string", diff --git a/backend/package-lock.json b/backend/package-lock.json index 3b83609..3af915e 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -3354,6 +3354,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "license": "MIT", diff --git a/backend/src/lib/pharmacyConfig.js b/backend/src/lib/pharmacyConfig.js index dd3fbd7..b85cc02 100644 --- a/backend/src/lib/pharmacyConfig.js +++ b/backend/src/lib/pharmacyConfig.js @@ -1,21 +1,25 @@ - -// Configuration state +// Configuration state let config = { - useIntermediary: process.env.USE_INTERMEDIARY, - intermediaryUrl: process.env.INTERMEDIARY_URL, - remsAdminUrl: process.env.REMS_ADMIN_NCPDP, - ehrUrl: process.env.EHR_NCPDP_URL + useIntermediary: process.env.USE_INTERMEDIARY === 'true', + intermediaryUrl: process.env.INTERMEDIARY_URL || '', + remsAdminUrl: process.env.REMS_ADMIN_NCPDP || '', + ehrUrl: process.env.EHR_NCPDP_URL || '' }; - - export function getConfig() { return { ...config }; } export function updateConfig(newConfig) { - config = { ...config, ...newConfig }; + const sanitized = { ...newConfig }; + + if ('useIntermediary' in sanitized) { + const val = sanitized.useIntermediary; + sanitized.useIntermediary = val === true || val === 'true'; + } + + config = { ...config, ...sanitized }; console.log('Configuration updated:', config); return { ...config }; } diff --git a/backend/src/server.ts b/backend/src/server.ts index 1627125..374f8aa 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -9,7 +9,6 @@ import env from 'var'; import https from 'https'; import fs from 'fs'; -//middleware and configurations import bodyParser from 'body-parser'; main().catch(err => console.log(err)); @@ -23,6 +22,7 @@ async function main() { console.log('CORS OPTIONS: ' + JSON.stringify(options)); + app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cors(options)); app.use('/doctorOrders', doctorOrders); @@ -48,4 +48,4 @@ async function main() { user: env.MONGO_USERNAME, pass: env.MONGO_PASSWORD }); -} +} \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8045496..3477c50 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -19518,9 +19518,10 @@ } }, "node_modules/vite-tsconfig-paths/node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", "optional": true, "peer": true, "bin": { From b28541063c0e4ba271bd8afef82c04e28de6954c Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Thu, 19 Feb 2026 10:30:57 -0500 Subject: [PATCH 2/5] config bug fix --- backend/src/routes/doctorOrders.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/routes/doctorOrders.js b/backend/src/routes/doctorOrders.js index cd23700..9dc1c85 100644 --- a/backend/src/routes/doctorOrders.js +++ b/backend/src/routes/doctorOrders.js @@ -385,7 +385,7 @@ const isRemsDrug = order => { const getEtasuUrl = order => { let baseUrl; - if (env.USE_INTERMEDIARY) { + if (getConfig().useIntermediary) { baseUrl = env.INTERMEDIARY_FHIR_URL; } else { const remsDrug = medicationRequestToRemsAdmins.find(entry => { @@ -419,7 +419,7 @@ const getGuidanceResponse = async order => { // Make the etasu call with the case number if it exists, if not call with patient and medication let body = {}; - if (order.caseNumber && !env.USE_INTERMEDIARY) { + if (order.caseNumber && !getConfig().useIntermediary) { body = { resourceType: 'Parameters', parameter: [ From fc53f2adf1507caa7f5de8021feaaa1be72ff484 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Thu, 19 Feb 2026 10:32:49 -0500 Subject: [PATCH 3/5] config menu --- frontend/src/components/ConfigToggle.tsx | 74 ++++++++++++++++++------ 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/ConfigToggle.tsx b/frontend/src/components/ConfigToggle.tsx index 70598c4..0235fe2 100644 --- a/frontend/src/components/ConfigToggle.tsx +++ b/frontend/src/components/ConfigToggle.tsx @@ -1,19 +1,30 @@ -import { IconButton, Menu, MenuItem, Switch, Typography, Box, Divider } from '@mui/material'; +import { IconButton, Menu, MenuItem, Switch, Typography, Box, Divider, TextField, Button } from '@mui/material'; import SettingsIcon from '@mui/icons-material/Settings'; import { useState, useEffect } from 'react'; import axios from 'axios'; +interface PharmacyConfig { + useIntermediary: boolean; + intermediaryUrl: string; + remsAdminUrl: string; + ehrUrl: string; +} + export default function ConfigToggle() { const [anchorEl, setAnchorEl] = useState(null); - const [useIntermediary, setUseIntermediary] = useState(false); + const [config, setConfig] = useState({ + useIntermediary: false, + intermediaryUrl: '', + remsAdminUrl: '', + ehrUrl: '', + }); const open = Boolean(anchorEl); - // Load config on mount + // Load config from backend on mount useEffect(() => { - const saved = localStorage.getItem('useIntermediary'); - if (saved !== null) { - setUseIntermediary(saved === 'true'); - } + axios.get('/doctorOrders/api/config') + .then(({ data }) => setConfig(data)) + .catch(() => console.error('Failed to load config')); }, []); const handleClick = (event: React.MouseEvent) => { @@ -24,15 +35,15 @@ export default function ConfigToggle() { setAnchorEl(null); }; - const handleToggle = async () => { - const newValue = !useIntermediary; - setUseIntermediary(newValue); - localStorage.setItem('useIntermediary', String(newValue)); + const handleToggle = () => { + setConfig(prev => ({ ...prev, useIntermediary: !prev.useIntermediary })); + }; - // Update backend + const handleSave = async () => { try { - await axios.post('/doctorOrders/api/config', { useIntermediary: newValue }); - console.log('Configuration updated:', newValue ? 'Using Intermediary' : 'Direct Connection'); + await axios.post('/doctorOrders/api/config', config); + console.log('Configuration updated:', config); + handleClose(); } catch (error) { console.error('Failed to update backend config:', error); } @@ -55,7 +66,7 @@ export default function ConfigToggle() { open={open} onClose={handleClose} PaperProps={{ - sx: { minWidth: 280, p: 1 } + sx: { minWidth: 300, p: 1 } }} > @@ -66,19 +77,44 @@ export default function ConfigToggle() { - + Use Intermediary - {useIntermediary - ? 'Routing via intermediary' - : 'Direct to REMS Admin'} + {config.useIntermediary ? 'Routing via intermediary' : 'Direct to REMS Admin'} + + + setConfig(prev => ({ ...prev, intermediaryUrl: e.target.value }))} + /> + setConfig(prev => ({ ...prev, remsAdminUrl: e.target.value }))} + /> + setConfig(prev => ({ ...prev, ehrUrl: e.target.value }))} + /> + + ); From b5c29df42c3ceeecbe0838ca4e52cd415c45cee3 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Thu, 19 Feb 2026 10:40:02 -0500 Subject: [PATCH 4/5] env update backend --- README.md | 5 +++-- backend/env.json | 4 ++-- backend/src/lib/pharmacyConfig.js | 12 +++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 71831bc..a3369a2 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ The backend environment variables are configured in `backend/env.json`: | USE_INTERMEDIARY | `true` | Set to `true` to route ETASU checks through the REMS intermediary instead of directly to REMS admin. | | INTERMEDIARY_FHIR_URL | `http://localhost:3003/4_0_0` | Base URL of the REMS intermediary FHIR server. Used when `USE_INTERMEDIARY` is true. | | REMS_ADMIN_NCPDP | `http://localhost:8090/ncpdp/script` | URL endpoint for sending NCPDP Script messages directly to REMS admin. | +| INTERMEDIARY_URL | `http://localhost:3003` | Base URL of the REMS intermediary. Used when `USE_INTERMEDIARY` is true to route NCPDP Script and RxFill messages. | +| EHR_NCPDP_URL | `http://localhost:8080/ncpdp/script` | URL endpoint for sending NCPDP Script messages directly to the EHR system. Used when `USE_INTERMEDIARY` is false. | ## Setup @@ -119,5 +121,4 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. - +limitations under the License. \ No newline at end of file diff --git a/backend/env.json b/backend/env.json index fb0b270..4d265bd 100644 --- a/backend/env.json +++ b/backend/env.json @@ -61,6 +61,6 @@ }, "EHR_NCPDP_URL": { "type": "string", - "default": "|| 'http://localhost:8080/ncpdp/script'" + "default": "http://localhost:8080/ncpdp/script" } -} +} \ No newline at end of file diff --git a/backend/src/lib/pharmacyConfig.js b/backend/src/lib/pharmacyConfig.js index b85cc02..f60d458 100644 --- a/backend/src/lib/pharmacyConfig.js +++ b/backend/src/lib/pharmacyConfig.js @@ -1,9 +1,11 @@ -// Configuration state +import env from 'var'; + +// Configuration state let config = { - useIntermediary: process.env.USE_INTERMEDIARY === 'true', - intermediaryUrl: process.env.INTERMEDIARY_URL || '', - remsAdminUrl: process.env.REMS_ADMIN_NCPDP || '', - ehrUrl: process.env.EHR_NCPDP_URL || '' + useIntermediary: env.USE_INTERMEDIARY, + intermediaryUrl: env.INTERMEDIARY_URL, + remsAdminUrl: env.REMS_ADMIN_NCPDP, + ehrUrl: env.EHR_NCPDP_URL }; export function getConfig() { From bd1169d6bf1f81313e555e7d3084509a97f55af5 Mon Sep 17 00:00:00 2001 From: Sahil Malhotra Date: Thu, 19 Feb 2026 10:41:59 -0500 Subject: [PATCH 5/5] quotes --- backend/src/routes/doctorOrders.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/routes/doctorOrders.js b/backend/src/routes/doctorOrders.js index 9dc1c85..630cfa8 100644 --- a/backend/src/routes/doctorOrders.js +++ b/backend/src/routes/doctorOrders.js @@ -5,7 +5,7 @@ import axios from 'axios'; // XML Parsing Middleware used for NCPDP SCRIPT import bodyParser from 'body-parser'; import bpx from 'body-parser-xml'; -import { parseStringPromise } from "xml2js"; +import { parseStringPromise } from 'xml2js'; import env from 'var'; import { buildRxStatus,