Skip to content

SOP-OB-002: Customer Onboarding — New ERP Integration Required (Full Path)

Version: 1.1 Owner: CS Lead + Engineering Lead Audience: Customer Success (CS), Engineering (ENG) Target timeline: 4–8 weeks (depending on ERP API complexity)


This SOP governs onboarding for customers whose ERP is either:

  • Not yet in the integration registry at all, or
  • In the registry but not yet implemented (status 'beta' with a NotImplementedError in the factory, e.g., some dynamics or sap variants)

This path requires an engineering build sprint before full customer onboarding can proceed. To minimize elapsed time, provisioning work that does not depend on the integration being built starts immediately in parallel.

Not covered: If the customer’s ERP is already in the registry and the integration is implemented, use SOP-OB-001.

Role key:

AbbreviationRole
CSCustomer Success
ENGEngineering / DevOps
CUSTCustomer (their IT or admin contact)

Once the contract is signed, work splits into two tracks that run concurrently and merge when engineering signals “ready.”

Contract signed
|
+------------------------+
| |
TRACK A TRACK B
Engineering Build Pre-Provisioning
(SOP-OB-003) (CS + ENG, no ERP needed)
| |
| ENG signals "ready" |
+------------------------+
|
Track Merge
(Steps C1–C8)
|
UAT → Go-Live

3. Prerequisites — Extended Intake Checklist

Section titled “3. Prerequisites — Extended Intake Checklist”

All items from SOP-OB-001 Section 2, plus:

  • ERP vendor name, exact product name, and version
  • Link to the vendor’s API documentation (or confirmed NDA for confidential docs)
  • API type: REST/JSON, OData, SOAP/XML, JSON-RPC, direct database
  • Authentication mechanism: Basic auth, OAuth2 (client credentials / auth code), API key, session cookie, token
  • Sandbox / test environment credentials obtained and verified with curl or Postman
  • API rate limits documented (requests/min, page size limits)
  • Entities available via the API:
    • Products / items (required)
    • Customers / accounts (required)
    • Shipping addresses / ship-to locations
    • Cross-references / customer item aliases
    • Ship-to links / customer–address relationships
    • Orders and order lines (for write-back)
  • Incremental sync mechanism available? (e.g., lastModifiedDate filter, sequence number, change log endpoint)
  • Pagination approach: offset/limit, cursor-based, OData $skip/$top
  • ERP vendor API terms of service reviewed (no restrictions on third-party automation)
  • Customer has confirmed they are permitted to grant API access to ERP Unlocked
  • NDA in place if vendor API docs are confidential
  • Rough scope estimate completed by ENG (days of engineering work)
  • Timeline agreed with customer in writing — milestone-based, not a fixed go-live date
  • Customer explicitly notified: go-live date is contingent on sandbox API access and successful test

All Track A work follows SOP-OB-003 in detail. This section provides the project management checkpoints.


Step A1 — Engineering Scoping Call + Manual Discovery Owner: ENG + CUST IT

Schedule a 1-hour technical call with the customer’s IT or ERP admin contact. Because there is no Instance Explorer yet for this ERP, this call must gather the information the explorer would normally auto-detect.

Standard scoping outputs:

  • Confirmed entity list for Phase 1 of the integration (products, customers, addresses, etc.)
  • Auth mechanism confirmed and tested in sandbox with curl or Postman
  • Sandbox credentials granted to ENG
  • Blocker list documented (missing docs, no sandbox, rate limit concerns, SOAP/XML complexity)
  • ENG produces a written scope estimate within 2 business days

Manual discovery — answers to gather (replace the Instance Explorer for this ERP):

  • Which entity modules are licensed and API-accessible?
  • Are there custom fields on customer, item, or order records? What are their names and types?
  • What is the pricing model? (list price, customer-specific, volume tiers, third-party pricing engine such as RPM or Cavallo)
  • Multi-company or multi-branch setup? Does order submission require a Branch or Company ID?
  • Approximate record counts for products and customers (for sync time planning)
  • API version and any known quirks (rate limits, null handling, non-standard date formats)
  • Any known data quality issues (duplicate records, missing required fields, etc.)

Document findings in docs/erp/<slug>-discovery.md — this file becomes the seed for the Instance Explorer that will be built in SOP-OB-003.

