Case studies/IES Limited
CASE 03Daily MI alerting
20 days→30 min

A quote-funnel collapse took IES 20 days to notice. Now it takes 30 minutes.

Around 50 people received a 25-page MI pack every morning, and nobody read all of it. Ovidius built a system that reads every page, every working day, and tells the handful of people who need to act what moved, before noon.

Time to detectionEvery working day
Then20 working days
Drop startsSomeone connects it to a cause
NowOne lunchtime window
11:30Pack lands
2.7 minMedian ingest
12:00Alerts in Teams
11:3011:4011:5012:00
14 metrics4 brands6 Teams audiencesNo human in the chain
Client
IES LimitedGibraltar-registered travel insurance group
Scope
Four travel insurance brandsUK, Ireland and Australia
Problem
One 25-page Excel pack, around 50 readers17 hand-maintained worksheets
Built with
n8n, Supabase, OpenRouterMicrosoft Graph, Streamlit
Audience
Six Teams audiencesFinance, trading, marketing, operations
30min
Pack to alert

11:30 in, 12:00 out, unattended. Median ingest 2.7 min, p90 3.0 min.

1,751
Metric evaluations

38 working days, four brands, 116 cards sent.

34
Threshold changes

Made by IES in six weeks. Zero developer tickets.

4of 4
Replayed incidents caught

Every in-scope incident with a baseline available.

01
The challenge

The information was all there. A genuine movement could still sit in plain sight for weeks.

Daily trading, pricing and marketing decisions across four brands traced back to one MI workbook, rebuilt by hand every morning and emailed to around 50 people. Most readers got five or six pages in. The pack had no way to say which of its 14 metric areas had moved.

25 pages14 metric areas50 recipientsEvery working day
Lost time

Twenty days to notice a drop

A significant drop in the quote funnel took the business 20 days to pick up. That was the time to notice it, before anyone began diagnosing it.

Noise

Single days hid real variance

Each day was compared to target and prior year one at a time, and the swings were wide enough to bury a genuine trend.

Misdiagnosis

No outside context

With no competitor or macro context attached, an external market shift could read as an internal failure.

The old way: six manual steps, met at month-end

02
The solution

The maths lives in the database. The model is only allowed to explain it.

Every figure is a PostgreSQL view. n8n reads the result and decides who needs to know. The language model receives finished numbers and writes a sentence around them. Nothing calculates in two places.

In
OneDrive MI packThe same workbook IES already produced. No change to how finance works.
n8n watcherPolls OneDrive, resolves which brand the pack belongs to, lands 17 worksheets into mirror tables.
Control CentreStreamlit app where IES sets each metric's band and spike sensitivity.

Supabase / PostgreSQL The source of truth

14 headline metrics7, 14 and 30 working-day rolling averages, calculated in database views, never in workflow logic.
Band and spike testsEvery metric checked against its expected range and against its own daily volatility.
Append-only historyEvery evaluation logged, flagged or not, with the band, the move, the spike score and the channels that received it.
23tables
16views
1schema
Out
OpenRouter modelHanded finished numbers, asked for a sentence. A verification step names any figure it was not given.
Microsoft GraphSummary first, then prioritised cards drip-fed in order.
Six Teams audiencesRouted by brand and by sensitivity, in place of one 50-person email.
The database decidesLatest reading, rolling averages, band limits, the move and the spike score are all database values.
The model describesThe narrative, and outside context in its own clearly labelled block, so external and internal figures never mix.
11:30

Pack detected

n8n polls OneDrive and resolves the brand. Automatic.

+2.7 min

Landed and typed

17 mirror tables, flattening views. Median time.

In the database

Recalculated

14 metrics, 7/14/30 working-day rolling.

Both directions

Evaluated

Expected-range band plus spike test.

Guarded

Explained

The model writes the narrative behind a numeric guardrail.

12:00

Delivered

Summary first, then cards to six audiences. Fixed, UK time.

03
The detection logic

One test catches the drift, the other catches the crash, so both run every day.

Both tests fire in either direction, so an unusually good movement surfaces as readily as a bad one. The spike test calibrates to each metric's own volatility, so a naturally jumpy metric is not flagged every day.

Daily value7-day averageExpected range
Expected-range band
Spike test

Schematic. The shapes show how each test fires and are not IES data.

Expected-range bandSpike test
Watches7 and 14-day rolling averagesToday's move versus yesterday
Fires whenA rolling average sits outside its bandThe move exceeds 2.75 SD of the trailing 20 working days
CatchesSustained driftA sharp one-day break the average hides
Card reads“Outside Expected Range”“Unusual Daily Movement”

IES sets the band per metric in the Control Centre. The 2.75 SD spike sensitivity is adjustable per metric too.

04
Deep dive

The guardrail that stops the model reporting a number nobody calculated.

For a finance audience, a hallucinated figure is worse than no summary at all. Every field on this card is a database value: latest reading, rolling averages, band limits, the move. The model writes the sentence around them, never the numbers inside them.

A verification step names any figure the model was not handed. Macro and competitor commentary is rendered in a separate, labelled block, so outside context and internal figures are never conflated.

