Skip to content
Menu
All work

Client projectPrivate

A customer portfolio analysis that rebuilds and checks itself every month

For a European parcel operator, 32 monthly sales exports turned into a workbook, a management summary, a deck and an offline view, with every figure checked before it ships.

Industry
European parcel operator
What it shows
Data analytics, Automated reporting, Verification
Year
2026
Status
Private
Portfolio analysisMonthly run · rebuilt from the raw files · about 26 stepsDummy data32 monthly exportsmonth 32 addedRead three waysall agreeCell checks23 of 23Quoted figures563 of 563Rerunbyte-identical!Narrative guard1 sentence to rewriteMonthly exportsOne file a month, all read again every run1234567891011121314151617181920212223242526272829303132newRead three waysMain readerSQL check pathService mixOne numbers fileevery output is built from itDECK · SLIDE 6 OF 16REVIEW“Growth came mainly fromexisting customers.”Revenue index, previous 12 months = 100Previous 12 months100Last 12 months113new +18existing +9Narrative guard · not supportedNew customers now add 18 points and existingcustomers 9, so the sentence no longer holds.The deck is not saved until the sentence is rewritten.The workbook, summary and offline view are ready.OutputsAll four from the same numbers fileWorkbook14 sheets, live formulaswrittenSummary2 pages for managementwrittenOffline viewsearch any customerwrittenDeck16 slidesheldSummary cells cross-checked~1,800Error cells after recalculation0Monthly update, end to endunder 30 minSHA-256 of every delivered file recorded
Illustration with dummy figures; the client stays anonymous. The run, the check counts and the outputs are the project's real ones.

In numbers

monthly sales exports, rebuilt from scratch on every run
32
summary cells checked against an independent calculation
~1,800
figures quoted in the texts, recalculated from source rows
563
for the monthly update, end to end
<30 min

Figures come from the project’s own files and records.

What changes

The steps people did by hand, and the route the work takes now.

A new month of sales data arrives

Before

  1. Merge the exports by hand
  2. Rebuild the pivot tables
  3. Re-check every chart
  4. Rewrite the deck

With AI

  1. The pipeline rebuilds every output from scratch
  2. Independent checks must agree before anything ships

Workbook, summary, deck and offline view, ready to present

The problem

Management wanted answers that a monthly sales export can hold but rarely gives up easily. Is growth coming from new customers or existing ones? How much is price and how much is volume? How dependent is the business on a few large accounts, and which services are growing or declining? The data sat in dozens of monthly files with changing layouts, and one change of accounting system in the middle of the period.

What we built

A pipeline that answers eleven management questions and three costed proposals from 32 monthly files. One command runs about 26 steps, each in its own process, and publishes nothing if any step fails. Every run starts from the raw files, so nothing carries over by accident from the previous version.

It produces four things from the same numbers: a workbook for analysts, a two-page summary for management, a 16-slide deck, and an offline interactive view with a search for any customer.

Why the numbers can be trusted

Every figure is checked by something that shares no code with the thing that produced it. The raw files are read three separate ways: by the main reader, by a SQL path that exists only to check it, and by a third re-read of the service mix that stops the run if any month, customer and product sum differs. 23 checks compare about 1,800 summary cells against an independent calculation, and the 563 numbers quoted in the written texts are recalculated from the source rows.

Before the first presentation the pipeline was also tested against itself. A backtest on the earlier 11-sheet version of the workbook compared 806,179 filled cells across two runs: 806,173 matched, and all six differences were explained. Two were a tie in a most-common-value calculation being broken at random, now fixed, and four were sentences now generated from the data. It also caught empty text turning into a missing value in the SQL path, which dropped a line. Two forward tests followed, one removing the latest month and one adding a fake month, and they caught hard-coded dates, file names and lists that would have broken the next monthly update.

The last guard is about words, not numbers. If a new month contradicts a sentence in the deck, the run flags it and refuses to save the deck until the sentence is rewritten.

A monthly routine, not a one-off

