This document describes the applications developed as solution to the Mooncascade take home test.
The task describes a scenario of sports event times management and requires three applications:
- Server-side service that receives the timing information
- Client-side application that displays the information from the service
- Test client for sending dummy data to the service for demo/test purposes
- NodeJS
- MongoDB
-
Go to the server directory and install the dependencies via NPM:
yarn
or
npm install
-
Edit
config.json
with the appropriate configuration parameters:port
- Port on which server will listen to connections (both HTTP and WS)mongodb
- MongoDB database connection detailshost
- Hostname or IP address of the machine hosting the MongoDB databaseport
- Port of the MongoDB server on the host machinedatabase
- Name of the MongoDB database to be used. You should create the database with this name
-
Run the application:
yarn run
or
npm run-script run
The server is an application written in NodeJS using the Express.js framework. It's main function is to receive timing information and relay that to the client.
For this, it exposes the following endpoints:
Returns the list of athletes in the database. Currently used by the test client.
Returns the list of timing data between the given time values. Used by the client to receive list of times that were saved while the client was inactive.
Query parameters:
to
- Number. Time, in milliseconds, of the beginning of the time period for which to return times.from
- Number. Time, in milliseconds, of the end of the time period for which to return times.
Records a new time. Sends the data about this time to all of the clients currently listening to WebSocket messages.
The body of the request should be a JSON object with the following data:
code
- Code of the athletetimingPoint
- Timing point. Assumed to be eitherfinishCorridor
orfinishLine
clockTime
- Time (accurate to a fraction of a second)
None of the endpoints currently really validate the incoming data. This was assumed to be sufficient for the test task, especially since it was understood to be mostly about the client-side.
- NodeJS
-
Go to the client directory and install the dependencies via NPM:
yarn
or
npm install
-
Edit
src/config.json
with the appropriate configuration parameters:server_url
- Hostname/IP and port of the server
-
Run the application:
yarn start
or
npm run-script start
Client is an application bootstrapped with create-react-app
and written using the React framework and
Redux application state management framework. It connects to the server using the WebSocket API and listens receives new
times in real time. The times are then shown in a table, as described in the task description.
When the application window is inactive, the WebSocket connection is terminated and the client no longer receives
updates from the server. The timestamp of this event is recorded. When the focus is returned, WebSocket connection is
re-established and the missing times up to the time of re-focus are fetched from the server (GET /times
). Naturally,
this could also have been alternatively implemented through the WebSocket connection - e.g. sending a message with the
two timestamps to the server, to which it would respond with a list of the missing times.
Because of the client's functionality being paused when the window is inactive, it is recommended to open the dummy client in another device (e.g. a smartphone - look how responsive that thing is!) to test the applications.
- NodeJS
-
Go to the client directory and install the dependencies via NPM:
yarn
or
npm install
-
Edit
src/config.json
with the appropriate configuration parameters:server_url
- Hostname/IP and port of the server
-
Run the application:
yarn start
or
npm run-script start
Client is an application bootstrapped with create-react-app
and written using the React framework.
It gets the list of athletes from the server and allows the user to record the times when they enter the finish corridor and cross the finish line, sending this data to the server that in turn communicates it to the client.
- Setup and run all the applications
- Open the client in a web browser
- Open the test client in a web browser, preferably on another device, to leave the client in focus
- Play around with recording the times - take the focus away form the client, play around some more. Go nuts!
- One "session" represents one sports event. If you want to start over, just refresh the client and the test client.
All the applications use ESLint to ensure consistent code style. The client-side applications use the popular Airbnb preset and the NodeJS application uses the base (react-less) Airbnb preset as well as another plugin specifically meant for Node. Prop validation is done with PropTypes, although typically I'd rather go for Flow or TypeScript.
Because of the simplicity of the task, not a lot of styling is needed and it's bundled directly with the React components. Typically I prefer to style larger projects with SASS and I've been pretty sceptical about various CSS-in-JS solutions (Styled Components, CSS Modules, and what have you), although I'm slowly starting to be more open to the idea in certain contexts.
Redux Thunk middleware is used for asynchronous Redux action creators and general action creator combination.
Moment.js is used for date parsing/display and classnames is used for JSX className manipulation. One might argue that they weren't necessary for a task of this size, but I just think they're neat.