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

# Temporal Orchestration

> How workflows, activities, and core functions fit together — and the shared ingestion pipeline that every integration runs through

# Temporal Orchestration

39 workflow functions and 238 activities across 33 task queues. The important structural
fact is that **almost all of it is one shared pipeline** — provider-specific code is a
thin adapter at the front.

## The layering

```mermaid theme={null}
flowchart TB
    WebApp["@cona/webapp<br/>trigger-sync.ts"] -->|"start workflow<br/>on provider task queue"| Temporal["Temporal Cloud"]
    Temporal -->|"task queue poll"| Worker["Worker process<br/>@cona/temporal-workers"]
    Worker -->|"executes"| Workflow["Workflow<br/>deterministic, no I/O"]
    Workflow -->|"proxyActivities"| Activity["Activity<br/>238 exported"]
    Activity -->|"@cona/core/domains/*"| Core["@cona/core<br/>business logic"]
    Core -->|"Prisma"| DB[("Supabase Postgres")]

    classDef app fill:#dbe2fb,stroke:#3B56C5,color:#111827
    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    classDef pkg fill:#e8eafd,stroke:#4967E6,color:#111827
    classDef data fill:#fde8e8,stroke:#c53b3b,color:#111827

    class WebApp app
    class Temporal,Worker,Workflow,Activity async
    class Core pkg
    class DB data
```

Activities import `@cona/core/domains/*` 292 times. The most-imported domain is `actors`
(21) — confirming that mutation attribution is enforced at the activity layer, not left to
core.

## The shared ingestion pipeline

`syncIntegrationWorkflow` is the universal entry point for **every** integration. Its own
docstring calls it "a universal workflow that can process ANY integration using the
adapter pattern" (`sync/sync-integration-workflow.ts:1-9`).

```mermaid theme={null}
flowchart TB
    Trigger["trigger-sync.ts<br/>or CSV upload"] --> Entry["syncIntegrationWorkflow<br/>sync-integration-workflow.ts:44"]

    Entry -->|"sourceType = api"| Api["runApiModeSync<br/>api-mode-sync.ts:108<br/>paginated, time-chunked"]
    Entry -->|"sourceType = csv"| Csv["runCsvModeSync<br/>csv-mode-sync.ts:67<br/>signal-driven batch queue"]

    Api --> Chunk["processChunkData<br/>chunk-processor.ts:99"]
    Csv --> Chunk

    Chunk --> S1["1 · Transform via adapter"]
    S1 --> S2["1.5 · Apply import mapping rules"]
    S2 --> S3["2 · Process customers + addresses"]
    S3 --> S4["2.5 · Process sender addresses"]
    S4 --> S5["3 · Deduplication check"]
    S5 --> S6["4 · Prepare documents for creation"]
    S6 --> S7["4.5 · Resolve line item SKUs to items"]
    S7 --> S8["5 · Create documents in batches"]
    S8 --> S9["5.5 · Explode bundle line items"]
    S9 --> S10["5.6 · Portal tokens + auto-send"]
    S10 --> S11["6 · Existing document updates"]
    S11 --> S12["7 · Update subsidiary address"]
    S12 --> Enqueue["enqueueAccountingJobsActivity<br/>chunk-processor.ts:801"]

    Enqueue --> Queue[("accounting_work_queue")]
    Queue --> Accounting["syncAccountingQueueWorkflow"]

    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    classDef data fill:#fde8e8,stroke:#c53b3b,color:#111827
    classDef step fill:#f4f6fb,stroke:#94a3b8,color:#111827

    class Entry,Api,Csv,Chunk,Accounting,Enqueue,Trigger async
    class Queue data
    class S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12 step
```

**This is why every integration worker registers 20-35 near-identical activities.** The
adapter contributes steps 1 and the data fetch; steps 1.5 through 7 are shared by all
providers.

The pipeline ends by enqueuing to `accounting_work_queue` rather than calling accounting
directly. That decoupling is the subject of
[Accounting Engine](/architecture/accounting-engine).

### Provider-specific escapes

Three steps branch on provider inside the shared pipeline:

| Step      | Branch                                             | Location                   |
| --------- | -------------------------------------------------- | -------------------------- |
| 2         | `resolveXentralCustomersBatchActivity` for Xentral | `chunk-processor.ts:209`   |
| 5.5       | Shopify document write-back, marked non-critical   | `chunk-processor.ts:409`   |
| API fetch | Amazon report download + VAT report polling        | `api-mode-sync.ts:508,598` |

<Note>
  `chunk-processor.ts` labels two consecutive blocks `STEP 5.5` (lines 370 and 409). A cosmetic
  duplication in the source comments, not a logic error — recorded so a reader comparing this
  diagram to the file is not confused.
</Note>

## Task queue routing

33 queue constants in `packages/temporal-config/src/shared.ts`. 29 have a live worker.