Updating it takes under half an hour; the two logged monthly runs took 17 and 22 minutes. Add the new file, run it, read the run report and settle any flagged sentences. A follow-on monthly churn report reuses the same building blocks, with two calculation paths that must report zero mismatches, 14 tests on synthetic data and a verifier that checks the workbook.

The system map shows every part of the run and eight journeys through it, from a new month to a failed check, the backtest and where AI was used. It uses generic names, and the client stays anonymous.

Inside a monthly run

Pick a management question to see its answer, add a month and watch the run rebuild and recheck everything, or see how the pipeline was tested to break.

Interactive · 8 journeys

Interactive system map

One new month, read three ways, checked before it ships

28 parts and 8 journeys, from a new file to the four outputs, the checks, the narrative guard and the backtest. Generic part names; the client stays anonymous.

Play 8 journeys, or click any of its 28 parts.

monthly files, read fresh on every run
32
checks over about 1,800 summary cells
23
quoted figures recalculated
563

Explore the map

InteractivePick a question, or add a new month and watch the checks run.
View
The analysis answers 11 management questions and costs 3 proposals. Here are five of the questions, with dummy figures.
Question
Question

How much of the growth is price, and how much is volume?

Answer
Price rose in every segment. Volume fell in Segments C and D, and in D the price rise did not make up for it.
Question

Is growth coming from new customers or existing ones?

Revenue index, previous 12 months = 100. Unconfirmed: customers whose IDs changed with the accounting system.
Previous 12 months100
Last 12 months113
Answer
New customers added 18 points, twice what existing customers grew, and more than covered the 14 points lost or unconfirmed.
Question

How dependent are we on a few large, low-price accounts?

Largest accounts
70%revenue per parcel, against the average across all accounts
Answer
The 10 largest accounts bring 31% of revenue but 44% of parcels: each of their parcels earns 70% of the average.
76%revenue per parcel, against the average across all accounts
Answer
The 20 largest accounts bring 42% of revenue but 55% of parcels: each of their parcels earns 76% of the average.
85%revenue per parcel, against the average across all accounts
Answer
The 50 largest accounts bring 58% of revenue but 68% of parcels: each of their parcels earns 85% of the average.
Question

Which services are growing, and which are declining?

Answer
Services 1 to 3 grow and the rest decline. The two fastest-growing already bring 56% of revenue.
Question

How many customers do we lose each month?

Months 17 to 19: the change of accounting system
Answer
About 1.5% of customers are lost each month. The jump at the system change is mostly customers who came back under new IDs, so they count as unconfirmed, not lost.

A new month arrives

Add the next export and everything is rebuilt from the raw files. One runner, about 26 steps, each in its own process. If any step fails, nothing is published.
Data
Last run: 31 files. Every check passed.Run on 32 files finished. Every check passed.
Run report
3132 files · from scratch
  1. 1 Read three ways
    Every monthly file is read by the main reader, again by a SQL path in DuckDB that exists only to check it, and a third time for the service mix.
  2. 2 Paths agree
    The SQL path recomputes the quoted figures, and the third read must match every month, customer and product sum. Any mismatch stops the run.
  3. 3 Rules
    Products in 17 groups, customers matched across a change of file format, private persons masked.
  4. 4 Numbers
    One numbers file, which every output is built from.
  5. 5 Outputs
    A 14-sheet workbook, a 2-page summary, a 16-slide deck and an offline view with customer search.
  6. 6 Checks
    1. Summary cells against an independent calculation, 23 checks~1,800
    2. Figures quoted in the texts, recalculated, from source rows563
    3. Error cells after recalculation0
    4. Second run byte-identical, SHA-256 recordedYes
  7. 7 Narrative guard
    Every sentence in the texts is still supported by the numbers.Reads the texts once the checks pass.1 sentence flagged REVIEW. The deck will not save.The flagged sentence was rewritten and checked again.
