diff --git a/Dockerfile b/Dockerfile index 7a27089..00ab7c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ RUN npm install WORKDIR /home/node/app/frontend RUN npm install +RUN npm run build WORKDIR /home/node/app diff --git a/README.md b/README.md index 2a2989c..19ad5a2 100644 --- a/README.md +++ b/README.md @@ -52,3 +52,35 @@ This application requires node.js v20.0 or greater. Using [`nvm`](https://github - `nvm install 20` - `nvm use 20` or `nvm use default 20`, as most of the REMS Integration Prototype repositories are compatible with node v20.0. + +# Data Rights + +
+NOTICE +
+ +This (software/technical data) was produced for the U. S. Government under Contract Number 75FCMC18D0047/75FCMC23D0004, and is subject to Federal Acquisition Regulation Clause 52.227-14, Rights in Data-General. + + +No other use other than that granted to the U. S. Government, or to those acting on behalf of the U. S. Government under that Clause is authorized without the express written permission of The MITRE Corporation. + + +For further information, please contact The MITRE Corporation, Contracts Management Office, 7515 Colshire Drive, McLean, VA 22102-7539, (703) 983-6000. + +
+©2025 The MITRE Corporation. +
+ +
+ +Licensed under the Apache License, Version 2.0 (the "License"); use of this repository is permitted in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. + diff --git a/backend/env.json b/backend/env.json index 138415c..30e25f1 100644 --- a/backend/env.json +++ b/backend/env.json @@ -4,19 +4,8 @@ "default": 5051 }, "ALLOWED_ORIGIN": { - "type": "object", - "default": [ - "http://localhost:3000", - "http://localhost:3000/", - "http://localhost:3005", - "http://localhost:3005/", - "http://localhost:3008", - "http://localhost:3008/", - "http://localhost:5050", - "http://localhost:5050/", - "http://localhost:4040", - "http://localhost:4040/" - ] + "type": "string", + "default": "*" }, "MONGO_USERNAME": { "type": "string", diff --git a/backend/src/routes/doctorOrders.js b/backend/src/routes/doctorOrders.js index a7d101e..9af2b78 100644 --- a/backend/src/routes/doctorOrders.js +++ b/backend/src/routes/doctorOrders.js @@ -396,51 +396,53 @@ const getDispenseStatus = (order, guidanceResponse) => { */ async function parseNCPDPScript(newRx) { // Parsing XML NCPDP SCRIPT from EHR + const patient = newRx.Message.Body.NewRx.Patient; + const prescriber = newRx.Message.Body.NewRx.Prescriber; + const medicationPrescribed = newRx.Message.Body.NewRx.MedicationPrescribed; + const incompleteOrder = { orderId: newRx.Message.Header.MessageID.toString(), // Will need to return to this and use actual pt identifier or uuid caseNumber: newRx.Message.Header.AuthorizationNumber, prescriberOrderNumber: newRx.Message.Header.PrescriberOrderNumber, - patientName: - newRx.Message.Body.NewRx.Patient.HumanPatient.Name.FirstName + - ' ' + - newRx.Message.Body.NewRx.Patient.HumanPatient.Name.LastName, - patientFirstName: newRx.Message.Body.NewRx.Patient.HumanPatient.Name.FirstName, - patientLastName: newRx.Message.Body.NewRx.Patient.HumanPatient.Name.LastName, - patientDOB: newRx.Message.Body.NewRx.Patient.HumanPatient.DateOfBirth.Date, - patientCity: newRx.Message.Body.NewRx.Patient.HumanPatient.Address.City, - patientStateProvince: newRx.Message.Body.NewRx.Patient.HumanPatient.Address.StateProvince, - patientPostalCode: newRx.Message.Body.NewRx.Patient.HumanPatient.Address.PostalCode, - patientCountry: newRx.Message.Body.NewRx.Patient.HumanPatient.Address.Country, + patientName: patient.HumanPatient.Name.FirstName + ' ' + patient.HumanPatient.Name.LastName, + patientFirstName: patient.HumanPatient.Name.FirstName, + patientLastName: patient.HumanPatient.Name.LastName, + patientDOB: patient.HumanPatient.DateOfBirth.Date, + patientCity: patient.HumanPatient.Address.City, + patientStateProvince: patient.HumanPatient.Address.StateProvince, + patientPostalCode: patient.HumanPatient.Address.PostalCode, + patientCountry: patient.HumanPatient.Address.Country, doctorName: 'Dr. ' + - newRx.Message.Body.NewRx.Prescriber.NonVeterinarian.Name.FirstName + + prescriber.NonVeterinarian.Name.FirstName + ' ' + - newRx.Message.Body.NewRx.Prescriber.NonVeterinarian.Name.LastName, - doctorContact: - newRx.Message.Body.NewRx.Prescriber.NonVeterinarian.CommunicationNumbers.PrimaryTelephone - ?.Number, - doctorID: newRx.Message.Body.NewRx.Prescriber.NonVeterinarian.Identification.NPI, - doctorEmail: - newRx.Message.Body.NewRx.Prescriber.NonVeterinarian.CommunicationNumbers.ElectronicMail, - drugNames: newRx.Message.Body.NewRx.MedicationPrescribed.DrugDescription, - simpleDrugName: newRx.Message.Body.NewRx.MedicationPrescribed.DrugDescription.split(' ')[0], + prescriber.NonVeterinarian.Name.LastName, + doctorContact: prescriber.NonVeterinarian.CommunicationNumbers.PrimaryTelephone?.Number, + doctorID: prescriber.NonVeterinarian.Identification.NPI, + doctorEmail: prescriber.NonVeterinarian.CommunicationNumbers.ElectronicMail, + drugNames: medicationPrescribed.DrugDescription, + simpleDrugName: medicationPrescribed.DrugDescription?.split(' ')[0], drugNdcCode: - newRx.Message.Body.NewRx.MedicationPrescribed.DrugCoded.ProductCode?.Code || - newRx.Message.Body.NewRx.MedicationPrescribed.DrugCoded.NDC || + medicationPrescribed.DrugCoded.ProductCode?.Code || + medicationPrescribed.DrugCoded.NDC || null, - drugRxnormCode: - newRx.Message.Body.NewRx.MedicationPrescribed.DrugCoded.DrugDBCode?.Code || null, + drugRxnormCode: medicationPrescribed.DrugCoded.DrugDBCode?.Code || null, - rxDate: newRx.Message.Body.NewRx.MedicationPrescribed.WrittenDate.Date, + rxDate: medicationPrescribed.WrittenDate.Date, drugPrice: 200, // Add later? - quantities: newRx.Message.Body.NewRx.MedicationPrescribed.Quantity.Value, + quantities: medicationPrescribed.Quantity.Value, total: 1800, pickupDate: 'Tue Dec 13 2022', // Add later? dispenseStatus: 'Pending' }; + if (incompleteOrder.drugNames === undefined || incompleteOrder.drugNames === 'undefined') { + incompleteOrder.drugNames = incompleteOrder.drugNdcCode; + incompleteOrder.simpleDrugName = incompleteOrder.drugNdcCode; + } + const metRequirements = isRemsDrug(incompleteOrder) ? [] : null; const order = new doctorOrder({ ...incompleteOrder, metRequirements }); return order; diff --git a/backend/src/server.ts b/backend/src/server.ts index 802c10d..1627125 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -21,6 +21,8 @@ async function main() { origin: env.ALLOWED_ORIGIN }; + console.log('CORS OPTIONS: ' + JSON.stringify(options)); + app.use(bodyParser.urlencoded({ extended: false })); app.use(cors(options)); app.use('/doctorOrders', doctorOrders); diff --git a/dockerRunnerProd.sh b/dockerRunnerProd.sh index 2c2806e..7e90354 100755 --- a/dockerRunnerProd.sh +++ b/dockerRunnerProd.sh @@ -1,7 +1,8 @@ #!/bin/sh cd frontend -( npm run start ) & SERVER_PID=$! +npm run build +( npm run preview ) & SERVER_PID=$! cd ../backend ( npm run start ) & BACKEND_SERVER_PID=$! diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ca85400..8045496 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -6748,14 +6748,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6876,9 +6868,10 @@ } }, "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -7223,16 +7216,17 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { @@ -7252,10 +7246,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, "node_modules/concat-map": { "version": "0.0.1", @@ -14705,9 +14703,10 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -16511,14 +16510,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 7b9f888..afe7688 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -13,10 +13,12 @@ axios.defaults.baseURL = process.env.REACT_APP_PIMS_BACKEND_URL : 'http://localhost:' + (process.env.REACT_APP_PIMS_BACKEND_PORT ? process.env.REACT_APP_PIMS_BACKEND_PORT : '5051'); +const basename = process.env.REACT_APP_VITE_BASE?.replace(/\/$/, '') || ''; + function App() { return ( - +
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index c729b1d..187cc8c 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -6,10 +6,12 @@ import dotenv from 'dotenv'; dotenv.config({ path: '.env' }); // load env vars from .env export default defineConfig({ // depending on your application, base can also be "/" - base: '', + base: process.env.REACT_APP_VITE_BASE || '', plugins: [react()], preview: { - allowedHosts: ['.mitre.org', '.us-east-1.elb.amazonaws.com'] + allowedHosts: ['.mitre.org', '.elb.us-east-1.amazonaws.com'], + port: parseInt(process.env.PORT!), + host: true }, define: { 'process.env': process.env @@ -18,6 +20,6 @@ export default defineConfig({ port: parseInt(process.env.PORT!), open: false, host: true, - allowedHosts: ['.mitre.org', '.us-east-1.elb.amazonaws.com'] + allowedHosts: ['.mitre.org', '.elb.us-east-1.amazonaws.com'] } });