Open In App

Hospital Appointment System using Express

Last Updated : 28 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Hospital Appointment System project using Express and MongoDB contains various endpoints that will help to manage hospital appointments. In this project, there is an appointment endpoint for user management and appointment management. API will be able to register users, authenticate users, book appointments, and cancel appointments. We’ll be using Node JS, Express, and MongoDB.

Preview Image: Let us have a look at how the final data will look like

Screenshot-(54)

Prerequisites:

Approach to create Hospital Management System:

  • We will build an express server that will act as a backend API.
  • Then we will configure MongoDB Atlas for storing user and appointment data.
  • Then we will configure server for managing hospital data with Mongoose.
  • We will add routes for getting patients , doctors and appointments specific to user from backend with GET request.
  • For authentication we will add login, logout , session route which use jwt and local passport authentication.
  • Then we will add route book appointment which will create new appointment by taking appointment data from patient.
  • Similarly, we will add routes that will perform cancellation of appointment.
  • after this we will add route for fetching appointments from database.
  • All the above routes will use HTTP POST request.

Functionalities:

  • Register Patient / Doctor: Register and save user as doctor or patient into collection.
  • Authenticate: Authenticates user with username and password.
  • Get Patients / Doctors: Can View all available users in system.
  • Book Appointment: creates and save new appointment in collection.
  • Cancel Appointment: Allow user to borrow available book from system.
  • Get appointments: fetch booked appointments from database.

Steps to create a project:

Step 1: First, we will initiate the Node project using below command. Go to project folder and run below command.

npm init -y

Step 2: Install the required dependencies as mentioned below using below npm command.

npm i express body-parser connect-mongo express-session jsonwebtoken mongoose
nodemon passport passport-jwt passport-local

Step 3: We will add logic for routes according to the functionality mentioned above .

Step 4: Configure the database collection after starting the server. Create unique index for appointments and appointmentavailability collection as shown below through mongodb console.

Appointments:

appointments-index

Appointment availability :

appointmentavailability-index

Project Structure:

Screenshot-(52)

The updated dependencies in package.json file will look like:

"dependencies": {
"body-parser": "^1.20.2",
"connect-mongo": "^5.1.0",
"express": "^4.18.2",
"express-session": "^1.17.3",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.0.3",
"nodemon": "^3.0.2",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0"
}

Steps to run the application: Run the following command in the terminal.

nodemon index.js 

NOTE: For accessing routes which requires LOGIN you need to pass JWT token specific to doctor or patient as ‘x-access-token’ from headers.

List of All API links:

  • http://localhost:5000/
  • http://localhost:5000/registerpatient
  • http://localhost:5000/registerdoctor
  • http://localhost:5000/login
  • http://localhost:5000/logout
  • http://localhost:5000/session
  • http://localhost:5000/getpatients
  • http://localhost:5000/getdoctors
  • http://localhost:5000/getappointments
  • http://localhost:5000/bookappointment
  • http://localhost:5000/cancelappointment

Example: Write the following code in the filename mentioned at top of each code block

Javascript




//index.js
 
const express = require('express');
const bodyParser = require('body-parser');
var session = require('express-session');
const MongoStore = require("connect-mongo");
const port = 5000;
const app = express();
const { db } = require('./db');
const authRouter = require('./auth');
const hospitalRouter = require('./hospital');
 
//body-parser configuration
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
    extended: true
}))
 
//session configuration
app.use(session({
    secret: 'gfgsecret',
    resave: false,
    saveUninitialized: true,
    store: MongoStore.create({
        client: db.getClient(),
        dbName: 'testdb',
        collectionName: "sessions",
        stringify: false,
        autoRemove: "interval",
        autoRemoveInterval: 1
    })
}));
 
app.use('/', authRouter);
app.use('/', hospitalRouter);
 
//server listening
app.listen(port, () => {
    console.log(`server started on ${port}`);
});


Javascript




//db.js
 
const mongoose = require('mongoose');
 
