Case study / Dubai-based forex broker / 2026
Know what reached customers. See what needs attention.
An internal Next.js console replacing a spreadsheet send-ledger — with role-based access, audit logging and per-message funnel reporting.
01 / What changed
From activity without a record to a system you can inspect.
Before
Campaign state lived in a spreadsheet the automation both read and wrote. It hit rate limits under load, and nobody could say which template failed or why.
After
A relational send ledger, an append-only event log and a console with per-template funnels, failure reasons and access controls.
02 / How it works
Every branch has a reason.
Campaign delivery console
Simplified for publication03 / The decisions
Reliability lives in the details.
- 01
Moved the send ledger into a relational schema with a uniqueness constraint across channel, recipient, campaign and date
- 02
Made dispatch claim-by-insert: the workflow inserts first and only sends if the insert created a row, so duplicates are impossible by construction rather than by check-then-act
- 03
Separated status events into an append-only table fed by delivery webhooks, giving a real funnel from accepted through delivered, read and replied
- 04
Built attribution across three databases in application code rather than cross-database SQL, keeping each connection read-only and independently replaceable
- 05
Masked contact details server-side so raw customer data never reaches the browser, including for read-only share links
- 06
Added a Claude-powered analyst over the campaign data with real guardrails — an access allow-list, a daily query quota, prompt caching to control cost, and a route that shows users exactly what the model can see
04 / What it changed
- Next.js
- MySQL
- NextAuth
- Claude
- Docker
- GCP
- Recharts
The spreadsheet rate-limit failure mode was eliminated entirely
Duplicate sends became structurally impossible rather than merely unlikely
Per-template funnels and a failure-reason breakdown replaced manual reporting
Read-only share links let stakeholders see performance without an account and without exposing contact data
The analyst answers questions over aggregates only — raw contact rows are never sent to the model
What the evidence shows
The console reports operational state — what was sent, delivered, read and replied to. It does not attribute revenue to any single message.
Your next chapter
Can your team see what your campaigns actually did?
Bring one process, one bottleneck or one growth goal. Let’s find a useful next step.
Book a strategy call