Giter Club home page Giter Club logo

pollvotingsystem's Introduction

MCS Poll Voting System

MCS Project with Prof. Zingaro and Ilir

poll.utm.utoronto.ca

InstallationProject StructureArchitectureRunning the App (Server)Running the App (Locally)Updating the App

Installation

  1. Install the following requirements
  • Yarn >= 2+
  • Node 14.17.0
  • Latest version of Docker and Docker-Compose
  1. Install the dependencies for the client
cd client
yarn install
  1. Install the dependencies for the server
cd server
yarn install

Project Structure

Note: Only the core files & directories are listed below

├── server
|   |── controllers
|   |   |── pollController.ts
|   |   |── socketController.ts
|   |   └── userController.ts
|   |── db
|   |   |── mongoose.ts
|   |   └── schema.ts               # Contains all database related schemas to store poll & student data
|   |── routes
|   |   |── pollRoute.ts
|   |   └── userRoutes.ts
|   |── redis.ts                    # Redis related configurations to setup the professor list
|   |── server.ts
|   └── socket.ts
├── client
│   ├── public                      # All public facing assets/files
│   │   ├── index.html
│   │   ├── newQuestions.wav
│   │   ├── favicon.ico
│   ├── components
│   │   ├── Button
│   │   ├── Chart
│   │   ├── FormInput
│   │   ├── Header
│   │   ├── Modal
│   │   ├── Navbar
│   │   ├── PollCode
│   │   ├── PollCodeSegment         # Subcomponent of PollCode
│   │   └── PollOptionButton
│   ├── pages
│   │   ├── CreatePoll
│   │   ├── JoinPoll
│   │   ├── PastPolls              
│   │   ├── ProfHome              
│   │   ├── VoteControls              
│   │   ├── VotePage              
│   ├── socket.ts                   
│   ├── axios.ts                    
│   └── App.tsx                     # Starting point of the client
├── README.md                       # You are here! 
├── nginx.conf                      # Configuration for nginx proxy 
└── docker-compose.yml              # Running the entire application (Redis, Client, Server, DB, Proxy)

Architecture

Note: The client, proxy, server, database and cache are all running in separate containers image

General Flow:

  1. Students/Professors sign in through Shibboleth
  2. If a professor's utorid is found in Redis, then they'll be redirected to the professor page
  3. Voting is done through Socket.io (Pass through the nginx proxy)
  4. All other methods of communication are through the Axios HTTP client (i.e. Fetching previous poll data) (Pass through the nginx proxy)
  5. All poll and student data is stored on MongoDB

Running the app (on a server)

Note: The app installation assumes you already have Shibboleth installed on the server.

  1. Setting up the client .env file (Placed in the root of your client folder)
REACT_APP_BACKEND_URL="https://poll.utm.utoronto.ca"
  1. Setting up the server .env file (Placed in the root of your server folder)
PORT=3001
MONGODB_URL="mongodb://mongodb:27017/quiz"
FRONTEND_URL="https://poll.utm.utoronto.ca"
REDIS_URL="redis://default:password@redis:6379"
WHITELIST=../whitelist
  1. Add instructor Utorid's to your whitelist file. It should be placed at the root of the server folder.

Your whitelist file should be named "whitelist" and should look like the following...

utorid1
utorid2
utorid3
...
  1. Running the entire app
docker-compose up --build -d

Running the app (Locally/Debugging Purposes)

Mongo and Redis Setup

  1. Open the docker-compose.yml file and comment out all services except caching and mongodb

  2. Running Redis and Mongo

docker-compose up --build -d

Client Setup

  1. Setting up the client .env file (Placed in the root of your client folder)
REACT_APP_BACKEND_URL="http://localhost:3001"
  1. Setting up axios.ts

Note: Since we're running poll voting app locally, we'll need to provide some extra information that normally Shibboleth would provide to us.

Your axios.ts file should look like the following:

export const instance = axios.create({
  headers: { utorid: "utorid" },
  baseURL: `${process.env.REACT_APP_BACKEND_URL}`,
});
  1. Setting up socket.ts

Note: Since we're running poll voting app locally, we'll need to provide some extra information that normally Shibboleth would provide to us.

Your socket.ts file should look like the following:

