From 9a7d61ee766564236c350288d42b412da050919a Mon Sep 17 00:00:00 2001 From: Rafael Park Date: Thu, 28 Nov 2024 16:13:00 -0800 Subject: [PATCH] refactored code to add helpers & added better error handling --- backend/src/middlewares/auth.js | 1 + backend/src/routes/logbooks-route.js | 24 ++- backend/src/services/logbooks-service.js | 240 +++-------------------- backend/src/utils/get-logbook-type.js | 11 ++ backend/src/utils/get-table.js | 18 ++ backend/src/utils/insert-table.js | 12 ++ backend/src/utils/parse-user-id.js | 9 + 7 files changed, 103 insertions(+), 212 deletions(-) create mode 100644 backend/src/utils/get-logbook-type.js create mode 100644 backend/src/utils/get-table.js create mode 100644 backend/src/utils/insert-table.js create mode 100644 backend/src/utils/parse-user-id.js diff --git a/backend/src/middlewares/auth.js b/backend/src/middlewares/auth.js index b8d71ea2..90cccfb9 100644 --- a/backend/src/middlewares/auth.js +++ b/backend/src/middlewares/auth.js @@ -4,6 +4,7 @@ import { createClient } from "@supabase/supabase-js"; const auth = async (req, res, next) => { try { const token = req.header("Authorization")?.split(" ")[1]; + console.log(token) const supabaseSecret = process.env.SUPABASE_JWT_SECRET; if (token) { jwt.verify(token, supabaseSecret); diff --git a/backend/src/routes/logbooks-route.js b/backend/src/routes/logbooks-route.js index ca8b116c..5f7f4e59 100644 --- a/backend/src/routes/logbooks-route.js +++ b/backend/src/routes/logbooks-route.js @@ -6,22 +6,38 @@ const router = express.Router(); router.post("", auth, async (req, res) => { const logbook = await createLogbook(req); - res.status(201).json({ data: logbook }); + if (logbook.error) { + res.status(500).json({ error: logbook.error }); + } else { + res.status(201).json({ data: logbook }); + } }); router.get("", auth, async (req, res) => { const userLogbooks = await getUserLogbooks(req); - res.status(200).json({ data: userLogbooks }); + if (userLogbooks.error) { + res.status(500).json({ error: userLogbooks.error }); + } else { + res.status(200).json({ data: userLogbooks }); + } }); router.get("/:logbookID", auth, async (req, res) => { const logbook = await getLogbook(req); - res.status(200).json({ data: logbook }); + if (logbook.error) { + res.status(500).json({ error: logbook.error }); + } else { + res.status(200).json({ data: logbook }); + } }); router.post("/:logbookID/logs", auth, async (req, res) => { const log = await createLog(req); - res.status(201).json({ data: log }); + if (log.error) { + res.status(500).json({ error: log.error }); + } else { + res.status(201).json({ data: log }); + } }); router.get("/:logbookID/logs", auth, async (req, res) => { diff --git a/backend/src/services/logbooks-service.js b/backend/src/services/logbooks-service.js index ecf9b1c2..34ff3e4f 100644 --- a/backend/src/services/logbooks-service.js +++ b/backend/src/services/logbooks-service.js @@ -1,234 +1,58 @@ +import getLogbookType from "../utils/get-logbook-type.js"; +import getTable from "../utils/get-table.js"; +import insertTable from "../utils/insert-table.js"; +import parseUserID from "../utils/parse-user-id.js"; + export async function createLogbook(req) { - try { - const supabase = req.supabase; - const { type } = req.body; - const { data, error } = await supabase.from("logbooks").insert({ type: type }).select(); - if (error) { - throw new Error(error.message); - } - return data[0]; - } catch (error) { - throw new Error(error.message); - } + const supabase = req.supabase; + const body = req.body + return insertTable(supabase, "logbooks", body); } export async function getUserLogbooks(req) { - try { - const supabase = req.supabase; - const token = req.header("Authorization")?.split(" ")[1]; - const userID = parseUserID(token); - const { data, error } = await supabase.from("logbooks").select().eq("user_id", userID); - if (error) { - throw new Error(error.message); - } - return data; - } catch (error) { - throw new Error(error.message); - } -} - -function parseUserID(token) { - const parts = token.split("."); - const decodedPayload = JSON.parse(atob(parts[1])); - const userID = decodedPayload["sub"]; - return userID; + const supabase = req.supabase; + const token = req.header("Authorization")?.split(" ")[1]; + const userID = parseUserID(token); + return getTable(supabase, "logbooks", "user_id", userID, "collection"); } export async function getLogbook(req) { - try { - const supabase = req.supabase; - const { logbookID } = req.params; - const { data, error } = await supabase.from("logbooks").select().eq("id", logbookID); - if (error) { - throw new Error(error.message); - } - return data[0]; - } catch (error) { - throw new Error(error.message); - } + const supabase = req.supabase; + const { logbookID } = req.params; + return getTable(supabase, "logbooks", "id", logbookID, "resource"); } export async function createLog(req) { try { const supabase = req.supabase; const { logbookID } = req.params; - const { type } = req.body; + let body = req.body + body['logbook_id'] = logbookID const logbookType = await getLogbookType(logbookID, supabase); - if (type !== logbookType) { - throw new Error("Error: Log does not match logbook type"); + if (body['type'] !== logbookType) { + throw new Error(`log type '${body['type']}' does not match logbook type '${logbookType}'`); } - let data; - switch (type) { + switch (body['type']) { case "adult_cardiac_logs": - data = createAdultCardiacLog(req, supabase); - break; + return insertTable(supabase, "adult_cardiac_logs", body) default: - break; + throw new Error(`log and logbook type '${type}' are invalid`); } - return data; } catch (error) { - throw new Error(error.message); - } -} - -async function createAdultCardiacLog(req, supabase) { - const { logbookID } = req.params; - const { - type, - caseNo, - paitentID, - surgeon, - age, - gender, - orDate, - reason, - hpi, - socialEtOH, - socialDrugs, - socialSmoking, - socialMeds, - socialAllergies, - phmxHTN, - phmxDMII, - phmxDLP, - phmxCVA, - examWeight, - examHeight, - examBMI, - examVeins, - examAllenTest, - examPulsesSixtyTwo, - examPulsesSixtyFive, - examPulsesSixtyEight, - examPulsesSeventy, - cathLink, - invxEchoEF, - invxEchoRVFx, - invxWMA, - invxAorta, - invxValves, - invxCXR, - invxHb, - invxW, - invxPit, - invxCr, - ctLink, - surgicalPlan, - surgicalPlanFirstOperator, - surgicalPlanIssueOR, - surgicalPlanIssuePost, - surgicalPlanaFlagForFU, - operativeNotesCPBh, - operativeNotesCPBm, - operativeNotesXCh, - operativeNotesXCm, - operativeNotesCAh, - operativeNotesCAm, - myRole, - postOperativeCourse, - learningPointsKeyLessons, - } = req.body; - const { data, error } = await supabase - .from("adult_cardiac_logs") - .insert({ - logbook_id: logbookID, - type: type, - case_no: caseNo, - paitent_id: paitentID, - surgeon: surgeon, - age: age, - gender: gender, - or_date: orDate, - reason: reason, - hpi: hpi, - social_etoh: socialEtOH, - social_drugs: socialDrugs, - social_smoking: socialSmoking, - social_meds: socialMeds, - social_allergies: socialAllergies, - pmhx_htn: phmxHTN, - pmhx_dmii: phmxDMII, - pmhx_dlp: phmxDLP, - pmhx_cva: phmxCVA, - exam_weight: examWeight, - exam_height: examHeight, - exam_bmi: examBMI, - exam_veins: examVeins, - exam_allen_test: examAllenTest, - exam_pulses_sixtytwo: examPulsesSixtyTwo, - exam_pulses_sixtyfive: examPulsesSixtyFive, - exam_pulses_sixtyeight: examPulsesSixtyEight, - exam_pulses_seventy: examPulsesSeventy, - cath: cathLink, - invx_echo_ef: invxEchoEF, - invx_echo_rvfx: invxEchoRVFx, - invx_wma: invxWMA, - invx_aorta: invxAorta, - invx_valves: invxValves, - invx_cxr: invxCXR, - invx_hb: invxHb, - invx_w: invxW, - invx_pit: invxPit, - invx_cr: invxCr, - ct: ctLink, - surgical_plan: surgicalPlan, - surgical_plan_first_operator: surgicalPlanFirstOperator, - surgical_plan_issue_or: surgicalPlanIssueOR, - surgical_plan_issue_post: surgicalPlanIssuePost, - surgical_plan_flag_for_fu: surgicalPlanaFlagForFU, - operative_notes_cpb_h: operativeNotesCPBh, - operative_notes_cpb_m: operativeNotesCPBm, - operative_notes_xc_h: operativeNotesXCh, - operative_notes_xc_m: operativeNotesXCm, - operative_notes_ca_h: operativeNotesCAh, - operative_notes_ca_m: operativeNotesCAm, - my_role: myRole, - post_operative_course: postOperativeCourse, - learning_points_key_lessons: learningPointsKeyLessons, - }) - .select(); - if (error) { - throw new Error(error.message); - } - return data[0]; -} - -async function getLogbookType(logbookID, supabase) { - const { data, error } = await supabase.from("logbooks").select().eq("id", logbookID); - if (error) { - throw new Error(error.message); + return { error: error.message }; } - return data[0]["type"]; } export async function getLogbookLogs(req) { - try { - const supabase = req.supabase; - const { logbookID } = req.params; - const logbookType = await getLogbookType(logbookID, supabase); - const { data, error } = await supabase.from(logbookType).select(); - if (error) { - throw new Error(error.message); - } - return data; - } catch (error) { - console.error(error.message); - return {error: error.message} - } + const supabase = req.supabase; + const { logbookID } = req.params; + const logbookType = await getLogbookType(logbookID, supabase); + return getTable(supabase, logbookType, "logbook_id", logbookID, "collection"); } export async function getLog(req) { - try { - const supabase = req.supabase; - const { logbookID, logID } = req.params; - const logbookType = await getLogbookType(logbookID, supabase); - const { data, error } = await supabase.from(logbookType).select().eq("id", logID); - if (error) { - throw new Error(error.message); - } - return data[0]; - } catch (error) { - console.error(error.message); - return {error: error.message} - } -} + const supabase = req.supabase; + const { logbookID, logID } = req.params; + const logbookType = await getLogbookType(logbookID, supabase); + return getTable(supabase, logbookType, "id", logID, "resource"); +} \ No newline at end of file diff --git a/backend/src/utils/get-logbook-type.js b/backend/src/utils/get-logbook-type.js new file mode 100644 index 00000000..dc35e52d --- /dev/null +++ b/backend/src/utils/get-logbook-type.js @@ -0,0 +1,11 @@ +export default async function getLogbookType(logbookID, supabase) { + try { + const { data, error } = await supabase.from("logbooks").select().eq("id", logbookID); + if (error) { + throw new Error(error.message); + } + return data[0]['type']; + } catch (error) { + return { error: error.message }; + } +} \ No newline at end of file diff --git a/backend/src/utils/get-table.js b/backend/src/utils/get-table.js new file mode 100644 index 00000000..7e847b1f --- /dev/null +++ b/backend/src/utils/get-table.js @@ -0,0 +1,18 @@ +export default async function getTable(supabase, table, param, value, type) { + try { + let data, error; + if (param == null && value == null) { + ({ data, error } = await supabase.from(table).select()); + } else if (param !== null && value !== null) { + ({ data, error } = await supabase.from(table).select().eq(param, value)); + } else { + throw new Error(`${param == null ? "param" : "value"} is empty at getTable`); + } + if (error) { + throw new Error(error.message); + } + return type === "collection" ? data : data[0]; + } catch (error) { + return { error: error.message }; + } +} \ No newline at end of file diff --git a/backend/src/utils/insert-table.js b/backend/src/utils/insert-table.js new file mode 100644 index 00000000..796f3929 --- /dev/null +++ b/backend/src/utils/insert-table.js @@ -0,0 +1,12 @@ +export default async function insertTable(supabase, table, values) { + try { + const { data, error } = await supabase.from(table).insert(values).select(); + if (error) { + throw new Error(error.message); + } else { + return data[0]; + } + } catch (error) { + return { error: error.message }; + } +} \ No newline at end of file diff --git a/backend/src/utils/parse-user-id.js b/backend/src/utils/parse-user-id.js new file mode 100644 index 00000000..50012650 --- /dev/null +++ b/backend/src/utils/parse-user-id.js @@ -0,0 +1,9 @@ +export default function parseUserID(token) { + try { + const parts = token.split("."); + const decodedPayload = JSON.parse(atob(parts[1])); + return decodedPayload["sub"]; + } catch (error) { + return { error: error.message }; + } +} \ No newline at end of file