Summary Professional Experience Education Projects
BYU Office of Information Technology
2008 - 2010 Network Operations Analyst

While at college, I took on a job as a Network Operations Analyst working for the BYU Office of IT, and held the job from 2008 to 2010. While this wasn't a software development job, it gave me the chance to deepen my understanding in the field as it provided me the opportunity to work in the BYU Network Operations Center (NOC), where my job was to monitor the servers using Nagios, and serve as the first line of defense should problems arise. If the issue was simple enough, I would work to solve the issue myself. Otherwise I would assign the issue to an engineer and analyze the severity of the issue, so as to determine if it merited phoning an engineer in the middle of the night. Other responsibilities included basic maintenance work such as replacing a failed hard drive in a RAID cluster and the like.

CleanTelligent Software
2010 - 2018 Senior Web & Mobile Developer

In 2010, it came time for a switch, and I got my first Software Developer position working part time for a company called CleanTelligent Software, a company that provides software for the janitorial industry. I ultimately ended up working here for the rest of my college years, working part time during the school year, and full time during the summers, until I graduated in the Spring of 2013, at which point in time I took on a full time, salaried position, and was eventually given the title Senior Web and Mobile Developer in 2015. I continued to work there over the years until 2018.

The primary application was a Java application built on Spring with a PostgreSQL database and a front end built on JSTL and EL with some JavaScript and JQuery interspersed for richer functionality. There was also a corresponding mobile app that was built using Adobe AIR and ActionScript for its ability to cross-deploy to iOS and Android. Additionally, there was an IIS server using C# and SOAP that was used for Word document generation.

The Work

Over the years I had my hands in pretty much every part of the code base, and contributed a fair amount to the company. A few of my accomplishments are as follows:

During the first year working there, the company had the chance to acquire a particularly large chain company as a customer, but the deal required various improvements to the software to go through. We as a programming department banded together and put in the work to make those changes happen, where I put in work to add a customizable rating system for the inspection software and built key parts of the proposal document generation software, among other things. Ultimately this work paid off in sealing the deal with this customer and adding significantly to the company's revenue for years to come.

In later years I became responsible for the IIS/C# server that was previously built by a consultant for the company, and I did significant refactoring that drastically sped up and simplified the document generation process. Additionally, I added logging that allowed us to keep track of how customers were using this service.

A significant part of the software dealt with generating reports for customers based off of data collected through inspections and work orders, and to this end I spent a great deal of time optimizing large SQL queries, recursive queries, and PL/pgSQL stored procedures over the years.

Additionally, to further speed up the application, I took on the effort of sharding the largest tables in the database. The company couldn't afford to have extended downtime during this sharding process, so to get around this, I built a framework that could shard the tables while the application was up and running. This involved extensive use of the System Catalogs and PL/pgSQL to examine a table, set up triggers to monitor updates to the table, create the shards by making multiple partial copies of the table, update the shards based on the monitored changes from the triggers, and switch over to the shards, all without customers noticing and while maintaining data integrity. The end result was drastic speedups for the most used features of the application.

I also took on the role of mobile developer as needed, and put significant effort into a mobile UI update, and adding work order functionality to the mobile app, giving our customers access to one of our most popular products on their mobile devices.

It's also worth noting that while CleanTelligent now runs on the Spring framework, for the first number of years that I was there it was not. It instead ran on the Struts I framework, which was now outdated and vulnerable. As a team we put in a concerted effort to migrate off of Struts and on to Spring. To do this we utilized Mob Programming in order to determine how to tackle the problem as a whole, and then moved to tackling various pieces individually once we had a picture of the game plan. This allowed the company to move to a more modern and secure framework.

In another instance, I headed up the effort to build an integration testing framework built using Selenium and Selenium Grid. I utilized the Page Object Pattern to help keep the tests maintainable, and the tests were set up to run on Test-NG to allow the tests to run in parallel across multiple nodes. I used Vagrant to configure Windows VMs as Selenium Nodes running IE, Chrome, and Firefox. The Selenium Hub was controlled by Jenkins, which ran all test suites when new code was deployed to the test environment. This was in addition to our unit tests, which were built using JUnit and Mockito.