//database connection
mongoose.connect("Your_Database_URL");
 
const db = mongoose.connection;
 
db.on('error', console.error.bind(console, 'connection error:'));
 
 
db.once('open', function () {
    console.log("Connection Successful!");
});
 
//model and schema creation
var PatientSchema = mongoose.Schema({
    name: String,
    username: { type: String, unique: true },
    password: String,
    age: { type: Number },
    email: { type: String, unique: true },
    mobile: { type: Number, unique: true },
});
 
var DoctorSchema = mongoose.Schema({
    name: String,
    username: { type: String, unique: true },
    password: String,
    age: { type: Number },
    email: { type: String, unique: true },
    mobile: { type: Number, unique: true },
    speciality: { type: String },
});
 
var AppointmentSchema = mongoose.Schema({
    doctorid: { type: mongoose.ObjectId, ref: 'Doctor' },
    patientid: { type: mongoose.ObjectId },
    appointmentdate: {
        type: Date,
        default: () => new Date("<YYYY-mm-dd>"),
        required: 'Must Have Appointment Date'
    },
    slotnumber: {
        type: Number,
        required: 'Must Have Slot Number'
    }
}, { timestamps: true })
 
var AppointmentAvailabilitySchema = mongoose.Schema({
    doctorid: { type: mongoose.ObjectId, ref: 'Doctor' },
    appointmentdate: {
        type: Date,
        ref: 'Appointment'
    },
    appointmentsavailable: {
        type: Object
    }
}, { timestamps: true })
 
var Patient = mongoose.model('Patient', PatientSchema, 'patient');
var Doctor = mongoose.model('Doctor', DoctorSchema, 'doctor');
var Appointment = mongoose
                      .model('Appointment', AppointmentSchema, 'appointments');
var AppointmentAvailability = mongoose
                              .model('AppointmentAvailability',
                                        AppointmentAvailabilitySchema,
                                     'appointmentavailability');
 
module.exports = { db, Patient, Doctor, Appointment, AppointmentAvailability };


Javascript




//auth.js
 
const jwt = require("jsonwebtoken");
const JWTStrategy = require("passport-jwt").Strategy;
var LocalStrategy = require("passport-local");
var passport = require("passport");
const express = require("express");
var { Patient, Doctor } = require("./db");
var router = express.Router();
 
//passport local strategy configuration
passport.use(
    "patient",
    new LocalStrategy(async function verify(username, password, cb) {
        const querypatient = Patient.where({ username: username });
 
        await querypatient
            .findOne()
            .then(function (user) {
                if (user.password === password) {
                    cb(null, user, {
                        status: 200,
                        message: "Login Successful.",
                    });
                } else {
                    cb(null, false, {
                        status: 401,
                        message: "Incorrect username or password.",
                    });
                }
            })
            .catch(function (err) {
                cb(null, false, {
                    status: 401,
                    message: "Patient Does Not Exist",
                });
            });
    })
);
 
passport.use(
    "doctor",
    new LocalStrategy(async function verify(username, password, cb) {
        const querydoctor = Doctor.where({ username: username });
        await querydoctor
            .findOne()
            .then(function (user) {
                if (user.password === password) {
                    cb(null, user, {
                        status: 200,
                        message: "Login Successful.",
                    });
                } else {
                    cb(null, false, {
                        status: 401,
                        message: "Incorrect username or password.",
                    });
                }
            })
            .catch(function (err) {
                cb(null, false, {
                    status: 401,
                    message: "Doctor Does Not Exist",
                });
            });
    })
);
 
//passport jwt strategy configuration
passport.use(
    new JWTStrategy(
        {
            jwtFromRequest: (req) => req.headers["x-access-token"],
            secretOrKey: "examplesecret",
        },
        (payload, done) => {
            return done(null, payload);
        }
    )
);
 
passport.serializeUser(function (user, cb) {
    process.nextTick(function () {
        cb(null, { id: user.id, username: user.username });
    });
});
 
