SoundBYTE is a social network that allows users to record and share sound clips. Conceptually, it's extremely similar to Twitter and Instagram but uses audio clips instead of text snippets or images. The service is built around a mobile app, supporting only iOS as of the time of writing this, that allows users to easily record, post, search for, and listen to sound clips directly from their device.
This project was started by the team at Futurehaus and I was asked to join very late in the development of the initial MVP version of the system. As such, I inherited an existing Rails backend service and was asked to extend it to complete the remaining features targeted for the launch of the system. This included the following capabilities:
Password Reset Support
Spam/Inappropriate Content Reporting
Post Tagging Support
User Feed Management
The existing application was built on Rails, with a Grape-driven JSON API. It used Devise for user authentication and Sequel Rails for its ORM. For the most part it was in reasonably good shape but did have a few noticeable areas of technical debt. Firstly, the APIs were implemented in a single file, resulting in poor organization and making them challenging to maintain. Secondly, there was no automated test coverage across the entire service. While there was API documentation maintained in Apiary, it was out of date or incomplete in parts and the README for the app had been left completely blank.
I quickly got ramped up on the current state of the system and provided a detailed proposal for how I planned to complete each of the requested features. In addition to identifying the tasks required to complete each feature, I also called out any open questions pertaining to the requested capabilities, highlighted the design decisions or tradeoffs to be considered, identified the areas of technical debt I came across in my initial review, and provided a detailed breakdown of the time I estimated would be needed to complete each feature. This initial documentation got everyone involved in the project aligned on the remaining work to be done, allowing us to move more quickly and confidently toward its completion.
I was able to knock out the password reset feature by leveraging the existing support within the Devise gem, customizing all account management emails to match the appropriate styling and copy for the system, and integrating the system with SendGrid to enable email delivery capabilities. I then reused this functionality for the spam reporting by exposing a few new API endpoints and triggering an email to notify the system admin mailing list of any spam reports. Similarly, the post tagging support required a minor extension to the APIs but was otherwise a fairly "bread and butter" feature for the system. This left the user feed management as the final item to be completed before launch. The behavior of this feed was based on a set of queries that spanned the majority of the data model, so after verifying that the necessary indexes were included in the database migrations, I isolated the logic into a service class and added ample test coverage to convince myself and future developers that it was behaving as expected.
Throughout all of this, I did a bit of boy scouting along the way, adding automated test coverage, updating the API documentation to accurately reflect the current state of the API, and updating the README with relevant, developer-centric documentation to allow future developers to get up to speed quickly.
With the platform in a feature complete state, we were ready to launch and I was asked to set up the production environment. I did so using a full suite of AWS services, including an Elastic Beanstalk configuration, EC2 instances, an ELB, a Postgres RDS instance, the Certificate Manager, and a Route53 zone file.
Since it's initial launch, I have continued to provide DevOps support for this service and to add new features as requested. The following are a few of the key initiatives we have undertaken since launch:
ORM Migration: The use of the Sequel Rails ORM was an area of technical debt that repeatedly added complexity to the development of new features. I drafted up a proposal to replace this with the standard ActiveRecord ORM, providing evidence for how this would expedite our upcoming development efforts and reduce the overall cost of our maintenance. I used a test-driven strategy to execute this migration, ensuring there were no regressions introduced in the process. Specifically, I added full API/functional test coverage, replaced the ORM, and validated that all tests continued to pass. This not only increased the confidence in the changes made, but also provided valuable test coverage for all feature development down the road.
Admin Dashboard: To provide the internal stakeholders with greater control over the application at runtime, we exposed an admin dashboard that would allow them to manage various aspects of the production service and data. We used the ActiveAdmin library to significantly expedite this implementation, taking an iterative approach to exposing additional functionality within this dashboard as explicit needs arose rather than trying to anticipate its usage and implement this functionality out of the gate.
Post Muting: One of the first capabilities required within the admin dashboard was the ability to "mute" posts, preventing them from being included in users' feeds. With a minor data model modification, a slight adjustment to the post feed query, and the exposure of the post model within the admin dashboard, the implementation of this feature was completed quickly and smoothly.