Blockers must be resolved before engineering starts. A common blocker is a customer who has a sandbox environment in name only — verify that data in the sandbox is realistic (populated products, customers, etc.) before committing to the timeline.


Step A2 — Build the Integration Owner: ENG

Follow SOP-OB-003 in full. At minimum, the completed integration includes:

DeliverableLocation
Registry entrypackages/integrations/src/registry/registry.ts
Python auth handlerapps/dagster/erp_pipeline/sources/<slug>/auth.py
Python HTTP client + DLT sourceapps/dagster/erp_pipeline/sources/<slug>/
Transformers (all entities)apps/dagster/erp_pipeline/transformers/<slug>_*.py
Transformer registryapps/dagster/erp_pipeline/transformers/registry.py
Sync orchestratorapps/dagster/erp_pipeline/implementations/<slug>_sync_orchestrator.py
Factory registrationserp_source_factory.py + erp-sync-factory.ts
Default capabilitiesapps/dagster/erp_pipeline/capabilities.py
Auth getter in erp_auth.pyapps/dagster/erp_pipeline/sources/erp_auth.py
Unit + integration tests passingapps/dagster/tests/
Integration docsdocs/erp/<slug>-integration.md

Step A3 — Staging Deployment Owner: ENG

  1. Merge PR to main after code review (use PR label new-erp-integration)
  2. Confirm the Dagster staging environment picks up the new orchestrator
  3. Run one full sync against the customer’s sandbox ERP from staging
  4. Spot-check data quality: record counts match ERP admin UI within ~1%, field mapping correct for 10 sampled records
  5. Confirm no regressions on existing integrations (Prophet21, NetSuite test jobs still green)

ENG signals “ready” to CS — this is the Track Merge trigger. Send a Slack message in the customer’s internal channel with:

  • Confirmation the staging sync passed
  • The new ERP slug to use in connection setup
  • Any known limitations to communicate to the customer

5. Track B: Pre-Provisioning (Runs in Parallel with Track A)

Section titled “5. Track B: Pre-Provisioning (Runs in Parallel with Track A)”

These steps do not require the integration to be built. Start them immediately after contract signing.


Step B1 — Create Clerk Organization Owner: CS

Identical to SOP-OB-001 Step 1. Do this on Day 1 after contract signing.

Record the clerkOrganizationId. Do not invite users yet — wait until the integration is ready (Step C5).


Step B2 — Create Flagsmith Org Identity (Conservative) Owner: ENG

Create the Flagsmith identity using the clerkOrganizationId. Set conservative flags — disable anything that requires the integration:

erp_sync_enabled = false (enable in Step C4 after integration deployed)
order_review_enabled = true (safe to enable now — UI only)
pdf_extraction_enabled = true (ERP-agnostic, safe to enable now)
email_intake_enabled = true (ERP-agnostic, safe to enable now)

Step B3 — Set Up Email Intake Owner: CS + CUST

Email intake is ERP-agnostic — it can be configured, tested, and handed off to the customer before the ERP integration is built.

  1. Provision the customer’s dedicated inbound email address
  2. Send forward-rule setup instructions to CUST
  3. Verify receipt of a test email before Track Merge begins

This means by the time the integration is ready, the customer’s email flow is already working.


After ENG signals “ready” (Step A3 complete):


Step C1 — Create ERP Connection Record Owner: ENG

Identical to SOP-OB-001 Step 2, using the new registry slug. Use the production credentials provided by CUST (not sandbox).


Step C2 — Test Connection Owner: ENG ⛔ Gate

Use the same request format as SOP-OB-001 Step 3: send integrationSlug and credentials (the production credentials from Step C1). If the test is run from the webapp UI, it uses the existing connection and connectionId instead of a raw body.

POST /api/integrations/connections/test
{
"integrationSlug": "<slug>",
"credentials": { <production credentials from Step C1> }
}

Expected response: { "success": true }. This must pass against the production ERP before proceeding.


Step C3 — Run Instance Explorer Owner: ENG 🔍

If the Instance Explorer was built as part of the integration (SOP-OB-003 Phase 5), run it now against the production connection:

# Via Dagster UI or direct call:
orchestrator.run_instance_explorer(connection_id)
# Profile saved to erp_connections.extra_config["tenant_capability_profile"]

