Overview

With most of the preparation finished in the last term, we have been focusing on the development side of the project throughout this second term. Documentations are also being added alongside the development process. After that, we did thorough testing of the program and deployed the app onto our server which gave us our final product.

You can also look into the details of the project in our portfolio

Development

The development process has occupied most of our time in this term. Since we have already familiarised ourselves with the tech stack the last term, we began straight by first creating the essential pages for our app, then keep on adding extra functionalities according to the MoSCoW requirements list and client feedbacks.

Register and Login Page

First, we started development with the register and login page because we think that the authentication system is very important for the users. Both register and login page utilized pool.query. However, the difference is the register page inserts data into the database and the login page performs a query and gains data from the database. Also, the authentication system will assign a JWT to each valid user to track their login status.

Login

Register

Paitent Dashboard

Developing a highly customisable dashboard is the main focus of this project. The patient dashboard page will be where the treatment data will be visualised. It will display the feed data graphs which is a Linechart component that imports form react-chartjs-2.

Functionalities on this page include filtering the data, select data type, add feedback and change treatment plan (clinicians only).

Patient Dashboard

Clinician Dashboard

On the clinician dashboard, it shows the list of patients supervised by the clinician. This page is only visible by a clinician. When the patient’s name is clicked, it will redirect to that patient’s dashboard. The main functionality here will be Add Patients which the clinician will be able to assign patients they supervise so that they will not see the patients they are not looking after.

Clinician Dashboard

Functionalities

Target Feed

On the patient dashboard page, there will be a target feed graph in red dotted line overlayed onto the feed graph. This allows both clinicians and patients to compare the prescribed feed and target feed, thus reviewing the feed quality.

Patient Dashboard

Change Treatment Plan

Clinicians will be able to change a patient’s treatment plan to revise the prescribed feed for patients. In the change treatment plan form, which is below the patient dashboard by clicking the Change treatment plan button, the clinician will set the target feed volume and the target energy intake. Then, the database will update the treatment plan details by the back-end server performing a pool.query, and then the treatment information inputs will be kept in the table treatments which is then followed by a “Treatment Plan Change Successful!” message.

Change Treatment

Last Modification Time

We did this by adding the field last modified time to the table treatments. PostgreSQL provides two types of timestamp, which are TIMESTAMP and TIMESTAMPZ. Both of them can store the date and exact time, however, the biggest difference between them is TIMESTAMP cannot memory the time zone, which means if the time zone of the database server has changed, the time stored in it will not change. But in this project, since we think that the server’s time zone will be changed frequently, using TIMESTAMP is still a good choice.

After submitting the form of change treatment plan and saving the information to the table treatments in the database, the database server will automatically record the time of data input by timestamp.

Add Patients

This page is redirected to when the Add patients button is clicked on the clinician dashboard page. On this page, there will be a list of all patients stored in the database and the clinician will be assigned only the ones they are supervising by using the checkbox next to the patient names. This is because clinicians will only see the treatment data of the patients they are taking care of. This means if the patient is being added, the name of that patient will appear on the list on Clinician Dashboard page. As a patient is added, the user_perms will update, user_id is the id of the clinician and patient_scope is the id of the patient. In this way, the clinician can manage their patients conveniently.

Add Patients

Generating Feeds

To be able to simulate the data from the infusion pump, we have added data to the graph by generating feed data from the backend so we can simulate real data is being displayed. As we have no idea what kind of data exactly will be passed from the infusion pump (since there is no way for us to get hands-on an actual infusion pump), we did this to imitate the concept and functionality of the app. We created a genFeeds.py file that generates random dates and feed data with Math.random. The data generated will be then pushed and stored in the database, so it can then be used to visualise the line graph.

We used cron job to schedule to continuously run the genFeeds.py file to give us a large amount of data to be used. Cron job is a time-based job scheduler that gives the ability to do repetitive tasks. In our case, we used it to run the genFeeds.py file every 30 minutes, simulating the data fetched from the infusion pump every 30 minutes. We also make sure that all these data will be stored in the database and will not be discarded at any point.

Sort by Day/Month/Year

Another functionality we have added is the ability to show the line graph in different ways. Our previous graph was only capable of showing all the data we have collected, but it can be confusing and hard to keep track of to the user. Therefore, we decided to make the graph visible also by year, months and day. We have done this by implementing an option bar to let the user choose how they want to display. The option will be passed to the LineChart as a filter option when triggering onchangeFilter. On LineChart, we have added a function filterFeed to change the display accordingly. After determining what the filter option is, it will get the timestamps and feed data from the database.

