diff --git a/api/package-lock.json b/api/package-lock.json index 221a11c..ffc48c3 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -11,7 +11,8 @@ "cors": "^2.8.5", "dotenv": "^16.5.0", "express": "^5.2.0", - "pg": "^8.17.1" + "pg": "^8.17.1", + "yup": "^1.7.1" }, "devDependencies": { "nodemon": "^3.1.10" @@ -987,6 +988,12 @@ "node": ">=0.10.0" } }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1273,6 +1280,12 @@ "node": ">=4" } }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1295,6 +1308,12 @@ "node": ">=0.6" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, "node_modules/touch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", @@ -1305,6 +1324,18 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -1358,6 +1389,18 @@ "engines": { "node": ">=0.4" } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } } } } diff --git a/api/package.json b/api/package.json index f5932ac..2cb8d17 100644 --- a/api/package.json +++ b/api/package.json @@ -12,7 +12,8 @@ "cors": "^2.8.5", "dotenv": "^16.5.0", "express": "^5.2.0", - "pg": "^8.17.1" + "pg": "^8.17.1", + "yup": "^1.7.1" }, "devDependencies": { "nodemon": "^3.1.10" diff --git a/api/services/medications/index.js b/api/services/medications/index.js index a69a4b0..be48e98 100644 --- a/api/services/medications/index.js +++ b/api/services/medications/index.js @@ -1,5 +1,6 @@ import express from 'express'; import { databaseServices } from '../index.js'; +import { fullMedicationInformationSchema } from '../validations/medications.js'; export const medicationRouter = express.Router(); @@ -27,4 +28,19 @@ medicationRouter.get('/base/', async (req, res) => { } finally { res.send(data); } +}); + +medicationRouter.post('/full/', async (req, res) => { + let data; + const body = req?.body; + try { + await fullMedicationInformationSchema.validate(body); + data = await databaseServices.getFullMedicationInformation(body?.drugId); + res.status(200); + } catch (err) { + data = { Error: err?.message }; + res.status(500); + } finally { + res.send(data); + } }); \ No newline at end of file diff --git a/api/services/operations/helpers/medications.js b/api/services/operations/helpers/medications.js index 14624c1..4b60f91 100644 --- a/api/services/operations/helpers/medications.js +++ b/api/services/operations/helpers/medications.js @@ -64,5 +64,66 @@ export const medicationHelpers = { const fullMedList = Object.values(medMap); return fullMedList; + }, + getFullMedicationInformation: async (drugId) => { + const [medInformation, medRoutes] = await Promise.all([ + paramyxRunQuery( + `select + m.id, + m.generic, + m.trade, + m.system, + mi.class, + mi.indications, + mi.contraindications, + mi.precautions, + mi.adverse, + mi.onset, + mi.duration, + mi.tip, + mi.action + from medications m inner join medication_information mi on m.id = mi.id where m.id = $1;`, + [drugId] + ), + paramyxRunQuery(`select * from medication_routes mr where medication_id = $1;`, [drugId]) + ]); + + const fullMedicationInformation = { + ...medInformation + }; + + medRoutes?.forEach((row) => { + if (row?.is_adult) { + fullMedicationInformation.adult = { + totalMax: row.total_max, + iv: row.intravenous, + io: row.intraosseous, + im: row.intramuscular, + in: row.intranasal, + po: row.oral, + sl: row.sublingual, + pr: row.rectal, + neb: row.nebulizer, + et: row.endotracheal, + sga: row.supraglottic + } + } else { + fullMedicationInformation.pediatric = { + totalMax: row.total_max, + iv: row.intravenous, + io: row.intraosseous, + im: row.intramuscular, + in: row.intranasal, + po: row.oral, + sl: row.sublingual, + pr: row.rectal, + neb: row.nebulizer, + et: row.endotracheal, + sga: row.supraglottic + } + } + }); + + return fullMedicationInformation; } }; \ No newline at end of file diff --git a/api/services/operations/medications.js b/api/services/operations/medications.js index a225df5..5b7ca51 100644 --- a/api/services/operations/medications.js +++ b/api/services/operations/medications.js @@ -21,7 +21,18 @@ const getBaseMedications = async () => { } } +const getFullMedicationInformation = async (drugId) => { + try { + const dataResp = medicationHelpers.getFullMedicationInformation(drugId); + return dataResp; + } catch (err) { + console.log('GET FULL MEDICATION INFORMATION ERROR: ', err); + throw err; + } +} + export const medicationOperations = { getMedications, - getBaseMedications + getBaseMedications, + getFullMedicationInformation } \ No newline at end of file diff --git a/api/services/validations/medications.js b/api/services/validations/medications.js new file mode 100644 index 0000000..844cc15 --- /dev/null +++ b/api/services/validations/medications.js @@ -0,0 +1,5 @@ +import * as Yup from 'yup'; + +export const fullMedicationInformationSchema = Yup.object().shape({ + drugId: Yup.string().required("drugId is required"), +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f014d07..12cb1b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -809,9 +809,9 @@ "license": "MIT" }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, diff --git a/web/package-lock.json b/web/package-lock.json index f08aaf6..6d6f939 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -2103,12 +2103,16 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cosmiconfig": { @@ -3390,9 +3394,9 @@ } }, "node_modules/react-router": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.2.tgz", - "integrity": "sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.12.0.tgz", + "integrity": "sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -3412,12 +3416,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.2.tgz", - "integrity": "sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.12.0.tgz", + "integrity": "sha512-pfO9fiBcpEfX4Tx+iTYKDtPbrSLLCbwJ5EqP+SPYQu1VYCXdy79GSj0wttR0U4cikVdlImZuEZ/9ZNCgoaxwBA==", "license": "MIT", "dependencies": { - "react-router": "7.6.2" + "react-router": "7.12.0" }, "engines": { "node": ">=20.0.0" @@ -3536,9 +3540,9 @@ } }, "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, "node_modules/shebang-command": {