passport.deserializeUser(function (user, cb) {
    process.nextTick(function () {
        return cb(null, user);
    });
});
 
//route for registering user and admin
router.post("/registerpatient", async (req, res) => {
    //new user creation from request body data
    var user1 = new Patient(req.body);
 
    await user1.save().then(
        function (user) {
            if (user) {
                console.log(user.name + " saved to user collection.");
                res.send({ status: 200, message: user.name });
            }
        },
        function (err) {
            //errors for various primary key
            if (Object.keys(err.keyPattern)[0] == "mobile") {
                res.send({
                    status: 500,
                    message: "User with mobile already exist",
                });
            } else if (Object.keys(err.keyPattern)[0] == "username") {
                res.send({
                    status: 500,
                    message: "User with username already exist",
                });
            } else if (Object.keys(err.keyPattern)[0] == "email") {
                res.send({
                    status: 500,
                    message: "User with email already exist",
                });
            } else {
                res.send({ status: 500, message: "Internal Server Error" });
            }
        }
    );
});
 
//route for registering user and admin
router.post("/registerdoctor", async (req, res) => {
    //new user creation from request body data
    var user1 = new Doctor(req.body);
 
    await user1.save().then(
        function (user) {
            if (user) {
                console.log(user.name + " saved to user collection.");
                res.send({ status: 200, message: user.name });
            }
        },
        function (err) {
            //errors for various primary key
            if (Object.keys(err.keyPattern)[0] == "mobile") {
                res.send({
                    status: 500,
                    message: "User with mobile already exist",
                });
            } else if (Object.keys(err.keyPattern)[0] == "username") {
                res.send({
                    status: 500,
                    message: "User with username already exist",
                });
            } else if (Object.keys(err.keyPattern)[0] == "email") {
                res.send({
                    status: 500,
                    message: "User with email already exist",
                });
            } else {
                res.send({ status: 500, message: "Internal Server Error" });
            }
        }
    );
});
 
//route for logging user in
router.post("/login", (req, res) => {
    const isDoctor = req.body.isDoctor === "true";
    if (isDoctor) {
        passport.authenticate(
            "doctor",
            { session: false },
            (err, user, info) => {
                if (err || !user) {
                    return res.send({ status: 401, message: info.message });
                }
                req.login(user, { session: false }, (err) => {
                    if (err) {
                        res.send(err);
                    }
                    var userobject = {
                        userid: user["_id"],
                        username: user.username,
                        isDoctor: true,
                    };
                    var token = jwt.sign(userobject, "examplesecret");
                    req.session.jwt = token;
                    return res.send({ status: 200, token: token });
                });
            }
        )(req, res);
    } else {
        passport.authenticate(
            "patient",
            { session: false },
            (err, user, info) => {
                if (err || !user) {
                    return res.send({ status: 401, message: info.message });
                }
                req.login(user, { session: false }, (err) => {
                    if (err) {
                        res.send(err);
                    }
                    var userobject = {
                        userid: user["_id"],
                        username: user.username,
                        isDoctor: false,
                    };
                    var token = jwt.sign(userobject, "examplesecret");
                    req.session.jwt = token;
                    return res.send({ status: 200, token: token });
                });
            }
        )(req, res);
    }
});
 
//route for logging out user
router.post("/logout", (req, res, next) => {
    req.session.destroy(function (err) {
        if (err) {
            return next(err);
        }
        res.redirect("/");
    });
});
 
//route for getting session in frontend
router.get("/session", (req, res) => {
    passport.authenticate("jwt", { session: false }, (err, user) => {
        if (err || !user) {
            res.send(false);
        } else {
            res.send(user);
        }
    })(req, res);
});
 
module.exports = router;


Javascript




//hospital.js
 
const express = require('express');
var { Patient, Doctor, Appointment, AppointmentAvailability } = require('./db');
var router = express.Router();
var passport = require('passport');
 
