Skip to content

Commit 9a7d61e

Browse files
committed
refactored code to add helpers & added better error handling
1 parent 1b47439 commit 9a7d61e

File tree

7 files changed

+103
-212
lines changed

7 files changed

+103
-212
lines changed

backend/src/middlewares/auth.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createClient } from "@supabase/supabase-js";
44
const auth = async (req, res, next) => {
55
try {
66
const token = req.header("Authorization")?.split(" ")[1];
7+
console.log(token)
78
const supabaseSecret = process.env.SUPABASE_JWT_SECRET;
89
if (token) {
910
jwt.verify(token, supabaseSecret);

backend/src/routes/logbooks-route.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,38 @@ const router = express.Router();
66

77
router.post("", auth, async (req, res) => {
88
const logbook = await createLogbook(req);
9-
res.status(201).json({ data: logbook });
9+
if (logbook.error) {
10+
res.status(500).json({ error: logbook.error });
11+
} else {
12+
res.status(201).json({ data: logbook });
13+
}
1014
});
1115

1216
router.get("", auth, async (req, res) => {
1317
const userLogbooks = await getUserLogbooks(req);
14-
res.status(200).json({ data: userLogbooks });
18+
if (userLogbooks.error) {
19+
res.status(500).json({ error: userLogbooks.error });
20+
} else {
21+
res.status(200).json({ data: userLogbooks });
22+
}
1523
});
1624

1725
router.get("/:logbookID", auth, async (req, res) => {
1826
const logbook = await getLogbook(req);
19-
res.status(200).json({ data: logbook });
27+
if (logbook.error) {
28+
res.status(500).json({ error: logbook.error });
29+
} else {
30+
res.status(200).json({ data: logbook });
31+
}
2032
});
2133

2234
router.post("/:logbookID/logs", auth, async (req, res) => {
2335
const log = await createLog(req);
24-
res.status(201).json({ data: log });
36+
if (log.error) {
37+
res.status(500).json({ error: log.error });
38+
} else {
39+
res.status(201).json({ data: log });
40+
}
2541
});
2642

2743
router.get("/:logbookID/logs", auth, async (req, res) => {
Lines changed: 32 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -1,234 +1,58 @@
1+
import getLogbookType from "../utils/get-logbook-type.js";
2+
import getTable from "../utils/get-table.js";
3+
import insertTable from "../utils/insert-table.js";
4+
import parseUserID from "../utils/parse-user-id.js";
5+
16
export async function createLogbook(req) {
2-
try {
3-
const supabase = req.supabase;
4-
const { type } = req.body;
5-
const { data, error } = await supabase.from("logbooks").insert({ type: type }).select();
6-
if (error) {
7-
throw new Error(error.message);
8-
}
9-
return data[0];
10-
} catch (error) {
11-
throw new Error(error.message);
12-
}
7+
const supabase = req.supabase;
8+
const body = req.body
9+
return insertTable(supabase, "logbooks", body);
1310
}
1411

1512
export async function getUserLogbooks(req) {
16-
try {
17-
const supabase = req.supabase;
18-
const token = req.header("Authorization")?.split(" ")[1];
19-
const userID = parseUserID(token);
20-
const { data, error } = await supabase.from("logbooks").select().eq("user_id", userID);
21-
if (error) {
22-
throw new Error(error.message);
23-
}
24-
return data;
25-
} catch (error) {
26-
throw new Error(error.message);
27-
}
28-
}
29-
30-
function parseUserID(token) {
31-
const parts = token.split(".");
32-
const decodedPayload = JSON.parse(atob(parts[1]));
33-
const userID = decodedPayload["sub"];
34-
return userID;
13+
const supabase = req.supabase;
14+
const token = req.header("Authorization")?.split(" ")[1];
15+
const userID = parseUserID(token);
16+
return getTable(supabase, "logbooks", "user_id", userID, "collection");
3517
}
3618

3719
export async function getLogbook(req) {
38-
try {
39-
const supabase = req.supabase;
40-
const { logbookID } = req.params;
41-
const { data, error } = await supabase.from("logbooks").select().eq("id", logbookID);
42-
if (error) {
43-
throw new Error(error.message);
44-
}
45-
return data[0];
46-
} catch (error) {
47-
throw new Error(error.message);
48-
}
20+
const supabase = req.supabase;
21+
const { logbookID } = req.params;
22+
return getTable(supabase, "logbooks", "id", logbookID, "resource");
4923
}
5024

5125
export async function createLog(req) {
5226
try {
5327
const supabase = req.supabase;
5428
const { logbookID } = req.params;
55-
const { type } = req.body;
29+
let body = req.body
30+
body['logbook_id'] = logbookID
5631
const logbookType = await getLogbookType(logbookID, supabase);
57-
if (type !== logbookType) {
58-
throw new Error("Error: Log does not match logbook type");
32+
if (body['type'] !== logbookType) {
33+
throw new Error(`log type '${body['type']}' does not match logbook type '${logbookType}'`);
5934
}
60-
let data;
61-
switch (type) {
35+
switch (body['type']) {
6236
case "adult_cardiac_logs":
63-
data = createAdultCardiacLog(req, supabase);
64-
break;
37+
return insertTable(supabase, "adult_cardiac_logs", body)
6538
default:
66-
break;
39+
throw new Error(`log and logbook type '${type}' are invalid`);
6740
}
68-
return data;
6941
} catch (error) {
70-
throw new Error(error.message);
71-
}
72-
}
73-
74-
async function createAdultCardiacLog(req, supabase) {
75-
const { logbookID } = req.params;
76-
const {
77-
type,
78-
caseNo,
79-
paitentID,
80-
surgeon,
81-
age,
82-
gender,
83-
orDate,
84-
reason,
85-
hpi,
86-
socialEtOH,
87-
socialDrugs,
88-
socialSmoking,
89-
socialMeds,
90-
socialAllergies,
91-
phmxHTN,
92-
phmxDMII,
93-
phmxDLP,
94-
phmxCVA,
95-
examWeight,
96-
examHeight,
97-
examBMI,
98-
examVeins,
99-
examAllenTest,
100-
examPulsesSixtyTwo,
101-
examPulsesSixtyFive,
102-
examPulsesSixtyEight,
103-
examPulsesSeventy,
104-
cathLink,
105-
invxEchoEF,
106-
invxEchoRVFx,
107-
invxWMA,
108-
invxAorta,
109-
invxValves,
110-
invxCXR,
111-
invxHb,
112-
invxW,
113-
invxPit,
114-
invxCr,
115-
ctLink,
116-
surgicalPlan,
117-
surgicalPlanFirstOperator,
118-
surgicalPlanIssueOR,
119-
surgicalPlanIssuePost,
120-
surgicalPlanaFlagForFU,
121-
operativeNotesCPBh,
122-
operativeNotesCPBm,
123-
operativeNotesXCh,
124-
operativeNotesXCm,
125-
operativeNotesCAh,
126-
operativeNotesCAm,
127-
myRole,
128-
postOperativeCourse,
129-
learningPointsKeyLessons,
130-
} = req.body;
131-
const { data, error } = await supabase
132-
.from("adult_cardiac_logs")
133-
.insert({
134-
logbook_id: logbookID,
135-
type: type,
136-
case_no: caseNo,
137-
paitent_id: paitentID,
138-
surgeon: surgeon,
139-
age: age,
140-
gender: gender,
141-
or_date: orDate,
142-
reason: reason,
143-
hpi: hpi,
144-
social_etoh: socialEtOH,
145-
social_drugs: socialDrugs,
146-
social_smoking: socialSmoking,
147-
social_meds: socialMeds,
148-
social_allergies: socialAllergies,
149-
pmhx_htn: phmxHTN,
150-
pmhx_dmii: phmxDMII,
151-
pmhx_dlp: phmxDLP,
152-
pmhx_cva: phmxCVA,
153-
exam_weight: examWeight,
154-
exam_height: examHeight,
155-
exam_bmi: examBMI,
156-
exam_veins: examVeins,
157-
exam_allen_test: examAllenTest,
158-
exam_pulses_sixtytwo: examPulsesSixtyTwo,
159-
exam_pulses_sixtyfive: examPulsesSixtyFive,
160-
exam_pulses_sixtyeight: examPulsesSixtyEight,
161-
exam_pulses_seventy: examPulsesSeventy,
162-
cath: cathLink,
163-
invx_echo_ef: invxEchoEF,
164-
invx_echo_rvfx: invxEchoRVFx,
165-
invx_wma: invxWMA,
166-
invx_aorta: invxAorta,
167-
invx_valves: invxValves,
168-
invx_cxr: invxCXR,
169-
invx_hb: invxHb,
170-
invx_w: invxW,
171-
invx_pit: invxPit,
172-
invx_cr: invxCr,
173-
ct: ctLink,
174-
surgical_plan: surgicalPlan,
175-
surgical_plan_first_operator: surgicalPlanFirstOperator,
176-
surgical_plan_issue_or: surgicalPlanIssueOR,
177-
surgical_plan_issue_post: surgicalPlanIssuePost,
178-
surgical_plan_flag_for_fu: surgicalPlanaFlagForFU,
179-
operative_notes_cpb_h: operativeNotesCPBh,
180-
operative_notes_cpb_m: operativeNotesCPBm,
181-
operative_notes_xc_h: operativeNotesXCh,
182-
operative_notes_xc_m: operativeNotesXCm,
183-
operative_notes_ca_h: operativeNotesCAh,
184-
operative_notes_ca_m: operativeNotesCAm,
185-
my_role: myRole,
186-
post_operative_course: postOperativeCourse,
187-
learning_points_key_lessons: learningPointsKeyLessons,
188-
})
189-
.select();
190-
if (error) {
191-
throw new Error(error.message);
192-
}
193-
return data[0];
194-
}
195-
196-
async function getLogbookType(logbookID, supabase) {
197-
const { data, error } = await supabase.from("logbooks").select().eq("id", logbookID);
198-
if (error) {
199-
throw new Error(error.message);
42+
return { error: error.message };
20043
}
201-
return data[0]["type"];
20244
}
20345

20446
export async function getLogbookLogs(req) {
205-
try {
206-
const supabase = req.supabase;
207-
const { logbookID } = req.params;
208-
const logbookType = await getLogbookType(logbookID, supabase);
209-
const { data, error } = await supabase.from(logbookType).select();
210-
if (error) {
211-
throw new Error(error.message);
212-
}
213-
return data;
214-
} catch (error) {
215-
console.error(error.message);
216-
return {error: error.message}
217-
}
47+
const supabase = req.supabase;
48+
const { logbookID } = req.params;
49+
const logbookType = await getLogbookType(logbookID, supabase);
50+
return getTable(supabase, logbookType, "logbook_id", logbookID, "collection");
21851
}
21952

22053
export async function getLog(req) {
221-
try {
222-
const supabase = req.supabase;
223-
const { logbookID, logID } = req.params;
224-
const logbookType = await getLogbookType(logbookID, supabase);
225-
const { data, error } = await supabase.from(logbookType).select().eq("id", logID);
226-
if (error) {
227-
throw new Error(error.message);
228-
}
229-
return data[0];
230-
} catch (error) {
231-
console.error(error.message);
232-
return {error: error.message}
233-
}
234-
}
54+
const supabase = req.supabase;
55+
const { logbookID, logID } = req.params;
56+
const logbookType = await getLogbookType(logbookID, supabase);
57+
return getTable(supabase, logbookType, "id", logID, "resource");
58+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default async function getLogbookType(logbookID, supabase) {
2+
try {
3+
const { data, error } = await supabase.from("logbooks").select().eq("id", logbookID);
4+
if (error) {
5+
throw new Error(error.message);
6+
}
7+
return data[0]['type'];
8+
} catch (error) {
9+
return { error: error.message };
10+
}
11+
}

backend/src/utils/get-table.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export default async function getTable(supabase, table, param, value, type) {
2+
try {
3+
let data, error;
4+
if (param == null && value == null) {
5+
({ data, error } = await supabase.from(table).select());
6+
} else if (param !== null && value !== null) {
7+
({ data, error } = await supabase.from(table).select().eq(param, value));
8+
} else {
9+
throw new Error(`${param == null ? "param" : "value"} is empty at getTable`);
10+
}
11+
if (error) {
12+
throw new Error(error.message);
13+
}
14+
return type === "collection" ? data : data[0];
15+
} catch (error) {
16+
return { error: error.message };
17+
}
18+
}

backend/src/utils/insert-table.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export default async function insertTable(supabase, table, values) {
2+
try {
3+
const { data, error } = await supabase.from(table).insert(values).select();
4+
if (error) {
5+
throw new Error(error.message);
6+
} else {
7+
return data[0];
8+
}
9+
} catch (error) {
10+
return { error: error.message };
11+
}
12+
}

backend/src/utils/parse-user-id.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default function parseUserID(token) {
2+
try {
3+
const parts = token.split(".");
4+
const decodedPayload = JSON.parse(atob(parts[1]));
5+
return decodedPayload["sub"];
6+
} catch (error) {
7+
return { error: error.message };
8+
}
9+
}

0 commit comments

Comments
 (0)