Skip to content

Solution: BrightFuture Foundation

Work in Progress

This content is currently being reviewed for accuracy and will be updated soon.

Architecture Decisions

AD-1: Nonprofit Cloud Platform: Agentforce Nonprofit

Decision: Use Agentforce Nonprofit on Enterprise Edition, built on the current Nonprofit Cloud standard data model (Fundraising, Program Management, Volunteer Management). BrightFuture qualifies for 10 free Agentforce Nonprofit CRM licenses through the Power of Us program, which replaced the earlier free NPSP licenses in December 2025.

Rationale: Agentforce Nonprofit is the current Salesforce nonprofit platform and the successor to the legacy NPSP managed package. It provides a native standard object model for Fundraising (GiftCommitment, GiftTransaction, Gift Allocation), Program Management (Program, ProgramEngagement, BenefitAssignment), and Volunteer Management on the core platform. For a net-new implementation in 2026, Agentforce Nonprofit is the correct starting platform: Salesforce has consolidated nonprofit investment on the native data model, the partner ecosystem has shifted to Agentforce Nonprofit certifications, and Trailhead content is actively maintained for this platform. BrightFuture has a six-month Salesforce admin and no developer on staff, but the declarative configuration model makes it viable for a junior admin with implementation partner support.

Trade-offs: Agentforce Nonprofit uses a native standard object model that differs significantly from the legacy NPSP managed package. Community resources and older implementation guides still reference NPSP objects (Opportunity-as-gift, npe03__Recurring_Donation__c, GAU). The implementation partner must have current Nonprofit Cloud expertise on the new data model, not just legacy NPSP experience. Mitigate by selecting a Salesforce Certified Consulting Partner with a Nonprofit specialization and verifying recent Agentforce Nonprofit project references.

Alternatives rejected: Standard Sales Cloud without Agentforce Nonprofit; the donor-centric fundraising objects, program engagement model, and volunteer tracking built into Agentforce Nonprofit represent months of custom work to replicate on a bare Sales Cloud org. Not viable within budget or timeline. Legacy NPSP is no longer the recommended platform for new implementations; Salesforce has stopped investing in the managed package and the data model is not forward-compatible with the native Nonprofit Cloud objects.


AD-2: Integration Platform: Salesforce-Native Flows with Apex REST Handler for Stripe

Decision: Stripe webhooks are received by an Apex REST endpoint deployed and maintained by the implementation partner. Mailchimp sync is handled by Mailchimp for Salesforce (an AppExchange managed package published by Beaufort 12, starting at $25/month per Salesforce org).

Rationale: No in-house developer means any Apex must be written by the partner and must be minimal in scope. A small Apex REST handler class for Stripe is the documented Salesforce pattern for receiving webhooks and requires no third-party middleware. A middleware platform (MuleSoft, Boomi) would add $15,000-$40,000 per year in licensing and require admin-level knowledge to maintain; not justified at BrightFuture’s scale or budget.

Mailchimp for Salesforce (an AppExchange managed package published by Beaufort 12) handles both the outbound audience push and the inbound unsubscribe/bounce sync without custom code. It runs on a configurable schedule (minimum 15-minute intervals), which satisfies the 24-hour unsubscribe sync requirement. At $25/month ($300/year), it is a minor budget line item compared to the middleware alternative.

Trade-offs: The Apex handler is a code dependency. If BrightFuture loses its implementation partner relationship, changes to Stripe’s API schema could break the integration. Mitigate by adding integration error records and alerting so failures are caught within minutes. Document the handler thoroughly.


AD-3: Program Management: Custom Objects on Core Salesforce

Decision: Build program enrollment and attendance on custom objects within the Agentforce Nonprofit org rather than adopting the bundled Program Management capabilities.

Rationale: Agentforce Nonprofit includes Program Management features (formerly the Program Management Module). However, the bundled program model uses a Service Delivery object model that maps well to social services but is a less natural fit for school-year enrollment with attendance rosters. Given the site-coordinator access control requirement (coordinators see only their site’s data), a custom object model with a Site lookup gives cleaner sharing rule granularity than the standard Service Program model. Budget permits the custom build, and the admin can maintain standard objects more easily than adapting the bundled program model to a non-standard use case.

Trade-offs: Custom program objects sit outside the Agentforce Nonprofit managed package. Future platform upgrades to program management features will not automatically benefit the custom objects. Document object relationships clearly to simplify any future re-mapping.


AD-4: Deduplication: Pre-Migration Matching, No Real-Time Merge Automation

