Skip to content

Otterwerks/Chatterwerks

Repository files navigation

Chatterwerks

A chat that works

Heroku Links:

Heroku live/production HERE

Heroku development/staging HERE


                                      


This project was bootstrapped with Create React App.

Summary

Chatterwerks is a simple chat application that focuses on utilizing a PostgreSQL relational database to keep track of users, channels, channel subscriptions, and messages.

Hey Otter!

Otter is the chat bot in the home channel that I adapted from a command line virtual assistant script I had made some time ago. Otter can assist with arithmetic as well as the date and time.

  • Talk to Otter by starting off your message with Hey Otter,

Features

  • Home chat channel with chat bot
  • Private chat channels between users, click a username to start a private chat
  • Back End strict and acceptance tested with Pytest
  • Deployed using the Heroku development pipeline
  • Responsive Bootstrap 4 design

Security

In designing this project I wanted to make sure that users would not be able to manipulate data stored in the browser to gain unauthorized access to channels or submit fraudulent messages. The login process for Chatterwerks simply verifies that an associated User ID exists in the User table for the submitted credentials and stores those credentials in the browser for future requests if they are valid.

Loading channel messages

User credentials are submitting with this request in order to allow the backend to resolve a User ID. The User ID is then validated in the Subscription table to see if that User ID is allowed to view messages in the channel and messages are returned in the response if the user is subscribed.

Sending a message

Sending a message also involves submitting user credentials to not only authorize the user but also validate that the user is subscribed to the channel they are attempting to submit a message to.

Testing

The back-end of this project has multiple internal API endpoints and uses some functions for resolving record IDs within tables. I used PyTest to write the tests and decided to have the tests interact directly with the PostgreSQL database. Due to the nature of interacting with the database, I tried to write the tests in a way where they verified an initial state, performed an operation, and then verified the operation behaved as expected.

Technical

Clients use interval polling to receive new messages from the database. I understand this method carries additional network overhead and I chose to implement this method because it allowed me to continue making progress in developing other aspects of the project.

  • Front End (JavaScript)
    • React
    • React-Router
    • Redux
    • Axios
  • Back End (Python)
    • Flask
    • SQLAlchemy
    • PyTest
    • PostgreSQL
    • Gunicorn
  • Hosts
    • Heroku Pipeline (staging/production)
    • Heroku Postgres add-on, two separate for staging and production

Database Structure

  • Bold: primary key
  • Lines: foreign key relationship
  • Red: integer data type
  • Yellow: string/text data type

Known Polling Bug

The polling works by setting a delay to update the client store with new information through an HTTP request. The delayed function is set to run when the chat component renders. Under normal circumstances this works as intented because the new data from the request triggers a rerendering of the component and sets a new delayed function, so on and so forth. The problem is that any other interaction that causes the component to rerender will trigger additional delayed requests. This means that every time the user selects a different chat channel, an unnecessary parallel request is initialized. While this can make the application be perceived as 'speedier', it is not the intended behavior and has the potential to result in continuous back to back requests. The structure of the request function sets a queryStatus store value to requested after the request is sent and complete after a response is received. A new request can only be made if the queryStatus is complete to prevent request overlap. I believe the most straightforward way to solve this is to place the request into an isolated component.

Deployment

full instructions coming soon

The main site deployment process is almost identical to Tweet-Finder, except that the only hidden file that needs to be created is psql_info.py containing a variable psql_uri = <your postgres database URI>, in the project root directory. The project demos on Heroku use local environment variables instead of a static URI, per Heroku's suggestion.

For now you're on your own in setting up a PostgreSQL server, but I have included the script clear_database.py to wipe and reinitialize the database. This script needs to be run from the project root directory.

Resources Used: