Skip to main content

Integrations & Adapters

Two layers cooperate. The webapp owns install, OAuth, and sync triggering; the workflows package owns data fetching and normalisation.
Three different counts are all correct at different layers: 34 registry entries, 19 provider families, 29 integration folders. Any legend must say which it means.

The two layers

The adapter contributes the fetch and the transform. Everything after that — customers, addresses, deduplication, document creation, accounting handoff — is shared. See Temporal Orchestration.

Registry keys vs adapter slugs

registry.ts:49-66 documents a distinction that trips people up:
  • Registry keys are data-type-specific: shopify-orders, shopify-payments
  • Adapter slugs are generic: shopify
The workflow looks up by registry key. The slug builds custom property names like shopify_customer_id, so both shopify-orders and shopify-payments produce the same custom field.

Three tiers

Not every folder under app/lib/integrations/ is a working integration. Tier 2 has no trigger-sync.ts by design — those providers ingest by file upload, not API poll. docmorris is the clearest case: it has a registered adapter (docmorris-orders-csv) and a dedicated worker, but the provider offers no API sync. The registry naming carries the signal — docmorris-orders-csv, otto-payments-csv, paypal-payments-csv. Tier 3 are intentional placeholders. Each is a single constants.ts exporting only App Store listing metadata, referenced by exactly one file — its own settings page. They appear in the App Store and do nothing.

Special cases

  • mirakl — not a provider. The shared base for the six marketplaces below.
  • google — real OAuth config for Google Drive, but an export destination, not a data source. Used by api/google/auth, api/google/callback, api/export/google-sheets.

The Mirakl factory — the same pattern twice

Six marketplaces run on the Mirakl platform and share one implementation, at both layers. Drawing six independent integrations would triple the node count and hide the design.

Registry contents

Note that four providers ship both CSV and API adapters — amazon, paypal, otto, and docmorris (CSV only). The mode is chosen at sync time, not install time.

Notes

Adapters must be imported from their files, never from ./index.js. registry.ts:6-9 warns that importing through the barrel creates a circular dependency — index.js exports registry.js, which would import from index.js before the adapter exports are processed.
Sync triggering follows one convention. app/lib/integrations/<provider>/trigger-sync.ts starts the workflow on that provider’s queue. The six Mirakl marketplaces are one-line factory calls; shopify has three start sites, amazon-api builds its queue name dynamically. Credentials live in core. OAuth token handling is in the otto-oauth, stripe-app-oauth, and finapi domains; API keys go through api_keys, which mirakl/get-api-credentials.ts reads. Integration setup pages are uniform. All 24 live at setup/integrations/<provider>/[id] and share a layout. See Webapp.