Decision: All deduplication work happens in a pre-migration staging environment using a combination of Cloudingo (or similar data quality tool) and manual review for the fuzzy-match cases. Real-time duplicate prevention in Salesforce uses standard Duplicate Rules with the Salesforce default matching rules; no custom code.

Rationale: With 28,000 contact records across three source systems and no shared unique identifier, automated merge logic in a live org is high risk. A staging environment lets the implementation partner run matching algorithms (exact email match, fuzzy name match, phone match) and produce a conflict report for staff review before a single record goes into production. Cloudingo costs approximately $3,000-$5,000 for a one-time migration project and is widely used in nonprofit Salesforce implementations.


System Landscape


Data Model

Constituent Model (Agentforce Nonprofit Household Account)

Agentforce Nonprofit uses a Household Account model: every individual Contact is associated with a Household Account. This is different from standard Salesforce, where a Contact belongs to a business Account. In Agentforce Nonprofit:

  • Household Account: auto-created per household. Stores address, giving totals, and household name. Soft credits for household joint gifts attach here.
  • Contact; the individual. A person who is both a donor and a volunteer is one Contact record. Volunteer history and giving history both hang off the same Contact.
  • Organization Account: used for corporate sponsors, foundations, and grant-making organizations.
  • ContactContactRelation: the standard object that links a Contact to another Contact, Household, or Organization Account for corporate sponsor relationships, board affiliations, and staff-to-organization links.

Core Agentforce Nonprofit Objects for Giving

ObjectPurpose
GiftCommitmentCommitment to give: captures pledge, recurring donation, or one-time intent with amount, frequency, and schedule
GiftTransactionIndividual gift transaction: amount, status, transaction date, payment method, Stripe charge ID
GiftTransactionLineItemLine-level detail on a transaction, including Gift Designations for earmarking to programs
GiftSoftCreditSoft credits for matching gifts and joint household gifts
Gift Designation / Gift AllocationFund accounting: tags gifts to specific programs, campaigns, or funds

Custom Objects for Volunteers

ObjectPurpose
Volunteer_Shift__cSingle shift definition: site, program type, date, capacity
Volunteer_Assignment__cJunction: links Contact to Volunteer_Shift__c with attendance status
Volunteer_Hours_Log__cRolled-up hours per Contact per month for reporting

Custom Objects for Programs

ObjectPurpose
Program_Site__cRepresents one of 18 physical sites (city, address, coordinator lookup)
Program__cTutoring, STEM Club, Arts: program type for a site and school year
Enrollment__cLinks Student_Contact__c to Program__c: status, enrollment date, school year
Attendance_Record__cOne record per student per session: date, present/absent flag
Student_Outcome__cPre/post assessment scores, completion flag, linked to Enrollment__c

Donor/Volunteer/Family Overlap

A single Contact record carries all three roles via:

  • Giving history through GiftCommitment (for pledges/recurring) and GiftTransaction (for individual gifts)
  • Volunteer history through Volunteer_Assignment__c
  • Family connection through a lookup on Enrollment__c (Student’s primary contact / guardian is a Contact, which may also be a donor Contact)

Household vs Individual Giving

In Agentforce Nonprofit, GiftTransactions are associated with the Household Account, with the primary donor Contact linked via a contact lookup. GiftSoftCredit records link additional Contacts to the same transaction (for example, a matching employer, or a spouse who co-gave). This is the standard Nonprofit Cloud pattern and must be respected throughout data migration.


Integration Architecture

Stripe: Event-Driven Webhook Pattern

Stripe is entirely event-driven. BrightFuture’s donation page is hosted externally and processes payments through Stripe. Salesforce must listen for Stripe’s webhook notifications.

Flow:

  1. Donor completes a gift on the donation page. Stripe processes the charge.
  2. Stripe fires an HTTPS POST to the Apex REST endpoint URL (/services/apexrest/stripe/webhook).
  3. The Apex handler verifies the Stripe webhook signature (using the signing secret, stored in a Custom Metadata record; not hardcoded).
  4. The handler parses the event type and enqueues a Queueable Apex job for processing (to keep the REST response fast and return HTTP 200 to Stripe within Stripe’s timeout window).
  5. The Queueable job:
    • Looks up the Contact by the donor email in the event payload (case-insensitive SOQL query).
    • If a match is found: creates a GiftTransaction linked to the matched Contact’s Household Account (and a GiftCommitment for subscription events).
    • If no match: creates a new Contact record with NeedsReview__c = true and a staging GiftTransaction with a Pending Review status. An alert task is created for the admin queue.
    • Writes an Integration_Event_Log__c record regardless of outcome (event type, Stripe charge ID, email, match status, timestamp).

