> ## Documentation Index
> Fetch the complete documentation index at: https://cona.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrations & Adapters

> The adapter registry, three tiers of integration, and the Mirakl factory pattern that repeats at both layers

# Integrations & Adapters

Two layers cooperate. The webapp owns install, OAuth, and sync triggering; the workflows
package owns data fetching and normalisation.

<Warning>
  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.
</Warning>

## The two layers

```mermaid theme={null}
flowchart TB
    subgraph WebLayer["apps/webapp/app/lib/integrations/&lt;provider&gt;/"]
        Install["install.ts<br/>credentials, first setup"]
        Trigger["trigger-sync.ts<br/>start workflow on provider queue"]
        Constants["constants.ts<br/>App Store listing metadata"]
    end

    subgraph WfLayer["packages/temporal-workflows/src/adapters/&lt;provider&gt;/"]
        Registry["registry.ts<br/>34 entries<br/>getAdapter · hasAdapter · getAdapterSlugs"]
        Adapter["IntegrationAdapter<br/>fetch + transform, pure functions"]
    end

    Provider["External provider API"]
    Pipeline["syncIntegrationWorkflow<br/>shared pipeline"]

    Trigger --> Pipeline
    Pipeline -->|"getAdapter(registryKey)"| Registry
    Registry --> Adapter
    Adapter --> Provider
    Adapter --> Pipeline

    classDef boundary fill:#f8fafc,stroke:#94a3b8,color:#334155

    classDef app fill:#dbe2fb,stroke:#3B56C5,color:#111827
    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    classDef external fill:#fff4dd,stroke:#c98a12,color:#111827

    class Install,Trigger,Constants app
    class Registry,Adapter,Pipeline async
    class Provider external
    class WebLayer,WfLayer boundary
```

The adapter contributes the fetch and the transform. Everything after that — customers,
addresses, deduplication, document creation, accounting handoff — is shared. See
[Temporal Orchestration](/architecture/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.

```mermaid theme={null}
flowchart TB
    subgraph T1["Tier 1 — full API sync (15)"]
        A1["shopify · stripe · paypal-api · tiktok<br/>amazon-api · bank-account · orderchamp<br/>xentral · otto"]
        A2["6 Mirakl marketplaces:<br/>shop-apotheke · bild-marktplatz · douglas<br/>media-markt-saturn · fressnapf · decathlon"]
    end

    subgraph T2["Tier 2 — CSV / manual ingest (6)"]
        B1["amazon-csv · docmorris · mollie<br/>otto-csv · payla · paypal-csv"]
    end

    subgraph T3["Tier 3 — placeholder listing, no implementation (6)"]
        C1["adyen · amazon-pay · bop-data<br/>chargebee · kaufland · klarna"]
    end

    Pipeline["syncIntegrationWorkflow"]
    Upload["CSV upload"]

    A1 -->|"trigger-sync.ts → runApiModeSync"| Pipeline
    A2 -->|"trigger-sync.ts → runApiModeSync"| Pipeline
    Upload --> B1
    B1 -->|runCsvModeSync| Pipeline
    C1 -.->|"no data flow"| Nothing["settings page only"]

    classDef boundary fill:#f8fafc,stroke:#94a3b8,color:#334155

    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    classDef external fill:#fff4dd,stroke:#c98a12,color:#111827
    classDef planned fill:#f4f6fb,stroke:#94a3b8,color:#64748b,stroke-dasharray: 5 4

    class Pipeline,A1,A2 async
    class B1,Upload external
    class C1,Nothing planned
    class T1,T2,T3 boundary
```

**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.

```mermaid theme={null}
flowchart TB
    subgraph Web["Webapp action layer"]
        Factory["app/lib/integrations/mirakl/<br/>create-mirakl-install-action.ts<br/>create-mirakl-sync-action.ts<br/>create-mirakl-update-api-key-action.ts<br/>create-mirakl-verify-shop-id-action.ts"]
        Thin["6 thin wrapper folders<br/>install.ts · trigger-sync.ts<br/>update-api-key.ts · verify-shop-id.ts"]
    end

    subgraph Workers["Worker layer"]
        WFactory["workers/mirakl.ts:76-189<br/>createMiraklMarketplaceWorker<br/>29 activities"]
        Queues["6 task queues<br/>shop-apotheke · bild-marktplatz<br/>douglas · media-markt-saturn<br/>fressnapf · decathlon"]
    end

    Factory --> Thin
    Thin --> Queues
    WFactory --> Queues

    classDef boundary fill:#f8fafc,stroke:#94a3b8,color:#334155

    classDef app fill:#dbe2fb,stroke:#3B56C5,color:#111827
    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    class Factory,Thin app
    class WFactory,Queues async
    class Web,Workers boundary
```

Drawing six independent integrations would triple the node count and hide the design.

## Registry contents

| Family                                                                            | Registry keys                                                                                |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| amazon                                                                            | `amazon-settlements`, `amazon-vat-report`, `amazon-vat-report-api`, `amazon-settlements-api` |
| stripe                                                                            | `stripe-invoices`, `stripe-credit-notes`, `stripe-balance-transactions`                      |
| tiktok                                                                            | `tiktok-orders`, `tiktok-credit-notes`, `tiktok-payments`                                    |
| shopify                                                                           | `shopify-orders`, `shopify-payments`                                                         |
| paypal                                                                            | `paypal-payments-csv`, `paypal-payments-api`                                                 |
| orderchamp                                                                        | `orderchamp-orders`, `orderchamp-payments`                                                   |
| xentral                                                                           | `xentral-invoices`, `xentral-credit-notes`                                                   |
| otto                                                                              | `otto-receipts`, `otto-payments-csv`                                                         |
| shop-apotheke, bild-marktplatz, douglas, media-markt-saturn, fressnapf, decathlon | `<name>-orders`, `<name>-transactions` each                                                  |
| docmorris                                                                         | `docmorris-orders-csv`                                                                       |
| bank-account                                                                      | `bank-account-payments`                                                                      |

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

<Warning>
  **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.
</Warning>

**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](/architecture/webapp-architecture).
