CRM Rescue · Local-first internal tool

CRM cleanup where every change can be explained

CRM Rescue takes a messy CRM export and walks an operator through mapping, validation, and duplicate review — producing clean data plus an audit trail, without ever contacting a lead or touching the source CRM.

The problem

What kept going wrong

Every operations team eventually inherits a CRM export full of duplicates, missing owners, stale deals, and half-filled fields. The usual options are bad: clean it by hand for days, or run a tool that "fixes" things silently so nobody can say why two contacts became one.

Silent merges and opaque "lead quality" scores don't make data trustworthy — they just move the doubt somewhere you can't see it.

Who it's for

Who would use this

Sales operations and small-business teams using Salesforce, HubSpot, or spreadsheet-based tracking who need to repair an export before a migration, a campaign, or a report — and need to show their work afterward.

The build

What I built

A local-first web application that guides one operator through the whole cleanup: import a CSV, map its columns to a standard schema, run rule-based validation, review duplicate candidates with evidence side by side, and export clean data plus a complete change history.

Salesforce and HubSpot are supported as mapping presets. The deterministic core is complete without AI — there is no model, no scoring black box, and no network dependency.

The workflow

Six steps from raw export to an audit trail

A six-step operator journey. The three screenshots below show the main screens used at steps 1, 3–4, and 5–6.

  1. Import a CSV and map the columns

    Pick the export format, load the file, and map each source column to the standard schema. A preview shows sample values so mapping is a decision, not a guess.

  2. Validate and surface exceptions

    Plain, predictable rules check emails, phones, dates, owners, and stages. Invalid rows stay visible with rule codes — nothing is silently dropped or corrected.

  3. Review duplicate candidates

    The tool generates candidate pairs with the matching evidence spelled out: which fields matched, and how confident the rule is. Scores create review items — they never merge anything.

  4. Decide: merge or keep separate

    Each pair needs an explicit confirmation, and each decision lands in the audit trail. In the demo, a person resolved all six candidates: two merges, four kept separate.

  5. Check the pipeline's health

    Attention flags highlight records with missing owners, stale activity, or no next step — described as operational next actions, not a mystery score.

  6. Export the results and the audit

    Cleaned CSV, change audit, and a quality report — reproducible, so rerunning the same inputs gives the same outputs. A local run can be deleted entirely when you're done.

Worth a closer look

The most useful parts

  • Evidence-first duplicate reviewCandidates show both records side by side with exact reason codes (name match, email match, phone match) so the decision is informed, not blind.
  • A real audit trailEvery normalization, score, and merge decision is recorded with its reason — the export includes the history, not just the outcome.
  • Local by designRuntime CSVs, the SQLite database, and exports never leave the machine. The verified browser test observed zero non-loopback network requests.
  • Reproducible outputTwo independent demo generations produced byte-identical manifests — cleanup you can rerun and get the same answer.

The real screens

Three screens across the six-step workflow

These three views show the operator's main touchpoints: import and mapping, duplicate decisions, and final review with exports and an audit trail.

Technical verification

What I tested

Release evidence from the local verification run — synthetic fixtures, not customer data.

24 → 22synthetic rows in, active records out (6 duplicate candidates resolved)
12 + 4backend tests (91% configured coverage) + frontend tests
0axe accessibility violations in the tested import and audit states
0non-loopback network requests observed in the browser test

The repeatable demo processes 24 invented rows across Salesforce-style, HubSpot-style, and generic fixtures. A Chromium critical-flow test passed, dependency audits (npm and pinned Python) reported no known vulnerabilities, and two independent demo generations matched SHA-256 exactly. A backend test also sends a contact-data canary through the pipeline and asserts it never appears in application logs.

Current scope

  • The portfolio example uses invented records. A real engagement would begin with a sanitized sample and rules tailored to the team's workflow.
  • Designed for one local CSV at a time, with common North American phone formats and explainable exact/block-based duplicate matching.
  • Every merge requires a person's approval. The app exports cleaned files and an audit trail; it does not write changes back to a CRM.
  • This is a single-operator local tool, not a hosted multi-user service.