export const socket = io(`${process.env.REACT_APP_BACKEND_URL}`, {
  withCredentials: true,
  extraHeaders: { utorid: "utorid" }
});
  1. Running the client
yarn run start

Server Setup

  1. Add instructor Utorid's to your whitelist file. It should be placed at the root of the server folder.

Your whitelist file should be named "whitelist" and should look like the following...

utorid1
utorid2
utorid3
...
  1. Setting up the server .env file (Placed in the root of your server folder)
PPORT=3001
MONGODB_URL="mongodb://localhost:27018/quiz"
FRONTEND_URL="http://localhost:3000"
REDIS_URL="redis://default:password@localhost:6379"
WHITELIST=../whitelist
  1. Running the server
yarn run start

The client and server will be listening and serving on port 3000 and 3001 respectively.

Updating the App

If there's a new version of the app available, then do the following...

  1. Pull the latest version of the app from Github (Make sure you're on the main branch)
git pull
  1. Stop the app

Stopping the app won't purge any data. The data will persist and only the client and server will rebuild when re-launching

docker-compose down
  1. Re-Launch the app
docker-compose up --build -d

pollvotingsystem's People

Contributors

hiimchrislim avatar shubhbapna avatar akshitgoyal avatar huonggiangbui avatar

Stargazers

Ankah Harrison avatar Ephraim Duncan avatar  avatar Ryan Arora avatar Kaitian Zheng avatar Ian Quan avatar

Watchers

 avatar  avatar  avatar

pollvotingsystem's Issues

Accessibility Check

Describe the solution you'd like

It would be good to run through an accessibility check and take note of what we're missing/could be changed to improve our overall website accessibility.

Setup CI, Formatting and Linting

  • CI workflow for linting and formatting
  • Formatting should be done on a Git Commit Hook
  • Linting should be done on a Git Commit Hook

Linting and Formatting for the backend

Describe the solution you'd like

We currently only have linting and formatting set up for the client. Refer to it as an example.
Additionally, a Github action should be made for it as well to run on each PR

Server side type enforcements Github action.

Is your feature request related to a problem? Please describe.
We should make sure that the typescript build passes without build/type errors before merging PRs (have a look at #70 and #80)

Describe the solution you'd like
Github action that runs every commit/PR running yarn run build or npm build for the server

Describe alternatives you've considered
N/A

Additional context
If you approve this issue, please assign it to me if possible.

Showing poll results to students

Is your feature request related to a problem? Please describe.
Recently @embeddedt found out that we are sending the poll result message to students as well.
The product owner aka Prof Dan has decided to use these messages to display the vote results to students as well.
This feature request is to implement the same graph like vote results that profs see on the student side as well

Describe the solution you'd like
The students should only see the live vote results when the prof clicks a "show result" button.

  • Add a new API that emits a message to student sockets that they can start showing the vote
  • Add a button on the prof sides that calls the above API
  • Display the graph of results once this new message is received. You can possibly refactor and use the same code that we use for prof's view to display the graph

Additional context
Lets discuss here and finalize the subtasks that need to be done and we will then assign the sub tasks.

Deadline
We need this to be done by end of December

[TEST-1] Test

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Browser (please complete the following information):

  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]
  • Phone/Despktop
  • OS

Additional context
Add any other context about the problem here.

Redis Cache Reset

Describe the bug
From time to time, the Redis cache seems to reset/get wiped out which would cause professors to not be able to access the professor page of the application. This can easily be fixed by restarting the service but this is only a temporary workaround.

Expected behavior
The list of professors that we have stored on Redis should persist.

Additional context
We're currently not sure how long it takes for the Redis cache to reset/wipe out but this doesn't happen on a regular basis. This could perhaps be due to reboots that are done on the MCS servers.

Frontend Unit Tests

Describe the solution you'd like
Setting up unit tests for our frontend would be ideal to have instead of manually testing everything
Once the tests are made, a Github action should be made to run this automatically on each build/PR

Server Logging

Is your feature request related to a problem? Please describe.
Currently the server is using console.logs to perform any kind of logging. This can make it difficult to catch issues happening in production.

Describe the solution you'd like
Implement a logger service.
Features that would be nice to implement:

  • Prepend INFO, WARN, ERROR before logging a message
  • Centralize and collect logs to avoid using docker logs

Things to consider
https://sematext.com/guides/docker-logs

Persist user selection option refresh

Describe the bug
When a student refreshes their page after voting, their selected option should still persist. (Seems like we forgot to add this in at the time)

To Reproduce
Steps to reproduce the behavior:

  1. Vote for an option
  2. Refresh the page and the option chosen won't persist on a page refresh

Expected behavior
The student vote should persist on a page refresh

Production version fails to negotiate WebSocket upgrade

Problem

The production version of the poll voting app (https://poll.utm.utoronto.ca/) does not allow clients to upgrade to WebSockets for communication, forcing them to use inefficient HTTP polling instead. This could lead to heavy network traffic when there are many concurrent users.

Expected behavior

This screenshot is taken by running the production docker-compose.yaml setup (including the Nginx proxy) locally and browsing to the root page.
image

Actual behavior

This screenshot is taken by browsing to https://poll.utm.utoronto.ca/.
image

Sound queue on new question

  • When a new question is started a sound queue should appear
  • Tab should update when there's a new question for the student

Add API documentation

Describe the solution you'd like
Document each API (method, path, any path params, any queries, any request body, responses etc)

Frontend Integration Tests

Describe the solution you'd like
Setting up integration tests for our frontend would be ideal to have instead of manually testing everything
Once the tests are made, a Github action should be made to run this automatically on each build/PR

Backend Integration Tests

Describe the solution you'd like
Setting up integration tests for our backend would be ideal to have instead of manually testing everything
Once the tests are made, a Github action should be made to run this automatically on each build/PR

API error handling

Add a more fine tuned error handling for apis rather than just returning a 500 status

Start and end polls [Backend]

  • Start a poll: Accept socket connections for the room id from client
  • End a poll: Notify all the clients that the poll has ended

Local shibboleth setup

Is your feature request related to a problem? Please describe.
For testing currently we have to forcefully add an additional header utorid before running the client. The idea here is to explore ways to automate this.

Describe the solution you'd like

  • Consider using a env variable that decides whether or not to add the additional header
    OR
  • A more preferred fix would be to mimic the exact production setup i.e. run the application behind shibboleth. Explore whether we can setup shibboleth locally in docker for development and testing

Additional context
A guide to setup shibboleth locally - https://isea.utoronto.ca/services/weblogin/sso-howto-weblogin/

Ability to change vote after voting

Is your feature request related to a problem? Please describe.
Whenever I vote in class, I sometimes find myself rethinking my vote; and wanting to vote for a different option. What I did so far was refresh the page, which resets the vote. Apparently, this behaviour is unintentional (according to #57). Regardless if #57 is fixed or not, I think that there should be a way to change your vote.

Describe the solution you'd like
Either a button to select a new vote or just the ability to click another option after voting.

Describe alternatives you've considered
The only workaround is refreshing the page, but that's very unintuitive to users.

Additional context
N/A

"9" and "g" are hard to distinguish in poll codes

Describe the bug

The font weight/contrast/family choice makes it hard to distinguish between the digit 9 and the letter g, especially on a projector screen.

To Reproduce

Create a poll that contains a 9 and g in its code.

Expected behavior

The two characters should look different enough to be easily read.

Screenshots

The following poll code starts with 9g, however you cannot tell which is which without some very close analysis of the shape.

Apologies for the low-quality picture.

IMG-0284

Backend Unit Tests

Describe the solution you'd like
Setting up unit tests for our backend would be ideal to have instead of manually testing everything
Once the tests are made, a Github action should be made to run this automatically on each build/PR

Create a poll [Backend]

  • Create poll document with data like poll name, description, course code, questions
  • Create a unique URL

Better UX when server is unresponsive

Describe the bug

Currently, the selected vote only changes on the frontend once the server has acknowledged the vote. This leads to bad UX if the server is slow.

Expected behavior

Ideally, there should be some sort of visual indication that the vote is being sent to the server, and if no acknowledgement is received after 10 seconds or so, an error should be displayed.

Additional context

This is particularly relevant until we are able to sort out the ongoing server load issues.

Add Redis Persist

  • On restarts, the Redis cache for professor utorids should persist

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.