A.O.Akinloluwa Olumuyide, home

ShippedDemo client

n8n workflow · 2026

AI operations reporting

Sales, delivery and people data in one daily report: 27 metrics computed in code, each checked against ground truth, then explained by Claude.

The number

27

metrics per period, each checked against numbers I worked out separately

Client
Koya Talent
Role
Built end to end: spec, build, deploy
Timeline
2026
Stack
n8n · Google Sheets · Airtable · HTTP API · Supabase · Claude Sonnet 4.5 · Gmail · Vercel

Watch the walkthroughLive dashboard (opens in a new tab)

the walkthroughWatch on Loom (opens in a new tab)Open the live dashboard (opens in a new tab)

The problem

Sales lived in a spreadsheet, delivery in Airtable and people data behind an API. The founder needed one honest picture of all three, every morning.

The last 30 days, the last 90 days, the year so far, or any range they pick. Each compared with the right period before it, and explained in plain words.

  • The AI explains, never calculates
  • Unknown is never zero

What I asked first

The brief left these open. I answered each one in the workflow itself, where it can't drift.

  1. What date is "today" for this data? The data ends on 30 June 2026. Every period counts back from there, so the numbers follow the data, not the calendar.
  2. What should year to date compare against? The same months last year. Against the last six months, a seasonal dip looks like a performance problem.
  3. What counts as an active project? Any project running during the period, not only those that started in it. Otherwise a recent period shows zero active projects, and zero looks real.
  4. Who counts in headcount? Worked out from start and exit dates, never the status field. Some records marked "Active" hadn't started yet.
  5. What if a source fails? Its numbers show as unknown, with the reason. A failed source reported as zero would read as fact.
  6. What does the model get to see? The worked-out numbers and what they're compared against, never the raw rows. Raw rows invite it to do arithmetic.

How it runs

AI operations reporting · 33 n8n nodes in 9 stages
  • Start
  • Tool
  • Stored
  • Code
  • Check
  • AI
  • Result
  • Error
  1. 01, Trigger:

    Every morning, or on request

    Schedule, webhook

    6am daily, or any range from the dashboard.

    • Schedule Trigger
    • Webhook: Custom Range
    • Run Config
    • Close Abandoned Runs
  2. 02, Step:

    Pull three sources

    Sheets, Airtable, API

    Every date checked. Every problem logged.

    • Fetch Sales
    • Fetch Delivery
    • Fetch People Ops
    • Clean Sources
  3. 03, Data:

    Store the clean records

    Supabase

    One source of truth.

    • Upsert Sales Records
    • Upsert Delivery Records
    • Upsert People Records
  4. 04, Code:

    Work out 27 metrics

    Code

    Each against the right period before it.

    • Compute Metrics
  5. 05, Logic:

    One period at a time

    Loop

    Nothing moved? Reuse the last analysis.

    • Create Run
    • Loop Over Periods
    • Find Prior Insight
    • Decide Reuse
    • Reuse Insight?
  6. 06, AI:

    Explain what changed

    Claude Sonnet 4.5

    Sees the worked-out numbers, never raw rows.

    • Build Analysis Prompt
    • Claude: Analyse
    • Claude Sonnet
    • Parse Insights
  7. 07, Data:

    Save the report

    Supabase

    Metrics, warnings and insights, in one go.

    • Build Supabase Payloads
    • Insert Metrics
    • Insert Warnings
    • Insert Insights
    • Complete Run

    Then: step 5 (next period); step 8 (done).

  8. 08, Output:

    Email the founder

    Gmail

    One email per run, even when all is well.

    • All Periods Complete
    • Fetch Run Digest
    • Build Digest
    • Send Digest
    • Record Alert Sent
  9. 09, Error:

    Close a failed run

    Code

    Never left showing 'running'.

    • Mark Run Failed
    • Close Failed Run

Enforced, not requested

  1. The AI never does the maths Every number is computed in code. Claude only explains them.
  2. Unknown is never zero A number that can't be computed says why. A failed source is never reported as zero.
  3. Bad dates don't slip through A date like 30 February is rejected, not quietly moved into March.
  4. Nothing is dropped silently Every problem in the source data is logged, with what it affected.
  5. Small samples are flagged A rate built on fewer than five records is marked low confidence.
  6. No paying twice for one answer If the numbers haven't moved, the last analysis is reused.
  7. No run left hanging A run that fails is closed and marked failed, never left "running".
  8. Good news looks like good news Each metric knows which way is better, so rising costs never look like rising revenue.

The thing that nearly got past me

Incident

Marketing spend, counted once per row

Marketing spend in the sales sheet is a monthly figure, repeated on every row of that month. Adding the column up, the obvious move, overstated spend by roughly the number of rows in each month. Cost per lead would have been off by the same factor, on a report a founder reads to decide where money goes.

The fixOne figure per month, pro-rated when a period covers only part of it.

In numbers

  • 27

    metrics per period, all computed in code

  • 3

    sources in one report: sales, delivery and people

  • 1

    email to the founder at 6am, even when nothing's wrong

  • 4

    views: 30 days, 90 days, year to date, or any range

  • 0

    AI calls when the numbers haven't moved. The last analysis is reused.

  • 5

    records at least before a rate is trusted. Fewer is flagged.

From the workflow itself.

What it refuses to do

  • Do maths with the AI Claude only sees numbers worked out in code.
  • Report a failed source as zero Its numbers show as unknown, with the reason.
  • Send raw rows to the model It gets the worked-out picture, not the data.
  • Stay quiet when nothing's wrong A clean run still sends a short email. Silence looks like a workflow that stopped.

What I took from it

A number I can't compute is unknown, with a reason. Never zero. A zero reads as a fact.

The limit I'd fix first

if I did it again

  • AI cost is sometimes a guess. When n8n doesn't pass on the model's usage, the cost is estimated from the length of the text. It's labelled as an estimate, but I'd rather measure it.

Check it yourself

Contact

Got a messy problem?

Tell me what's broken, or what your team keeps doing by hand. Hiring? Tell me about the role. Or just book a call.