This page lists some of the specific projects we've worked with clients. The goal is to give you a brief overview of some of the skill set we've applied without boring you to dead.

Web platforms and Rails

[Web, Rails] Current health and monitoring messages

Send regular daily messages and notifications for the current system health and processes that are occurring in the platform.

[Web, Rails] Regular checks for invalid models

Active Records and the validations they have change. If a new validation is added to an Active Record all the previous records could become invalid. This introduced a lot of hard to debug and investigate issues as some of the records were valid while others were not. The example that triggered the project was the usernames were no longer allowed to have "@" as a symbol. But when the validation was introduced there were already many records with "@" in the username. 2 years down the road a bug occurred because 7 records with "@" in their username were still not migrated. When validating the whole DB it turned out more than 20000+ records from all the tables were not valid for the current version of the validations. We had to implement a new procedure of validating, resolve all the validation errors. Some of the validations required used to upload files, but users were no longer on the platform.

[Web, Rails] DB Schema clean up and update

Columns and tables that are no longer used. This lead to a scenario where a record could not be deleted because it had a foreign key to a relation that was no longer used. We revised, clean up and updated the scheme and the relations. We set a path for certain normalization and improvements to be later implemented.

[Web, Rails] Clean up dependencies

There were dependencies that were no longer used and should be migrated to new a better alternatives. The project was triggered because of - bootstrap3-datetimepicker-rails, momentjs-rails dependency. The dependencies were also Sprockets based and the platform had to be migrated to Webpacker/NPM

[Web, Rails] Introducing public UID for records

After preparing the whole platform to use .to_param instead of ids we introduced public random UIDs for many of the records. Spying eyes could no longer understand if the platform had 100 or 1000 subscriptions and how many "Users" or "Programs" it had.

[Web, Rails] Removing acts_as_paranoid

acts_as_paranoid was not working good with other gems like Globalize and Cancancan. A decision was made to remove acts_as_paranoid as a dependency. We complete removed it. The pain was that it made the platform difficult to understand and to support

[Web, Rails] Migration to Ahoy 2.0 with proper tracking

The API has changed and it changed a lot. The platform was sending a few tens of thousands emails easy week and it was important to migrate to Ahoy 2.0 because of a pending Rails 6.1 migration.

[Web, Rails] Regenerate Shrine Derivatives

Derivatives for hundreds of thousands of records were generated with wrong metadata. Users were complaining. On Save As in the browser a random hash name was suggested. We had to regenerate all the derivatives in a live system without loosing any of the data.

[Web, Rails] Improve RSpec readability

A large portion of the RSpecs were difficult to maintain. There were a lot of shared_examples and support classes that coupled the specs. Our projects was to reduce redundancies and abstractions. Review and make tests easier to read and maintain.

[Web, Rails, DevOps] Gemfile with many sources

Support a gem file with a number of sources. There were security concerns with the sources.

[Web, Rails] I18n of a platform

Every record with support for many languages and the whole user interface prepared for i18n with proper test procedures and checks. This is a tedious task that teams are reluctant to undertake, but is a must if you are to go international.

[Web, Rails] Implementing a simple Soft Delete without any gems

After the remove of acts_as_paranoid are task was to advice and implement a proper Soft Delete without any gems. The pain was the user were from time to time deleting records and the platform needed a simple "trash", without all the things coming from gems implementing soft delete.

[Web, Rails] Separating on smaller Rails Engines

First for simple separation of concerns and second to facilitate moving and extracting and reusing the code in a second platform the team was starting. There were a lot of important architectural decisions the team needed help with. The pain was coupling of the code in a monolith and expensive reuse of the code in the second platform.

[Web, Rails] Implementing a simple Soft Delete without any gems

After the remove of acts_as_paranoid are task was to advice and implement a proper Soft Delete without any gems. The pain was the user were from time to time deleting records and the platform needed a simple "trash", without all the things coming from gems implementing soft delete.

[Web, Rails] Consistently using to_param for all objects in production and test code

Subscriptions were shown in the url as "/subscritpions/:id". This exposed information about how many subscription the platform had. To hide this information from spying eyes the team need a random id to be shown, not the sequential id in the db table. On revision it turned out that from all the 100+ records in the platform on many places they were using the id while on other places the .to_param method was used. Our job was to bring consistency. To make the change easy so that the team could later introduce the easy change - random ids for many of the records, including Subscriptions.

DevOps

[Web, Rails, DevOps] Production live tests after deploy

The platform is deployed. We established a procedure for live test of specific features right after deploy. This allowed the team to be sure that nothing has slipped thought the CI, which has happened before. An unexpected benefit was that right after deploy in a manner of 30 seconds as the features were tested new cache entries were created which and were ready for when a real user would visit the pages.

[Web, Rails, DevOps] Setup of a private gem repo

The platform needed a private repo for about 100+ gems, with the requirement to be kept inside the organization network. We had to set up, establish build procedures and maintain the private repo

[Web, Rails, DevOps] Automatic update of dependencies

Each Wednesday a bundle update is executed automatically and the two clients platform are brought up to date with the latest released versions of dependencies.

Specs

[Specs, RSpec] Clean up specs dependency on seed.

Specs were dependent on seeds. The decisions was that specs should not depend on seeds. This turned out to be the right decisions in the long run. We migrated all the specs not to be dependent on the seeds and to creating the fixtures and records themselves. The pain was the coupling of specs with other specs and seeds which made the hard to maintain.

[Specs, RSpec] Clean up random failing RSpecs

These are the worst. Issues had to be identified, understood and resolved. The platform was experiencing a few hard to debug random failing specs. In all of the cases there were deep underlying issues of misunderstanding of how the production or the specs should work. Over the course of a few months we tracked this random failing specs, understood, resolved them and shared the knowledge with the team of why were this random failings occurring. As of writing this there are still 2 random failing specs failing every 5-10 builds. The pain that we resolved was the lack of understanding of how some specs work and the general disbelieve in the quality of the spec suite in the team. A spec suite is only as good as you could trust that it brings you value. Otherwise you are just maintaining more code.

[Specs, RSpec] RSpec and Capybara for forms with rails-ujs, turbolinks and stimulus that also work without any JavaScript

The goal of the platform was simple. Have the whole platform work with and without JS. This means that the whole platform could work even in browsers that have JS disabled and if it is enabled it enhance the experience. The production part of the problem was solved quite easy. But the specs were a challenge. Our goal was to build a spec suite that with the same specs could run against JS and non JS browsers and drivers without exploding into if statements. A truly browser agnostic spec suite. The result was that this made the specs extremely clean and easy to support.