| Purpose             | Queues                                                                                        |
| ------------------- | --------------------------------------------------------------------------------------------- |
| Shop imports        | `shops-global`, `shopify-shop`, `orderchamp`, `xentral`, `tiktok-shop`, `docmorris-orders`    |
| Mirakl marketplaces | `shop-apotheke`, `bild-marktplatz`, `douglas`, `media-markt-saturn`, `fressnapf`, `decathlon` |
| Amazon              | `amazon-settlements`, `amazon-vat-report`                                                     |
| Payments & banking  | `paypal-payments`, `stripe-invoices`, `bank-account-payments`, `otto`                         |
| Accounting          | `accounting-queue`, `recreate-accounting-impact-batch`                                        |
| Reconciliation      | `reconciliation-global`, `reconciliation-org`                                                 |
| Platform            | `fx-global`, `gdpr`, `data-retention`, `org-deletion`, `billing-renewals`, `datev-export`     |
| Non-production      | `test-doc-generation`                                                                         |

<Warning>
  Four declared constants have **no worker and no caller**: `amazon-orders`, `paypal-global`,
  `shopify-global`, and `queue` (`TASK_QUEUE_NAME`). Only `shopify-global` is marked deprecated in
  the source. A workflow started on any of them would wait forever. They are omitted from the table
  above.
</Warning>

### Two-tier scheduling

`shops-global` runs a lightweight parent that fans work out to per-shop children:

```mermaid theme={null}
flowchart TB
    Schedule["Temporal schedule"] --> Parent["syncAllShopsWorkflow<br/>queue: shops-global<br/>2 activities · importScheduler profile"]
    Parent -->|"child workflow per shop"| Child1["syncIntegrationWorkflow<br/>queue: shopify-shop"]
    Parent -->|"…"| Child2["syncIntegrationWorkflow<br/>queue: orderchamp, xentral, …"]

    classDef async fill:#e3f7ea,stroke:#2f9e5c,color:#111827
    class Schedule,Parent,Child1,Child2 async
```

The parent worker restricts `workflowsPath` to `scheduled/` so it cannot accidentally pick
up heavy import workflows (`workers/shopify.ts`).

### The Mirakl factory

Six marketplaces share one worker template — `createMiraklMarketplaceWorker` in
`workers/mirakl.ts:76-189`, instantiated once per queue with 29 activities each. The same
factory pattern repeats in the webapp action layer. See
[Integrations](/architecture/integrations-adapters).

## Workflows by group

| Group                                                                                               |  Count | Notable                                                            |
| --------------------------------------------------------------------------------------------------- | -----: | ------------------------------------------------------------------ |
| `sync`                                                                                              |     13 | the shared pipeline above                                          |
| `accounting`                                                                                        |      5 | `syncAccountingQueueWorkflow`, `monthlyRevenueRecognitionWorkflow` |
| `gdpr`                                                                                              |      3 | customer data request, customer redaction, shop redaction          |
| `mirakl`                                                                                            |      3 | invoice auto-submit (standard + OR74), product import              |
| `reconciliation`                                                                                    |      3 | global, per-organisation, agent suggestions                        |
| `general`                                                                                           |      2 | `deleteOrganizationWorkflow`, `generateTestDocumentsWorkflow`      |
| `shopify`                                                                                           |      2 | product import, expired gift cards                                 |
| `amazon`, `billing`, `data-retention`, `datev`, `fx`, `notifications`, `observability`, `scheduled` | 1 each |                                                                    |

## Activity groups

238 activities across 28 groups. The distribution is uneven:

| Group                                   |   Count | Group                                              |  Count |
| --------------------------------------- | ------: | -------------------------------------------------- | -----: |
| `datev`                                 |      44 | `data-retention`                                   |      6 |
| `xentral`                               |      26 | `gdpr`                                             |      5 |
| `general`                               |      21 | `orderchamp`                                       |      5 |
| `amazon`                                |      20 | `utils`, `csv-import`, `notifications`, `stripe`   | 4 each |
| `shopify`                               |      14 | `fx`, `integrations`, `generic`, `otto`, `billing` | 3 each |
| `accounting`, `mirakl`                  | 12 each | `paypal`, `revenue-recognition`, `entities`        | 2 each |
| `reconciliation`, `documents`, `tiktok` | 11 each | `observability`, `bank-account`, `items`           | 1 each |

`datev` at 44 is the largest single group — nearly a fifth of all activities.

## Notes

**Workflows must stay deterministic.** Activity calls go through `proxyActivities`;
the workflow itself performs no I/O. `syncIntegrationWorkflow` uses `continueAsNew` for
long paginated syncs (`api-mode-sync.ts:770,1040`).

**Adapters are imported from their files, never the barrel.** `adapters/registry.ts:6-9`
warns that importing from `./index.js` creates a circular dependency.

**A versioning patch is in flight.** `sync-integration-workflow.ts:26` declares
`LIVE_BACKGROUND_ACTIVITY_PATCH_ID` — a Temporal patch gate for the live background
activity feed.