const appointmentsArray = {
    "1": { slotname: "9AM TO 10AM", availability: true, appintmentid: null },
    "2": { slotname: "10AM TO 11AM", availability: true, appintmentid: null },
    "3": { slotname: "11AM TO 12PM", availability: true, appintmentid: null },
    "4": { slotname: "12PM TO 1PM", availability: true, appintmentid: null },
    "5": { slotname: "3PM TO 4PM", availability: true, appintmentid: null },
    "6": { slotname: "4PM TO 5PM", availability: true, appintmentid: null },
    "7": { slotname: "5PM TO 6PM", availability: true, appintmentid: null },
    "8": { slotname: "6PM TO 7PM", availability: true, appintmentid: null },
    "9": { slotname: "7PM TO 8PM", availability: true, appintmentid: null },
    "10": { slotname: "8PM TO 9PM", availability: true, appintmentid: null },
    "11": { slotname: "9PM TO 10PM", availability: true, appintmentid: null },
}
 
//home endpoint
router.get('/', (req, res) => {
    res.send("Welcome To Hospital Appointment System");
});
 
//route for getting all patients from database
router.get('/getpatients', async (req, res) => {
    const patients = await Patient.find({});
    res.send({ status: 200, users: patients });
})
 
//route for getting all doctors from database
router.get('/getdoctors', async (req, res) => {
    const doctors = await Doctor.find({});
    res.send({ status: 200, users: doctors });
})
 
 
//route for creating a new appointment
router.post('/bookappointment', async (req, res) => {
    //new appointment from request body
    var appointmentdata = req.body;
 
    //authentication
    passport.authenticate('jwt', { session: false }, async (err, user) => {
        if (err || !user) {
            res.send({ status: 401, message: "Not Authorized" });
        } else {
            if (!user.isDoctor) {
                // saving appointment to db
                Doctor.findOne({ _id: appointmentdata.doctorid }).then((doctor) => {
                    if (doctor) {
                        Appointment.findOne({ doctorid: doctor["_id"], appointmentdate: new Date(appointmentdata.appointmentdate.toString()), slotnumber: appointmentdata.slotnumber }).then((appointment) => {
                            if (appointment || slotnumber > 11) {
                                res.send({ status: 200, message: "Selected Slot is not available" });
                            }
                            else {
                                var appointment = new Appointment({
                                    doctorid: appointmentdata.doctorid,
                                    patientid: user.userid,
                                    appointmentdate: new Date(appointmentdata.appointmentdate.toString()),
                                    slotnumber: appointmentdata.slotnumber
                                })
 
                                appointment.save().then((appointment) => {
                                    AppointmentAvailability.findOne({ doctorid: appointment.doctorid, appointmentdate: appointment.appointmentdate }).then((appointmentmap) => {
                                        if (appointmentmap) {
                                            var appointmentavailability = appointmentmap.appointmentsavailable;
                                            appointmentavailability[appointmentdata.slotnumber].availability = false;
                                            appointmentavailability[appointmentdata.slotnumber].appintmentid = appointment["_id"];
                                            AppointmentAvailability.where({ _id: appointmentmap["_id"] }).updateOne({ appointmentsavailable: appointmentavailability }).then((updateres) => {
                                                if (updateres) {
                                                    res.send({ status: 200, message: `Appointment Booked Successfully. Appointment ID is ${appointment["_id"]}` });
                                                }
                                                else {
                                                    res.send({ status: 500, message: "Internal Server Error" })
                                                }
                                            })
                                        }
                                        else {
                                            var appointmentavailability = appointmentsArray;
                                            appointmentavailability[appointmentdata.slotnumber].availability = false;
                                            appointmentavailability[appointmentdata.slotnumber].appintmentid = appointment["_id"];
                                            var appointmentavailabilityrecord = new AppointmentAvailability({
                                                doctorid: appointment.doctorid,
                                                appointmentdate: appointment.appointmentdate,
                                                appointmentsavailable: appointmentavailability
                                            })
                                            appointmentavailabilityrecord.save().then((appointmentres) => {
                                                if (appointmentres) {
                                                    res.send({ status: 200, message: `Appointment Booked Successfully. Appointment ID is ${appointment["_id"]}` })
                                                }
                                                else {
                                                    res.send({ status: 500, message: "Internal Server Error" });
                                                }
                                            })
                                        }
                                    })
                                }).catch((err) => {
                                    res.send({ status: 500, message: "Internal Server Error" });
                                })
                            }
                        }).catch((err) => {
                            console.log(err);
                        })
                    }
                    else {
                        res.send({ status: 200, message: "Selected Doctor Does Not Exist" });
                    }
                })
            }
            else {
                res.send({ status: 401, message: "This action cannot be performed by doctor" });
            }
        }
    })(req, res);
})
 
