Skip to content

All projects

Lead-to-Pipeline Systems

Synthetic benchmark Synthetic data: Ledgerly

A Salesforce lead lifecycle and routing design, shipped the way a GTM Systems team would: discovery brief, requirements, SFDX metadata, a replay simulator, UAT tests in CI and release notes.

Status
Write-up ready, code not public yet
Relevant to
GTM Systems

Results · Synthetic data: Ledgerly

  • open leads owned by a rep who had left, down to 0 in the replaySynthetic benchmark
  • leads that skipped their account’s active owner, down to 0Synthetic benchmark
  • duplicate leads caught at entry, where there had been noneSynthetic benchmark
  • each named by its UAT ID and acceptance criterionImplementation fact

At a glance

Question
Why do leads end up with reps who left or skip the account’s owner, and what routing design fixes it?
Data
29,447 historical Ledgerly leads (synthetic), replayed in time order.
Compared with
The routing outcomes recorded in the data.
How it was tested
Run every lead through the new rules in time order, with reps joining and leaving on their real dates, and recount from SQL independently.
Result
In the replay, open leads owned by a departed rep went from 2,658 to 0, and leads that skipped their account owner from 965 to 0.
What it doesn’t show
Not deployed to a Salesforce org, so the Apex and flows haven’t been compiled there. The replay shows the rules, not adoption by a sales team.
Lead-to-pipeline admin report with routing outcomes, SLA flags and a data remediation run
Lead-to-pipeline admin report with routing outcomes, SLA flags and a data remediation run

The problem

Open leads sat with reps who had left, leads from existing accounts skipped the account’s owner, and only 3.1% of MQLs became an opportunity within 48 hours.

What I built, in detail

  • A discovery brief measured from the data, requirements with acceptance criteria, and a field dictionary.
  • SFDX source: 28 custom fields, 6 validation rules, 2 record-triggered flows, 3 Apex classes with tests, queues, territory metadata and permission sets.
  • A TypeScript simulator that replays 29,447 historical leads in time order through the same rules, with reps joining and leaving on their real dates.
  • Metadata checks that need no org, including parity checks so the simulator and the metadata can’t drift apart.

How I checked it

  • Every number came from the data twice: SQL during discovery, then independently from the simulator’s replay.
  • Tests were checked by breaking the code. Reversing the account tie-break and the backward-move rule made the matching UAT tests fail.

Limitations

  • Not deployed to a Salesforce org yet, so the Apex and flows haven’t been compiled there. The metadata converts cleanly with the Salesforce CLI.

Where it came from

My website routes every lead by type, area, language and agent into my CRM with the right campaign. This is the Salesforce version, designed for scale. Read the AI CRM case study.

Stack

Salesforce DX, Flow, Apex, TypeScript, DuckDB, GitHub Actions