Salesforce Migration

Companion to the Digital Infrastructure & Growth Plan · By Clearoute

Salesforce migration — the full plan

How Every Pregnancy moves from HubSpot and a custom encrypted backend to one source of truth in Salesforce — partner data, donor data, giving history and reporting — in three dependency-ordered phases, without disrupting the live donation flow.

Draft  Working statement of work, v1.0 · June 2026. All hour estimates are indicative and are confirmed once the pre-scoping questions are answered. Salesforce org provisioning & licensing sit with Every Pregnancy; this plan covers configuration & development.

Start here

The goal & the scope

Unify two competing data homes into one: partner/organisation data leaves HubSpot, donor data leaves the encrypted backend — both become Salesforce, the system of record. Every dashboard, the website and reporting then read from one place.

Jeremy’s EP Statement of Work v1 + Clearoute review brief (EP-Salesforce-migration-brief.md). Full breakdown: plans/salesforce-sow.md.

Crucially, "one source of truth" means Salesforce is the record + reporting brain — it does not mean every experience moves inside the CRM. The donation widget, the partner dashboard UI, and content authoring stay where they are and feed Salesforce or read from it. Seven components are in scope across three phases; the originally-scoped work is a draft 204–284 hours, with a donation-ingestion deliverable added by the decision below.

ComponentPhaseEst. hoursStatus
Partner provisioningPhase 124–32In scope
Donor management (nonprofit CRM)Phase 160–80In scope
Offline donation approval workflowPhase 124–32In scope
Donation ingestion (widget → Salesforce)Phase 1TBDAdded by decision
Goal meter & boost algorithmPhase 240–56In scope
Partner dashboard (data integration)Phase 232–48In scope
WordPress API re-pointPhase 316–24In scope
Data decryption / CSV export utilityPhase 38–12Deprecate
Donation widgetKeep + integrate
BigQuery data pipelineEvaluatePending review

Draft Total for originally-scoped in-scope components: 204–284 hours. Donation ingestion is additive and scoped once the feed pattern is confirmed.

Decision applied — the donation widget stays

An earlier draft left the donation flow on hold pending evaluation of a third-party platform. That is resolved: the existing custom donation widget is retained and integrated with Salesforce — not replaced. This removes the highest-risk item from the migration and turns it into a clean data-feed (see Donation widget).

Target state

Salesforce is the brain; the platform stays the hands

Salesforce becomes the system of record and reporting. The donation widget, ep-server and Stripe keep running the live money flow and feed Salesforce via a batch/queue sync. The partner dashboard and public website read from Salesforce. Nothing in the payment path depends on Salesforce being up.

OPERATIONAL LAYER — STAYS the live money flow Donation widget Stripe · Gift Aid · recurring · multi-currency Stripe ep-server Bull/Redis queue Donation ingestion batch / queue · Bulk + Composite API idempotent · carries currency + Gift Aid added by the keep-the-widget decision feed SALESFORCE single system of record + reporting Accounts — partners / orgsreplaces HubSpot Donor Contacts + Gift objectsreplaces encrypted backend Offline donations — Approvals + Flow Boost / match rollups — Apex Reports + dashboards + analytics common-currency basis for the boost competition Partner dashboard keep UI · re-point to SF WordPress site reads partner content REST + cache DEFERRED Experience Cloud portal Marketing Cloud + Data Cloud BigQuery (audit)

Feeding via ep-server (not widget-direct or per-webhook) protects the live money flow, reuses the existing Bull/Redis queue, and stays under platform-event limits.

Phase 1Foundation — Salesforce becomes the system of record

The highest-confidence components — strongest native Salesforce fit, lowest execution risk, and prerequisites for everything that follows. Plus the donation-ingestion feed that keeps the donor CRM live.

Partner provisioning

24–32 hrs
Today

A HubSpot contact’s Approved field triggers a custom integration that provisions a dashboard login and welcome email — managed manually.

Salesforce

Partner orgs become Account records. A Flow triggers on approval, fires an Email Alert, and provisions an Experience Cloud user natively or calls an outbound webhook to the existing dashboard.

Deliverables: Account config · approval Flow · Email Alert template · outbound webhook (if dashboard retained) · deactivation flow.

Assumption: range reflects whether the existing dashboard is retained — full Experience Cloud adoption is near-entirely native (lower end).

Donor management — nonprofit CRM

60–80 hrs
Today

Donor data sits in an encrypted backend with no CRM layer; access needs a manual CSV decrypt. No reporting, lifecycle tracking, or tax receipts.

Salesforce

Salesforce’s nonprofit CRM as donor CRM — Contact records with full giving history, campaign & partner attribution, location, recurring support, duplicate detection. Tax receipts auto-generate on confirmation.

Deliverables: nonprofit-CRM install & config · donor schema · giving-history model · attribution · tax-receipt automation · duplicate rules · lifecycle segmentation · migration of existing encrypted records.

Assumption: lower end assumes a single tax jurisdiction and clean data; more jurisdictions, data remediation, and record volume move it upward.

Build on Nonprofit Cloud with dedicated Gift objects (not legacy NPSP, which isn’t offered to new orgs and models gifts on Opportunities). Same goal — different data model, migration and rollups. Correct the “install in a net-new org” assumption with the Salesforce partners.

Offline donation approval workflow

24–32 hrs
Today

Partners submit offline donations via the dashboard; an approval email with a link goes to the approver; approved amounts credit the partner total; receipt upload required.

Salesforce

Submission via Experience Cloud; Salesforce Approvals routes to the approver with approve/reject; receipt upload handled natively; on approval a Flow rolls up to the partner total. Full audit trail in standard reporting.

Deliverables: offline-donation object & records · Experience Cloud submission · Approval process with email routing · file-upload config · rollup Flow · per-partner / per-campaign reporting.

Assumption: single primary approver; delegated approvers or a reject-and-resubmit flow sit at the upper end.

Donation ingestion — widget → Salesforce added by decision

TBD · to scope
Why

Because the widget stays, live gifts are still born in the widget + Stripe + ep-server. Without a live feed, the donor CRM holds only migrated history that goes stale on the next donation.

Pattern

Batch / queue sync — reuse the existing Bull/Redis queue, Bulk + Composite API, idempotent with catch-up; carry currency + Gift Aid per gift. Not a Salesforce call per Stripe webhook.

Deliverables (draft): ingestion job in ep-server · Salesforce inbound staging · idempotency, retry & catch-up · field mapping (amount, currency, attribution, recurring, Gift Aid) · reconciliation reporting.

Principle: Salesforce being down must never stop donations — the feed is asynchronous and reconciles.

Phase 2Data & dashboard — built on the Phase 1 foundation

These depend on Phase 1: the boost needs donation data already in Salesforce, and the dashboard re-point needs Salesforce confirmed as the system of record.

Goal meter & boost algorithm

40–56 hrs
Today

A Google Sheet is the calc engine — donations feed in, a person maintains the boost formula by hand, the dashboard pulls the output. The client has flagged this as a priority pain point to replace.

Salesforce

Per-partner totals as rollup summary fields on Accounts; boost logic in Flow (simple) or Apex (complex). Meter UI stays in the dashboard via REST, or becomes a Lightning Web Component if the dashboard moves to Experience Cloud.

Deliverables: rollup config for donation totals · boost in Flow or Apex · goal-meter data endpoint or LWC · updated downstream feed if boost data is used elsewhere.

Assumption — widest variance: a simple Flow formula ≈ 40 hrs; a multi-variable algorithm needing Apex ≈ 56+ hrs. The boost formula must be documented and shared before this estimate is confirmed.

The boost is cohort-competitive → stateful batch Apex, not a simple Flow; a real-time meter is hard natively. Multi-currency is real (donations carry a currency; 20+ countries) — decide the common-currency basis before designing rollups. The LWC / Experience Cloud rebuild is deferred unless the dashboard is retired into a Salesforce portal.

Partner dashboard — data integration

32–48 hrs
Today

A custom multi-tenant web app where partners manage their campaign presence, view their goal meter and donor activity; profile content also feeds the public website via API.

Salesforce

Phase 2 is data integration only — re-point the existing dashboard to Salesforce via REST. Salesforce becomes the system of record; the dashboard UI is preserved. A full UI migration into Experience Cloud is a future phase, not in this plan.

Deliverables: Salesforce REST config for partner data · dashboard re-point from custom backend to Salesforce · auth & access scoping · testing across partner and admin views.

Assumption: the dashboard exposes REST endpoints and the maintaining team is available; GraphQL or adapter work moves toward the upper end.

Keep content authoring in the dashboard (re-pointed to Salesforce) and add a read cache in front of the REST calls — store partner data in Salesforce, don’t migrate the authoring experience into Salesforce CMS (built for an org’s own authors, not 55+ partners self-managing profiles).

Phase 3Cleanup & closeout — once the data is stable

Low-effort items that become viable once Salesforce holds all partner and donor data. Done after the Phase 1 & 2 migrations are stable.

WordPress API re-point

16–24 hrs
Today

The public site pulls partner-profile content from the custom backend API; dashboard-entered content appears on the site automatically.

Salesforce

WordPress calls Salesforce REST APIs for the same content — the pattern is unchanged, only the data source moves. If a WordPress rebuild is planned, fold this into that project.

Deliverables: SF REST endpoint config for public partner content · WordPress connector update · auth for public requests · end-to-end render testing on the live site.

Assumption: read-only from WordPress to Salesforce (add caching); any write-back use case is scoped separately.

Data decryption / CSV export utility Deprecate

8–12 hrs
Today

A utility that decrypts donor records from the encrypted backend and exports CSV — a workaround, and the only ad-hoc donor-data access today.

Salesforce

Once donor data is in Salesforce, this serves no purpose — export is handled by native reports, the scheduled export service, or the API. Formally decommission.

Deliverables: confirm all donor-data use cases are covered by Salesforce reporting · document existing export users & workflows · formal decommission.

Assumption: donor data is the only type through this utility; other record types add scoping.

Decision

Donation widget — kept and integrated

Was — on hold, highest risk

An earlier draft held the live donation flow pending a discovery session to evaluate a third-party donation platform. As a live production money flow, replacing it carried the highest execution risk of any component in the migration.

Now — retain & integrate resolved

The decision is made: the existing custom widget (Stripe, UK Gift Aid, recurring, multi-currency) stays in production. There is no risky replacement — only the Phase-1 donation-ingestion feed into Salesforce, the lower-risk path the analysis itself recommended.

Net effect: the migration’s biggest unknown is removed, the donor CRM stays live rather than going stale, and the “schedule a third-party discovery session” step drops out of the plan — replaced by scoping the ingestion feed.

Boundaries

Deferred & excluded

Experience Cloud portal

Migrating the dashboard UI into a Salesforce portal (with per-user licences) is a future phase — not needed while the existing dashboard is re-pointed to Salesforce data.

Donor marketing

Email marketing (Mailchimp today) consolidating into Salesforce Marketing Cloud Growth + Data Cloud is deferred to a later stage, once donor data is unified.

BigQuery pipeline evaluate

Its full scope wasn’t established in the walkthrough. Likely the same workaround as the decrypt utility — run a dependency audit; default to deprecate-or-downstream, and if kept, feed it from Salesforce.

Ground rules

Assumptions & exclusions

  • Salesforce org provisioning & licensing are Every Pregnancy’s responsibility; this plan covers configuration & development.
  • The nonprofit CRM is installed in a net-new / clean org (confirm Nonprofit Cloud vs legacy NPSP before finalising).
  • A Salesforce-certified sandbox is available for dev/test before production deployment.
  • The team maintaining the existing partner dashboard is available to support the Phase 2 integration.
  • The backend / widget subject-matter expert (Fidil) is available to consult during Phases 1 & 2 — now especially for the donation-ingestion feed.
  • Hour estimates exclude project management, status reporting, and documentation beyond handoff.
  • UAT is Every Pregnancy’s responsibility; Clearoute supports & facilitates, but UAT hours are not included.
  • This plan excludes work on the BigQuery pipeline (separate engagement). The donation widget is no longer excluded — it is integrated.
Close

Next steps

Answer the pre-scoping questions

The ten questions in the accompanying pre-scoping document — estimates are confirmed or revised once responses are received.

Review & sign off on scope, phasing & exclusions

Align before work is scheduled, including the deferred items and the BigQuery review.

Scope the donation-ingestion feed

Confirm the widget / ep-server → Salesforce pattern (batch/queue), field mapping, and currency / Gift-Aid handling — replacing the former third-party discovery step.

Review the BigQuery data-engineering roadmap

A brief internal review of what the pipeline powers and who depends on it, before a retain / replace / deprecate recommendation.