By Day.

Filter by Day

By Month.

Filter by Mpnth

By Year.

Filter by Year

Filter Date

This is another feature that allows users to view specific data on specific dates. We achieved this with the user of RainbowDatepicker from react-rainbow-components. It allows user to have a popup of a calendar to pick two dates which are the start and end date of the desired range. We then get that date and format it using fornmatDates to get the range of the date. Only the data within the range will then be determined and displayed on the graph.

Date Range Selector

Date Range 1

Date Range 2

Weight Graph

Our client reflected that a weight graph would be useful since they can extract information by comparing the change in weight to the feed rate. We decided then to overlay the weight graph onto the feed graph.

On the patient dashboard, we have added a showWeight check box which when on click, will show the weight graph. This is done by adding a weight graph to the LineChart component. To do this, we need to map the weight data using a findWeights function which returns the weights within the timestamp. The value of the weights will also be multiplied by a constant so that it will be in a similar range as the feed rate so that it can be better viewed.

Date Range 2

User Feedback System

This feedback system is for clinicians or patients to leave a message on specific data points on the graph. This enables them to explain what happened at that moment which may justify the anomaly. We have added a component Modal which is a popup for the user to submit their feedback. After it is entered, the message will be stored in the database. Users will be able to view this by hovering on the point and there will be a new column patient_feedback added.

We later also changed the colour of the point if it is commented so that it is more visible on the graph. The feedback is also annotated with the user who gave the feedback, making it easier to track the messages.

Hover Point

Feedback

Refactoring

After all the functionalities were implemented, we have refactored our code using Redux which is a library with a simple API, designed to be a predictable container for the application state. It operates similarly to a reducing function, a functional programming concept that is great for improving state management. We have modified using useSelector and useDispatch throughout the whole program. Selector helps with storing minimal state by deriving data from the state when it is needed, so this helps avoid repeating logic as different parts of the app need to read the same data. A Dispatch makes the only way to update the state by calling store.dispatch and pass in an action object so that the states are better managed and will not be updated elsewhere. The Provider is also used is our index.js which allows the Redux store available to any nested components which we have wrapped our entire app with.

Documentation

User Manual

We did the user manual as we have finished all the functions and UI design. This can act as a tutorial for the users to be able to get familiar with the web app and understand the functionality clearly.

We have four pages for the user-manual and the pages are Home, Getting Started, Clinicians and Patients. Home page contains a piece of welcome information, an abstract of our project and a list of shortcuts for the users the contents they want quickly. The Getting Started page is like a condensed version of the whole user manual. It consisted of some important functions, but they are not described in details. Since we have two roles in this web app, clinicians and patients, thus, this user manual also describes how to use the web app for both two roles. On both the Clinicians page and Patients page, we provide a lot of detailed descriptions and screenshots for every single step to make sure that the users can follow with us and never feel confused.

Our user manual documentation can be found here.

Deployment Manual

As our app is deployed, we have added a thorough ReadME in our GitHub repository https://github.com/COMP0016-Team6/NHS-Patient-Dashboard which has very detailed step-by-step instructions to run the application locally and to deploy it on a Linux VPS of any cloud providers (AWS, Digital Ocean, GCP, etc.).

There is also the same deployment manual is available on our portfolio website here.

Testing

We have done comprehensive testing for our application to ensure the quality of our program. This is very important for us to cover all the scenarios so that we can be certain that the system is functioning correctly.

We have multiple tests for different aspects of the application:

Front end – Snapshot Testing

Snapshot Testing

Testing coverage

Back end – Unit and Integration Testing

Back End Testing

End-to-end Test

End-to-end Tests

User Acceptance Tests

User Acceptance Tests

Responsive Design Tests

Responsive Design Tests 1

Responsive Design Tests 2

Responsive Design Tests 3

Responsive Design Tests 4

Deployment

We decided to deploy the application on the Virtual Private Server (VPS) with Digital Ocean, as Daulet had previous experience deploying a full-stack application there. We nicely wrapped up our code, added Dockerfiles, as well as extracted all the database credentials, admin passwords in environment variables, added baseURL variables, and prepared the codebase to be deployed.

We have set up our PostgreSQL database on the server-side, and run the database.sql script to create the suitable schema. We seamlessly installed all the dependencies for the Node.js backend and used pm2 for running the Node.js server.

Then we have configured the Nginx web server and reverse proxy, and have successfully deployed the application at https://dauletbatayev.com/ for demonstration purposes.