About the Project

KEEP is a healthcare app made for families who are collectively taking care of their sick family members. It takes away the administrative hassle of coordinating medical visits, keeps track of medication refills and allows for easy sharing of patient’s medical details with family members.


1. App Security

KEEP is a secure app with protected routes that requires user authentication. Users accessing any KEEP URLs without being logged in are redirected to the login page.

How It Was Achieved:
  1. Upon Login: Once the user’s email and password are verified to match the database, the user’s login details are stored in a JSON Web Token and sent from the backend Express server to the frontend React server. The token is saved in the browser’s local storage.
  2. On Access of KEEP URLs: When any of the KEEP app’s URLs are accessed, a useEffect React Hook runs in the ProtectedRoute component, that wraps all routes in the app. This triggers user authentication to occur.
  3. User Authentication: The JSON Web Token is retrieved from local storage and sent to the Express server where the token is then verified. The outcome is then sent to the React server. If the token was not successfully verfied, the app would redirect to the login page. If verification is successful, users can navigate to their intended page and the Express server will send the users details to the React server, allowing for the user’s details to be correctly displayed even upon refresh or reopening of the browser.


KEEP provides a seamless signup and login process by accounting for and validating errors on the frontend. These include incorrect passwords, incorrect email formats, passwords not matching and empty input fields.


2. Appointments

View upcoming appointments for the month in calendar view. Schedule appointments, appoint chaperones, reschedule appointments and write memos after the hospital visit.


Easily toggle between calendar and list views. Filter appointments in list view.


3. Patient Hub

Access all the patient’s information from the patient hub.


View, add and edit patient’s medication.


Schedule medication refill reminders sent via Telegram.

How It Was Achieved:
  1. Initiate Chat: Users are instructed to initiate a Telegram chat with KEEP apps Telegram bot and provide the patient ID.
  2. Storing Users Telegram ID: The telegram API receives the user’s initiation message which includes the user’s telegram ID. KEEP saves this ID in the patient’s document in the database. Each patient’s document in the database will have a list of telegram IDs of users that have subscribed to this patient’s medicine reminders.
  3. Sending Reminders: When a new prescription is added, users can opt to set a refill reminder. KEEP calculates when the reminder is to be sent, based on the users choice of timing and number of days prior to the medication finishing. KEEP will draft a Telegram message with the patients name, medication name and days left till the medication runs out. The CRON API queues and sends the medicine refill reminder message based on the date and time determined.


View and add clinics and departments that patient frequently visit and chaperones who typically accompany them.


View and filter memos that are tagged to patients to get a comprehensive overview of their medical status during each hospital visit.


4. Contacts

Add other users as contacts. Share patient details with contacts, allowing for access of mutual patient’s appointments, medications and memos.


Chat with users within the app.

How It Was Achieved:
  1. Establish Socket Connection: When a user enters a chatroom, a socket connection is established in the Express server. The users socket ID, user ID and the user ID of the person they are texting is stored as a document in an OnlineChatModel collection in the database. The user is then placed in a socket room (channel) named after their user ID.
  2. Sending Real-Time Messages: When a user sends a message, the Express server will check the OnlineChatModel collection in the database to determine if the textee is also in the same chatroom. If they are, the user joins the textees socket room and the message is emitted to both rooms and hence the user and the textee. If not, the message is only sent to the user.
  3. Leaving Chatroom: When a user leaves the chatroom, their document is removed from the OnlineChatModel collection in the database, so as to allow for accurate checking of online users.


5. Mobile Responsive

Provide users with the ease of access to KEEP, both at home and on-the-go.


Technologies Used


User Interface:

Component Routing:

CSS Framework:

Live Chatroom:





Telegram Medication Reminder:

Live Chatroom:

Rationale for Choice of Technologies


Reason for Choosing a NoSQL Database:

  • Due to a short development time, we required a flexible schema that would allow us to make changes quickly and easily as requirements changed.
  • The size and complexity of the app meant that a lot of information was being accessed by the various components. This would have required multiple join tables if a SQL database was used. MongoDB allowed us to embed information, allowing for ease of storage and access of data. Since we had sets of data which needed to be queried alongside one another, a NoSQL database was better suited as it removed the need for multiple queries and joins.

Telegram API & CRON

  • We decided on chat messages as our mode of reminders due to their concise nature and ability to attract immediate attention as opposed to emails or in app notifications.
  • CRON was utilized to allow reminders to be sent at a specific date and time.
  • One downside of using CRON was that we were unable to reschedule messages once the CRON job had been queued.


  • Our desire to implement a live chatroom necessitated a Javascript library with such capabilities.
  • Socket.IO’s ability to enable real-time, bi-directional communication between the clients and our servers suited this need.

Argon2 & JWT

Argon2 Password Hashing:

  • We used Argon2 to hash our passwords before saving into our database over other hashing algorithms such as bcrypt.
  • This was due to it having better security as displayed in it winning the Password Hashing Competition in 2015.

JWT Authentication:

  • We chose JSON Web Tokens as our method of authentication due to its increased security through its digital signature capabilities.


Bryan Luke Tan | LinkedIn

Hsiu Ping Gay | LinkedIn

Shannon Suresh | LinkedIn


View Github