Compare the automated findings against the manual discovery from Step A1:

  • Did the explorer find any additional custom fields not mentioned during scoping?
  • Does the entity availability match what customer IT said was licensed?
  • Does the record count match expectations (or is data much larger/smaller than anticipated)?
  • Any unexpected pricing engines or multi-branch structure?

Document discrepancies. If the explorer surfaces something new (e.g., a third-party pricing engine the customer didn’t mention), flag it immediately — it may require development work before order write-back is safe.

If the Instance Explorer was not built yet (deferred to Phase 2 work): fall back to the manual discovery findings from Step A1 to inform capability overrides in the next step.


Step C4 — Configure Capability Overrides Owner: ENG

Use the defaults from capabilities.py for the new ERP type (set in SOP-OB-003 Phase 9), adjusted by explorer findings from Step C3 (or manual discovery from Step A1 if explorer not yet built).

The ENG who built the integration must brief CS on any capability limitations before this step.


Step C5 — Configure Extra Config Owner: ENG

Set extra_config as appropriate, including the tenant_capability_profile from Step C3 if the explorer ran successfully.


Step C6 — Enable Flagsmith Flags Owner: ENG

Update the Flagsmith org identity to enable erp_sync_enabled = true and any other flags that were deferred in Step B2.


Step C7 — Initial Data Sync Owner: ENG

Identical to SOP-OB-001 Step 9. Trigger the initial full sync via Dagster for the new connection.


Step C8 — User Invites → UAT → Go-Live Owner: CS + CUST

Identical to SOP-OB-001 Steps 10–14. The process is identical once the integration is live.


  • Do not build write operations (order submission Temporal workflows) without sandbox access
  • Read-only sync (Dagster pipeline) can be built against production ERP data in a non-destructive manner — GET operations only
  • Communicate clearly in the contract: order write-back is deferred until sandbox access is confirmed
  • Timeline: customer must provide sandbox within 30 days of contract signing or write-back is scoped to a Phase 2

No existing connector uses SOAP/XML. Budget 2–3 additional engineering days for a custom XML client. Identify this in Step A1 and update the scope estimate before committing to a timeline.

If the ERP has no external API and only exposes data via ODBC/JDBC or direct SQL:

  • Use the database_connector.py pattern from apps/dagster/erp_pipeline/sources/prophet21/ as the reference
  • Requires the customer to open a firewall port and provide database-level read credentials
  • Budget 2–4 additional engineering days for the DB connector + schema discovery
  • Coordinate security requirements with CUST IT carefully (principle of least privilege)

Customer Requests Order Write-Back Before Read Sync Is Complete

Section titled “Customer Requests Order Write-Back Before Read Sync Is Complete”

Do not allow this. The order matching and fuzzy lookup logic depends on having a populated local product and customer dataset. If write-back is attempted before read sync is complete, order submission will fail or produce garbage matches. Enforce sequencing: read sync must show at least one successful completed run before any write operations are enabled.

If the customer requests additional entities or capabilities that were not scoped in A1:

  • Assess the impact to the timeline
  • Get customer written acknowledgment of the revised timeline
  • Do not delay go-live for out-of-scope requests — build them as Phase 2

8. Milestone Gates and Customer Communication

Section titled “8. Milestone Gates and Customer Communication”
MilestoneOwnerCustomer Communication
Contract signedCSKickoff email: welcome + estimated timeline + what we need from them
Intake complete + scope confirmedCS + ENGTimeline confirmation email + blocker/risk list
Sandbox access confirmedCUST + ENG”Unblocked — engineering starting” notification
Staging sync validatedENG”Ready for onboarding” email to CS; CS notifies customer
Initial prod sync completeENGInvite users; schedule UAT call
UAT passedCS + CUSTGo-live confirmation email + support info
30-day check-inCSProactive health check: sync status, order volume, any issues

  • Mark the registry entry status: 'draft' in registry.ts — prevents new connections
  • Remove the orchestrator from ERPSourceFactory._SUPPORTED_ERP_TYPES if the ERP type will not be offered to other customers
  • Archive all engineering artifacts (branches, PRs, docs) — do not delete
  • Follow SOP-OB-001 Section 6 for the customer provisioning rollback

Same as SOP-OB-001 Section 6.