Stripe events handled:

Stripe EventSalesforce Action
payment_intent.succeededCreate GiftTransaction with Status = Paid and link to Household Account
payment_intent.payment_failedCreate Integration_Event_Log__c with Failed status; create Task for admin
customer.subscription.createdCreate GiftCommitment with Status = Active and recurring schedule
customer.subscription.deletedUpdate GiftCommitment to Status = Closed
payment_method.updatedUpdate Payment Method on the GiftCommitment

SLA: The 2-minute SLA (requirement 7) is met because Stripe fires the webhook within seconds of the charge and the Queueable job processes in the async queue. Under normal Salesforce org load, end-to-end time is under 30 seconds. The 2-minute clock starts when Stripe fires, not when the donor clicks submit.

Error handling: Stripe retries failed deliveries (HTTP non-200 responses) with exponential back-off over 3 days. The Apex handler always returns HTTP 200 on receipt (before processing) to prevent retry storms, then handles processing errors internally and writes to Integration_Event_Log__c.


Mailchimp: Scheduled Bidirectional Sync

Mailchimp is not event-driven for Salesforce’s purposes. Mailchimp for Salesforce (AppExchange managed package by Beaufort 12, starting at $25/month) uses a pull/push model on a scheduled interval.

Outbound (Salesforce to Mailchimp):

  • Staff build a List View or Report of Contacts meeting campaign criteria.
  • The Mailchimp connector maps Salesforce Contact fields to Mailchimp audience fields.
  • Segment membership in Mailchimp can be driven by a Salesforce Report (one of the connector’s core features), eliminating the manual export step.
  • Sync runs on a 15-minute schedule, or on-demand via a button on the Campaign record.

Inbound (Mailchimp to Salesforce):

  • The connector polls Mailchimp for unsubscribe and hard bounce events on a scheduled interval (configurable to as low as 15 minutes, well within the 24-hour requirement).
  • On unsubscribe: sets HasOptedOutOfEmail = true on the matching Contact.
  • On hard bounce: sets Email_Bounce_Status__c = 'Hard Bounce' on the Contact (custom field) and also sets HasOptedOutOfEmail = true to prevent future sends.
  • Unmatched Mailchimp subscribers (email not found in Salesforce) are written to Integration_Event_Log__c for admin review.

Error visibility: Both Stripe and Mailchimp write to the same Integration_Event_Log__c object. A Lightning Dashboard component on the admin home page shows open error records grouped by integration source, with links to resolve each one.


Security and Sharing Model

Organization-Wide Defaults

ObjectOWDReason
Contact / AccountPrivateDonor records must not be visible across teams without explicit sharing
GiftTransaction / GiftCommitmentPrivateGift amounts are sensitive; development team only
Enrollment__cPrivateStudent records contain minor data; site-scoped access required
Attendance_Record__cPrivateRolls up from Enrollment; same restriction
Student_Outcome__cPrivateAssessment scores are sensitive
Volunteer_Shift__cPublic Read OnlyVolunteers need to see available shifts
Volunteer_Assignment__cPrivateOnly the coordinator and the assigned volunteer should see confirmed assignments
Program_Site__cPublic Read OnlyReference data; all staff need to see site list
Integration_Event_Log__cPrivateAdmin team only

Role Hierarchy

Executive Director
├── Development Manager
│ └── Development Staff (fundraising team)
├── Programs Director
│ ├── Seattle Site Coordinators (one role per city, or one per site)
│ ├── Portland Site Coordinators
│ └── Spokane Site Coordinators
├── Operations / Admin
└── Technology Team (system admin profile)

Sharing Rules

  • Development team sees all Contacts, GiftCommitments, and GiftTransactions (sharing rule: Role = Development Manager or subordinates, access = Read/Write on Contact, Read on GiftCommitment and GiftTransaction).
  • Site coordinators see Enrollments and Attendance only for their assigned Program_Site__c records. Criteria-based sharing rules share records matching a field value with a specific public group; they do not dynamically compare against the current user. The implementation uses public groups per site (e.g., “Downtown Site Staff”) and a criteria-based sharing rule that shares Enrollment__c records where Site__c = “Downtown” with the “Downtown Site Staff” public group. Each site coordinator is a member of their site’s public group.
  • Programs Director has a role above all site coordinator roles, granting rollup visibility across all sites without any extra sharing configuration.
  • Volunteers are not Salesforce users; they interact with the public shift sign-up page only. No internal Salesforce licenses are consumed by volunteers.