Monthly files
3132
was 31
Growth on the previous year
+11.0%+13.0%
was +11.0%
From new customers
+11 pts+18 pts
was +11 pts
From existing customers
+13 pts+9 pts
was +13 pts
Where the growth came from
Index, previous 12 months = 100
Previous 12 months100100
Last 12 months111113
Narrative guard · slide 6
SupportedWaiting for the runReviewRewritten
“Growth came mainly from existing customers.”
Existing customers add 13 points and new customers 11, so the sentence holds.
“Growth came mainly from existing customers.”
Each sentence is tested against the new numbers once every check has passed.
“Growth came mainly from existing customers.”
New customers now add 18 points and existing customers 9. The new numbers no longer support it.
“Growth came mainly from new customers.”
Checked again against the numbers file: 18 points from new customers, 9 from existing ones.
Sentence
  1. Workbook · 14 sheetsWritten
  2. Summary · 2 pagesWritten
  3. Offline view · customer searchWritten
  4. Deck · 16 slidesSavedWaitingNot savedSaved

Tested to break before the first presentation

Before anyone saw a number, the pipeline was run against itself: two runs of the earlier 11-sheet workbook compared cell by cell, then one run with the latest month taken away and one with a fake month added.
  1. Backtest
    Two runs of the earlier 11-sheet workbook, cell by cell
    806,179cells compared, 806,173 matched
    All 6 differences explained
    1. 2 ties in a most-common-value calculation, broken at random. Now fixed.
    2. 4 sentences, now generated from the data.
    3. Empty text loaded as NULL in the SQL path, which dropped a line. Now normalised.
  2. Forward test A
    Remove the latest month
    −1month
    The window shrank by itself, every check passed, and the guard flagged one sentence
  3. Forward test B
    Add a fake month
    +1month
    Totals matched to the cent, and the guard flagged the new versus existing customers sentence
What the forward tests caught
Assumptions that would have broken the next monthly update. Each was fixed so a new month needs no edits.
  1. Hard-coded period keys
  2. Hard-coded file names and row counts
  3. A hard-coded date range in the SQL
  4. A document block a rerun did not rewrite
  5. Lists typed in by hand
On every run
A second run must produce byte-identical files, and the SHA-256 of every delivered file is recorded.
Monthly churn report
Two calculation paths must report 0 mismatches, and 14 tests on synthetic data and a verifier check the churn workbook.
Dummy segments and values; the client stays anonymous. The run, checks and test results are the project’s real ones.

What it shows

AI made building this fast: Claude helped write and review the code, including the independent re-reads, and the monthly run happens in a Claude session. No model runs inside the pipeline itself; every figure comes from deterministic scripts and checks. The trust comes from the design around it: independent checks, tests that try to break it, and a rule that the story cannot get ahead of the data. The same approach fits any recurring analysis that ends up in front of a board.

Under the hood

  • Claude
  • Python
  • pandas
  • DuckDB
  • openpyxl
  • LibreOffice
  • python-pptx
  • docx
  1. 01Read three ways

    Every monthly file is read by the main reader, again by a separate SQL path in DuckDB that exists only to check it, and a third time to re-sum the service mix. Any mismatch stops the run.

  2. 02Rules

    Products are grouped into 17 families, the same customer is matched across a change of file format, and the names of private persons are replaced while their sums still count.

  3. 03One numbers file

    A single set of results feeds every output, so the workbook, summary, deck and offline view cannot disagree.

  4. 04Outputs

    A 14-sheet workbook whose summaries are live formulas over the raw data, a two-page management summary, a 16-slide deck and an interactive view that works offline.

  5. 05Checks

    23 checks compare about 1,800 summary cells with an independent calculation, 563 quoted figures are recalculated, no cell may show an error, and a rerun must produce byte-identical files.

  6. 06Narrative guard

    Sentences the new numbers no longer support are flagged for review, and the deck refuses to save until they are rewritten.

Want something like this built for your team?

Tell us about the process or the data. We'll reply within two business days with a first view of what we'd build.