Turtini

Prove the Salesforce migration is complete before you cancel

Do not cancel a Salesforce contract on the strength of an import that reports its own success. Turtini reconciles instead: it counts both sides independently and shows you whether they balance.

WHAT RECONCILIATION MEANS HERE

After an import, Turtini reads your Turtini records BACK OUT and matches them to the Salesforce ids in your export. The number you see is the count of records that are actually there -- not a tally the import kept while it was running. Every row in the export lands in exactly one bucket:

• present -- a Turtini record carrying that Salesforce id exists right now
• skipped -- deliberately not imported, with the reason (a module is off, a name-only duplicate)
• could not be mapped -- no Turtini shape for it, with the reason (no name, no id, no store for products)
• failed -- attempted and threw, with the error message

When present + skipped + could-not-be-mapped equals the number of rows in the export and nothing failed, the migration is balanced and the report says so plainly: "Salesforce had 4,412 Account records; 4,412 exist here."

THE BUCKET THAT MATTERS MOST

"Unaccounted for" means a record was planned, reported no error, and is not there. That is the only kind of loss a self-reported count can never show you, and it is why the check reads your data back instead of trusting the run. If anything is unaccounted for, the report tells you not to switch Salesforce off yet.

WHERE TO SEE IT

The result appears on the migration card on /setup/migrate as soon as the import finishes. To re-check later, re-upload the same export and run the reconcile command -- it performs no writes, so you can run it as often as you like.

IF SOMETHING IS MISSING

The report names the failed rows and their error messages. Fix the cause -- a module that needs turning on, a store that needs creating, a row missing a name in Salesforce -- and upload the same export again. Records already imported are updated rather than duplicated, so a second pass only fills the gaps.