Student Data Privacy

Student Contacts are a distinct record type from donor/volunteer Contacts. The Record_Type = Student filter is built into the sharing rules; volunteers (even if they are donor Contacts in Salesforce) have no profile access to the Student Contact record type. Development staff can see donor-linked family Contacts but not the student’s program records.

Minor Data Compliance

Student records contain information about children. BrightFuture should consult legal counsel on FERPA compliance and any applicable Washington, Oregon, or Idaho state data privacy laws before go-live. The sharing model described here creates the technical controls; the compliance review determines whether those controls are sufficient.


Migration Strategy

Source Systems and Volumes

SourceObjectRecordsNotes
Little Green LightContacts28,00015% bad phone, 8% no email
Little Green LightGift records41,0006 years of history
Little Green LightRecurring gifts (as notes)800Requires structured conversion
VolunteerLocalVolunteer contacts310 activeSubset overlaps LGL
VolunteerLocalShift records4,800/yearLoad 2 years of history
VolunteerLocalHour logs9,200/yearLoad 2 years of history
Google SheetsStudent enrollments2,400 activeCurrent school year + one prior
Google SheetsAttendance records~18,000/monthCurrent school year only

Deduplication Approach

Phase 1: Pre-migration staging (6 weeks before cutover):

  1. Export all three source systems to CSV.
  2. Load into a staging spreadsheet or Cloudingo staging environment.
  3. Run matching passes in priority order:
    • Pass 1: Exact email match (catches most LGL/VolunteerLocal overlaps).
    • Pass 2: Fuzzy name + zip code match (catches “Bob” vs. “Robert” with same address).
    • Pass 3: Phone number match for records with no valid email.
  4. Produce a deduplication report: confirmed matches (auto-merge), probable matches (human review), unmatched (load as new).

Survivorship rules:

  • Email: prefer LGL (donor system, more carefully maintained).
  • Phone: prefer whichever record has a valid formatted phone.
  • Name: prefer the more complete full name; flag “Bob” vs. “Robert” cases for staff confirmation.
  • Address: prefer LGL.
  • Volunteer hours: always preserve from VolunteerLocal; this data does not exist in LGL.

Phase 2: Structured data conversion:

  • Recurring gift notes in LGL require manual review by the development team. Each of the 800 notes must be interpreted and mapped to amount, frequency, and next payment date before the migration load. Allocate 3 weeks for the development team to complete this review using a provided spreadsheet template.

Load Order

Data must be loaded in dependency order to satisfy lookup relationships:

  1. Program_Site__c records (reference data, no dependencies)
  2. Account records: Household Accounts and Organization Accounts
  3. Contact records (requires Account IDs from step 2)
  4. ContactContactRelation records (corporate/board/staff affiliations, requires Contact IDs)
  5. GiftCommitment records (recurring pledges, requires Contact + Account IDs)
  6. GiftTransaction records (individual gifts, requires Account + Contact IDs, optional GiftCommitment parent)
  7. GiftTransactionLineItem and Gift Designation records (requires GiftTransaction IDs)
  8. Volunteer_Shift__c records
  9. Volunteer_Assignment__c records (requires Contact + Shift IDs)
  10. Program__c records (requires Site IDs)
  11. Enrollment__c records (requires Contact + Program IDs)
  12. Attendance_Record__c records (requires Enrollment IDs)
  13. Student_Outcome__c records (requires Enrollment IDs)

Use Salesforce Data Loader or Dataloader.io for all loads. Agentforce Nonprofit rollup and automation processes should be paused during bulk loads and rerun from the Nonprofit Cloud settings page afterwards to prevent runaway recalculation during migration.

Cutover Constraints

  • The end-of-year giving campaign runs November 15 through December 31.
  • Go-live target is before the school year enrollment window (approximately 11 months from project start, roughly September).
  • Target cutover window: late August, after the summer fundraising lull and before the enrollment window opens. This avoids the November-December blackout.
  • For the Stripe integration specifically: run in parallel mode for 2 weeks pre-cutover. Stripe webhooks fire to both the old donation page processor and the new Salesforce endpoint. Compare records. Only decommission the old workflow once parity is confirmed.

Reporting Approach

All reports use native Salesforce Reports and Dashboards. No external BI tool is needed at BrightFuture’s data volume.

Executive Director dashboard (requirement 17): Four dashboard components on a single Lightning Dashboard: Summary Number for active donors (filter: GiftTransaction Transaction Date = this fiscal year, deduplicated by Contact); Summary Number for volunteer hours (filter: Volunteer_Hours_Log__c, current fiscal year); Summary Number for current student enrollments (filter: Enrollment__c status = Enrolled, school year = current); and a Gauge or Progress Bar chart for YTD funds raised against a manually entered Campaign target field.

