Skip to main content

Add a Connector Checklist

Use this checklist before opening a connector pull request. Start by deciding whether the provider belongs on the generic adapter path or needs a dedicated workflow. Most imports belong on the generic path.

Identity and installation

  • Define one stable integration slug and connection mode.
  • Use the shared integration create/upsert path unless the provider requires stronger atomic credential handling. Record any exception beside the connector architecture.
  • Use a provider-owned external_id when the install response exposes a stable account or shop identifier. Never substitute a mutable label or domain.
  • Verify OAuth credentials, API keys, or personal access tokens before activation. Store secrets only in encrypted api_keys; keep them out of settings, logs, activity metadata, and responses.
  • Attribute credential and resource mutations to the authenticated actor and record the install activity.
  • Prove reinstall behavior for active, soft-deleted, and concurrently created rows. Preserve user settings and linked resources deliberately, and delete replaced keys only when orphaned.
  • Run the App Store billing gate for a priced listing. An unpublished or free connector may use a documented exception, but the exception must be removed or re-evaluated before pricing.
  • Seed sales channels, payment methods, custom properties, and posting fields with idempotent find-or-create/upsert functions.

Adapter and orchestration

  • Add the adapter under packages/temporal-workflows/src/adapters/<provider>/ and register every data-type-specific key in registry.ts.
  • Import registry implementations from their files, not the adapter barrel, to avoid the registry/index circular dependency.
  • Add each stream to getShopAdapterConfig, including its enabled setting, watermark, task queue, and any provider-specific freshness interval.
  • Use generateShopWorkflowId and getShopTaskQueue for both scheduled and manual syncs. Build standard manual actions with createShopTriggerSyncAction.
  • Start syncIntegrationWorkflow as the connector entry point. Provider-specific files called by the generic chunk processor are internal processors, not additional workflow entries.
  • Register every activity used by the workflow on the worker polling that stream’s task queue. Do not add a queue unless the connector cannot safely share an existing one.
  • Import the worker factory in apps/temporal-workers/src/workers/index.ts, add its workers to the worker list, and test that the expected activities are registered.
  • Make adapter transforms and downstream writes idempotent using immutable provider identities.

Product and UI surface

  • Add constants, install/connection settings, manual sync controls, and the setup route under the provider’s webapp folders. Remove scaffolding once the real settings UI replaces it.
  • Add translated user-facing copy in both message catalogs.
  • Reserve the provider’s custom-property namespace and use snake-case provider identity keys.
  • Add a product external-ID label when imported line items expose a provider product identity.
  • Keep the integration folder list and adapter registry tables in docs/codebase/integrations.md current.

Seed and release gate

  • Add one App Store listing plus required translations to shared seed data. The seed must upsert by stable keys so repeated runs converge.
  • Set connection_modes and creates_sales_documents to match actual behavior.
  • Keep is_published: false until install, settings, sync, worker registration, billing, and operator support are ready. Do not use publication as an implementation placeholder.
  • Add seed tests that assert slug, mode, document behavior, translation presence, and intended publication state.
  • Add an Unreleased changelog entry and focused tests for install idempotency, adapter selection, deterministic workflow IDs, already-running workflows, and redacted failures.

Xentral’s documented install exception

Xentral uses the generic shop adapter and scheduler path, but its PAT installer intentionally does not call createIntegration:
  • Installation probes invoice, credit-note, and customer reads before persisting the PAT.
  • The app actor, encrypted key, integration row, activity log, key rotation, and orphan cleanup commit in one serializable transaction. Splitting this across createIntegration would weaken that all-or-nothing guarantee.
  • Xentral is limited to one API integration per organization. The installer checks that invariant before verification and again inside the transaction, and resurrects the matching archived row. That organization-scoped slot is the install identity because the read-only preflight does not supply a stable provider account ID for external_id.
  • Sales-channel and custom-property setup is idempotent and may retry after the credential transaction.
  • The listing remains unpublished and free, so the shared billing gate is currently a no-op in behavioral terms. Revisit the custom installer before publishing or pricing Xentral.
Xentral manual and scheduled imports both start syncIntegrationWorkflow. The process-xentral-invoices.ts and process-xentral-credit-notes.ts files are live internal chunk processors that preserve Xentral identity, source metadata, lifecycle updates, and accounting behavior; they are not alternate workflow entry points.