Skip to content
VAARDE

Case study

Building a production data backbone.

A fresh-produce processor in West Africa was running its factory floor on paper. We were asked to design something that would take the paper away. What the operation actually needed was a working model of how its production really happens, and that turned out to be a rather different piece of work.

In progress since 2026West AfricaFresh-produce processing

The problem

More than a hundred paper forms, every shift.

Everything needed to work out yield, efficiency and labour productivity was already being written down carefully. The difficulty was the journey it took afterwards: from a form on the line, to a supervisor, into a spreadsheet, and eventually into a report. By the time a number reached anyone who could act on it, the shift it described had long finished.

The reporting workbooks we were given showed how much the team had already built for themselves. They also showed the limits of running an operation out of spreadsheets: multi-level headers, dates expanding sideways across the sheet, supplier and batch conventions that varied by who had entered them, and calculations sitting inside the same sheets that presented the results. These were structures built to be read by a person, not queried by a system.

So we reframed the engagement early. Reproducing the same forms on a tablet would have moved the typing, not the problem. The work we proposed instead was to design a reliable digital representation of how production actually runs, and then let the capture screens follow from that.

Approach

The system follows the path through the work.

An operator chooses their site once, and that context carries through every screen after it rather than being asked for again. From there the route through the application runs the way the work itself runs: site, then process, then line, then production session, then the entries themselves.

Technical identifiers stay underneath, where they belong. The people entering data work with the descriptions they already use on the floor, not with production-log keys or batch-group keys. A production system has to hold strict relational integrity without asking a supervisor in the middle of a shift to think like a database administrator.

  1. 01

    Capture at source

    • Tablet entry on the floor
    • Validation and business rules
  2. 02

    Transactional store

    • Batch and production fact tables
    • Site, product, line and shift reference tables
  3. 03

    Derived measures

    • Shift and daily KPI engine
    • Calculated from transactions only
  4. 04

    Analyst layer

    • Cleaned fact and dimension tables
    • Approved fields only
  5. 05

    Business intelligence

    • Cross-period reporting
    • Next phase
Figure 01 — Capture through to reporting. Each layer has one job.

Traceability

Batch identity, kept separate from intake tallies.

A simpler system would assume that one batch becomes one production session. This factory does not work that way, and pretending otherwise would have produced a tidy model that quietly disagreed with the floor.

Several batches of the same product can feed a single session. A batch can carry on across operational periods. Material comes back. And the physical reality of a batch rarely matches a calculated balance to the kilogram. So a batch header represents the operational batch, repeated receipts sit beneath it as child transactions, and production sessions reference one or more eligible batches through a separate batch-usage layer.

Returns are where that structure earns its keep. A returned quantity is not filed away as a negative number. It resolves back to the batch it came from, so that net input falls and batch availability is restored in the same movement. Where a session drew on one batch the attribution happens on its own; where it drew on several, the operator identifies the batch. Rejects are tracked separately, so the same quantity can never be deducted twice from one measure.

  1. 01

    Batch identity

    • Supplier, product, variety
    • One header per operational batch
  2. 02

    Intake tallies

    • Repeated receipts sit beneath the header
    • Never overwrite it
  3. 03

    Batch usage

    • A session may draw on several batches
    • A batch may span several sessions
  4. 04

    Production session

    • Staff-count events
    • Returns
    • Rejects and waste
  5. 05

    Output

    • Cut-product tallies by specification
    • KPI and production history
Figure 02 — Batch identity, usage and the return path back to source.

Exceptions

Product-level rules for the cases that do not fit.

One product in the range behaves differently from the others. Its first intake may establish weight and piece count, while usage can begin before a complete intake weight exists. Forcing it into the model built for everything else would have meant either blocking production or recording something untrue, and neither was acceptable.

The system therefore carries behaviour at product level: whether a product is tracked by pieces, whether open-batch usage is permitted, and how its batch codes should be validated. That product stays available for production even when its intake does not behave like a closed inventory balance, while official productivity still uses the kilograms actually recorded as used. Digitisation should encode the real operating model. It should not quietly reshape an operation to suit whatever made the software easier to build.

