Skip to content

Case study

We read the spreadsheet before we rewrote it

An industrial manufacturer ran a business-critical process through Excel workbooks built up over many years. The engagement is under NDA, so this is written about our method rather than about their operation. The method is the interesting part anyway.

Client

Industrial manufacturer, under NDA

Scope

Business-critical process, Excel to application

Role

Design, build, and deployment

Status

In production, ongoing development

This engagement is covered by an NDA, so the client and the details of their process are not described here. We can go further in a direct conversation.

01The problem

The requirements were never missing. They were in the cells.

A workbook that runs a real business process is rarely a tidy calculation. It is years of accumulated rules, exceptions, and corrections, spread across sheets, encoded in formulas, and understood completely by nobody.

That is the genuine difficulty in replacing one, and it is usually underestimated. The requirements do exist. They are just not in a document, they are in the cells. The people who run the process can explain it well, but very few can enumerate every rule inside it, because most of those rules stopped being decisions a long time ago and became habit.

The usual approach is to interview people, write a specification from what they remember, build to it, and then find the missing rules in production when a number comes out wrong and somebody notices. We wanted to know what the workbooks actually did before writing a line of application code.

02The method

We turned the workbooks into a dependency graph

Every formula in a spreadsheet is an edge between cells. Taken together they form a directed graph of what depends on what. So before building anything, we parsed the workbooks and constructed that graph. It changed the shape of the whole project.

INPUTDERIVEDOUTPUTCIRCULAR REFERENCERATE: Confirmed input, traced to a maintained sourceRATEQTY: Confirmed input, traced to a maintained sourceQTYESC: Assumed: hardcoded in the sheet, no source givenESCFX: Missing: referenced but never suppliedFXMATL: Derived value, all inputs resolvedMATLLABR: Derived value, all inputs resolvedLABRADJ: Defect: participates in a circular referenceADJCONT: Cannot resolve: depends on a missing inputCONTSUB: Derived value, all inputs resolvedSUBTOTAL: Output is affected by the circular reference upstreamTOTAL

Hover or tab a cell to inspect it

InputDerivedOutput
ConfirmedAssumedMissingDefect found
  • A map of what actually drives what

    Not what anyone believes drives what. The graph shows every path from an input to a final number, including the paths nobody remembered existed. Reverse engineering by interview is guesswork with a confident tone. This is not.

  • The real inputs, separated from everything derived

    Walking back to the cells that depend on nothing else tells you what the true inputs are, and everything else is computed. That distinction is the data model, discovered from the source rather than guessed at in a design meeting.

  • Problems found during analysis, not during rollout

    The graph surfaces what hides in a large workbook: circular references, cells orphaned from any output, branches that no longer feed anything, and a formula copied across a range with one cell quietly different from its neighbors. Some of what we found were live defects. Far better to catch those in analysis than to faithfully reproduce them in code and inherit them.

  • An order to build in

    The graph gives a topological order: leaf calculations first, then whatever depends on them. That is a build sequence derived from the work itself rather than from a project manager's intuition, and it means each piece can be verified as it lands instead of at the end.

  • The original workbook as a test oracle

    This is the part that changes how a rebuild feels. The spreadsheet becomes the reference implementation. Feed the same inputs to both, compare the outputs, and any divergence is either a bug we introduced or a bug we just found in the original. The rewrite gets verified continuously rather than hoped about.

A spreadsheet is not documentation of a process. It is an executable definition of one, and it can be read as such.

03What the application added

The things a file cannot do, however good the logic inside it is

Once the logic was understood and rebuilt in code, the rest of the value came from being an application rather than a document.

  • An audit trail behind every change

    Every change is attributed and timestamped, and prior states are preserved rather than overwritten. The distinction that matters is between a change log and an audit trail. A hosted workbook can tell you a cell changed. What the business needed was to ask which values on a specific record changed, who changed them, and what it looked like before, and to still have that answer years later rather than inside a retention window.

  • One authoritative version

    There is no longer a question of which file is current, because there is no longer a file to be a copy of. Everyone is looking at the same record.

  • Access by role

    Maintaining the underlying rules and using the application day to day became separate permissions, rather than the single undifferentiated ability to open a document and edit any cell in it.

  • Validation where the data enters

    Bad values are rejected at the point of entry instead of propagating silently into a total that somebody trusts three steps later.

  • A review step in front of rule changes

    Changes to the underlying rules go through a diff of exactly what will change, reviewed before anything commits. Previously an edit to a cell was live the moment it was typed.

04A deliberate decision

Excel stayed in the workflow, on purpose

It would have been easy to treat the spreadsheet as the enemy and remove it entirely. That is a reliable way to build software people quietly refuse to use.

The people who maintain this kind of work are genuinely fast in Excel, often faster than they would be in any interface we could build for the same task. Taking that away would make their day worse in exchange for an abstraction they did not ask for. So the maintenance path runs through it: export the current state as a workbook, edit in the tool you already know, upload it back, and review a diff of what your edit will actually change before it commits.

The application is the system of record. Excel remains a perfectly good editing surface. Those two things stop being in conflict as soon as the question of authority is settled.

05How it runs

Built to be operated, not just delivered

This is a production application carrying real commercial work, so it was built with what production requires from the start rather than having it added later.

Backend

Go, with interface-driven services and repositories

Database

PostgreSQL, with versioned migrations

Frontend

Next.js and TypeScript in strict mode

Authentication

Auth0, with role-based authorization

Infrastructure

AWS, deployed through CDK

Testing

Table-driven Go tests and a frontend suite, required for every feature

06Where it stands

What actually changed

The process now runs on an application with a single authoritative record and a full history behind it. The logic that used to be editable by anyone who could open a file is code: testable, reviewable, and corrected once rather than in every copy that happens to exist.

The dependency graph work is the part we would repeat on any engagement like this. It turned the riskiest phase of the project, working out what the spreadsheet actually did, from an open-ended series of interviews into an analysis with an answer we could check. That is most of why the project moved as quickly as it did.

The system is in production and still under active development, which is the normal and healthy state for software carrying a live process. New capability gets added as the work shows what is needed next.