Sumo Survey

Premier data collection & survey machine: Sumo Survey. An Angular + Loopback responsive survey app with a d3 graphical admin interface.
See Live
Source Code

Sumo Survey

One company (SumoMe) challenges their interviewees to build the following survey app.  I heard about this challenge and thought I’d give it a go.


  • Create a web app written in Node.JS using an Express based framework, SequelizeJS, and MySQL.
    I got everything except SequelizeJS.  My rational for failing this requirement: I wanted to take this challenge as an opportunity to explore Loopback (or Sails) but I didn’t see a path where SequelizeJS could fit in with this framework.  I made a decision to deviate from the requirements to pursue my own learning initiative. To quote a local bank robber: “my [project], my rules”. However! Along the way I DID figure out how I could use SequelizeJS within Loopback!  Conceptually it goes like this: 1) create a model that extends the base “Model”, 2) manually map API endpoints to remote methods on that model, and 3) at this point you can do whatever you want, import/call/return SequelizeJS model methods.  Maybe in a future version I will make this requirement pass.
  • Use NPM to declare all dependencies so that we can run it in a test environment.
    npm i
  • The app should allow an admin to enter survey questions with multiple choice answers.
    Login with username: [email protected] password: secret.  Navigate to the add question form.
  • When a guest visits the app in a browser it should present a random survey question to the guest and allow them to answer.
    For this, I created an API endpoint on the Guest model to getOneUnanswered question.  That method gets called when the survey page is loaded.  If you’re looking closely, you may have noticed an intermediary Survey Service that doesn’t really do anything.  Good observation!  Loopback has this wonderful workflow where you can really do anything on the client without touching the initial API.  Initially, this Survey Service contained all the logic to get unanswered questions.  It was poorly optimized, but great for getting up and running very quickly.  Once it was up and running that logic got refactored to server side code.  I actually really liked this workflow.
  • Record answers and display the survey results in an admin interface.
    The admin interface uses the d3 library to create a very basic visual summary of the data.
  • Avoid showing a previously answered question to the same guest.
    I attempted to do this in a RESTful (ie state-less, session-less) way.  On the client I use a library called Fingerprintjs2.  This library aggregates several  details about your browser-environment and creates a ‘fingerprint’ that has a very high probability of being unique.  On the server I pair that fingerprint with the client’s IP for even more uniqueness.  These 2 fields describe anonymous guests without using sessions or cookies.
    Using client IP certainly is a form of state, but the point of avoiding ‘sessions’ is to allow MASSIVE scalability.  Using client IP doesn’t hinder your scaling options at all!
  • Make sure the UI is mobile browser friendly.
    I used a gutted version of bootstrap for its normalization and responsive utilities.  For development, I used Browsersync to design a mobile and desktop UI simultaneously.
  • Provide a clear README with instructions on how to setup and run the app.
    See for installation instructions.
  • Create a repository with the app that we can pull from and test.

Known Bugs

  • Firefox: ‘admin add survey’ form submits form when adding a choice.
  • The d3 frequency charts are not respecting the width of its container (on smaller screen sizes).
  • New SSL certificate issue with heroku and subdomain.