⚠ OUTSIDE EXPECTED RANGE: BRAND A2026-08-26 11:01 UTC
AMT Conversion
2026-08-25 · Brand A
Latest value
33.9%
Recent average (7/14 days)
35.1% / 34.7%
Expected range
26.8% to 34.6%
Moved (recent average → latest)
35.1% → 33.9% (−1.20 pp, −3.4% relative)
Status
Above expected (7-day)
Change since yesterday
Within normal range
What this meansBrand A AMT Conversion. Its 7-day average (35.1%) is above the expected range (26.8% to 34.6%). It moved from 35.1% (recent average) to 33.9% (latest), a change of −1.20 pp, −3.4% relative. Recommend confirming whether this reflects a genuine change or a data issue.
Single-metric breach card as delivered to Teams. Real system output: brands renamed, figures scrambled.
5

Outside expected range

51

Within range, evaluated and logged

2

Unverified figures, declared rather than hidden

The daily briefThe summary lands before the individual cards. It opens with the count, names the largest anomaly, then works down. When the model put two MI numbers in its narrative that were not in the input data, the brief said so at the top and asked for verification before distribution.
05
Detection win

The band said in range. The spike test said one call in five went unanswered.

AUG10

One brand's sales answer rate fell to 81.7% in a single day.

The seven-day baseline was 95.1%. The rolling average never left its band, so band-only detection would have reported nothing. The spike test scored the move at z = −11.65 and routed the card to the two analysis teams by noon.

Same pattern on 1 July: a second brand's visit-to-web-call at 0.0155 against a 0.0938 baseline, −83.5%, z = −11.51, again inside the band.

Sales answer rate, one brand
Expected-range band (illustrative position)95.1% seven-day baseline81.7% on 10 AugAverage stays in bandSpike test fires
81.7%On the day
95.1%Baseline, in band
−14.0%Single-day move
z −11.65Spike score
06
The obstacle

Backtesting showed the bands alone would have missed a one-day collapse entirely.

IES supplied dates where they knew something had gone wrong. Replayed against them, the rolling bands handled drift well and slept through a single-day shock: a system outage on 11 May cut one brand's call-to-sale by 38.1% while the 7-day average stayed inside its band. So Ovidius added the spike test.

3

Caught by the band

1

Caught by the spike test only

0

Missed with a baseline available

2

No baseline yet: the incident fell in the first days of data

2

Outside the 14 contracted metrics

4 of 4 incidents both in scope and with a baseline available were caught.Incident dates supplied by IES; the replay is Ovidius's.
The band needed a partnerRolling averages are built to ignore a single bad day. That is exactly what makes them good at drift and blind to a crash, so the spike test runs beside them on every metric.
Then the bands were too loudBands calibrated on 2024 data flagged almost every day. IES reloaded thresholds across six months of current-year data and widened the bands themselves, in the Control Centre, without Ovidius.
07
Alert volume

1,751 evaluations, 116 cards, and eleven days that flagged nothing at all.

An alerting system that fires every day gets muted. The share of evaluations that breached, week by week, from the first two brands through all four.

Weekly breach rate

Two brands, 140 evaluations a weekFour brands, up to 280
View as table
Week ofBreach rateBrands
8.3%

Breach rate across 38 working days

11 of 38

Days with no flag at all, the first on 8 July

34

Threshold changes made by IES, no tickets raised

Today was the first day we got it to not flag once, which was really good, which is what we've been trying to get to.
Commercial Finance · IES Limited
08
Handover

The business tunes the thresholds itself.

Finance owns what counts as normal. The Control Centre lets IES move a band, preview its impact against recent history, and save it with their name on the change. Drag the sensitivity to see the band respond.

Threshold Editor

Adjust a metric's threshold band and preview the impact before saving.

Brand A
AMT Conversion

Current: band centre 30.7% · sensitivity ±3.9 pp → flags below 26.8% / above 34.6% · tested on the 7-day average · spike 2.75σ

7-day 35.1%
20%30%40%
Save new threshold

Recreation of the IES Control Centre, using the figures from the breach card in chapter 04.

Five views, one sourceDashboard, editor, threshold history, alert history and metric overview all read the same Supabase schema the alerts come from.
Append-only audit trailEvery threshold change is recorded with who made it, from when and to when.
Zero tickets34 self-served changes in six weeks, none of which needed a developer.
09
The results

Every metric evaluated by noon, across four brands.

Brand A

Alerting since 16 June

38

breaches surfaced

Brand B

Alerting since 16 June

51

breaches surfaced

Brand C

Joined week of 3 August

53

breaches surfaced

Brand D

Joined week of 3 August

31

breaches surfaced

Figures cover 24 June to 25 August 2026, working days only. Calculations were validated against IES's own source files before handoff. Timings and counts are Ovidius-instrumented from the alert history. The 20-day figure and the 50-person distribution are IES's own account. Brand names are withheld.

Stackn8nSupabase / PostgreSQLOpenRouterMicrosoft Graph APIStreamlit

What is sitting unread in your reporting pack?

Bring the report everyone receives and nobody finishes. In a discovery call we work out which numbers should alert whom, and what it takes to build.

Owen, CEO of Ovidius AI
OwenCEO · sales and scoping
Jason, COO of Ovidius AI
JasonCOO · audit, ship and run
Book a Discovery Call30 minutes with Owen and Jason. You bring the process.