I also co-led the development of a REST API with an OpenAPI Specification, opening the door for Third Party integration.

It was also my responsibility to to train new hires and get them up to speed, making sure that they knew how to navigate through the code and find what they were looking for, and generally being available for any questions that they had.

Canopy
2018 - Present Senior Backend Engineer

In 2018 I decided it was time for a change again, and I got hired on as a Senior Backend Engineer for Canopy, a venture funded startup that serves tax accountants by providing practice management tools in the cloud to assist them in their work.

Canopy is built on a microservices architecture using Docker and Kubernetes and deployed on AWS via CD pipelines built in GitLab. The microservices are owned by Cross Functional Teams consisting of front end and back end devs, QA, design, and product management.

The Work

When I first began at Canopy, I started on one of the squads that was responsible for an as yet to be released product for filling out and submitting tax returns to the IRS, with my squad being responsible specifically for the part of assisting the practitioners in gathering and filling out the necessary information on a client's behalf, as well as tying together the various parts from the other squads into a cohesive final product. These microservices were built using Java, VertX, and RxJava, with a PostgreSQL database.

When I came on, the company was working towards the goal of releasing the beta version of their tax prep product, which would support doing a federal tax return, as well as a limited number of states, for individuals. The target goal, tax season of 2019, was a a little less than a year away, and the company had already been working multiple years towards this goal, but there was still plenty left to be done. And this deadline wasn't an artificial deadline. No, this deadline was dictated by the seasonality of the tax industry. In essence, we miss this deadline, and we'd miss our target by a full year. Add to this the fact tax returns are complex, and a great deal is required to even reach the bar of minimum viable product.

So, I went to work, and so did each and every other person in the squads that made up the tax prep team. We worked, and we pushed, and we hit that deadline. Some of the work I did during this time includes:

Building out in house QA tools that allowed our in house tax practitioners to test the tax logic that they were responsible for building. This helped to ensure that we could provide accurate tax returns, which in turn would allow our customers to place trust in our product.

Building out the backend of our streamlined client esign experience. After a tax practitioner prepares a tax return, he is required by law to obtain a signature from the client. This can be done the old fashioned way on paper, or it can be done through esign. Unfortunately the process for esigning for many practitioners is far from smooth. It usually involves sending the tax return as an attachment in one email, and then sending an esign request via a second email. This is both time consuming and not overly secure. I streamlined this process and integrated it with our client portal, making it so that the practitioner could effortlessly send a single email to the client, which would direct the client to the client portal where they could log in and see their tax return and go through the esigning process all in one place.

Building out the connection between our services and services of team responsible for efiling. A separate squad was responsible for building out the necessary services to allow us to efile with the IRS. My responsibility was building out the glue that allowed our services to communicate and interact smoothly with their services, and also expose api endpoints that would allow the front end devs to build out a proper user interface for this step in the process.

In an unfortunate turn of events, not too long after our accomplishments, it was determined that the company was struggling with its other product offerings in practice management did not have a sufficient runway to build out its tax prep product, which would ultimately need to support both individual and business returns at the federal level and for all 50 states. At this point, the company pivoted to double down on improving its practice management tools, and the tax prep product was shelved indefinitely.

I ultimately survived two rounds of layoffs, and moved in to fill a void left in one of the practice management squads where both the backend devs quit in short order after the second round of layoffs. This new squad owned the workflow and task services, and its backend services were written in Python, so I worked to get up to speed on the new language and the new code base so that I could properly support the front end devs and the rest of the squad in their work. In short order we hired on another developer, and I worked to train him while simultaneously working to get up to speed myself. As part of this new squad, the work I've done has included:

Building a system for saving custom task filters and providing default filters. Prior to this, a customer could filter their list of tasks, but had no way to save the filter, so if they wanted to look at the data using the same filter in the future, they would have to go through the full process of creating the filter again. But now customers are able to save their filters and reapply them at any point, and a few custom filters have been provided for their use right out of the gate.

