DEV Community

Cover image for Before You Add Features: How to Understand an Internal System Nobody Documented
SandraMeshack
SandraMeshack

Posted on

Before You Add Features: How to Understand an Internal System Nobody Documented

One of the most challenging pieces of work I have encountered isn't building software from scratch. It's inheriting software that already exists.

You join an organisation, a team, or a project and are told that a new feature is needed. The software is important to the organisation. People use it everday and business processes depend on it.

There is just one problem - nobody is entirely sure how it works. Documentation is sparse. The original developers have moved on. Some decisions were never written down while others live in old email chains, meeting notes or in the memories of people who left years ago.

At this point, the temptation is to jump straight into the codebase and start building. I have learnt that this is usually the most expensive mistake you can make.

Before adding a feature, you first need to understand the system. Here's the process I use to understand undocumented systems before making changes.

A. Start by Getting the Platform Running Locally

The first objective is not writing code. The first objective is ownership. If you cannot run the application on your own machine, you do not really own your understanding of it yet.

This means:

  • Cloning the repositories

  • Installing dependencies

  • Configuring environment variables

  • Setting up databases

  • Understanding deployment configurations

  • Reproducing the production environment as closely as practical

Sometimes this takes a few hours, sometimes it take several days. Both are normal. The rule of the game is to remain tenacious and the goal is to create a safe environment where you can experiment freely without fear of damaging production systems.

Only once the application is running locally can real investigation begin.

B. Understand the Architecture Before Reading Every File

A common mistake is opening random files and hoping understanding emerges. In large systems, it rarely does. Instead, start by understanding the shape of the system.

Ask questions such as:

  • What applications make up the platform?

  • Where is data stored?

  • Which external services are integrated?

  • How do users access the system?

  • What happens when a request enters the application?

Then go ahead and draw diagrams. They do not need to be perfect. My first architecture diagrams are often rough sketches on paper. The purpose is not documentation at this stage. The purpose is orientation. You are building a map of unfamiliar territory.

C. Use the Software as a User

This is probably the most important step and the one that is skipped most often.

Before changing a system, use it :

  • Create records

  • Submit forms

  • Generate reports

  • Approve workflows

  • Upload files

  • Break things

  • Observe what happens

Many developers learn systems through code alone. I prefer to learn systems through behaviour first. The code explains how the software works, the software itself explains why it exists.

As you move through the application, document what you discover:

  • Which pages are connected

  • Which data appears where

  • Which actions trigger emails, notifications or database updates

  • What assumption does the system make about its users

These observations often reveal more about the architecture than the code ever will.

D. Build a Seed Data Framework

One of the most valuable things I have done when inheriting systems is creating reliable seed data.

Undocumented systems are often difficult to test because nobody knows what a "normal" dataset should look like.

You spend hours creating records manually, only to discover a workflow requires five other pieces of related information before it functions correctly.

Instead, create representative datasets.

For example:

  • Test users

  • Departments

  • Membership records

  • Products

  • Orders

  • Reports

  • Permissions

Whatever makes sense for the application.

The goal is to be able to recreate realistic testing scenarios quickly and consistently.

A good seed data framework becomes more than a development tool.

It becomes documentation.

Future developers can examine the seeded data and immediately understand how the application expects information to be structured.

E. Document Everything You Learn

Documentation should not be something you write at the end.

Documentation should be a by-product of understanding.

Every time you answer a question, record the answer.

Every time you discover a dependency, document it.

Every time you trace a workflow, capture it.

I often create documents covering:

  • System architecture

  • Data flows

  • Deployment processes

  • User journeys

  • Integrations

  • Known limitations

You do not need a perfect documentation strategy from day one.

You simply need to avoid learning the same lesson twice.

F. Create a Feature Impact Map

Before writing a single line of code, understand where the proposed feature will affect the system.

I like to ask:

  • Which users are affected?

  • Which pages will change?

  • Which services will change?

  • Which database tables are involved?

  • Which reports might be impacted?

  • Which integrations depend on this functionality?

The answers often reveal hidden complexity.

A feature that appears small on the surface may touch half a dozen different areas of the platform.

Understanding this early prevents surprises later.

G. Establish Current Behaviour

Before changing anything, establish what "correct" currently looks like.

This is especially important in systems with limited automated testing.

  • Document existing workflows.

  • Record expected outputs.

  • Capture screenshots.

  • Create test scenarios.

The objective is simple. When something breaks, you need to know whether you introduced the problem or whether it already existed.

Without a baseline, every issue becomes an investigation. With a baseline, problems become easier to identify and resolve.

H. Design Before You Build

Once the system is understood, the feature can finally be designed.

Notice that design comes before implementation.

By this stage, you should understand:

  • The architecture

  • The workflows

  • The constraints

  • The technical debt

  • The likely impact of the change

Now you can make informed decisions rather than guesses.

Good architecture is often less about finding the perfect solution and more about avoiding unnecessary problems.

I. Implement Conservatively

In mature systems, small changes are often better than ambitious rewrites.

There is usually a reason things evolved the way they did, even if that reason is no longer obvious.

I prefer:

  • Incremental improvements

  • Small pull requests

  • Clear documentation

  • Careful testing

  • Reversible changes

The goal is not to prove how clever we are. The goal is to improve the system safely.

J. Leave the System Better Than You Found It

Adding the feature is not the end of the work.

  • Update the documentation.

  • Record architectural decisions.

  • Improve onboarding notes.

  • Capture lessons learned.

  • Add missing tests.

  • Refine the seed data.

The next person who works on the system should not have to repeat the same investigation.

That is how undocumented systems gradually become documented systems.

Not through a single grand effort, but through a series of small improvements made by people who cared enough to leave clear paths behind them.

Understanding a system before changing it may feel slower at the beginning.

In practice, it is usually the fastest route to delivering features safely, confidently, and sustainably.

Top comments (0)