Measurement

Staffing recorded as timed events, not one headcount.

Output divided by headcount is the obvious calculation, and it misstates the period whenever staffing changes mid-session. If twenty people work part of an hour and fifteen work the remainder, neither figure describes what actually happened.

Staffing is therefore modelled as a series of timed events. The first count applies from the start of the production session, and every entry after it takes effect from its own timestamp until the next change or the end of the calculation period. Weighted staff-hours are derived from those intervals, and each processing stage is measured against the staff-hours that stage actually consumed. The specification requires this weighting explicitly, because it is what allows the system to reproduce the manual calculations the team already trusted.

Reporting

Shift measures, aggregated into a daily view.

Shift-level records are held at the grain of date, site, shift and product. Every measure on them is derived from the underlying transactions rather than re-entered by hand, which means a supervisor is never asked to type a summary figure that the system already knows.

From there a daily layer aggregates production by product across sites and shifts. Management can move from a day, to a product, to a site, to a single shift, and at every level they are reading the same record that captured the work in the first place.

  1. 01

    Daily summary

    • All sites, all shifts, by product
  2. 02

    Date

    • One production day
  3. 03

    Product

    • One product across sites
  4. 04

    Site

    • One processing site
  5. 05

    Shift

    • One shift on one line
  6. 06

    Measures

    • Net input and output
    • Yield
    • Labour productivity per stage
    • Rejects
Figure 03 — The path from a daily summary down to a single shift.

Architecture

A separate analyst layer, reading the same record.

The application needs to be very good at collecting, validating and structuring production events. Analysts need something quite different. Serving both from one interface tends to produce a tool that does neither well.

The transactional store therefore remains the operational source of truth, while a separate analyst layer publishes cleaned fact and dimension tables from approved fields only: batch intake, production, batch usage, cut output, returns, rejects and staff counts, alongside their reference dimensions. Blank and gap rows are removed on primary keys and field types are standardised on the way through. Cross-period reporting then belongs in a business-intelligence layer reading that clean model, rather than in an operator interface that widens every time someone asks a new question.

Portability

The domain model documented apart from the tools running it.

Phase 1 runs as a low-code capture layer on the client's existing spreadsheet environment. That is a sensible way to get a working pilot onto the floor quickly. It also becomes very difficult to leave if the business logic exists only inside undocumented screens and formulas.

So we treated documentation as part of the engineering rather than as something written afterwards. The domain model is recorded independently of the tools running it: entities, relationships, formulas, actions, views, automation, validation and test criteria, written to be sufficient either to rebuild the current application or to implement the same behaviour in a conventional stack. Tables map to relational tables, references to foreign keys, virtual calculations to computed fields or database views, validation rules to domain validation, and application actions to command handlers or endpoints. A PostgreSQL schema and API contract exist as future-state design.

No migration has taken place, and none is promised here. The point is that a fast first deployment does not get to decide the architecture that follows it, and that nobody will have to rediscover this factory's business logic from scratch in order to move.

Status

Where the pilot stands today.

Position as of September 2026.

The latest version is on the factory floor and under operational testing. Issues raised in earlier rounds, including KPI display and daily-summary behaviour, have been resolved and returned to users for verification. Early feedback has been encouraging, but full pilot acceptance remains the honest threshold before we say the digital workflow has replaced paper.

Next

Finishing the pilot, then building on the same foundation.

The immediate priority is completing pilot testing and resolving the remaining edge cases on the floor. After that, the existing yield and productivity reporting can be rebuilt on the clean analytical layer, deeper validation and exception monitoring can follow as operational history accumulates, and the documented domain model can move to a SQL-backed application if scale eventually calls for it. The technology may change. The production model should not have to be worked out again.

Build with Vaarde

Complex operations deserve better software.

Tell us how the operation works today. We will come back with what we think the system should hold, and what it should be telling you by the end of each shift.

What gets written down, what gets re-entered, and where the record stops being trusted.