Most Salesforce account-assignment setups fall apart at the exact moment they matter most. A rep closes a deal, loses one, or flags an account as a bad fit, and now someone has to notice, manually reassign the account, and keep the territory list current. This project builds that logic directly into Salesforce instead. Real public facility data flows in and gets deduplicated. Each account gets enriched with a real decision-maker contact. Once a rep is loaded up with a territory, the platform manages every reassignment on its own.
Here's how the full pipeline works, from a raw public dataset to a sales territory that keeps itself current.
๐ฉ The Challenge
The brief was to build a working Salesforce Developer Edition instance around a real public dataset (CMS nursing home data across four states) and turn it into a self-managing territory system. Specifically:
- Import facility data as Accounts for Arizona, Nevada, Utah and Colorado. The import has to be idempotent, so re-running it never creates duplicate accounts.
- Enrich every Arizona account with its real Chief Administrator as a Contact, skip accounts that already have one, and mark any existing "Administrator" contact inactive if the data source names someone different.
- Bonus: infer a plausible email address for that administrator from public data.
- Stand up a dummy sales rep, assign them a state as a territory, and hand them the 20 accounts most in need of attention. From there, closing an account (won or lost) or disqualifying it should automatically free it and backfill the rep with the next-best account in their territory. No one should have to touch a list by hand.
๐ก The Solution
The system is built entirely out of Apex batch jobs and an Invocable Apex method wired into a Flow, so everything can be kicked off from inside Salesforce. No external tooling is required to operate it day to day.
- Account import. The CMS dataset was filtered down to the four target states, loaded into Salesforce, and run through an Apex batch class that checks each facility against existing Accounts before inserting. A second run does nothing to records that already exist. Custom fields were added to store every informational field the assignment called for: CMS Certification Number, address, and the specific metric the whole distribution system is built around, Reported Total Nurse Staffing Hours per Resident per Day.
- Contact enrichment. The Chief Administrator isn't in the CMS dataset. It's on each facility's page in Arizona's public care-check registry. A Python + Selenium script searches that registry for every Arizona account created in step one, scrapes the administrator's name, title, phone and address off the detail page, and infers an email address by combining the administrator's name with a simplified version of the facility's name as a domain. A second Apex batch class then takes that output and creates Contact records against the matching Account. It checks for an existing contact first, then flips any existing "Administrator" contact to inactive if the scraped name doesn't match.
- Initial territory assignment. An Invocable Apex method sets the rep's custom
Territory__cfield to their assigned state, then queries the accounts in that state currently owned by the admin, sorted by Reported Total Nurse Staffing Hours per Resident per Day ascending, and hands the rep the top 20. Those are the accounts with the lowest reported staffing, the ones most worth a rep's attention first. - Automated redistribution. A Flow listens for the three disqualifying actions the brief called for: Closed Won, Closed Lost, and a custom Disqualify action built for reps to use directly on an account. Whichever one fires, the Flow calls a single Invocable Apex method with the rep's ID and the account ID. That method reassigns the freed account back to the admin, looks up the rep's territory, queries the next-highest-priority account in that same territory not already owned by the rep, and reassigns it. The freed account and the newly assigned one are updated together in one transaction.
๐ The Impact
The result is a territory system that runs itself once it's seeded:
- Idempotent by design. Both the account import and contact enrichment scripts can be re-run safely. Existing facilities and existing contacts are always checked for first, never duplicated.
- Real contact enrichment, not placeholder data. Every Arizona account gets a genuine, sourced administrator contact, with stale conflicting records automatically retired instead of silently overwritten.
- Reassignment happens automatically. One Invocable Apex method and one Flow keep a rep's account list correct the moment they close or disqualify anything. No admin has to notice or manually reassign.
- Everything kicks off from inside Salesforce. The account import, the contact enrichment batch, and the initial 20-account assignment are all Invocable Apex, so any of them can be run from a button or a Flow without touching the org's setup menu.
Stop Doing By Hand What Salesforce Can Automate
This system is a real example of the kind of Salesforce and Apex automation work I build: turning manual, error-prone CRM processes into something that runs itself, whether that's account assignment, data enrichment, or the day-to-day upkeep no one has time for.
If you're dealing with a similar data, automation, or CRM-management problem in Salesforce, get in touch.