Donor retention report (requirement 18): A joined report (or a Salesforce Report with cross-filter) showing Contacts who have a Paid GiftTransaction in the prior fiscal year but no Paid GiftTransaction in the current fiscal year, grouped by gift size range (using bucket columns: under $100, $100-$499, $500-$999, $1,000-$4,999, $5,000+). This is a standard Nonprofit Cloud lapsed donor pattern and does not require custom code.

Monthly site attendance summary (requirement 19): A custom Attendance Report Type (Contact + Enrollment + Attendance_Record) grouped by Program_Site__c, Program__c, and calendar month. A formula field on Enrollment__c calculates attendance rate as (present days / total session days). A dashboard filter lets the Programs Director drill by site. Site coordinators see only their site’s data due to sharing rules; the same report is safe to share with all coordinators.

Impact report by city (requirement 20): A cross-object impact view by city. Custom Report Types (CRTs) are built from one primary object plus related objects in a parent-child chain; a single CRT cannot join GiftTransaction, Enrollment, and Volunteer_Hours_Log as independent primaries. Use separate CRTs for each reporting domain (e.g., GiftTransaction + Account for fundraising by city; Enrollment + Program_Site__c for students served by city; Volunteer_Hours_Log + Program_Site__c for hours by city), or use CRM Analytics to join these datasets in a single lens. For a budget-conscious implementation without CRM Analytics, the three separate reports can be combined in a multi-component dashboard filtered by city.

Grant reporting (requirement 21): Each grant is tracked as a GiftCommitment with a Grant record type, associated to the funder’s Organization Account, and fulfilled by one or more GiftTransactions. Gift Designations on those transactions tag the funded programs. A grant reporting template (saved report) filters Enrollment and Attendance records by the programs tagged on the grant’s designations, making it possible for staff to run a quarterly grant report without customization per funder.

Volunteer impact export (requirement 22): Volunteer_Hours_Log__c rolls up hours by Contact, Site, and Program_Type__c (a picklist on Volunteer_Shift__c). A Report Export to CSV handles employer matching documentation. For formal letters, a Salesforce Document Generation tool (Conga Composer or DocGen, both available on AppExchange) generates a PDF volunteer hour summary letter. This is a light implementation effort and within budget.


Requirements Addressed

#RequirementSolution
1Unified constituent modelAgentforce Nonprofit Household Account + Contact model; all constituent types as one Contact with record type differentiation
2Single record for donor-volunteer overlapOne Contact record; GiftTransaction for giving history, Volunteer_Assignment__c for shift history
3Deduplication with name variationsPre-migration staged deduplication: exact email, fuzzy name+zip, phone match; manual review for edge cases
4Complete history post-migrationFull load of LGL gifts, VolunteerLocal shifts/hours, and Google Sheets enrollments per load order
5Recurring gifts as structured recordsStructured conversion of LGL notes to GiftCommitment with amount, frequency, next payment date, payment method type
6Soft credits for matching gifts and householdGiftSoftCredit records on GiftTransaction; standard Nonprofit Cloud feature, no custom build required
7Stripe webhook: gift created within 2 minutesApex REST endpoint + Queueable Apex; webhook receipt to record creation typically under 30 seconds
8All five Stripe event types handledpayment_intent.succeeded, payment_intent.payment_failed, customer.subscription.created, customer.subscription.deleted, payment_method.updated; all handled in Apex event router
9Match on email or create new with review flagSOQL lookup by email in Queueable job; no match creates Contact with NeedsReview__c flag and admin Task
10Mailchimp segments driven from SalesforceMailchimp for Salesforce (AppExchange managed package by Beaufort 12, $25/month); Salesforce Report drives Mailchimp audience segment; no manual export
11Unsubscribe/bounce back to Salesforce within 24 hoursMailchimp for Salesforce package polls on 15-minute schedule; sets HasOptedOutOfEmail and bounce status field
12Integration errors in one placeIntegration_Event_Log__c custom object; dashboard component on admin home page showing all open errors by source
13Program enrollment in SalesforceEnrollment__c custom object linking Contact, Program__c, Program_Site__c, school year, and status
14Attendance with site-scoped coordinator accessAttendance_Record__c per student per session; criteria-based sharing rules restrict coordinators to own site
15Outcome tracking with pre/post scoresStudent_Outcome__c linked to Enrollment__c; fields for pre/post reading level scores, attendance rate formula, completion flag
16Programs Director consolidated viewRole hierarchy position above all site coordinator roles provides rollup visibility; single report covers all 18 sites
17Executive Director one-view dashboardFour-component Lightning Dashboard: active donors, volunteer hours, enrolled students, YTD funds vs. target
18Lapsed donor retention reportCross-filter report: Contacts with prior-year Paid GiftTransaction, no current-year Paid GiftTransaction; bucketed by gift size
19Monthly attendance by site with drill-downCustom report type with attendance rate formula; sharing rules make it safe to deploy to all coordinators
20Impact by citySeparate CRTs per domain (GiftTransaction, Enrollment, Volunteer_Hours_Log) filtered by city field on Program_Site__c; combined in a multi-component dashboard, or CRM Analytics for true cross-object joins
21Grant reporting without per-funder custom devGift Designations on the grant’s GiftTransactions tag funded programs; saved report template filters by designation for any grant funder
22Volunteer impact export for documentationVolunteer_Hours_Log__c report export to CSV; optional Conga/DocGen for PDF letter generation

