5,189 companies, 5,807 people, and 1,433 deals migrated with source verification
Pluspartners needed to leave Affinity without turning years of relationship history into an opaque bulk import. We built a replayable migration system, mapped the fund data model, preserved identifiers, and verified the loaded records against the source before handover.
5,189
Companies verified
5,807
People verified
1,433
Deals verified
5.0
Directory rating
The constraint
An Affinity migration is not a CSV import. The source stores people, companies, deals, lists, interaction history, and relationship context in different shapes. Attio has a more flexible data model, but that flexibility creates a decision: what should become an object, what belongs on a record, and what should remain a view.
The second constraint was trust. The team needed to know what moved, what did not, and why. A total in the Attio UI could not be used as the migration count because email sync creates records that never existed in Affinity.
The migration system
We separated the work into five controlled stages:
- Cache the source and preserve immutable exports.
- Map source entities and relationships to the target model.
- Resolve duplicate and identity conflicts before writes.
- Load in dependency order with a write ledger.
- Verify source identifiers and relationships against the loaded workspace.
Affinity cache
→ canonical company/person/deal rows
→ identity conflict queue
→ Attio dry-run
→ production write ledger
→ source-to-target verification
Every loaded source record kept an Affinity identifier. That stamp made the verification query deterministic: count source records with eligible status, then count Attio records carrying the corresponding source ID.
What was verified
- 5,189 companies carried the expected Affinity source stamp.
- 5,807 people were loaded and verified.
- 1,433 deals were loaded and verified.
- 731 LP records were present against 736 source rows, with the difference documented for review.
- Source records that could not be safely matched remained in a review queue instead of being silently merged.
These counts are deliberately not the totals visible in Attio. Live workspace totals include records created independently by email sync.
What changed beyond the migration
The project also moved the firm from a legacy relationship database to an operating model that could support:
- fund and LP relationships,
- pass reasons and deal context,
- Granola-linked meeting history,
- reporting from canonical objects rather than list-specific fields,
- later context-system work without rebuilding the CRM foundation.
Outcome
The migration completed with an auditable path from the Affinity cache to the Attio records. The team received the workspace, review queues, verification outputs, and the logic behind the model. The work can be explained, rerun, and checked without trusting a black-box import.
"We needed to move fast but carefully, in order to migrate our CRM and it was done in a great way, showing proactiveness along the way as well as transparency and visibility of the process."
Stack: Affinity · Attio · Granola