Happy path / Lifecycle
Choose a Salesforce campaign.
Organizer opens campaign sync, selects a campaign, previews member count, and maps Salesforce member status to Voyage registration status.
Import members.
Campaign members become registrations, deduped by normalized email, with row-level import outcomes.
Export registrations.
Voyage registrations are written back to Salesforce campaign members and an audit row records counts and transaction id.
Failure modes
Expired token refresh
Expired OAuth token refreshes and retries the campaign member request.
429 backoff
Salesforce 429 backs off with jitter without compounding independent sync runs.
Webhook replay
Campaign callback replay does not duplicate imports or exports.
Schema drift
Unknown CampaignMember fields are ignored; optional status fields default.
Missing credential
Invalid credential shows re-auth CTA and no stack trace.
Sandbox isolation
Mock fixture cannot read live Salesforce data.
Audit row
Each import/export run writes tx-id, status, imported, exported, skipped, and failed counts.
Partial rollback
Mid-batch failure either rolls back or shows durable per-row partial success.
Email dedupe
Duplicate emails map to one registration with conflict outcome.
Status mapping missing
Unmapped member status blocks commit until the organizer maps or skips it.
Export conflict
Salesforce duplicate campaign member conflict is surfaced per row.
Parity gap
Gap panel remains visible until campaign import/export exists.
Stable test attributes
Visibility teeth. Preview, commit, outcome, and gap attributes must be visible whenever active.
| data-test | Where | Purpose |
|---|---|---|
salesforce-campaign-sync-panel | campaign sync | main surface |
salesforce-campaign-picker | campaign sync | campaign selection |
salesforce-member-status-map | campaign sync | status mapping |
salesforce-import-preview | campaign sync | row preview |
salesforce-import-commit-cta | campaign sync | import commit |
salesforce-export-commit-cta | campaign sync | export commit |
salesforce-row-outcome-table | campaign sync | per-row outcomes |
salesforce-campaign-gap-panel | campaign sync | absent gap marker |
Agent test plan
- salesforce-campaign-sync-opens
- salesforce-campaign-preview-import
- oauth-refresh-on-expired-token
- rate-limit-backoff
- webhook-replay-idempotent
- schema-drift-degrades-gracefully
- missing-credential-graceful-error
- sandbox-vs-prod-isolation
- audit-log-row-per-sync
- partial-import-rollback
- email-dedupe
- member-status-map-required
- export-conflict-row-outcome
- salesforce-campaign-gap-probe