
Safety Tag
Launched may 2014
Overview
Speed and Function completed a beta release of the Safety Tag on May 6, 2014. This is a continuing major effort that’s been keeping us busy since December of 2013.
The Safety Tag is a web application that addresses a problem in youth sports today, where practices and games don’t have medically trained personnel on hand to handle injuries and chronic illnesses.
Technology
Architecture summary/highlights
- Data is stored in MongoDB. Access to the database allowed only for the API server.
- The API server works with the database based on
CRUD model. - Authorization logic runs on a separate auth server via oAuth 2.0 protocol, it provides auth tokens necessary for accessing the API.
- Business logic runs on a separate application server, which processes client requests using the API server.
The structure described above is highly scalable and allows us to quickly implement future business requirements using the API for mobile applications, third-party application integration, etc.
The scalability offered by this approach allows us to have more than one API servers that work with the same database. Also, we can distribute load by setting up multiple API servers which serve various API functions: one server would perform searching and returning of data, another would do only updating operations, etc.
The MVC software architecture pattern allows for separation of HTML (view), data (model) and application logic (controller), which gets us a more structured and easier to maintain code base.
Frontend
Zurb Foundation font-based Icons
We used this SVG icon-based set because it works well with high-PPI (Retina) displays without any additional logic, such as a need to create 2x-sized images for image-based icons. It’s easily customizable via CSS. For example, we don’t need to create a separate color instance of an icon for each of its states (just set a proper color in CSS). We are using the same icons for both mobile and desktop versions.
We decided to use a GruntJS task manager for compiling and assembling static assets (JavaScript and CSS), converting JADE to HTML. Also GruntJS is a part of the Sails.js framework, which we are using as backend framework.
Autoprefixer simplifies usage of vendor prefixes in CSS. Based on a list of supported browsers, Autoprefixed decides what vendor prefixes are needed (-webkit-, -moz-, -o-, -ms-) to support different CSS3 properties in browsers which do not support native CSS3 properties. We use the same browser list for both mobile and desktop versions.
LESS is a powerful tool for providing robust, clear structure of CSS code, creating and using mixins and variables. We are using LESS to provide a “syntax-sugar” and transparent structure of our CSS code.
Nuff said ;) The most commonly used JavaScript framework for performing all kinds of operations with DOM and much more. Also, it is a main dependency for the jQuery Mobile framework.
We are using the jQuery Mobile framework to adapt the application for different mobile devices such as iPhones and Android phones. jQuery Mobile framework was chosen because it is fully touch-optimized, well-documented, has a big community, wide ecosystem and wide list of supported devices. We created a new theme for jQuery Mobile to match UI design comps.
MaskedInput
Maskedinput input is used to improve UX and UI. We used it to help the user provide us with proper values. A user can see an example of format/value/etc., and submit information without wasting time on putting incorrect values and receiving “wrong format/value” messages.
DateTimePicker provides a datepicker functionality without restricting manual date input. This allows the user both options for choosing a needed date: using datepicker GUI, or using manual input.
Custom design necessitated using custom checkboxes to get cross-browser compatibility. That is why we used the iCheck plugin to style checkboxes and radio buttons for the desktop version of Safety Tag.
easyDropDown was used as a lightweight solution for customizing select boxes according to the design. It provides all the necessary functionality and API for performing common-meeting tasks with drop-down controls.
formValidator is a powerful solution for validating forms in the browser. We decided to use the same validation rules for different types of fields both for backend and frontend code.
Outdated browser notification message
A gentle reminder for our less technical users that they could have a better experience with a more modern browser. The list of modern browsers available for upgrading is accessible by clicking on the notification message at the top of the page. The message is non-intrusive and allows users to browse application pages, while notifying them that some features may not work or may work incorrectly in their browser because of vendor restrictions and lack of browser’s API capabilities. The same list of outdated browsers is used for both desktop and mobile versions.
Backend
(Express.js framework, Sails.js framework based on Express.js). One of our requirements was to accommodate 1 million users, so this platform was a natural choice, especially given our prior expertise.
- A NoSQL document-oriented database that gives us fast access to stored data due to a wide range of utilizing indexes, the capability to scale horizontally through sharding, and high availability with replication feature.
- Waterline – adapter-based ORM for Node.js with support for MySQL, MongoDB, PostgreSQL, Redis, and more. Waterline strives to inherit the best parts of ORMs like ActiveRecord, Hibernate, and Mongoose, but with a fresh perspective and emphasis on modularity, testability, and consistency across adapters.
Redis is used for storing session user data to improve performance. We get session data from the Redis twice as fast as we would from MongoDB.
JADE template engine
Jade templating engine is a powerful solution for abstracting and structuring HTML. It allows us to provide robust, clear structure of views/templates inside our application. We are using Jade as a static HTML generator and View component of MVC on the server side.
We used Nginx as frontend server-side proxy because it’s one of the fastest ways to deliver static files and recognize type of devices (mobile or desktop).
MMS is one of the most advanced tools for monitoring and backing up MongoDB databases, built and provided by MongoDB developers. It’s perfect for keeping (2-factor authorization required to get the data back) and restoring (any point of time) any database that less than 3TB in size.
PayPal SDK (PayPal’s Node.js SDK for REST APIs) was used for payment processing: both one-time payments and subscriptions.
UglifyJS, CssMin are libraries to minify CSS and Javascript, which improves UI performance.
OAuth 2.0 allows us to integrate our application with partners, such as Ripken Baseball
MOBILE APP (HYBRID)
Ionic Framework
An open source front-end framework for developing hybrid mobile apps with HTML5.
We picked Ionic because it seemed the most mature at this time, with the largest community support and it has best documentation.
AngularJS
Templates, data binding, and dependency injection reduce the amount of code we have to write.
Cordova
Apache Cordova is a set of device APIs that allow a mobile app developer to access native device function – such as the camera or accelerometer – via Javascript.
We need a few device-specific features and automated updates, but at the same time we’d like to reuse as much code as possible between the platforms supported (currently iOS and Android).
Intel XDK
Intel XDK build platform consists of a set of development tools to help you code, debug, test and build mobile web apps and hybrid HTML5 apps for multiple target platforms. We picked Intel XDK over PhoneGap due to smaller number of restrictions, such cloud projects size limit, and more extensive configuration options.
Corporate site (WordPress)
Base technology: WordPress, CSS, JavaScript, jQuery, Custom WP Theme.
Theme: new, built from scratch. The alternative was to customize a similar base theme but eventually opted for fully custom, cleaner code base.
SEO: All in One SEO Pro
Analytics: Alexa, Google Analytics
Menu customization: WP Custom Menu Walker class for overriding menu behavior and lookup, to match any advanced designs.
Editability: dynamic content management via Advanced Custom Fields
- We organize data for WP Post as a table of data elements where you can define the columns (sub fields) and add infinite rows.
- All rows can be collapsed and sorted via drag and drop.
Performance: W3 Total Cache
Interaction with the main application: WP JSON API
- WP JSON API and WP actions help us create a data bridge between WordPress and the Node.js application to allow for editorial control over some application content and labels. Essentially, we use WP as a CMS for a few frequently updated items inside the Node.js application.
- WP content is cached on both WP and Node.js level, which ensures zero performance impact.
Testing
Cucumber
We used Cucumber with Watir to improve testing quality. When the amount of functionality grows, the time required for manual testing increases significantly. Cucumber allows automate QA and Jenkins runs the automated tests each time a developer commits a change. This approach simplifies testing and allows early bug discovery.
Jasmine
Jasmine-node node.js module for running tests, frisby.js node.js module for testing REST API.
Jenkins
Jenkins continuous integration – for useful code coverage statistics and graphs of aggregate test failures.
Load testing tools
- Bees with Machine Guns: was used for distributed load testing of application’s pages.
- Apache Benchmark: being a part of Bees with Machine Guns utility it was used for quick point load testing during server side enhancement.
Load testing results
The application can support ~500 continuously simultaneous requests without a noticeable impact on performance if a requested page requires database access. ~1000 if page doesn’t require database access.
Management
We managed the Safety Tag in a semi-Agile fashion, where we had a 2-month long initial iteration to build out core functionality and then switched to more traditional 1 month-long sprints.
In addition to daily scrums and weekly on-site meetings, we’ve ran progress demos via Hangouts screen sharing with our product team twice a week. This approach helped us effectively communicate and visualize our progress to the client-side team, thus eliminating some reporting overhead and ensuring an overall better client satisfaction.