E-commerce · our own US store

A figure somebody had to remember to produce,
now produces itself.

Orders, supplier costs and profit were tracked by hand in a spreadsheet. Every figure needed a person to produce it, and the failures were quiet rather than loud.

Our own operation — a US store we ran, reporting to us every morning from July 2026.

A scheduled run, nobody watching A scheduled run that catches up if a day was missed feeds six independently testable stages, then a duplicate guard, then the report where the team already reads messages. 07:00 · NOBODY WATCHINGScheduled runcatches up if a day was missedSix stages, each testable aloneDuplicate guarda repeat run is a no-opThe report, where you already read messagesIt shows the subtraction, not just the result.
Nobody starts it. Nobody remembers it. It still ran.

Every figure here is a build fact — counted, not claimed. No outcome numbers appear on this site until a client’s system produces one.

  • 257automated tests
  • 10,780lines of production code
  • 6stages, each testable alone
  • Jul–Aug 2026ran unattended
  • dailyran without being started
  • 0customer name, address, phone or email columns fetched
  • no-opwhat a repeated run does
  • 1codebase behind both the report and the dashboard

The run, recorded

1 min 36 sec · one order, from the storefront to the margin report

It went quietly wrong rather than visibly missing. When sourcing fell behind, orders had no cost data, so profit read low — but it still read as a number, so nobody checked it. Manual price lookups drifted, because supplier prices change and nothing flagged the difference. And it only happened when someone remembered, which was not daily.

Six stages replaced it, each independently testable: fetch the orders, map them to products, price the sourcing, append to the ledger, compute the margin, publish the report. It runs on a schedule, catches up if a run is missed, and a repeat is a no-op so a catch-up never doubles a figure.

How it works

The order is the architecture: each stage can be tested without running the five around it.

  1. 01

    Fetch the orders scheduled

    Pulled on a timetable rather than when somebody opens a tab. A missed day is caught up on the next run instead of leaving a hole nobody sees.

  2. 02

    Map to products deterministic

    Every order line resolved to the product actually sold. This is where a hand-built sheet silently mismatches, and where a test is cheap.

  3. 03

    Price the sourcing against live cost

    Supplier cost attached per line. When a supplier rearranged their page, this stage stopped loudly — which is the entire point of it being a stage rather than a lookup someone does by eye.

  4. 04

    Append to the ledger append-only

    Nothing is edited in place. The history of what was recorded, and when, survives the next run — you can go back and see what the number was on the day it was published.

  5. 05

    Compute the margin shows the subtraction

    Revenue, cost, fees, and what is left. It always shows the subtraction rather than only the result, because a profit figure you cannot take apart is a figure you cannot check.

  6. 06

    Publish duplicate-guarded

    The report arrives where we already read messages, and the dashboard is generated from the same code that produces the report — so the two cannot disagree. Running it twice does nothing.

Why the dashboard exists at all

A partner asked “yesterday, how much profit did we have — where is that written?” and a chat message could not answer it. The page and the report are the same code, which is the only version of a dashboard that cannot quietly disagree with the number it came from.

Six stages, top to bottom Orders are fetched, mapped to products, priced against supplier data, appended to a ledger, reduced to a margin, and published as a report and a dashboard. Each stage is independently testable, and the publish step is duplicate-guarded so a repeated run does nothing. 01 Fetch orders02 Map to products03 Price the sourcing04 Append to ledger05 Compute margin06 Publishreport + dashboard, same codeDuplicate guard — a repeat run is a no-opReport, where you already read itCustomer name, address, phone and email columnsare never fetched. A test asserts it.
Six stages. The last one is guarded, so running it twice does nothing.

What you get

Every morning

The number is there before you are

Nobody opens a spreadsheet, nobody retypes a figure, and the answer to “how did yesterday go” exists before the question is asked.

Loudly

It fails where you can see it

A broken supplier page stops the stage and says so. The failure mode that costs money is the one that keeps producing a plausible number, and that is the one this design removes.

Never twice

A catch-up cannot double a figure

Miss a day and the next run fills it. Run it twice and the second run does nothing. Both of those are tested rather than assumed.

It ran unattended from July 2026. The store it served is paused for reasons that have nothing to do with the software — the automation is not the part that stopped. That is a fact about our own operation, not a promise about yours.

Want this one walked through against your own numbers? Email info@adapton.io and we will show you the parts that transfer and the parts that do not.

The limits

We publish this rather than claim an unbroken streak, because an unbroken streak is the kind of claim people check.

  • A supplier rearranged a page and the scraper stopped. Loudly, which is the point — but it stopped, and it needed a fix.
  • A scheduled run was missed on one day in August 2026 and the catch-up filled it. Both halves of that sentence are true and both belong here.
  • Customer names, addresses, phone numbers and emails are never fetched. Those columns are not read because the report does not need them, and a test asserts it.
  • It reports on what the store already records. It does not forecast, and it does not tell you what to stock.
  • It is our own store. It is not a client engagement, and nothing here should be read as one.
The columns that are never fetched Customer name, address, phone number and email sit above a refusal line: the reporting code never requests them, because the report does not need them, and a test asserts it. NEVER FETCHED — AND A TEST ASSERTS ITCustomer nameAddressPhone numberEmailThe report does not need them, so the codenever asks. That is cheaper than a policy.
Data minimisation as a build decision, not a policy paragraph.

Next step

Fifteen minutes. We ask three questions and do the arithmetic with your real numbers. If it is not worth automating we will say so on the call.

Send us the details

All case studies · info@adapton.io