In September I worked with a customer on a data quality problem and recorded a short demo of the general case. Contacts come out of HubSpot, get cleaned and deduplicated, and only the rows that pass land in Supabase.
The interactive demo is on the original post. Here is a separate 6-minute live build of the same flow; it matches duplicates with fuzzy (Jaro-Winkler) matching rather than the exact email match described below.
The problem the customer brought us
Their sales team lives in HubSpot. Their product and reporting live on a Supabase database. A nightly job copied contacts from one to the other, and it copied everything: the same person three times under three spellings of their email, trailing spaces in names, companies typed in four different ways, and records with no usable email at all.
None of that looks dramatic in a CRM. It looks dramatic in the results. Duplicate contacts get counted twice in pipeline reports, two reps reach out to the same person in the same week, and the product team builds features for a customer base that is smaller and cleaner than the one the numbers describe. Bad data does not stay in the database. It shows up in decisions.
What the demo shows
The recording is a walk through the general case, not the customer's data. It uses the Spanish version of the Neblex workspace, which is the language the customer works in; every screen in Neblex Integration Fabric is available in English, German, and Spanish.
- Pull the contacts from HubSpot. The HubSpot connector reads contacts with the properties the customer cares about. The flow can run on a schedule or start when a contact is created or changed.
- Clean the rows. Emails are lower-cased and trimmed, names lose their stray spaces, and company names are normalized so "Acme", "ACME Inc" and "acme, inc." stop being three companies.
- Remove duplicates. The Remove duplicates step matches records on the normalized email and drops the repeats. It can also keep every record and tag each one as unique or duplicate, with a pointer to the match, so a review branch can look at the borderline cases.
- Check quality before writing. The Assert data quality step checks the batch against the rules the customer chose, such as required fields and an email address on every row. If a rule fails, the run stops with the failing records and the rule named, so nothing questionable reaches the database and someone can fix the source in HubSpot instead of quietly inheriting the problem downstream.
- Insert into Supabase. Only the rows that passed are written to the Supabase table, with the run recorded end to end.
That last point is the one the customer cared about most. Every run shows each step, what stopped the run and why, and how many records were written; with run data kept for replay, the records themselves are there too. If a number looks wrong in a report, the answer is in the run history, not in a guess.
Why we clean at the boundary
It is tempting to fix data quality in the database with a cleanup script that runs once a month. It never stays fixed, because the source keeps producing the same problems. Cleaning at the boundary, in the flow that moves the data, means every record is checked every time and the source system gets the feedback it needs.
It also means the cleanup is not a separate tool. Bulk data processing and data sync and change data capture run on the same platform, with the same connectors and the same audit trail as everything else. When the customer later wants to push a cleaned company list back into HubSpot, that is another flow, not another product.
What this means for your team
If your reporting and your CRM disagree, the fix is rarely a bigger dashboard. It is usually a clean, checked path from one system to the other, with the failures visible instead of silently loaded.
Frequently asked questions
Does the cleanup change the data in HubSpot?
No. The flow reads from HubSpot and writes to Supabase. When a quality rule fails, the run stops and names the records and the rule, so the team can correct them in HubSpot, and the next run picks up the corrected contacts. Writing corrections back to HubSpot would be a separate flow you choose to turn on.
How are duplicates decided?
By the field you choose, or the whole record. In the demo it is the normalized email address. Matching can be exact or fuzzy with a similarity threshold, and instead of dropping duplicates the step can tag them for a review branch.
Can this run as contacts change instead of on a schedule?
Yes. The HubSpot connector has 46 polled triggers, checked as often as every minute, so a flow can start when a contact is created or changed and check the new record on its way through.
Does it work with a plain PostgreSQL database instead of Supabase?
Yes. Supabase is PostgreSQL underneath, and the same flow writes to any PostgreSQL, MySQL, SQL Server, or Snowflake target through their connectors.
Maria Soria works in customer success at Neblex. Originally published at neblex.com.