Risk Assessment

RiskLikelihoodImpactMitigation
Recurring gift note conversion takes longer than plannedHighMediumAllocate full 3 weeks; bring implementation partner in for a data conversion workshop with the development team in month 2
No developer on staff (Apex webhook handler becomes unmaintainable)MediumHighThoroughly document the handler; include a maintenance retainer with the implementation partner contract; monitor Integration_Event_Log__c proactively
Deduplication edge cases delay migrationMediumHighRun staging dedup 8 weeks before cutover (not 6); set a cutoff rule; records with no confident match are loaded as new and flagged for post-migration cleanup
Cutover timing conflicts with enrollment windowLowHighHard constraint: complete enrollment module go-live by week 36 of the 14-month project; if slipping, descope outcome tracking (requirement 15) to phase 2

Domain Scoring Notes

Integration Domain Probes

The review board will probe integration decisions heavily because the two integrations have different patterns and the candidate must demonstrate they understand why.

  • Stripe is push (event-driven). Salesforce cannot poll Stripe for new transactions; it must receive webhook events. The key design decisions are: how you secure the endpoint (signature verification), how you handle Stripe’s retry behavior, and what happens when no matching contact exists.
  • Mailchimp is pull/push on schedule. Salesforce cannot receive Mailchimp events in real time; the connector polls. The key design decision is the polling interval and what happens on a failed sync (retry queue, error log).
  • Error handling is a first-class concern. Any answer that does not address what happens when an integration fails will lose marks. The Integration_Event_Log__c pattern with an admin dashboard component is the minimum expected answer.

Data Domain Probes

  • The board will ask about the constituent model choice and expect a crisp rationale with trade-offs, not just “it’s easier.”
  • Deduplication must not be treated as a migration task only. Post-migration, what prevents new duplicates from entering the system? Answer: Salesforce Duplicate Rules with a configured Standard Matching Rule using Email as the primary match key, supplemented by custom matching rules for Name + Zip fuzzy matching.
  • The recurring gift conversion from unstructured notes is a data quality problem, not a migration problem. The board expects a plan for staff involvement in the conversion, not just a technical mapping.

What Would Fail

Anti-pattern 1: Using a middleware platform to receive Stripe webhooks. Adding MuleSoft Anypoint or a similar iPaaS for a single webhook endpoint adds $15,000+ per year in licensing, introduces a new system for a four-person tech team to maintain, and is architecturally disproportionate. The board would view this as over-engineering given the stated budget and staffing constraints.

Anti-pattern 2: Relying on scheduled data exports from the existing systems during migration. LGL has no API on the current tier; VolunteerLocal has no webhook or API on the current tier. Any migration architecture that assumes API access from these systems will fail. The only exit path is CSV export. A candidate who designs an API-based migration without checking the system constraints has missed a key fact in the scenario.

Anti-pattern 3: Giving site coordinators Public Read/Write on Enrollment__c and relying on honor-system data access. Student records are records about minors. An OWD of Public Read/Write on enrollment data, even with training, is not an acceptable design for a CTA review board. The scenario explicitly states that coordinators must not see other sites’ data, and the implicit requirement calls out minor data privacy. Private OWD with criteria-based sharing rules is the correct answer.


Scoring Rubric

