Delivering High Quality Code - Our Process

Our approach to scoping, building, and delivering high quality software projects.

I wanted to take this opportunity to briefly show case our process for getting software projects out the door and into the hands of excited users:

  • Identifying what to build
  • Scoping out product and technical features
  • Delivering it to customers
  • Monitoring for success

We'll walk through an example of a product feature developed for Legaci.

What to build?

At Legaci, we always start from the foundational problem we built our company on: as an artist, I feel like I don't own my audience and can't reliably monetize outside of tours and merch.

We typically find a few sources from where product ideas can be sourced from.

  • Existing user complaints
  • Opportunities found from having conversations with our artists
  • Researching the industry
  • Shower thoughts when reflecting on our product

Prioritization of these is so heavily centered on what the business objectives are for a given stage. For a Pre-PMF company such as Legaci, more weight might be placed on iterating features that'll have an outsized impact on word of mouth growth versus monetization.

Wherever the team lands on choosing a particular product feature to develop, given enough time, the bottleneck typically isn't in the idea phase. It is however, important to understand where these next iterations come from as this may inform certain aspects of the feature to focus in on.

The decision to build out a paid membership feature came from two places:

1. Legaci artists said they wanted it

2. Every creator platform and increasingly social media sites have started introducing the feature set.

Vetting ideas

Time is the most precious resource for a pre-PMF team, and so we owe it to ourselves to gain confidence on our spread of ideas to best understand what's going to move the needle the most.

There's a lot of established frameworks to accomplish this like ICE, but often we feel they're a bit too heavy on the process our team of 3.

The justification to dedicate ourselves to paid memberships came from a more gut reaction. A lot of finding product market fit is "you'll know it when you see it". As we're operating this business, we started to build a sixth sense for when something is working and we're headed the right direction. Don't shy away from this!

A gut reaction is almost a hack to tap into a meta-systematic view of your business, encapsulating all your customer interviews, analytics data, personal creativity, etc.

Product requirements doc and the tech spec

The core question now becomes "How do we make this a reality for Legaci?".

We start with what most would generally call a product requirements doc (PRD), then turn that into a technician spec detailing the blueprint for implementation.

Product requirements doc

Let's start with the PRD. These usually take the following form:

  • Problem description
  • High level product solution
  • Fine grained product changes (user stories in agile)

Problem description

We use this section to back our gut reactions with those relevant customer interviews, analytics data, or any other tangible evidence.

High level product solution

Here we describe from a 10,000 ft view what the solution needs to be. In the case of paid memberships, this was as simple as "clone Patreon, but without the exclusive member posts".

Fine grained product changes

This will take the form of a todo list for where updates need to be made in the app. If needed, this is where we'll add in designs and high level wireframes to mock out flows.

So for paid memberships we would have tasks like "ability to create a membership tier, and adjust the pricing", or "ability to join/cancel/resubscribe to an artists premium membership".

More clarity in the PRD process has an incredible effect in making development easier. Small example, but if a feature can be walked back and isn't critical to MVP, we can avoid adding a new table and all the work involved in that effort.

Tech spec document

We break out our tech specs into three or four general sections:

  • Front end changes
  • Back end changes
  • Database changes
  • Third party services

For each product update, we'll go through each of these sections and enumerate what is required. I find it easier to rationalize what the new user experience needs to be first, then work my way backward deeper into the tech stack. But that may just be a personal preference given my background doing years of front end development!

Paid memberships was a huge feature requiring updates in all categories. We needed new views and UIs to allow artist to create their membership tiers, connect their bank accounts, handle payouts, among more. Users also needed to manage all their subscriptions, update their subscription settings, see they're premium members in the community, etc.

Once the front end changes were scoped out, I can begin to think about what new GraphQL queries and endpoints will be needed to support them.

This leads naturally to thinking about new columns and tables needed to store the new data requirements, tables to record artist membership tiers, user subscriptions, etc.

And to support the payments functionality, we leveraged Stripe's Connect platform. The tech spec allows us the flexibility to change our tech spec to fit the integration as needed.

Writing code

After all the work above is done, writing the code ends up being the easiest part. Actually writing the code becomes a very simple task of going through the tech spec and ticking off checkboxes. This is where you can confidently say you built a massive feature "in a weekend" part in the headline comes in, all the requisite queries and mutations were implemented in roughly 3/4 days.

Since we've parsed out all the work ahead of time, it became much easier to spot clean divisions in tracks of work to split with my cofounder to get this out the door quickly.

Testing, release, and monitoring

For Legaci, TDD is not appropriate. For where we're at, the process is just not quite fast enough. Once the general implementation of functionality is done, then we layer on integration and maybe end to end tests to validate behavior of the code.

QA

We move the code up to our staging environment, which we've been able to keep as close to 1:1 with production as possible. Here we now create a QA checklist using the PRD and perform manual QA. All of the team is involved in QA.

Once we feel good about the changes, and have QAd the functionality, we release our front end and back end apps and monitor for issues.

Monitoring

Our monitoring suite is very simple, we have a few tools to validate the health of our app in production, a quick run through:

  • Mezmo for logging. Dashboards for 400/500 status codes and our app errors are essential.
  • AWS CloudWatch dashboards. We track memory, CPU, and containers deployed across our ECS services
  • ZenDesk to track customer support
  • Microsoft Clarity to take a pulse check on user experience

Takeways

Generally we follow this process for more intensive projects with a lot of moving pieces.

One of the many silver lining of working on your own startup is we can quickly adjust to forgoing certain steps if we feel they're not needed or will hamper us in delivering value to our artists.

Having some process to fall back helps immensely in making some sense between the sheer number of things you can be working on as a business owner.

Could your startup use some TypeScript development help?