Solution 02: BookBridge Education Foundation
AI-Generated Content — Use for Reference Only
This content is AI-generated and has only been validated by AI review processes. It has NOT been reviewed or validated by certified Salesforce CTAs or human subject matter experts. Do not rely on this content as authoritative or completely accurate. Use it solely as a reference point for your own study and preparation. Always verify architectural recommendations against official Salesforce documentation.
AI-Assisted Reference Solution
This page is the spoiler side of the mini-scenario package. Use it to compare architecture choices, trade-offs, and artifact quality only after your own attempt.
Solution Snapshot
| Field | Detail |
|---|---|
| Start here | Question page |
| Difficulty | Beginner |
| Heavy domains | Integration and Dev Lifecycle |
| Page role | Worked reference solution |
| Best used for | Comparing your own answer against a complete architecture recommendation |
| Coverage available | Question page + this solution page |
Why This Solution Matters
- Use this page to compare your own approach against a full reference answer without losing the context of what the scenario was testing.
Only Open After Your Own Attempt
If you have not yet worked through the question page, stop here. Finish your timed mini-board attempt first, then use this solution with the 9 Essential Artifacts as your comparison checklist.
Assumptions
- Salesforce Nonprofit Cloud (NPC) — current-generation platform built on Industries Cloud (not legacy NPSP). Pre-built donation management, constituent modeling, and grant tracking at nonprofit pricing
- MuleSoft Composer for integration middleware — visual middleware for an 8-person team with no integration experience. Rejected Anypoint Platform (budget $1.2M/18 months cannot absorb enterprise licensing). Rejected point-to-point (6+ systems = 15 possible connections = unmaintainable)
- Single Experience Cloud site for school and volunteer portals with audience-based visibility — reduces licensing cost vs two separate sites
- Retain Stripe for payment processing — working system, no benefit to replacing during migration
- Keep ShelfTrack Cloud as the warehouse system — working SaaS with documented API; integrate, do not replace
Key Architectural Decisions
Decision 1: Hub-and-Spoke Integration (D5 — HEAVY)
MuleSoft Composer as the central hub because BookBridge has 6 systems with different protocols and anticipates adding 2-3 per year (Req 41). Every system connects to the hub, not to each other. Adding a new system requires one connection.
| System | Protocol | Pattern | Direction | Volume |
|---|---|---|---|---|
| Stripe | Webhooks + REST | Event-Driven | Inbound | 2K-12K/day |
| ShelfTrack | REST v3.1 + Webhooks | Event-Driven + Polling | Bidirectional | ~4,700/day |
| School Districts | SFTP + CSV | Batch ETL (via Anypoint SFTP connector — Composer lacks SFTP support) | Inbound | Monthly (15 districts) |
| QuickBooks | REST + OAuth 2.0 | Scheduled Batch | Outbound | Weekly |
| MailChimp | REST v3.0 + Webhooks | Event-Driven + Batch | Bidirectional | ~2.5M emails/mo |
| Eventbrite | REST + Webhooks | Event-Driven | Inbound | ~120 events/yr |
Judge Signal
Judges want each integration classified by protocol, pattern, and direction. Saying “we’ll integrate everything with MuleSoft” without this breakdown will fail. They also want to see the SFTP challenge addressed specifically — it is a different protocol class from REST.
Decision 2: SFTP Staging Pipeline (D5)
SFTP staging pipeline with staging object pattern for the 15 district SFTP feeds, each in a different format (Req 36).
MuleSoft Composer Does Not Support SFTP
MuleSoft Composer does not have a native SFTP connector — it supports REST/webhook-based SaaS systems (Stripe, Salesforce, Slack, etc.) but not SFTP. The SFTP district feeds require either: (a) MuleSoft Anypoint Platform (runtime-level SFTP connector) for this specific integration, retaining Composer for simpler REST integrations; or (b) a lightweight scheduled script or Salesforce-native solution (e.g., Apex + external SFTP library, or a third-party AppExchange SFTP tool) that downloads files and loads into a staging object. Option (a) is recommended if the budget allows a limited Anypoint license; option (b) is the budget-constrained fallback.
- SFTP files retrieved on schedule (via Anypoint SFTP connector or scheduled script)
- District-specific transformation mapping (15 mappings) transforms files
- Records land in
District_Data_Staging__cstaging object - Validation Flow checks for anomalies (>50% student count drop, missing fields)
- Clean records promote to production
School__c; flagged records route to manual review
Staging decouples ingestion from consumption — a bad file is contained in staging, not production.
Decision 3: Year-End Campaign Resilience + Environment Strategy (D5 + D6 — HEAVY)
Async event-driven donation processing for the year-end spike (12K/day, ~750/hour): Stripe webhooks received by Composer, pushed as Platform Events into Salesforce with built-in replay (72-hour retention). Migration must NOT happen during November-January — recommend spring cutover with old GiveHub running through one complete year-end cycle.
4-environment strategy with DevOps Center for a team new to Salesforce development (grew from 3 to 8 in 6 months):
| Environment | Type | Purpose |
|---|---|---|
| DEV (x3) | Developer Pro Sandboxes | Individual developer work |
| QA/TEST | Partial Copy | Integration testing, QA validation |
| UAT | Partial Copy | Business stakeholder acceptance |
| PROD | Production | Live system |
Chose DevOps Center over custom CI/CD (GitHub Actions + SFDX) because the team has zero prior experience. DevOps Center provides visual work item tracking and deployment pipeline as a stepping stone. 2-week release cadence with QA gate, UAT business approval, and rollback plan per release.
Judge Signal
Dev lifecycle judges want to see you acknowledge the team maturity gap. Prescribing enterprise-grade CI/CD for a team that just learned what a sandbox is will be viewed as tone-deaf.
Critical Diagrams
System Landscape
graph TB
subgraph SF["Salesforce Nonprofit Cloud (NEW)"]
NPC["🟢 Nonprofit Cloud (NEW)"]
EC["🟢 Experience Cloud Portal (NEW)<br/>School Partners + Volunteers"]
PE["🟢 Platform Events (NEW)"]
end
subgraph Hub["Integration Layer"]
MSC["🟠 MuleSoft Composer<br/>(NEW — Integration Hub)"]
end
subgraph External["External Systems"]
Stripe["⚪ Stripe (KEEPING)"]
ST["⚪ ShelfTrack Cloud (KEEPING)"]
SFTP["⚪ 15 School Districts SFTP (KEEPING)"]
QB["⚪ QuickBooks Online (KEEPING)"]
MC["⚪ MailChimp (KEEPING)"]
EB["⚪ Eventbrite (KEEPING)"]
end
subgraph Retiring["Retiring Systems"]
GH["🔴 GiveHub (RETIRING)<br/>Rails 5.2 EOL — Custom Donation App"]
GS["🔴 City Google Sheets (RETIRING)<br/>Volunteer Hour Tracking"]
WB["🔴 Whiteboards + Spreadsheets (RETIRING)<br/>Manual Processes"]
end
subgraph Legend
direction LR
NEW["🟢 NEW - Being Built"]
KEEP["⚪ KEEPING - No Changes"]
RETIRE["🔴 RETIRING - Decommissioning"]
INT["🟠 INTEGRATION LAYER"]
end
Stripe -->|"Webhooks, OAuth 2.0<br/>2K-12K donations/day"| MSC
ST <-->|"REST v3.1 + Webhooks<br/>~4,700 transactions/day"| MSC
SFTP -->|"SFTP, batch<br/>Monthly from 15 districts<br/>(Anypoint SFTP connector)"| MSC
QB <-->|"REST, OAuth 2.0<br/>Weekly journal entries"| MSC
MC <-->|"REST v3.0 + Webhooks<br/>~2.5M emails/month"| MSC
EB -->|"Webhooks<br/>~120 events/year"| MSC
MSC -->|"Platform Events"| PE
PE --> NPC
NPC --> EC
GH -.->|"500K donors migrated to SF"| NPC
GS -.->|"Volunteer data migrated"| NPC
WB -.->|"Replaced by SF workflows"| NPC
Integration Architecture (Hub-and-Spoke)
graph TB
subgraph External["External Systems"]
Stripe["⚪ Stripe (KEEPING)"]
ST["⚪ ShelfTrack Cloud (KEEPING)"]
SFTP["⚪ 15 School Districts SFTP (KEEPING)"]
QB["⚪ QuickBooks Online (KEEPING)"]
MC["⚪ MailChimp (KEEPING)"]
EB["⚪ Eventbrite (KEEPING)"]
end
subgraph Hub["MuleSoft Composer — Integration Hub"]
DH["🟠 Donation Handler"]
WH["🟠 Warehouse Sync"]
ETL["🟠 District ETL"]
FIN["🟠 Finance Sync"]
MKT["🟠 Marketing Sync"]
VOL["🟠 Volunteer Sync"]
ERR["🟠 Error Handler + Retry"]
end
subgraph SF["Salesforce Nonprofit Cloud"]
PE["🟢 Platform Events"]
Core["🟢 Core Objects"]
Staging["🟢 Staging Objects"]
EC["🟢 Experience Cloud Portal"]
end
Stripe -->|"Webhooks, OAuth 2.0<br/>Real-time, 2K-12K/day<br/>Donor + amount + campaign"| DH
ST <-->|"REST v3.1 + Webhooks<br/>Bidirectional, ~4,700/day<br/>Inventory + shipments"| WH
SFTP -->|"SFTP + CSV, batch<br/>Monthly, 15 districts<br/>(via Anypoint SFTP connector)"| ETL
QB <-->|"REST, OAuth 2.0<br/>Scheduled weekly<br/>Journal entries + fund coding"| FIN
MC <-->|"REST v3.0 + Webhooks<br/>Bidirectional<br/>Segments out, engagement in"| MKT
EB -->|"Webhooks<br/>Event-driven<br/>Registrations + check-ins + hours"| VOL
DH -->|"Platform Events"| PE
WH -->|"Platform Events"| PE
ETL -->|"Batch load"| Staging
FIN <-->|"REST sync"| Core
MKT <-->|"Sync"| Core
VOL -->|"Platform Events"| PE
PE --> Core
Staging -->|"Validation Flow"| Core
Core --> EC
ERR -.->|"Retry queue"| DH
CI/CD Pipeline
graph LR
DEV[Dev Sandboxes x3] -->|Commit| GH[GitHub Feature Branches]
GH -->|DevOps Center Promote| QA[QA Sandbox]
QA --> AT{Tests Pass?}
AT -->|Yes| UAT[UAT Sandbox]
AT -->|No| DEV
UAT --> BIZ{Stakeholder Approval?}
BIZ -->|Approved| PROD[Production]
BIZ -->|Rejected| DEV
Data Model
erDiagram
CONTACT ||--o{ DONATION : "donor (Lookup)"
CONTACT ||--o{ VOLUNTEER_ACTIVITY : "volunteer (Lookup)"
CONTACT ||--o{ CAMPAIGN_MEMBER : "member (Lookup)"
CAMPAIGN ||--|{ CAMPAIGN_MEMBER : "has (M-D)"
DONATION ||--o{ BOOK_DONATION : "linked to (Lookup)"
BOOK_DONATION ||--o{ INVENTORY_ITEM : "warehouse intake (Lookup)"
INVENTORY_ITEM ||--o{ DISTRIBUTION_RECORD : "shipped as (Lookup)"
SCHOOL ||--|{ DISTRIBUTION_RECORD : "recipient (M-D)"
SCHOOL ||--o{ BOOK_REQUEST : "submitted by (Lookup)"
SCHOOL }|--o{ SCHOOL_DISTRICT : "belongs to (Lookup)"
SCHOOL_DISTRICT ||--o{ DISTRICT_DATA_STAGING : "ingested from (Lookup)"
CONTACT ||--o{ CORPORATE_SPONSORSHIP : "sponsor contact (Lookup)"
ACCOUNT ||--|{ CORPORATE_SPONSORSHIP : "sponsor org (M-D)"
CONTACT ||--o{ GRANT : "grant manager (Lookup)"
CAMPAIGN ||--o{ DONATION : "campaign source (Lookup)"
CONTACT {
string Name "Unified constituent profile"
string OWD "Private"
string Volume "500K donors plus 2800 volunteers"
string Dedup "Fuzzy match across 3 systems"
}
ACCOUNT {
string Name "Corporate sponsors and orgs"
string OWD "Private"
string Volume "5K organizations"
}
DONATION {
string Name "One-time and recurring gifts"
string OWD "Private"
string Volume "3.2M historical plus 600K per year - LDV"
string Stripe_ID "Payment processor reference"
}
CAMPAIGN {
string Name "Fundraising campaigns"
string OWD "Public Read Only"
string Volume "200 per year"
}
BOOK_DONATION {
string Name "Donated book batches"
string OWD "Private"
string Volume "600K per year - LDV"
string Donor_Attribution "Links donor to books"
}
INVENTORY_ITEM {
string Name "Warehouse book inventory"
string OWD "Public Read Only"
string Volume "180K current inventory"
string Attributes "Condition grade genre level language"
}
DISTRIBUTION_RECORD {
string Name "Books shipped to schools"
string OWD "Controlled by Parent (School)"
string Volume "4M historical plus 550K per year - LDV"
string Tracking "Shipment tracking info"
}
SCHOOL {
string Name "Partner school profiles"
string OWD "Public Read Only"
string Volume "2500 current to 5000 in 3 years"
string Title_I "Title I status and demographics"
}
SCHOOL_DISTRICT {
string Name "District aggregations"
string OWD "Public Read Only"
string Volume "15 districts"
}
DISTRICT_DATA_STAGING {
string Name "SFTP ingestion staging"
string OWD "Private"
string Volume "Monthly loads from 15 districts"
string Status "Pending Validated Failed Promoted"
}
BOOK_REQUEST {
string Name "School book requests"
string OWD "Private"
string Volume "5K per year"
string Approval "Inventory plus equity workflow"
}
VOLUNTEER_ACTIVITY {
string Name "Event hours and participation"
string OWD "Private"
string Volume "20K records per year"
string Certification "Hour letters for tax and employer match"
}
CORPORATE_SPONSORSHIP {
string Name "Multi-year pledges and tiers"
string OWD "Controlled by Parent (Account)"
string Volume "500 active sponsorships"
string Installments "Schedule and deliverable tracking"
}
GRANT {
string Name "Grant applications and awards"
string OWD "Private"
string Volume "100 active grants"
string Fund_Restrictions "Program-level expenditure tracking"
}
LDV Strategy
Three objects exceed the LDV threshold and will grow significantly with the 3-year scaling target (5,000 schools):
| Object | Current Volume | Annual Growth | 3-Year Projection (5K schools) | Strategy |
|---|---|---|---|---|
| Donation | 3.2M historical + 600K/year | Growing with donor base | ~5M total | Custom indexes on Contact + Date + Campaign. Archive donations >5 years to Big Objects for reporting. Skinny tables on Amount, Date, Campaign |
| Book Donation | ~600K/year | Scales with school count | ~2.4M in 3 years | Indexed on Donor + Date + Warehouse. Linked to Inventory Item for lifecycle chain |
| Distribution Record | 4M historical + 550K/year | Doubles with 5K schools (~1.1M/year) | ~7.3M total | Custom indexes on School + Date + Warehouse. Archive completed distributions >3 years. Critical for impact reporting chain |
Impact Reporting Chain and LDV
The full book lifecycle chain (Donation -> Book Donation -> Inventory Item -> Distribution Record -> School) spans multiple LDV objects. Cross-object report types linking these objects will require careful query optimization. Consider CRM Analytics datasets for the impact reporting chain (Req 29) rather than live cross-object SOQL queries across millions of records.
Sharing Model
Role Hierarchy
graph TB
ED["Executive Director<br/>View All Data"]
CTO["CTO<br/>Full system access"]
DFD["Dir of Fundraising<br/>All donor + campaign data"]
DPR["Dir of Programs<br/>All school + distribution data"]
DFI["Dir of Finance<br/>All financial data"]
subgraph Fundraising["Fundraising Team (20)"]
FM["Fundraising Managers<br/>Donor records + campaigns"]
FA["Fundraising Associates<br/>Own donor assignments"]
end
subgraph Programs["Programs Team (35)"]
CM["City Managers (15)<br/>Own city: schools + volunteers + events"]
PA["Programs Associates<br/>Assigned school partnerships"]
end
subgraph Warehouse["Warehouse Team (25)"]
WM["Warehouse Managers (4)<br/>Own warehouse inventory"]
WS["Warehouse Staff<br/>Inbound + outbound only"]
end
subgraph Finance["Finance Team"]
FC["Finance Controller<br/>Donations + grants + QBO"]
FK["Finance Clerk<br/>Transaction processing"]
end
subgraph Tech["Tech Team (8)"]
TL["Tech Lead<br/>Full donor + config access"]
DEV["Developers (7)<br/>No HR or accounting data"]
end
subgraph PortalUsers["Portal Users (External — Outside Hierarchy)"]
SP["School Partners (2,500)<br/>Own school: requests + shipments + impact"]
VL["Volunteers (800+)<br/>Own participation + events + certifications"]
end
ED --> CTO
ED --> DFD
ED --> DPR
ED --> DFI
DFD --> FM --> FA
DPR --> CM --> PA
DFI --> FC --> FK
CTO --> TL --> DEV
DPR --> WM --> WS
OWD Summary
| Object | OWD | Sharing Mechanism |
|---|---|---|
| Contact (Constituent) | Private | Role hierarchy; fundraising sees donors, programs sees volunteers, dedup links both |
| Account (Organization) | Private | Role hierarchy; corporate sponsors visible to fundraising + finance |
| Donation | Private | Role hierarchy; finance and fundraising access via role; tech team via permission set (read-only) |
| Campaign | Public Read Only | All internal staff can view; edit restricted to fundraising team via profile |
| School | Public Read Only | All internal staff can view school profiles; school partners see only own school via portal sharing |
| Distribution Record | Controlled by Parent (School) | Inherits School sharing (Public Read Only); programs team and warehouse team access via parent; edit restricted to programs team via profile |
| Inventory Item | Public Read Only | All internal staff can view inventory; warehouse team edits via profile |
| Book Request | Private | Owned by requesting school portal user; programs team access via sharing rules |
| Volunteer Activity | Private | City managers see own city via criteria-based sharing on City field; volunteers see own records via portal |
| Grant | Private | Finance team access via role hierarchy; programs team read-only via sharing rules |
| Corporate Sponsorship | Controlled by Parent (Account) | Inherits Account sharing; fundraising and finance access via parent Account role hierarchy |
City Manager Isolation
City managers (Req 23) see volunteer and event data for their city only. This is implemented via criteria-based sharing rules on the City__c field across Volunteer Activity, Event, and School objects. City managers also see regional school partnerships through territory-based sharing. This prevents a NYC city manager from seeing Chicago volunteer data.
Migration Strategy
flowchart LR
subgraph P1["Phase 1: Foundation<br/>Months 1-4"]
P1A["Deploy Salesforce NPC<br/>+ MuleSoft Composer"]
P1B["Environment strategy<br/>DEV x3, QA, UAT"]
P1C["Configure core objects<br/>+ Experience Cloud site"]
P1A --> P1B --> P1C
end
subgraph P2["Phase 2: GiveHub Migration<br/>Months 5-8"]
P2A["Export 500K donors<br/>+ 3.2M transactions<br/>from PostgreSQL"]
P2B["Fuzzy dedup across<br/>GiveHub + MailChimp +<br/>Eventbrite (email + name)"]
P2C["Load unified constituents<br/>+ giving history<br/>into NPC"]
P2D["Stripe webhooks<br/>cutover to Composer<br/>(spring — NOT December)"]
P2A --> P2B --> P2C --> P2D
end
subgraph P3["Phase 3: Integrations<br/>Months 9-14"]
P3A["ShelfTrack bidirectional<br/>sync + book lifecycle"]
P3B["SFTP district ETL<br/>15 district mappings<br/>(Anypoint SFTP connector)"]
P3C["MailChimp + Eventbrite<br/>bidirectional sync"]
P3D["QuickBooks weekly<br/>journal entries"]
P3A --> P3B --> P3C --> P3D
end
subgraph P4["Phase 4: Go-Live<br/>Months 15-18"]
P4A["GiveHub decommissioned<br/>(Rails 5.2 EOL)"]
P4B["Google Sheets retired<br/>volunteer data in SF"]
P4C["Full impact reporting<br/>chain validated"]
P4A --> P4B --> P4C
end
P1 --> P2 --> P3 --> P4
| Phase | Key Activities | Validation Criteria |
|---|---|---|
| Phase 1 (Mo 1-4) | NPC deployment, environment setup, DevOps Center, core object config | Environments operational; CI/CD pipeline tested; Experience Cloud site live |
| Phase 2 (Mo 5-8) | GiveHub donor migration, 3-system dedup, Stripe cutover (spring only) | 500K donors loaded; <1% unresolved duplicates; giving history intact; Stripe live via Composer |
| Phase 3 (Mo 9-14) | All 6 integrations live one-at-a-time; load testing at 2x peak | Each integration passing end-to-end; 12K/day donation simulation passes; SFTP all 15 districts validated |
| Phase 4 (Mo 15-18) | GiveHub decommission, Google Sheets retired, full impact chain | Impact report generates end-to-end; GiveHub read-only then off; board report automated |
Year-End Campaign Blackout
GiveHub-to-Salesforce donation cutover MUST happen in spring (April-May recommended). GiveHub remains the donation system of record through at least one complete December year-end campaign cycle. No production deployments November 1 through January 15. The $15K lost-donation incident from a fundraising-event outage underscores why this blackout window is non-negotiable.
Identity & SSO Flow
sequenceDiagram
participant Staff as BookBridge Staff
participant Browser as Browser
participant Google as Google Workspace<br/>(IdP)
participant SF as Salesforce NPC
Staff->>Browser: Navigate to Salesforce
Browser->>Google: Redirect (SP-initiated SAML 2.0)
Google->>Google: Authenticate (Google MFA)
Google->>Browser: SAML Assertion (Federation ID = Google email)
Browser->>SF: POST SAML to ACS URL
SF->>SF: Match Federation ID → User record
SF->>Browser: Session Cookie + Redirect
sequenceDiagram
participant ExtUser as School Partner /<br/>Volunteer
participant Browser as Browser
participant SF as Experience Cloud Portal
ExtUser->>Browser: Navigate to Portal
Browser->>SF: Login page (email + password)
SF->>SF: Authenticate (optional MFA)
SF->>SF: Assign portal profile<br/>(School Partner or Volunteer)
SF->>SF: Apply sharing: audience-based visibility
SF->>Browser: Session Cookie + Portal Home
SSO Design Rationale
Internal staff (120 employees): SAML 2.0 SP-initiated SSO via Google Workspace (standard for nonprofits using Google for Nonprofits). Google handles MFA. Federation ID is the Google email address. If BookBridge later moves to Microsoft 365 or Okta, only the IdP metadata needs updating.
School partners and volunteers: Username/password through Experience Cloud (single site with audience-based visibility). School contacts submit book requests and track shipments; volunteers view participation history and download hour certifications. No SSO for external users — the diverse partner base (2,500 schools, 800 volunteers) makes a shared IdP impractical. Self-registration with email verification is enabled for new school contacts.
Integration Error Handling
Each integration has specific error handling tailored to its pattern, volume, and business criticality.
| Integration | Pattern | Retry | DLQ | Monitor | Fallback |
|---|---|---|---|---|---|
| Stripe → Donations | Webhook → Composer → Platform Event | 3x exponential (2s, 15s, 120s) | Integration_Error__c with full Stripe payload + event ID | Email alert to tech team on 3rd failure; Slack notification for >10 failures/hour | Stripe retries webhooks for up to 72 hours; Platform Event replay (72-hour window); manual reprocess UI |
| ShelfTrack (bidirectional) | REST + Webhooks via Composer | 3x exponential (5s, 30s, 300s) | Integration_Error__c with payload + ShelfTrack transaction ID | Daily digest of failed syncs to warehouse manager + tech team | Queue failed records; ShelfTrack webhook retry (configurable); manual reconciliation report |
| School Districts SFTP | Batch ETL via Anypoint SFTP connector → Staging object (Composer lacks SFTP support) | 1 automatic re-fetch per district after 24 hours | District_Data_Staging__c with Status__c = Validation_Failed | Monthly summary of failed/flagged records to programs team | Bad files quarantined in staging; clean records still promote; manual review queue for anomalies |
| QuickBooks (outbound) | Scheduled batch REST via Composer | 2x retry (immediate + 1 hour) | Integration_Error__c with journal entry payload | Email to finance director on any failure (weekly financial data is sensitive) | Finance team manually enters weekly summary CSV (current process) as interim fallback |
| MailChimp (bidirectional) | REST + Webhooks via Composer | 3x exponential (5s, 30s, 120s) | Integration_Error__c with contact/campaign IDs | Weekly digest of sync failures to marketing team | Segments can be manually exported as CSV (current process) while integration is restored |
| Eventbrite (inbound) | Webhooks via Composer | 3x exponential (2s, 15s, 120s) | Integration_Error__c with event/attendee payload | Alert on registration sync failures during active event windows | Eventbrite retains all data; manual CSV export available; volunteer hours tracked in backup Google Sheet per city |
Year-End Campaign — Elevated Monitoring
During December 15-31 (year-end campaign, up to 12K donations/day), the Stripe integration monitoring threshold drops from 10 failures/hour to 3 failures/hour for immediate alerting. A dedicated on-call rotation covers the integration layer. Platform Event replay (72-hour window) provides the safety net — no donation data is lost even if processing is delayed.
Governance & DevOps
Environment Strategy
flowchart LR
DEV1[Dev Sandbox 1<br/>Developer Pro] --> QA[QA / Integration<br/>Partial Copy]
DEV2[Dev Sandbox 2<br/>Developer Pro] --> QA
DEV3[Dev Sandbox 3<br/>Developer Pro] --> QA
QA --> AT{Automated Tests<br/>+ QA Analyst}
AT -->|Pass| UAT[UAT<br/>Partial Copy]
AT -->|Fail| DEV1
UAT --> BIZ{Business Stakeholder<br/>Approval}
BIZ -->|Approved| PROD[Production]
BIZ -->|Rejected| DEV1
Sandbox Strategy
| Sandbox | Type | Purpose | Notes |
|---|---|---|---|
| DEV-1, DEV-2, DEV-3 | Developer Pro | Individual developer work (team of 8, 3 active sandboxes) | Seed data with synthetic donors, schools, inventory |
| QA/TEST | Partial Copy | Integration testing with Composer sandbox connections, QA validation | Connected to ShelfTrack staging, Stripe test mode, MailChimp test list |
| UAT | Partial Copy | Business stakeholder acceptance | Programs, fundraising, and warehouse staff validate workflows |
Partial Copy (not Full Copy) for both QA and UAT is appropriate for BookBridge — the nonprofit budget ($1.2M) does not justify Full Copy licensing, and Partial Copy with sampled data provides sufficient test coverage for the data volumes involved.
Branching Strategy
- main — production-ready; deploys to Production via DevOps Center
- develop — integration branch; auto-deploys to QA sandbox
- feature/[work-item]-description — individual feature branches in Dev sandboxes
- Pull requests require 1 peer review (team is learning; reviews double as knowledge transfer)
- Merges to
mainrequire QA analyst sign-off + business stakeholder UAT approval
Testing Strategy
| Test Type | Environment | Scope | Criteria |
|---|---|---|---|
| Apex Unit Tests | Developer sandboxes | Custom Apex, triggers, batch jobs | >75% coverage; mock callouts for all Composer-invoked APIs |
| Integration Tests | QA | All 6 system connections via Composer sandbox | End-to-end data flow validated; error handling exercised |
| Load Testing | QA | Stripe webhook processing at peak volume | Simulate 12K donations/day (year-end); validate Platform Event processing |
| UAT | UAT | Donor management, book requests, volunteer workflows | Business users validate real-world scenarios; 3-day UAT per release |
CoE / Post-Go-Live Governance
Team Growth Path: The 8-person tech team (from 3 six months ago) needs structure, not overhead. DevOps Center provides visual deployment tracking as a stepping stone. Plan to evaluate migration to GitHub Actions + SFDX at the 12-month mark once the team has foundational skills.
Release Cadence:
- Standard releases: Bi-weekly (2-week sprints) aligned with DevOps Center work items
- Hotfixes: Same-day path for critical defects (e.g., donation processing failures)
- Blackout window: No production deployments November 1 through January 15 (year-end campaign + reconciliation period)
Onboarding: Development process documented in a runbook (Req 48) covering sandbox setup, branching conventions, deployment steps, and integration testing procedures. Target: new team member onboards within 5 business days.
Ongoing Governance: CTO reviews all integration changes; QA analyst gates all deployments; monthly tech debt review to prevent the “GiveHub problem” (undocumented, untested custom code) from recurring.
Requirements Addressed
- ✅ Unified constituent profiles — Single Contact record linking donor, volunteer, and event data (Reqs 1-2, 13)
- ✅ Zero-downtime donation processing — Stripe webhooks → Platform Events with 72-hour replay; spring cutover avoids December (Req 3)
- ✅ Hub-and-spoke integration — MuleSoft Composer central hub for 6 systems, extensible for 2-3 new/year (Reqs 33-40)
- ✅ SFTP district data ingestion — District-specific ETL mappings with staging object and validation (Reqs 20, 35)
- ✅ Book lifecycle tracking — Donation → warehouse → distribution chain linked via Composer sync with ShelfTrack (Reqs 8-12)
- ✅ School/volunteer portal — Single Experience Cloud site with audience-based visibility (Reqs 24, 26)
- ✅ Structured dev process — DevOps Center with 4-environment strategy; QA + stakeholder gates (Reqs 41-48)
- ✅ Donor deduplication — Fuzzy matching across GiveHub, MailChimp, and Eventbrite with survivorship rules (Reqs 16, 19)
Risk Assessment
| Risk | Impact | Prob | Mitigation |
|---|---|---|---|
| Year-end donation processing failure | CRITICAL | MED | Async Platform Events with replay; no cutover Nov-Jan; load test at 2x peak (24K/day) |
| Team overwhelm (simultaneous process + platform change) | HIGH | HIGH | Phased rollout: environments first (Mo 1-2), core platform (Mo 3-8), integrations one-at-a-time (Mo 9-14) |
| SFTP format changes break ingestion | MED | HIGH | District-specific mappings isolated; staging object catches bad data; monitoring alerts on validation failures |
| GiveHub security vulnerability before decommission | HIGH | MED | Rails 5.2 EOL; implement WAF rules; accelerate Stripe-direct to reduce GiveHub to read-only |
Domain Scoring Notes
- D5 Integration (HEAVY): Classify EACH integration by protocol/pattern/direction/volume. Address SFTP separately from REST. Explain error handling per integration individually — “MuleSoft handles errors” is not sufficient.
- D6 Dev Lifecycle (HEAVY): Design CI/CD for the team’s current maturity. Acknowledge the maturity gap. Include onboarding documentation, release process, and automated testing strategy (mock callouts in sandboxes).
- D3 Data (MED): Unified constituent model — single Contact for a person who is both donor and volunteer (Req 13). Donor deduplication across 3 systems.
- D1 System Arch (LIGHT): Mention Power of Us program (10 free licenses) to show budget awareness.
Reporting Approach
Standard Salesforce reports and dashboards cover the Executive Director dashboard (Req 27), campaign performance (Req 28), and grant funder reports (Req 32). The impact reporting chain (donation → books → schools → students, Req 29) requires cross-object report types linking Donation, Inventory, Distribution, and School records. The automated monthly reconciliation (Req 30) is a scheduled Apex batch comparing platform totals against Stripe settlements and QBO journal entries. If the board quarterly report (Req 31) or cross-system impact analytics demand more sophisticated visualization, consider CRM Analytics (included in some nonprofit bundles) for cross-source dashboards.
What Would Fail
- Point-to-point integrations for everything — 6 systems growing to 9 means up to 36 connections. Req 41 explicitly requires accommodating new connections without re-architecture. Hub-and-spoke is the only defensible answer.
- Treating SFTP the same as REST APIs — The 15 district feeds are batch, schema-less, and arrive on different schedules. Lumping them with REST integrations shows you did not read the scenario. Note: MuleSoft Composer does not support SFTP natively — this integration requires Anypoint Platform’s SFTP connector or an alternative approach. Judges expect a specific staging and transformation strategy.
- Prescribing enterprise CI/CD for a beginner team — Jenkins, GitHub Actions + SFDX, and feature-flag management for a team that was deploying to production manually 3 months ago is tone-deaf. Start with DevOps Center, then evolve.
Self-Scoring Checklist
- Did I classify every integration by protocol, pattern, direction, and volume?
- Did I justify middleware vs point-to-point with a specific rationale?
- Did I handle the SFTP feeds differently from the REST APIs?
- Did I design the CI/CD for the team’s current maturity level?
- Did I avoid the December cutover window?
- Did I present a unified constituent model (not separate donor/volunteer)?
- Did I include error handling for each integration?
Scoring Rubric
| Criterion | Weight | What Judges Look For |
|---|---|---|
| Integration Architecture | 30% | Every integration classified by protocol, pattern, direction, and volume. Hub-and-spoke justification over point-to-point. SFTP feeds treated differently from REST APIs. Error handling per integration with retry, DLQ, and monitoring strategies |
| Dev Lifecycle & Governance | 25% | CI/CD maturity matched to team capability (not enterprise overkill for a beginner team). Environment strategy with appropriate sandbox types. Release planning that avoids the December donation spike. Change management process |
| Solution Design | 20% | Unified constituent model (not separate donor/volunteer objects). Nonprofit Cloud justification. Build-vs-buy decisions for each capability area |
| Data Architecture | 15% | Constituent deduplication strategy across 6 systems. Data quality handling for inconsistent SFTP formats. Scaling plan for 5,000-school growth target |
| Communication & Trade-offs | 10% | Clear explanation of middleware choice, why DevOps Center before full CI/CD, how the architecture accommodates future integrations (Req 41) without re-architecture |
This is a personal study site for Salesforce CTA exam preparation. Built with AI assistance. Not affiliated with Salesforce.