Second part of backend rework
- Improved consistency in routes - Fixed permission issues - Added new endpoints - Fixed some issues - SQL: Switched status to ENUM - SQL: Changed rooms table - SQL: Added unique constraints
This commit is contained in:
21
database.sql
21
database.sql
@@ -43,7 +43,7 @@ CREATE TABLE users (
|
||||
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
phone VARCHAR(32) DEFAULT 'None',
|
||||
phone_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY (id),
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE user_roles (
|
||||
@@ -99,7 +99,7 @@ CREATE TABLE doctors (
|
||||
email VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
speciality VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(255) NOT NULL,
|
||||
status ENUM('Available', 'Absent', 'Unavailable') NOT NULL,
|
||||
is_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT dt_user_id
|
||||
@@ -107,7 +107,8 @@ CREATE TABLE doctors (
|
||||
REFERENCES users(id)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE,
|
||||
INDEX dt_user_id_idx (user_id)
|
||||
INDEX dt_user_id_idx (user_id),
|
||||
CONSTRAINT uc_doctor_user_id UNIQUE (user_id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE patients (
|
||||
@@ -118,7 +119,8 @@ CREATE TABLE patients (
|
||||
address VARCHAR(255) NOT NULL,
|
||||
social_security_number VARCHAR(128) NOT NULL,
|
||||
insurance_number VARCHAR(128) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT uc_user_id UNIQUE (user_id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE services (
|
||||
@@ -126,7 +128,6 @@ CREATE TABLE services (
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
price DECIMAL(10, 2) NOT NULL,
|
||||
status VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
@@ -178,7 +179,11 @@ CREATE TABLE rooms (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
hospital_id INT UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
code VARCHAR(3) NOT NULL,
|
||||
floor INT UNSIGNED NOT NULL,
|
||||
room_number INT UNSIGNED NOT NULL,
|
||||
room_type ENUM('General Ward', 'Private', 'Intensive Care Unit', 'Labor and Delivery', 'Operating', 'Recovery', 'Isolation', 'Emergency', 'Imaging', 'Procedure', 'Physical Therapy', 'Consultation') NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT ch_hospital_id
|
||||
FOREIGN KEY (hospital_id)
|
||||
REFERENCES hospitals(id)
|
||||
@@ -213,8 +218,8 @@ CREATE TABLE appointments (
|
||||
room_id INT UNSIGNED DEFAULT NULL,
|
||||
date DATE NOT NULL,
|
||||
time TIME NOT NULL,
|
||||
status VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
status ENUM('Confirmed', 'Completed', 'Absent', 'Cancelled by Patient', 'Cancelled by Doctor') NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT ap_patient_id
|
||||
FOREIGN KEY (patient_id)
|
||||
REFERENCES patients(id)
|
||||
|
||||
@@ -7,10 +7,9 @@ import { respondWithStatus, respondWithStatusJSON } from '../modules/requestHand
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('companies', 1), async (req, res) => {
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('company', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE 1');
|
||||
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Companies not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
@@ -20,7 +19,7 @@ router.get('/', verifyToken, checkBanned, checkPermissions('companies', 1), asyn
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('companies', 2), async (req, res) => {
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('company', 2), async (req, res) => {
|
||||
const { name, code, logo } = req.body;
|
||||
if ([ name, code, logo ].every(Boolean)) {
|
||||
try {
|
||||
@@ -41,10 +40,9 @@ router.post('/', verifyToken, checkBanned, checkPermissions('companies', 2), asy
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:companyId', verifyToken, checkBanned, checkPermissions('companies', 1), async (req, res) => {
|
||||
router.get('/:companyId', verifyToken, checkBanned, checkPermissions('company', 1), async (req, res) => {
|
||||
try {
|
||||
const id = req.params.companyId;
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [id]);
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [req.params.companyId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Company not found');
|
||||
return await respondWithStatusJSON(res, 200, rows[0]);
|
||||
}
|
||||
@@ -54,18 +52,16 @@ router.get('/:companyId', verifyToken, checkBanned, checkPermissions('companies'
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/:companyId', verifyToken, checkBanned, checkPermissions('companies', 2), async (req, res) => {
|
||||
router.patch('/:companyId', verifyToken, checkBanned, checkPermissions('company', 2), async (req, res) => {
|
||||
try {
|
||||
const id = req.params.companyId;
|
||||
const { type, value } = req.body;
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [id]);
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [req.params.companyId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Company not found');
|
||||
|
||||
const excludedKeys = ['id'];
|
||||
const fields = rows.map(row => Object.keys(row).filter(key => !excludedKeys.includes(key)));
|
||||
if (fields[0].includes(type)) {
|
||||
const [result] = await pool.execute(`UPDATE companies SET ${type} = ? WHERE id = ?`, [value, id]);
|
||||
|
||||
const [result] = await pool.execute(`UPDATE companies SET ${type} = ? WHERE id = ?`, [value, req.params.companyId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating companie');
|
||||
return await respondWithStatus(res, 200, 'Company updated successfully');
|
||||
}
|
||||
@@ -79,17 +75,16 @@ router.patch('/:companyId', verifyToken, checkBanned, checkPermissions('companie
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:companyId', verifyToken, checkBanned, checkPermissions('companies', 2), async (req, res) => {
|
||||
const id = req.params.companyId;
|
||||
router.put('/:companyId', verifyToken, checkBanned, checkPermissions('company', 2), async (req, res) => {
|
||||
const { name, code, logo } = req.body;
|
||||
if ([name, code, logo].every(Boolean)) {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [id]);
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [req.params.companyId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Company not found');
|
||||
|
||||
const [result] = await pool.execute(
|
||||
'UPDATE companies SET name = ?, code = ?, logo = ? WHERE id = ?',
|
||||
[name, code, logo, id],
|
||||
[name, code, logo, req.params.companyId],
|
||||
);
|
||||
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating companie');
|
||||
@@ -105,14 +100,12 @@ router.put('/:companyId', verifyToken, checkBanned, checkPermissions('companies'
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:companyId', verifyToken, checkBanned, checkPermissions('companies', 4), async (req, res) => {
|
||||
router.delete('/:companyId', verifyToken, checkBanned, checkPermissions('company', 4), async (req, res) => {
|
||||
try {
|
||||
const id = req.params.companyId;
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [id]);
|
||||
const [rows] = await pool.execute('SELECT * FROM companies WHERE id = ? LIMIT 1', [req.params.companyId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Company not found');
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM companies WHERE id = ?', [id]);
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM companies WHERE id = ?', [req.params.companyId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing companie');
|
||||
return await respondWithStatus(res, 200, 'Company removed successfully');
|
||||
}
|
||||
@@ -123,7 +116,17 @@ router.delete('/:companyId', verifyToken, checkBanned, checkPermissions('compani
|
||||
});
|
||||
|
||||
// Hospital endpoints
|
||||
// GET /:companyId/hospitals
|
||||
router.get('/:companyId/hospitals', verifyToken, checkBanned, checkPermissions('company', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE company_id = ?', [req.params.companyId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Hospitals not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default router;
|
||||
@@ -12,7 +12,7 @@ const router = express.Router();
|
||||
*
|
||||
* @returns {Promise<Array>} A promise that resolves to an array of doctor objects.
|
||||
*/
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('doctors', 1), async (req, res) => {
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('doctor', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE 1');
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Doctors not found');
|
||||
@@ -28,15 +28,16 @@ router.get('/', verifyToken, checkBanned, checkPermissions('doctors', 1), async
|
||||
* Inserts a new doctor record into the database.
|
||||
*
|
||||
* @param {number} user_id - The ID of the user associated with the doctor.
|
||||
* @param {date} date_of_birth - The date of birth of the doctor.
|
||||
* @param {string} gender - The gender of the doctor.
|
||||
* @param {string} address - The address of the doctor.
|
||||
* @param {string} social_security_number - The social security number of the doctor.
|
||||
* @param {string} insurance_number - The insurance number of the doctor.
|
||||
* @param {string} email - The email of the doctor.
|
||||
* @param {string} phone - The phone number of the doctor.
|
||||
* @param {string} speciality - The speciality of the doctor.
|
||||
* @param {string} status - The status of the doctor.
|
||||
* @param {boolean} is_verified - The verification status of the doctor.
|
||||
* @returns {Promise} - A promise that resolves with the result of the insertion.
|
||||
*/
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('doctors', 2), async (req, res) => {
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('doctor', 2), async (req, res) => {
|
||||
const { user_id, email, phone, speciality, status, is_verified = false } = req.body;
|
||||
if (!['Available', 'Absent', 'Unavailable'].includes(status)) return await respondWithStatus(res, 400, 'Invalid status');
|
||||
if ([ user_id, email, phone, speciality, status ].every(Boolean)) {
|
||||
try {
|
||||
const [result] = await pool.execute(
|
||||
@@ -58,6 +59,7 @@ router.post('/', verifyToken, checkBanned, checkPermissions('doctors', 2), async
|
||||
|
||||
router.post('/register', verifyToken, checkEmailVerified, checkBanned, async (req, res) => {
|
||||
const { email, phone, speciality, status } = req.body;
|
||||
if (!['Available', 'Absent', 'Unavailable'].includes(status)) return await respondWithStatus(res, 400, 'Invalid status');
|
||||
if ([ email, phone, speciality, status ].every(Boolean)) {
|
||||
try {
|
||||
const [result] = await pool.execute(
|
||||
@@ -77,12 +79,32 @@ router.post('/register', verifyToken, checkEmailVerified, checkBanned, async (re
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:doctorId/validate', verifyToken, checkBanned, checkPermissions('doctor', 2), async (req, res) => {
|
||||
const { doctor_id } = req.body;
|
||||
if (doctor_id) {
|
||||
try {
|
||||
const [result] = await pool.execute('UPDATE doctors SET is_verified = 1 WHERE id = ?', [doctor_id]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error validating doctor');
|
||||
const [result2] = await pool.execute('INSERT INTO user_roles (user_id, role_id) VALUES (?, (SELECT id FROM roles WHERE name = ? LIMIT 1))', [req.userId, 'Doctor']);
|
||||
if (result2.affectedRows === 0) return await respondWithStatus(res, 500, 'Error adding role to user');
|
||||
return await respondWithStatus(res, 200, 'Doctor validated successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const id = req.params.doctorId;
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [id]);
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'doctor', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [req.params.doctorId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Doctor not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'doctors', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
return await respondWithStatusJSON(res, 200, rows[0]);
|
||||
}
|
||||
catch (err) {
|
||||
@@ -93,17 +115,16 @@ router.get('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
|
||||
router.patch('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const id = req.params.doctorId;
|
||||
const { type, value } = req.body;
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [id]);
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'doctor', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [req.params.doctorId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Doctor not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'doctors', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
|
||||
const excludedKeys = [ 'id', 'user_id' ];
|
||||
const fields = rows.map(row => Object.keys(row).filter(key => !excludedKeys.includes(key)));
|
||||
if (fields[0].includes(type)) {
|
||||
const [result] = await pool.execute(`UPDATE doctors SET ${type} = ? WHERE id = ?`, [value, id]);
|
||||
|
||||
const [result] = await pool.execute(`UPDATE doctors SET ${type} = ? WHERE id = ?`, [value, req.params.doctorId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating doctor');
|
||||
return await respondWithStatus(res, 200, 'Doctor updated successfully');
|
||||
}
|
||||
@@ -118,17 +139,17 @@ router.patch('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
});
|
||||
|
||||
router.put('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
const id = req.params.doctorId;
|
||||
const { user_id, email, phone, speciality, status, is_verified } = req.body;
|
||||
if ([ user_id, email, phone, speciality, status, is_verified ].every(Boolean)) {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [id]);
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'doctor', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [req.params.doctorId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Doctor not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'doctors', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
|
||||
const [result] = await pool.execute(
|
||||
'UPDATE doctors SET name = ?, email = ?, phone = ?, speciality = ?, status = ?, is_verified = ? WHERE id = ?',
|
||||
[user_id, email, phone, speciality, status, is_verified, id],
|
||||
[user_id, email, phone, speciality, status, is_verified, req.params.doctorId],
|
||||
);
|
||||
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating doctor');
|
||||
@@ -146,13 +167,12 @@ router.put('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
|
||||
router.delete('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const id = req.params.doctorId;
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT', [id]);
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'doctor', 4)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM doctors WHERE id = ? LIMIT 1', [req.params.doctorId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Doctor not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'doctors', 4)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM doctors WHERE id = ?', [id]);
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM doctors WHERE id = ?', [req.params.doctorId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing doctor');
|
||||
return await respondWithStatus(res, 200, 'Doctor deleted successfully');
|
||||
}
|
||||
@@ -163,11 +183,207 @@ router.delete('/:doctorId', verifyToken, checkBanned, async (req, res) => {
|
||||
});
|
||||
|
||||
// Appointments endpoints
|
||||
// GET /:doctorId/appointments
|
||||
// POST /:doctorId/appointments
|
||||
// GET /:doctorId/appointments/:appointmentId
|
||||
// PATCH /:doctorId/appointments/:appointmentId
|
||||
// PUT /:doctorId/appointments/:appointmentId
|
||||
// DELETE /:doctorId/appointments/:appointmentId
|
||||
router.get('/:doctorId/appointments', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'appointment', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT a.*, u.first_name, u.last_name, p.gender, p.date_of_birth, s.service_name, a.service_id FROM appointments AS a JOIN patients AS p ON a.patient_id = p.id JOIN users AS u ON p.user_id = u.id JOIN services AS s ON a.service_id = s.id WHERE a.doctor_id = ?',
|
||||
[req.params.doctorId],
|
||||
);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Appointments not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:doctorId/appointments', verifyToken, checkBanned, async (req, res) => {
|
||||
const { patient_id, service_id, hospital_id, room_id = null, date, time, status } = req.body;
|
||||
if (!['Confirmed', 'Completed', 'Absent', 'Cancelled by Patient', 'Cancelled by Doctor'].includes(status)) return await respondWithStatus(res, 400, 'Invalid status');
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'appointment', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
if ([patient_id, service_id, hospital_id, date, time, status].every(Boolean)) {
|
||||
try {
|
||||
const [result] = await pool.execute(
|
||||
'INSERT INTO appointments (patient_id, doctor_id, service_id, hospital_id, room_id, date, time, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[patient_id, req.params.doctorId, service_id, hospital_id, room_id, date, time, status],
|
||||
);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing appointment');
|
||||
return await respondWithStatus(res, 200, 'Appointment created successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:doctorId/appointments/:appointmentId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'appointment', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT a.*, u.first_name, u.last_name, p.gender, p.date_of_birth, s.service_name, a.service_id FROM appointments AS a JOIN patients AS p ON a.patient_id = p.id JOIN users AS u ON p.user_id = u.id WHERE a.id = ? AND a.doctor_id = ? LIMIT 1',
|
||||
[req.params.appointmentId, req.params.doctorId],
|
||||
);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Appointment not found');
|
||||
return await respondWithStatusJSON(res, 200, rows[0]);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/:doctorId/appointments/:appointmentId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const { type, value } = req.body;
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'appointment', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM appointments WHERE id = ? LIMIT 1', [req.params.appointmentId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Appointment not found');
|
||||
|
||||
const excludedKeys = [ 'id', 'patient_id', 'doctor_id' ];
|
||||
const fields = rows.map(row => Object.keys(row).filter(key => !excludedKeys.includes(key)));
|
||||
if (type === 'status' && !['Confirmed', 'Completed', 'Absent', 'Cancelled by Patient', 'Cancelled by Doctor'].includes(value)) return await respondWithStatus(res, 400, 'Invalid status');
|
||||
if (fields[0].includes(type)) {
|
||||
const [result] = await pool.execute(`UPDATE appointments SET ${type} = ? WHERE id = ?`, [value, req.params.appointmentId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating appointment');
|
||||
return await respondWithStatus(res, 200, 'Appointment updated successfully');
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Invalid type');
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:doctorId/appointments/:appointmentId', verifyToken, checkBanned, async (req, res) => {
|
||||
const { patient_id, service_id, hospital_id, room_id, date, time, status } = req.body;
|
||||
if (!['Confirmed', 'Completed', 'Absent', 'Cancelled by Patient', 'Cancelled by Doctor'].includes(status)) return await respondWithStatus(res, 400, 'Invalid status');
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'appointment', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
if ([patient_id, service_id, hospital_id, room_id, date, time, status].every(Boolean)) {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM appointments WHERE id = ? LIMIT 1', [req.params.appointmentId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Appointment not found');
|
||||
|
||||
const [result] = await pool.execute(
|
||||
'UPDATE appointments SET patient_id = ?, doctor_id = ?, service_id = ?, hospital_id = ?, room_id = ?, date = ?, time = ?, status = ? WHERE id = ?',
|
||||
[patient_id, req.params.doctorId, service_id, hospital_id, room_id, date, time, status, req.params.appointmentId],
|
||||
);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating appointment');
|
||||
return await respondWithStatus(res, 200, 'Appointment updated successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:doctorId/appointments/:appointmentId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'appointment', 4)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM appointments WHERE id = ? LIMIT 1', [req.params.appointmentId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Appointment not found');
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM appointments WHERE id = ?', [req.params.appointmentId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing appointment');
|
||||
return await respondWithStatus(res, 200, 'Appointment deleted successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
// Services endpoints
|
||||
router.get('/:doctorId/services', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'service', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT s.* FROM services s INNER JOIN service_doctors sd ON s.id = sd.service_id WHERE sd.doctor_id = ?', [req.params.doctorId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Services not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:doctorId/services', verifyToken, checkBanned, async (req, res) => {
|
||||
const { service_id } = req.body;
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'service', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
if (service_id) {
|
||||
try {
|
||||
const [result] = await pool.execute('INSERT INTO service_doctors (doctor_id, service_id) VALUES (?, ?)', [req.params.doctorId, service_id]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing service');
|
||||
return await respondWithStatus(res, 200, 'Service added successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/:doctorId/services/:serviceId', verifyToken, checkBanned, async (req, res) => {
|
||||
const { type, value } = req.body;
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'service', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
if (type === 'service_id') {
|
||||
try {
|
||||
const [result] = await pool.execute('UPDATE service_doctors SET service_id = ? WHERE doctor_id = ? AND service_id = ?', [value, req.params.doctorId, req.params.serviceId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating service');
|
||||
return await respondWithStatus(res, 200, 'Service updated successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Invalid type');
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:doctorId/services/:serviceId', verifyToken, checkBanned, async (req, res) => {
|
||||
const doctorId = await getDoctorId (req.userId);
|
||||
if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'service', 4)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
try {
|
||||
const [result] = await pool.execute('DELETE FROM service_doctors WHERE doctor_id = ? AND service_id = ?', [req.params.doctorId, req.params.serviceId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing service');
|
||||
return await respondWithStatus(res, 200, 'Service removed successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
|
||||
async function getDoctorId(userId) {
|
||||
const [rows] = await pool.execute('SELECT id FROM doctors WHERE user_id = ? LIMIT 1', [userId]);
|
||||
return rows.length ? rows[0].id : null;
|
||||
}
|
||||
@@ -7,13 +7,10 @@ import { respondWithStatus, respondWithStatusJSON } from '../modules/requestHand
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('hospitals', 1), async (req, res) => {
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('hospital', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE 1');
|
||||
|
||||
if (rows.length === 0) {
|
||||
return await respondWithStatus(res, 404, 'Hospitals not found');
|
||||
}
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Hospitals not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
@@ -22,7 +19,7 @@ router.get('/', verifyToken, checkBanned, checkPermissions('hospitals', 1), asyn
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('hospitals', 2), async (req, res) => {
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('hospital', 2), async (req, res) => {
|
||||
const { company_id, name, code, country, region, city, address } = req.body;
|
||||
if ([ company_id, name, code, country, region, city, address ].every(Boolean)) {
|
||||
try {
|
||||
@@ -30,9 +27,7 @@ router.post('/', verifyToken, checkBanned, checkPermissions('hospitals', 2), asy
|
||||
'INSERT INTO hospitals (company_id, name, code, country, region, city, address) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||
[ company_id, name, code, country, region, city, address ],
|
||||
);
|
||||
if (result.affectedRows === 0) {
|
||||
return await respondWithStatus(res, 500, 'Error storing hospital');
|
||||
}
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing hospital');
|
||||
return await respondWithStatus(res, 200, 'Hospital created successfully');
|
||||
}
|
||||
catch (err) {
|
||||
@@ -45,14 +40,10 @@ router.post('/', verifyToken, checkBanned, checkPermissions('hospitals', 2), asy
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospitals', 1), async (req, res) => {
|
||||
router.get('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospital', 1), async (req, res) => {
|
||||
try {
|
||||
const id = req.params.hospitalId;
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE id = ? LIMIT 1', [id]);
|
||||
|
||||
if (rows.length === 0) {
|
||||
return await respondWithStatus(res, 404, 'Hospitals not found');
|
||||
}
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE id = ? LIMIT 1', [req.params.hospitalId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Hospitals not found');
|
||||
return await respondWithStatusJSON(res, 200, rows[0]);
|
||||
}
|
||||
catch (err) {
|
||||
@@ -61,22 +52,16 @@ router.get('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospitals
|
||||
}
|
||||
});
|
||||
|
||||
router.patch('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospitals', 2), async (req, res) => {
|
||||
router.patch('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospital', 2), async (req, res) => {
|
||||
try {
|
||||
const id = req.params.hospitalId;
|
||||
const { type, value } = req.body;
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE id = ? LIMIT 1', [id]);
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE id = ? LIMIT 1', [req.params.hospitalId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Hospital not found');
|
||||
|
||||
if (rows.length === 0) {
|
||||
return await respondWithStatus(res, 404, 'Hospital not found');
|
||||
}
|
||||
const fields = rows.map(row => Object.keys(row));
|
||||
if (fields[0].includes(type)) {
|
||||
const [result] = await pool.execute(`UPDATE hospitals SET ${type} = ? WHERE id = ?`, [value, id]);
|
||||
|
||||
if (result.affectedRows === 0) {
|
||||
return await respondWithStatus(res, 500, 'Error updating hospital');
|
||||
}
|
||||
const [result] = await pool.execute(`UPDATE hospitals SET ${type} = ? WHERE id = ?`, [value, req.params.hospitalId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating hospital');
|
||||
return await respondWithStatus(res, 200, 'Hospital updated successfully');
|
||||
}
|
||||
else {
|
||||
@@ -89,7 +74,7 @@ router.patch('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospita
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospitals', 2), async (req, res) => {
|
||||
router.put('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospital', 2), async (req, res) => {
|
||||
const id = req.params.hospitalId;
|
||||
const { company_id, name, code, country, region, city, address } = req.body;
|
||||
if ([company_id, name, code, country, region, city, address].every(Boolean)) {
|
||||
@@ -119,20 +104,13 @@ router.put('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospitals
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospitals', 4), async (req, res) => {
|
||||
router.delete('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospital', 4), async (req, res) => {
|
||||
try {
|
||||
const id = req.params.hospitalId;
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE id = ? LIMIT 1', [id]);
|
||||
const [rows] = await pool.execute('SELECT * FROM hospitals WHERE id = ? LIMIT 1', [req.params.hospitalId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Hospital not found');
|
||||
|
||||
if (rows.length === 0) {
|
||||
return await respondWithStatus(res, 404, 'Hospital not found');
|
||||
}
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM hospitals WHERE id = ?', [id]);
|
||||
|
||||
if (result.affectedRows === 0) {
|
||||
return await respondWithStatus(res, 500, 'Error removing hospital');
|
||||
}
|
||||
const [result] = await pool.execute('DELETE FROM hospitals WHERE id = ?', [req.params.hospitalId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing hospital');
|
||||
return await respondWithStatus(res, 200, 'Hospital deleted successfully');
|
||||
}
|
||||
catch (err) {
|
||||
@@ -142,16 +120,110 @@ router.delete('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospit
|
||||
});
|
||||
|
||||
// Doctor endpoints
|
||||
// GET all doctors in a hospital
|
||||
// POST a new doctor to a hospital
|
||||
// DELETE a doctor from a hospital
|
||||
router.get('/:hospitalId/doctors', verifyToken, checkBanned, checkPermissions('doctor', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT doctors.* FROM hospital_doctors JOIN doctors ON hospital_doctors.doctor_id = doctors.id WHERE hospital_doctors.hospital_id = ?', [req.params.hospitalId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Doctors not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:hospitalId/doctors', verifyToken, checkBanned, checkPermissions('doctor', 2), async (req, res) => {
|
||||
const { doctor_id } = req.body;
|
||||
if ([doctor_id].every(Boolean)) {
|
||||
try {
|
||||
const [result] = await pool.execute('INSERT INTO hospital_doctors (hospital_id, doctor_id) VALUES (?, ?)', [req.params.hospitalId, doctor_id]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing doctor');
|
||||
return await respondWithStatus(res, 200, 'Doctor added to hospital successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:hospitalId/doctors/:doctorId', verifyToken, checkBanned, checkPermissions('doctor', 4), async (req, res) => {
|
||||
try {
|
||||
const { hospitalId, doctorId } = req.params;
|
||||
const [result] = await pool.execute('DELETE FROM hospital_doctors WHERE hospital_id = ? AND doctor_id = ?', [hospitalId, doctorId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing doctor');
|
||||
return await respondWithStatus(res, 200, 'Doctor removed from hospital successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
// Service endpoints
|
||||
// GET all services in a hospital
|
||||
router.get('/:hospitalId/services', verifyToken, checkBanned, checkPermissions('service', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT services.* FROM hospital_doctors JOIN doctors ON hospital_doctors.doctor_id = doctors.id JOIN doctor_services ON doctors.id = doctor_services.doctor_id JOIN services ON doctor_services.service_id = services.id WHERE hospital_doctors.hospital_id = ?',
|
||||
[req.params.hospitalId],
|
||||
);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Services not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
// Room endpoints
|
||||
// GET all rooms in a hospital
|
||||
// POST a new room to a hospital
|
||||
// DELETE a room from a hospital
|
||||
router.get('/:hospitalId/rooms', verifyToken, checkBanned, checkPermissions('room', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM rooms WHERE hospital_id = ?', [req.params.hospitalId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Rooms not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:hospitalId/rooms', verifyToken, checkBanned, checkPermissions('room', 2), async (req, res) => {
|
||||
const { name, code, floor, room_number, room_type } = req.body;
|
||||
if ([name, code, floor, room_number, room_type].every(Boolean)) {
|
||||
try {
|
||||
if (!['General Ward', 'Private', 'Intensive Care Unit', 'Labor and Delivery', 'Operating', 'Recovery', 'Isolation', 'Emergency', 'Imaging', 'Procedure', 'Physical Therapy', 'Consultation'].includes(room_type)) return await respondWithStatus(res, 400, 'Invalid room type');
|
||||
const [result] = await pool.execute(
|
||||
'INSERT INTO rooms (hospital_id, name, code, floor, room_number, room_type) VALUES (?, ?, ?, ?, ?, ?)',
|
||||
[req.params.hospitalId, name, code, floor, room_number, room_type],
|
||||
);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing room');
|
||||
return await respondWithStatus(res, 200, 'Room created successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:hospitalId/rooms/:roomId', verifyToken, checkBanned, checkPermissions('room', 4), async (req, res) => {
|
||||
try {
|
||||
const [result] = await pool.execute('DELETE FROM rooms WHERE hospital_id = ? AND id = ?', [req.params.hospitalId, req.params.roomId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing room');
|
||||
return await respondWithStatus(res, 200, 'Room removed from hospital successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -12,7 +12,7 @@ const router = express.Router();
|
||||
*
|
||||
* @returns {Promise<Array>} A promise that resolves to an array of patient objects.
|
||||
*/
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('patients', 1), async (req, res) => {
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('patient', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE 1');
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Patients not found');
|
||||
@@ -35,7 +35,7 @@ router.get('/', verifyToken, checkBanned, checkPermissions('patients', 1), async
|
||||
* @param {string} insurance_number - The insurance number of the patient.
|
||||
* @returns {Promise} - A promise that resolves with the result of the insertion.
|
||||
*/
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('patients', 2), async (req, res) => {
|
||||
router.post('/', verifyToken, checkBanned, checkPermissions('patient', 2), async (req, res) => {
|
||||
const { user_id, date_of_birth, gender, address, social_security_number, insurance_number } = req.body;
|
||||
if ([ user_id, date_of_birth, gender, address, social_security_number, insurance_number ].every(Boolean)) {
|
||||
try {
|
||||
@@ -65,6 +65,9 @@ router.post('/register', verifyToken, checkEmailVerified, checkBanned, async (re
|
||||
[ req.userId, date_of_birth, gender, address, social_security_number, insurance_number ],
|
||||
);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing patient');
|
||||
|
||||
const [result2] = await pool.execute('INSERT INTO user_roles (user_id, role_id) VALUES (?, (SELECT id FROM roles WHERE name = ? LIMIT 1))', [req.userId, 'Patient']);
|
||||
if (result2.affectedRows === 0) return await respondWithStatus(res, 500, 'Error adding role to user');
|
||||
return await respondWithStatus(res, 200, 'Patient created successfully');
|
||||
}
|
||||
catch (err) {
|
||||
@@ -79,10 +82,10 @@ router.post('/register', verifyToken, checkEmailVerified, checkBanned, async (re
|
||||
|
||||
router.get('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const id = req.params.patientId;
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [id]);
|
||||
const patientId = await getPatientId(req.userId);
|
||||
if (patientId != req.params.patientId && !verifyPermissions(req.userId, 'patient', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [req.params.patientId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Patient not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'patients', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
return await respondWithStatusJSON(res, 200, rows[0]);
|
||||
}
|
||||
catch (err) {
|
||||
@@ -93,17 +96,16 @@ router.get('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
|
||||
router.patch('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const id = req.params.patientId;
|
||||
const { type, value } = req.body;
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [id]);
|
||||
const patientId = await getPatientId(req.userId);
|
||||
if (patientId != req.params.patientId && !verifyPermissions(req.userId, 'patient', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [req.params.patientId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Patient not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'patients', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
|
||||
const excludedKeys = [ 'id', 'user_id' ];
|
||||
const fields = rows.map(row => Object.keys(row).filter(key => !excludedKeys.includes(key)));
|
||||
if (fields[0].includes(type)) {
|
||||
const [result] = await pool.execute(`UPDATE patients SET ${type} = ? WHERE id = ?`, [value, id]);
|
||||
|
||||
const [result] = await pool.execute(`UPDATE patients SET ${type} = ? WHERE id = ?`, [value, req.params.patientId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating patient');
|
||||
return await respondWithStatus(res, 200, 'Patient updated successfully');
|
||||
}
|
||||
@@ -118,17 +120,17 @@ router.patch('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
});
|
||||
|
||||
router.put('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
const id = req.params.patientId;
|
||||
const { user_id, date_of_birth, gender, address, social_security_number, insurance_number } = req.body;
|
||||
if ([ user_id, date_of_birth, gender, address, social_security_number, insurance_number ].every(Boolean)) {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [id]);
|
||||
const patientId = await getPatientId(req.userId);
|
||||
if (patientId != req.params.patientId && !verifyPermissions(req.userId, 'patient', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [req.params.patientId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Patient not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'patients', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
|
||||
const [result] = await pool.execute(
|
||||
'UPDATE patients SET name = ?, date_of_birth = ?, gender = ?, address = ?, social_security_number = ?, insurance_number = ? WHERE id = ?',
|
||||
[user_id, date_of_birth, gender, address, social_security_number, insurance_number, id],
|
||||
[user_id, date_of_birth, gender, address, social_security_number, insurance_number, req.params.patientId],
|
||||
);
|
||||
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating patient');
|
||||
@@ -146,13 +148,12 @@ router.put('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
|
||||
router.delete('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const id = req.params.patientId;
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT', [id]);
|
||||
const patientId = await getPatientId(req.userId);
|
||||
if (patientId != req.params.patientId && !verifyPermissions(req.userId, 'patient', 4)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE id = ? LIMIT 1', [req.params.patientId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Patient not found');
|
||||
if (rows[0].userId != req.userId && !verifyPermissions(req.userId, 'patients', 4)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM patients WHERE id = ?', [id]);
|
||||
|
||||
const [result] = await pool.execute('DELETE FROM patients WHERE id = ?', [req.params.patientId]);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing patient');
|
||||
return await respondWithStatus(res, 200, 'Patient deleted successfully');
|
||||
}
|
||||
@@ -163,11 +164,53 @@ router.delete('/:patientId', verifyToken, checkBanned, async (req, res) => {
|
||||
});
|
||||
|
||||
// Appointments endpoints
|
||||
// GET /:patientId/appointments
|
||||
// POST /:patientId/appointments
|
||||
router.get('/:patientId/appointments', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
const patientId = await getPatientId(req.userId);
|
||||
if (patientId != req.params.patientId && !verifyPermissions(req.userId, 'appointment', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT a.id, u.first_name, u.last_name, d.email, d.phone, h.name, h.address, a.date, a.time, a.status, s.name FROM appointments a JOIN doctors d ON a.doctor_id = d.id JOIN users u ON d.user_id = u.id JOIN hospitals h ON a.hospital_id = h.id JOIN services s ON a.service_id = s.id WHERE a.patient_id = ?',
|
||||
[req.params.patientId],
|
||||
);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Appointments not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:patientId/appointments', verifyToken, checkBanned, async (req, res) => {
|
||||
const { doctor_id, service_id, hospital_id, date, time } = req.body;
|
||||
if ([ doctor_id, service_id, hospital_id, date, time ].every(Boolean)) {
|
||||
try {
|
||||
const patientId = await getPatientId(req.userId);
|
||||
if (patientId != req.params.patientId && !verifyPermissions(req.userId, 'appointment', 2)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [result] = await pool.execute(
|
||||
'INSERT INTO appointments (doctor_id, service_id, hospital_id, patient_id, date, time) VALUES (?, ?, ?, ?, ?, ?)',
|
||||
[ doctor_id, service_id, hospital_id, req.params.patientId, date, time ],
|
||||
);
|
||||
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing appointment');
|
||||
return await respondWithStatus(res, 200, 'Appointment created successfully');
|
||||
}
|
||||
catch (err) {
|
||||
error(err);
|
||||
return await respondWithStatus(res, 500, 'An error has occured');
|
||||
}
|
||||
}
|
||||
else {
|
||||
return await respondWithStatus(res, 400, 'Missing fields');
|
||||
}
|
||||
});
|
||||
// GET /:patientId/appointments/:appointmentId
|
||||
// PATCH /:patientId/appointments/:appointmentId
|
||||
// PUT /:patientId/appointments/:appointmentId
|
||||
// DELETE /:patientId/appointments/:appointmentId
|
||||
|
||||
export default router;
|
||||
|
||||
async function getPatientId(userId) {
|
||||
const [rows] = await pool.execute('SELECT * FROM patients WHERE user_id = ? LIMIT 1', [userId]);
|
||||
return rows.length ? rows[0].id : null;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ router.post('/', (req, res) => {
|
||||
|
||||
router.patch('/', (req, res) => {
|
||||
|
||||
res.status(200).json({ code: 200, message:'Received PUT request' });
|
||||
res.status(200).json({ code: 200, message:'Received PATCH request' });
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -89,8 +89,7 @@ router.post('/login', requestLimiter, async (req, res) => {
|
||||
|
||||
router.get('/', verifyToken, checkBanned, checkPermissions('user', 1), async (req, res) => {
|
||||
try {
|
||||
const [rows] = await pool.execute('SELECT * FROM users WHERE 1');
|
||||
|
||||
const [rows] = await pool.execute('SELECT id, first_name, last_name, username, email, phone FROM users WHERE 1');
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'Users not found');
|
||||
return await respondWithStatusJSON(res, 200, rows);
|
||||
}
|
||||
@@ -124,11 +123,9 @@ router.post('/', verifyToken, checkBanned, checkPermissions('user', 2), async (r
|
||||
router.get('/:userId', verifyToken, checkBanned, async (req, res) => {
|
||||
try {
|
||||
if (req.params.userId != req.userId && !verifyPermissions(req.userId, 'user', 1)) return await respondWithStatus(res, 403, 'Missing permission');
|
||||
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ? LIMIT 1', [req.params.userId]);
|
||||
const [rows] = await pool.execute('SELECT id, first_name, last_name, username, email, phone FROM users WHERE id = ? LIMIT 1', [req.params.userId]);
|
||||
if (rows.length === 0) return await respondWithStatus(res, 404, 'User not found');
|
||||
|
||||
if (rows.length === 0) {
|
||||
return await respondWithStatus(res, 404, 'User not found');
|
||||
}
|
||||
const user = rows[0];
|
||||
delete user.password;
|
||||
return await respondWithStatusJSON(res, 200, user);
|
||||
|
||||
Reference in New Issue
Block a user