Adding a New Connector

Step-by-step guide for adding a new commerce platform connector to Brainerce.

For the live reference implementation, read apps/google-youtube-connector/ in the monorepo. It is the connector currently in production and every contract below is exercised there. apps/woocommerce-connector/ is an empty directory left behind by a retired service, and apps/google-merchant-connector/ is the superseded standalone service that google-youtube replaced; do not use either as a model.

Do not look for a TypeScript interface to implement: there is no ConnectorContract type anywhere in the monorepo, and packages/connectors/ holds legacy in-process mappers that only the Migration Tool's one-time import still uses. The endpoint list below is the contract, declared per app as connectorContract.endpoints in the manifest.

Quick Checklist

Required Endpoints

  • GET /health: returns { ok: true }
  • POST /sync/connection-status: test credentials, return { connected: boolean }
  • POST /sync/push-product: transform and push product, return { externalId }
  • POST /sync/pull-orders: fetch and normalize orders, return { orders, hasMore }
  • POST /sync/reconcile: list all external resource IDs

Optional Endpoints

  • POST /oauth/start: return OAuth redirect URL
  • POST /oauth/callback: exchange code for tokens, return { secrets }
  • POST /hooks/on-install: setup on installation
  • POST /hooks/on-uninstall: cleanup on uninstall
  • POST /hooks/on-config-update: validate new config

Manifest

  • App manifest with type: "connector" and connectorContract.endpoints
  • Config schema (JSON Schema) defining the settings form
  • Secret fields use "format": "password"

Data Mapping

  • Product mapper: Brainerce format → platform format (handle overlays)
  • Order mapper: platform format → Brainerce normalized format
  • Handle edge cases: missing images, duplicate SKUs, variants

Canonical Product URL

Feed-style connectors (Google Merchant, Meta Catalog, …) need a link per product that points back to the merchant's storefront. The backend computes this from the linked Sales Channel's domain + productUrlTemplate and injects it into push-product calls as productUrl: string in the request body.

  • Read req.body.productUrl in push-product and use it as the platform's link / landing_url / equivalent field
  • Decide what to do when productUrl is absent, and document the choice. The backend deliberately leaves this to the connector: reject the push, or fall back to a URL shape of your own. The shipped reference falls back to `${websiteUrl}/products/${encodeURIComponent(slug)}` rather than rejecting. There is no platform-wide MISSING_PRODUCT_URL error code; if you reject, define your own.
  • The bare primaryDomain (hostname only) is also available on the StoreContext for connectors that need to derive other URLs (e.g. homepage verification). There is no primaryProductUrlTemplate on StoreContext; the resolved per-product productUrl in the request body is the supported input.

Dependencies

{
  "dependencies": {
    "@brainerce/app-sdk": "workspace:*",
    "express": "^4.21.0"
  }
}