//route for creating a new appointment
router.delete('/cancelappointment', async (req, res) => {
    //new appointment from request body
    var appointmentdata = req.body;
 
    //authentication
    passport.authenticate('jwt', { session: false }, async (err, user) => {
        if (err || !user) {
            res.send({ status: 401, message: "Not Authorized" });
        } else {
            if (!user.isDoctor) {
                // finding and deleting appointment from db
                Appointment.findOne({ _id: appointmentdata.appointmentid }).then((appointment) => {
                    if (appointment) {
                        if (user.userid === appointment.patientid.toString()) {
                            Appointment.deleteOne({ _id: appointment["_id"] }).then((deleteres) => {
                                if (deleteres) {
                                    AppointmentAvailability.findOne({ doctorid: appointment.doctorid, appointmentdate: appointment.appointmentdate }).then((appointmentmap) => {
                                        var appointmentavailability = appointmentmap.appointmentsavailable;
                                        appointmentavailability[appointment.slotnumber].availability = true;
                                        appointmentavailability[appointment.slotnumber].appintmentid = null;
                                        AppointmentAvailability.where({ _id: appointmentmap["_id"] }).updateOne({ appointmentsavailable: appointmentavailability }).then((updateres) => {
                                            if (updateres) {
                                                res.send({ status: 200, message: `Appointment with Appointment ID : ${appointment["_id"]} is canceled successfully. ` });
                                            }
                                            else {
                                                res.send({ status: 500, message: "Internal Server Error" })
                                            }
                                        })
                                    })
                                }
                                else {
                                    res.send({ status: 500, message: "Internal Server Error" });
                                }
                            })
                        }
                        else {
                            res.send({ status: 200, message: "Invalid Appointment Number" });
                        }
                    }
                    else {
                        res.send({ status: 200, message: "Appointment Does Not Exist" });
                    }
                }).catch((err) => {
                    console.log(err);
                })
            }
            else {
                res.send({ status: 401, message: "This action cannot be performed by doctor" });
            }
        }
    })(req, res);
})
 
router.get("/getappointments", (req, res) => {
    //authentication
    passport.authenticate('jwt', { session: false }, async (err, user) => {
        if (err || !user) {
            res.send({ status: 401, message: "Not Authorized" });
        } else {
            if (!user.isDoctor) {
                // fetching appointments from db for patient
                Appointment.find({ patientid: user.userid }).then((appointments) => {
                    if (appointments) {
                        res.send({ status: 200, appointments: appointments });
                    }
                    else {
                        res.send({ status: 500, message: "Internal Server Error" });
                    }
                }).catch((err) => {
                    console.log(err);
                })
            }
            else {
                // fetching appointments from db for doctor
                Appointment.find({ doctorid: user.userid }).then((appointments) => {
                    if (appointments) {
                        res.send({ status: 200, appointments: appointments });
                    }
                    else {
                        res.send({ status: 500, message: "Internal Server Error" });
                    }
                }).catch((err) => {
                    console.log(err);
                })
            }
        }
    })(req, res);
})
 
module.exports = router;


Output :

2023-12-27-23-20-09-(online-video-cuttercom)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads