Cookie Consent by Free Privacy Policy Generator

How I Reinvented The Decision Log By Using Architecture Decision Records.

Published on • 6 minutes read

One day I got a report from the quality assurance team, that everything is working correctly, but the mobile app behaves oddly after the version upgrade. In such cases, it usually means there was a data mismatch, which will be an easy fix.

That’s what I thought at the time, but I didn’t realize that my life was about to get harder soon. Not because of the bug, but rather a solution in the codebase.

Reverse Engineering The Data Migrations

The problem with mobile apps is that you need to support different app versions. Users are using different devices and updates are usually not mandatory. You should test not only the most recent version but even app updates from the previous versions.

The most common issue with updates is a lack of some initial data while the app is upgraded. You can solve it by preparing data migrations, exactly like you would do on the backend side.

That was a new codebase for me, and my first thought was to just write a data migration. I briefly looked at the documentation to confirm how to do it properly and then looked at the exact place in the codebase. There was no such mechanism in the app.

I started thinking - how did they manage so far without migrations? The app was in production for quite some time, so there were many app versions to support.

The codebase was also hard to navigate, and you could clearly see that different developers had their own ideas on how the codebase should look like. But that didn’t answer the question - why no one used data migrations?

Realization

After testing the app behavior for the upgrades and searching all the places I realized that the app has indeed an existing data migration mechanism. Not only one but even two of them!

My mind wandered and I started to ask questions to myself, only because the previous team was long gone.

Why wasn’t the official mechanism used? Why is it implemented twice? Was it intentional or done by mistake? That’s the questions that might never be answered.

This was a realization moment for me. If I had any context for this decision made back then, I wouldn’t need to worry. My decision wouldn’t break the app for thousands of users if I make a mistake.

This was when it hit me - That’s what the Architecture Decisions Records are for!

After quite a long session of reverse engineering, git blaming, and comparing app behaviors, I resolved this issue. This was also the moment when I consciously and intentionally created an Architecture Decision Record. I hoped that it would save someone's struggle in the future. Maybe even it’ll help me after some time passes.

Architecture Decision Records

Architecture Decision Records is a little bit misleading name. It implies that every decision documented should be about architectural changes.

I like to think about it as Codebase Decision Log. In this case you can document decisions not related to architecture, but all of that documentation should be about the codebase.

Probably the best ADR definition I found was in this blog post about ADRs.

ADR is called there as “Any Decision Record”.

So, what should be included in such a decision log about the codebase?

For sure - Architectural changes. We’re not getting rid of such changes, but rather extending our documentation’s scope. What else?

Business Decisions Implications

The business decision that affects the codebase. Our log is not a place for outlining the business decisions which affect multiple stakeholders. We need to keep track of the changes made because of the business decision. All those changes should include a technical explanation, which is not a good fit for a decision log maintained by the product team.

If the solution is dictated by the business requirement, and it's ignoring the implication on the codebase, then you surely would need to know this context in the future.

Technology Changes

Codebase Decision Log should reflect all of the technology changes. Whether it’s a new tool, a new library, or just a script - you need to know the “why” behind it.

That’s the approach Google is taking with its ADRs. Every tool research and every choice is explained properly with their context, decision, and time marked by git.

If you want to see the example from the battlefield, you can see how the Google Cloud Platform does just that in its open-source repository. Read the Architecture Decision Records in Google Cloud Platform.

Naming, Convention Changes

If you create a change affecting the bigger chunk of the codebase, it’s a good idea to document that so it will not be forgotten. Think about the naming changes or the convention changes.

I had the cases when naming was mismatched or you had to suddenly switch naming in the codebase to reflect business changes.

I like to use it not only for keeping the context of changes for future reference but also as a communication tool for the team. Not the main communication tool, but rather a quick future reference. If such a change as naming is introduced to the codebase, it’s important to have it documented somewhere, and I believe that ADR is a good place to do that.

Tech Debt

I found ADRs to be an awesome tool to mark existing tech debt in the codebase. If the team knows that there was some restriction that made us cut corners, but we don’t want to forget about it in the nearest future, let’s describe that in ADR.

Examples of such ADRs were changes on Frontend caused by Backend lagging with introducing some endpoints properly. We had to ship the app, but we knew that it might impact performance in the future, so it should be eventually implemented properly.

ADRs have a status field, which is awesome for marking what’s happening with tech debt.

Usually, there should be values like: “proposed, accepted, rejected, deprecated, superseded”, but you can also use “resolved” or “pending” for this particular case.

Additional ADRs Resources

If you want to learn more about ADRs, you can find templates and tools on the homepage of ADR GitHub Organization.

This page explains in detail how ADRs should be used, how it creates a decision log for a project, and how to extend the scope of ADRs to make it “Any Decision Records”, exactly as I use it.

Summary

Architecture Decision Records is one of my main tools to create high-quality projects which are easier to maintain. I always set them up in the repository when kicking off the project along with Onboarding documentation and Software Design Doc. I prefer to use it as “Any Decision Records”, so I can focus not only on architecture but all the decisions regarding the codebase. Having the context of all the decisions and changes saved me many times, so this simple documentation brought a lot of value to me.

What is Your Experience with Architecture Decision Records? Did you use it as Any Decision Records?

Let me know your thoughts on Threads - @this.dev or Twitter - @IdaszakDaniel.

Tweet
Daniel Idaszak profile picture