The problem
The business lived in 13 disconnected spreadsheets — roughly a million records edited by hand, joined with lookups, quietly hitting row limits. The same customer existed in several under slightly different spellings, so no two files ever agreed. There was no audit trail, no backup strategy, no safe way to grow: one bad paste could lose data nobody could recover.
Separately, call-centre data sat in the telephony provider's database but never reached analytics. The off-the-shelf transfer tool kept failing because the provider enforces a hard limit of two concurrent connections — so reporting was always stale or missing.
What I built
All 13 spreadsheets cleaned, de-duplicated and normalised into one relational schema, then moved onto a self-hosted platform in the firm's own cloud: NocoDB over PostgreSQL, behind a reverse proxy with automatic HTTPS and Google SSO locked to the company domain, daily backups, and a verified restore path. Non-technical staff get a familiar spreadsheet-like UI; the data underneath is finally relational, access-controlled and auditable.
For the call-centre data I replaced the failing transfer with a scheduled job that syncs 27 tables into the warehouse every 15 minutes — single-connection by design to respect the provider's limit, using watermarks for incremental loads and merge-on-write de-duplication, so analytics stay current without ever exhausting the source.
A separate contract panel ties the legal workflow to the sales CRM via webhooks, syncing statuses both ways.
Stack
NocoDB · PostgreSQL · Google Cloud · Cloud Run · BigQuery · Python · Docker · Traefik · Next.js · Express