Skip to content
All case studies
CompletedPriority: UrgentNov 2025 – Feb 2026

Data Cleansing & Onboarding

Duplicate and incomplete restaurant records were quietly breaking sales, segmentation and AI labelling. Fixed the legacy data, then closed the door behind it.

My role
Project lead, PRD author
Team
Product (lead) · Backend · Growth · Commercial · Support
Stack
Odoo · Fuzzy matching · Webhooks · Instagram Graph API · AI enrichment
  • 99%

    Target data accuracy

    Active restaurants in Odoo

  • −50%

    Support load

    Record-confusion tickets

  • 20

    Tickets shipped

    Tracked in Linear

  • 0

    Free-text addresses

    Canonical zones only

01

The Problem

Rapid B2B growth had filled Odoo with duplicate, inconsistent and incomplete restaurant records. A commercial rep standing outside a venue could not reliably tell whether it was already in the system. Growth could not match external intelligence to internal records, so segmentation and AI labelling ran on unreliable input.

Meanwhile the signup flow was the source of the mess: free-text addresses and optional-everything fields meant every new account risked becoming another duplicate.

  • Duplicates on restaurant name + area, with no reliable de-dupe check
  • Free-text location entry producing unmatchable address data
  • Segmentation and AI enrichment degraded by dirty input
  • Manual support effort spent reconciling records by hand
02

The Architecture

Three tracks running in parallel: cleanse what exists, harden the front door, and keep it clean automatically. Automation and pragmatism drove coverage — manually correcting every legacy record was an explicit non-goal.

  • One-time cleansing: fuzzy match on restaurant name + area, merge, then enrich missing fields.
  • Phone verification as the authentication anchor for every new account.
  • Instagram handle as the business-identity signal — skippable, but the account stays flagged unverified pending a manual call.
  • Searchable multi-select of canonical cities and zones. No free-text location entry anywhere in the onboarding UI.
  • Branch count inferred from selected zones rather than demanded at signup.
  • Scheduled nightly job scanning for new duplicates, suspicious fields and critical missing data.
  • Save-time block: a clear name + area duplicate cannot be written.
  • Audit log on every merge and edit, visible to the internal team.
TrackMechanismOwner
Legacy cleanupFuzzy match, merge, enrichBackend + AI enrichment
PreventionPhone → Instagram → canonical zonesProduct + Mobile
Ongoing integrityNightly scan + flag for reviewSupport / Commercial
03

The Execution

20 tickets in Linear, priority Urgent, sequenced so prevention landed before the bulk merge — otherwise the cleanup would have been re-polluted while it ran.

  • Built canonical city and zone master lists, kept in lockstep with platform location changes.
  • Rewrote the signup flow: phone verification, then Instagram, then zone multi-select — no address, no documents.
  • Added real-time de-dupe checks between the customer app and the Odoo data store via webhooks.
  • Shipped a lightweight flag-for-review workflow so commercial and support could correct records without engineering.
  • Ran the merge in batches with audit logging, so any bad merge stayed reversible.
  • Rolled corrections out without disrupting live internal workflows — a stated project risk.
04

The Impact

Data stopped being a hurdle and started being usable input. Field reps can search a name and area and trust the answer; growth can match external intelligence to internal records.

  • Target of 99% accuracy and uniqueness for active restaurant records.
  • Roughly half the manual support workload on record confusion removed.
  • Segmentation by cuisine, location and menu intelligence unblocked.
  • Signup friction reduced rather than increased — phone plus Instagram plus zones, in seconds.
  • Designed to hold at 10x current data volume with batched scheduled jobs.

The hard cases

  • Common restaurant names — a 'Grill House' in every zone defeats naive matching.
  • Blocking obvious duplicates without adding customer-facing friction.
  • Weak social footprint venues that legitimately have no Instagram presence.

Source: Linear — Development › Completed projects export