1,032 investor records consolidated from broker lists into a single canonical Investors object
Anker Capital had years of investor relationships fragmented across broker-specific lists in their CRM, with deal values stuck inside list entries instead of on actual deal records. We consolidated the data, fixed the schema, and rebuilt the views — without losing a single broker attribution along the way.
1,032
Investor records consolidated
~1,200
Deal records repaired
~5
Days to delivery
0
Data lost in migration
The situation
Anker ran their entire investor network out of broker-tagged lists in Attio. Each broker’s investors lived in a separate list with their own ad-hoc attributes; deal values were stored as fields on list entries instead of on the underlying Deal records. Three real problems came out of this:
- Reporting was impossible. No single answer to “how many investors do we have, total?” because the same person might appear on three broker lists with three different cleanliness levels.
- Deal value lived in the wrong place. Currency type collisions and field-on-list-entry storage meant deal-value rollups were unreliable.
- Broker attribution was fragile. Tracking which broker introduced which investor relied on which list a record was sitting in — easy to lose in any migration.
What we built
A clean 5-phase migration with full backups and broker attribution preserved end-to-end.
Phase 0 Discovery + full CSV backup of every list and object
Phase 1 Schema repair add `broker` attribute, fix currency types
Phase 2 Investors migration 1,032 records, broker tag preserved
Phase 3 Deals migration ~1,200 records, deal_value moved off list entries
Phase 4 Broker-filtered views per-broker views on Investors + Deals
Phase 5 Cleanup spot checks, archive source lists, walkthrough
Phase 0 — Discovery & Backup
Full export of every list and every Investor / Deal record to CSV before touching anything. The migration could be re-run or rolled back at any point.
Phase 1 — Schema repair
- Added a
broker(select) attribute to both the Investors and Deals objects, populated with the full broker list. - Resolved the deal-value currency type collision — the new
deal_amount(number) field pluscurrency_codegave clean reporting without losing the typed-currency UX.
Phase 2 — Investors migration (1,032 records)
For each broker list, every entry was checked against the Investors object: existing records were updated with any missing data and tagged with the right broker; new records were created with broker attribution baked in from the start. Every change logged.
for each broker_list in source:
for each entry in broker_list:
investor = find_investor(entry.email)
if investor:
patch(investor, missing_fields_from(entry))
patch(investor, broker = broker_list.name)
else:
create_investor(entry, broker = broker_list.name)
log(action, broker_list.name, entry.id)
Phase 3 — Deals migration (~1,200 records)
Same pattern: pull deal values off the list entries, write them onto the Deal records with currency code intact, set the broker attribute. No deal data was ever the source of truth on a list entry again.
Phase 4 — Broker-filtered views
Each broker got their own filtered views on both Investors and Deals — so the day-to-day workflow (“show me everyone Broker X has introduced this quarter”) still works, but the underlying data is now centralized.
Phase 5 — Cleanup
Spot checks across every broker’s data, removal of broker licenses no longer needed, archive of source lists only after client confirmation, and a walkthrough call.
Outcome
- 1,032 investors now live as a single canonical object, not 12 fragmented lists.
- Every deal value is on the deal record where it belongs, with currency intact.
- Broker attribution preserved for every single record migrated.
- Reporting unblocked: one query answers “how many investors total” or “deal flow by broker this quarter”.
Why this matters for placement-style funds
Broker networks are messy by nature — every introducer keeps their own list, every list has its own conventions. The fix isn’t to ban the per-broker view (you still need it for daily work). The fix is to make sure the data lives in a clean canonical model and the per-broker view becomes a filter on top of that, not the source of truth. Migrating in that direction is straightforward — but only if every step is logged and reversible. We don’t touch production data without a backup that can roll the entire migration back.
"We had a really good experience working with Nacho. He understood the assignment and delivered in due time. Looking forward to working with him again."