CriterionWeightWhat Strong Looks Like
Constituent data model20%Agentforce Nonprofit Household Account model explained correctly; donor/volunteer overlap handled via single Contact; soft credits addressed
Integration architecture25%Stripe and Mailchimp treated with different patterns; error handling and the unmatched-email case explicitly addressed; 2-minute SLA explained mechanically
Migration and deduplication20%Three-source deduplication with matching passes explained; survivorship rules defined; load order correct; recurring gift conversion acknowledged as a staff work item
Security and access model20%OWDs and sharing rules correctly set; student/minor data explicitly protected; volunteer access (no internal licenses) addressed
Reporting and impact measurement15%All four reporting requirements addressed; grant reporting explained without requiring per-funder customization; no BI tool needed at this scale

Self-Assessment Checklist

  • Did I explain the Agentforce Nonprofit platform choice with trade-offs, or just say which one I picked?
  • Did I address what happens when a Stripe webhook arrives for an email that has no matching Contact?
  • Did I give Stripe and Mailchimp different integration patterns and explain why?
  • Did I include student/minor data privacy as an explicit design concern in the sharing model?
  • Did I plan for recurring gift conversion as a staff effort, not just a technical mapping?
  • Did I define survivorship rules for deduplication, not just say “we’ll deduplicate”?
  • Did I explain how grant reporting works for any funder without requiring custom development per funder?
  • Did I show that all 22 requirements map to a specific design decision?

Q&A Prep

Q: Why Agentforce Nonprofit rather than building on standard Sales Cloud or using the legacy NPSP? A: Agentforce Nonprofit is the current Salesforce nonprofit platform and the only one receiving active investment. It provides native standard objects for fundraising (GiftCommitment, GiftTransaction, Gift Designation), program management, and volunteer management. Building these on bare Sales Cloud would take months of custom work outside this budget. Legacy NPSP is no longer the recommended starting point for new implementations; the native data model is forward-compatible and has the active Trailhead documentation, active partner certifications, and free CRM licenses through Power of Us.

Q: A Stripe webhook arrives with a donor email that is not in Salesforce. Walk me through exactly what happens. A: The Queueable job runs the SOQL query, finds no match, creates a new Contact with record type Individual and sets a NeedsReview__c checkbox to true. It creates a staging GiftTransaction with Status = Pending Review linked to the new Contact’s Household Account. It writes a record to Integration_Event_Log__c with status “Unmatched - New Contact Created.” It creates a Task assigned to the admin queue with subject “Review new Stripe donor contact.” The admin reviews, either merges with an existing record or confirms it as a new donor, and moves the GiftTransaction status to Paid.

Q: How does Mailchimp unsubscribe sync work if the Mailchimp connector polls every 15 minutes but Salesforce only has the 24-hour SLA? A: The 15-minute polling interval gives a comfortable margin inside the 24-hour requirement. The connector checks Mailchimp’s activity feed for unsubscribe and bounce events since the last poll timestamp, then updates the matching Salesforce Contact. If a poll fails, the connector logs the error and retries on the next cycle. The Integration_Event_Log__c catches persistent failures for admin attention.

Q: How do you prevent new duplicates from entering the org after migration? A: Standard Salesforce Duplicate Rules with a configured Standard Matching Rule using Email as the primary match key, supplemented by custom matching rules for Name + Zip fuzzy matching. The out-of-the-box standard matching rule on Email + First Name + Last Name is a starting point, but the custom fuzzy-name rule is needed to catch “Bob” vs. “Robert” variations at the same zip code. For donor-facing entry (Stripe webhook creates new contacts), the Apex handler always queries by email before creating a new record. For manual entry, Duplicate Rules surface a warning (or block, depending on the rule setting) if a rep tries to create a Contact that closely matches an existing one.

Q: Site coordinators are not technical users. How does attendance recording work for them? A: A simple Lightning page with a filtered list view of their site’s Enrollment records and an inline edit option on a custom Attendance_Record__c quick action. The sharing rules limit what they see automatically; they do not need to filter by site; their view only shows their records. Onboarding is under two hours because the workflow is: open the list, click the student’s name, click “Record Attendance,” select present or absent, save. No reports, no configuration.

Q: What happens if the implementation runs over budget? A: The scenario states no contingency. The architecture is designed to avoid this: Agentforce Nonprofit, Mailchimp for Salesforce ($25/month AppExchange managed package), and minimal Apex reduce implementation hours. If a risk materializes, the first thing to descope is Student_Outcome__c (requirement 15); pre/post assessment scores are valuable but not critical to go-live. That can launch as a phase 2 after the enrollment window opens. Volunteer impact PDF letters (requirement 22) could also move to phase 2.

