Tips for planning and executing larger engineering epics

Published Feb 28, 2023, 9:21 AM
Written by Chris Kelly

Here's how we managed the early planning stage of a complex web development project.

At Symbiote, we recently rolled out multi-factor authentication (MFA) for Public Transport Victoria (PTV), to give commuters a higher level of protection for their personal data. This is a critical security addition for any modern web application.

This was a project with many moving parts that involved many of our developers working simultaneously. I thought I'd share some ways of working that helped us in the early technical planning stages when it came to setting the foundations for building this functionality.

We work using Agile project management methods.

In case you're not familiar with Agile terms: 

  • Stories are short requirements or requests written from the perspective of an end user.
  • Epics are large bodies of work that can be broken down into a number of stories.

So, how does a mid-sized development team execute large technical epics that consist of dozens of features? Here’s what I suggest:

(Note: the thinking in this article is largely in the context of "frontend" web development, but can be equally applied anywhere.)

1 – Take a step back

There are a large number of moving parts when rolling out something like MFA to an existing, complex web application such as the myki dashboard. (The myki dashboard is the hub for travellers, giving them easy access to do things like check their account balance, report a lost myki card and update account information.) 

It can take time to "grok" everything in play.

I find that taking a step back from the screen helps me immensely when it comes to large scale projects. It helps my brain digest high level requirements without the distractions of notifications and, more importantly, reduces the temptation to enter "implementation mode" too early.

The goal of this step is to see the big picture as much as possible. I find it helpful to avoid focusing on any one story, and see the epic as a whole.

For the MFA project this meant mentally conceptualising the state of when a page would need to prompt the user for a one-time token and the broad categories of when this "blocking" state would need to occur. For example, on page load, prior to form submission, and so on.

2 – Whiteboard

Pick a diagramming medium – this can be a physical whiteboard, Miro, or even pen and paper.

Use your diagram to rapidly plot out the building blocks, data flows and state transitions. Aim to avoid implementation – rather, focus on how the building blocks piece together.

"Whiteboards allow you to ruthlessly dispose of ideas that aren't working. At any time, you should feel comfortable wiping the board clean and starting fresh. It's much cheaper to dispose of ideas at this stage, before developers start coding."

Tip: Don't spend time making these diagrams pretty, an especially real temptation when using digital whiteboards. The prettier they are, the less likely we are to dispose of them if they aren't working.

By the end of the whiteboard stage of the MFA project, we had mapped out the key data flows and state transitions, and had a solid high level understanding of how the MFA modal prompts would work asynchronously while waiting for user input.

3 – Talk, continually

Communication. Hey, who would've thought that was key to success?

This might seem obvious, but ask questions to key stakeholders, such as project owners, and continue to confirm your understanding of the requirements. This is especially important during the early stages, as it's likely that all the stories within the epic are not complete, fully understood, or even completely explored.

4 – Take stock before abstracting

One of my favourite micro-patterns is the rule of three

A quick sidestep: The “rule of three” is about avoiding refactoring reused code too early, instead, refactoring it once you have sufficient information to create the right abstraction. I find this pattern useful because it balances out the more commonly applied DRY principle (Don’t Repeat Yourself), which leads into …

Devs hate repetition, but often aim to remove duplication too early. This leads to rigid architecture due to the wrong pieces of code being refactored out.

It is difficult to create the correct abstractions on stories that are within a larger, in-development, epic because all the code hasn’t been written. You might feel you need a crystal ball.

However, you can still take stock of the upcoming work by looking through the requirements of upcoming stories within the epic, even if you won’t be the developer for that story.

When making these abstractions ahead of time, make sure to keep your team in the loop. A note in Slack can be useful, or even better an example branch in Git, for example:

Hey @chris, looks like you'll be working on ticket003. That shares some behaviour with ticket001 I'm working on, so I'm going to pull that behaviour into a service. I'll push up an example branch of that service for when you pick up ticket003.

5 – Iterate and be flexible

On larger epics, despite all the best planning, established solutions often still need adjusting. Some issues and gaps only become clear once further features are added or pathways are explored. Sometimes certain stories are dependent on others and time is needed to apply the "glue".

When estimating individual stories, factor the above into your budget. When a story is part of a much larger deliverable, it’s very likely you’ll need to allow extra time.

The key to remember here is that a large epic is made up of multiple features. They are being built in parallel, so it helps to maintain a flexible mindset during development as the pieces fall into place.

In the MFA project, this often meant stubbing particular components in one story – a stub being a snippet that shims in placeholder functionality – while another developer worked on the stubbed functionality in another. We allowed time to "glue" those pieces together.

6 – Document, constantly

Try to avoid leaving the writing of your documentation to the end. Details may be lost over the course of a large project, so it's best to document as you go. Iterate on your documentation as you iterate on code.

With larger projects, timely documentation is important because you have multiple developers working in parallel, on interlocking features. They need to understand how your parts work to avoid being blocked or approaching it from another angle.

As a developer, if you aren’t seeing documentation from others in your team, don’t be afraid to ask them to add it, or mention it as part of reviewing a pull request. 

Successfully navigating complexity

Every team has their own techniques for navigating complexity found in large scale projects. I hope you find these ideas useful for your upcoming projects.