Building a system to supply predefined task templates. The system already supported building custom templates for use in creating tasks, which makes task creation a streamlined process, but these templates were complex and difficult to build. So we built this system to allow us to give them some predefined task templates that they could use as is, or use as a starting point to make tweaks and changes to create their own task templates.

Building a system to allow customers to create client request templates. A client request is a piece that hooked into the task and workflow system as a tool for requesting additional information from the client via the client portal. While it was integrated with tasks, it did not have any templating functionality as of yet. So we built out client request templates, and made it so that it could hook in with task templates, thus allowing for tasks with client requests to be created in a streamlined fashion.

Built a database migration test framework so that developers could test the accuracy of their migrations, understand how long they will take on large data sets, and how the table locks from their migrations will affect incoming traffic.

Migrating functionality off of the legacy PHP system into the Python system. The workflow system still had parts existing in the legacy PHP system that the previous team had been working at converting over to Python for years. As I inherited the system, I made it a priority to finish getting off the legacy system so that there could be a unified, cohesive code base.

The Dev Book Club

In addition to this work that I've done to further the company goals, I also took on the work of helping myself and my fellow developers improve in our skill sets, and to this end I established and ran a developer book club, with an emphasis on helping us to better understand and utilize the tools that we were working with.

I chose to start the group off with Learning RxJava by Thomas Nield. I chose this because I knew I wasn't as comfortable with RxJava as I'd like to be, and I assumed many of the other developers weren't, either. I assumed correctly, and I had a solid turnout for that first book, with the end result of developers better understanding how to use their tools to do their jobs. During our read through, I also experimented with writing some articles on my blog for the chapters that we were going through, which you can see here. Ultimately this article format wasn't the most helpful to the other engineers, and tried taking it from another angle with our next book.

The next book was Kotlin in Action by Dmitry Jemerov and Svetlana Isakova, and came as a suggestion from management, since Kotlin was being considered at that time as a potential language for use on our JVM microservices. This has ultimately led to some of the newer microservices using Kotlin. Something that I ended up doing as part of this particular read through that ended up being very helpful to the other engineers was to come up with practice problems around what we were reading for that week, which I would post to my blog a couple days before our meetup, and then at our meetup, we would solve the problem together, mob programming style. Then after our meetup, I would post a follow up article that was the solution that we came up with together (sometimes with some extra notes and additions). This ultimately gave the developers a chance to practice what they were reading, which helped to make the content more sticky. You can see the various practice problems here.

Following this, the group voted on the next book, and chose to go through Accelerate by Nicole Forsgren, Jez Humble, and Gene Kim. This helped the group to better understand some of the Devops and CI/CD practices that were in place at the company. With this book, the concepts were higher level, and practice problems wouldn't work so well. Instead I put together chapter summary outlines, which would help aid in the discussion during our weekly meetup. These outlines can be found here.

It was around this time that the second layoff and the company's decision to pivot to focus on the practice management side of the business occurred. Many of the developers from the tax prep teams were shuffled around to practice management teams, and many of them, like myself, found that now they needed to be Python developers, whereas previously they were Java developers. I decided to try and help make this transition as smooth as possible, and chose a Python book as the next book for us to go through. And so with that, the next book we went through was Effective Python by Brett Slatkin. This did ultimately help a number of developers find their groove in their newly assigned roles. With this book, I resorted back to practice problems, but I experimented and instead of coming up with all the practice problems myself, I had others in the group take turns coming up with and presenting the practice problems, and I would assist them in the process. The idea here being that the presenter tends to learn the content better, so having the others be presenters would benefit them. I've written a few high level articles on this, here.

The next book was once again opened to a group vote, and we chose to go through Domain Driven Design by Eric Evans with the goal of improving our skill set and the most fundamental level, that of writing better, clearer code. Once again, the concepts in this book were higher level, so I built chapter summaries that helped stimulate our group conversations and could be gone back to and referenced at a later time. The chapter summaries can be found here.