Q: Why not use Salesforce Experience Cloud for volunteer shift sign-ups? A: Experience Cloud would require additional licenses (Partner or Customer Community licenses for ~310 active volunteers), adding cost. The existing VolunteerLocal sign-up workflow can be kept in place as the public-facing volunteer portal post-migration, with only the back-end hour data migrated into Salesforce. Alternatively, a public-facing Salesforce Site (free, no license per volunteer) with a Web-to-Object form handles shift sign-ups without Community licenses.

Q: The development manager says the Mailchimp export currently takes two hours per campaign. How does your solution eliminate that? A: The Mailchimp for Salesforce package maps a Salesforce Report directly to a Mailchimp audience segment. When Rosa’s team needs to send a campaign, they build a Contact report in Salesforce with their criteria, save it, and map it in the package settings. The package syncs the segment on schedule. No export, no format conversion, no two-hour manual step. The only manual action is setting up the Report-to-Segment mapping the first time, which takes about 20 minutes.

Q: Can you walk me through the migration cutover sequence for the donation workflow? A: Three phases. In the month before cutover, the new Stripe webhook endpoint is deployed to production and tested in a sandbox with Stripe test events. Two weeks before cutover, parallel mode begins: the old LGL donation entry continues in parallel with the new Salesforce endpoint. Both receive events; staff reconcile daily to confirm parity. One week before cutover, the development team does a final data load of LGL gift records through the day prior. On cutover day (targeting late August), the LGL donation workflow is deactivated and the Salesforce endpoint becomes the sole path. The old system stays in read-only mode for 60 days as a backstop.

Q: How do you handle Agentforce Nonprofit automation behavior during bulk data loads? A: Nonprofit Cloud provides settings to pause roll-up calculations and automation during bulk operations. Before each load phase, the admin suspends the Fundraising automations and rollups from Nonprofit Cloud settings. After the load, the admin runs the batch recalculation jobs from the same settings page. This is standard nonprofit platform migration practice and the implementation partner would own this step.

Q: How does the Programs Director see all 18 sites without manually combining data? A: The role hierarchy places the Programs Director above all site coordinator roles. Because Enrollment__c OWD is Private, records owned by site coordinator users are visible to the Programs Director via role hierarchy rollup. The consolidated view is a Salesforce Report filtered to the current school year with no site filter; the role hierarchy makes all records visible automatically. No sharing rules, no manual export.


Presentation Notes

Diagram Order

Present in this sequence to build the story logically:

  1. System landscape diagram: establish current state (three disconnected tools) and target state (single Salesforce org with two live integrations). Set the context in 90 seconds.
  2. Data model: walk the constituent model (Agentforce Nonprofit Household Account), then volunteer objects, then program objects. Emphasize that one Contact holds all roles. 4-5 minutes.
  3. Integration architecture: Stripe webhook flow end-to-end, then Mailchimp sync. Call out that they are different patterns. 5-6 minutes.
  4. Security and sharing model: OWD table plus role hierarchy sketch. Call out student/minor data explicitly; the board will probe this. 3-4 minutes.
  5. Migration strategy: three-source deduplication, load order, cutover window. Reference the November-December blackout explicitly to show you read the constraints. 4-5 minutes.
  6. Reporting: cover the executive dashboard, lapsed donor report, and grant reporting approach. 3-4 minutes.

Time Allocation (30-minute presentation)

  • System landscape: 2 minutes
  • Data model: 5 minutes
  • Integration architecture: 7 minutes
  • Security model: 4 minutes
  • Migration strategy: 6 minutes
  • Reporting: 4 minutes
  • Wrap-up and assumptions stated: 2 minutes

Talking Points to Emphasize

  • The implicit requirement you caught on minor data privacy (board expects unprompted identification).
  • Why Stripe and Mailchimp need different patterns; this is the core integration design point.
  • The recurring gift note conversion is a staff effort, not just a technical task; shows operational awareness.
  • The cutover window choice (late August) is driven by two explicit constraints in the scenario: enrollment window opens in 11 months, November-December blackout. Naming these shows you read carefully.
  • Agentforce Nonprofit platform choice: explain why it is the correct starting platform for a new nonprofit implementation in 2026, and how the free CRM licenses through Power of Us reduce cost.

Always verify against official Salesforce documentation

This content is study material for CTA exam preparation. Content compiled and presented with AI assistance. Not affiliated with Salesforce.

Personal study notes for the Salesforce CTA exam. Content compiled from VJ's study notes, official Salesforce documentation, community sources, and online publicly available content, then organized and presented with AI assistance. Not affiliated with Salesforce. © 2025–2026 VJ Srivastava.