Skip to main content

Ecommerce Shopify Operations Runbook

Operational runbook for diagnosing and recovering ecommerce integration issues in apps/backend/src/ecommerce/.

This runbook is source-backed and reflects the current Shopify-only implementation.


Scope

Codepaths covered:

  • interfaces/ecommerce.controller.ts
  • infrastructure/shopify/shopify-webhook.controller.ts
  • application/ecommerce.service.ts
  • infrastructure/ecommerce-polling.processor.ts
  • infrastructure/ecommerce-provider.factory.ts
  • infrastructure/ecommerce-connection.repository.ts

1) Triage matrix

SymptomLikely area
OAuth callback redirects with ?error=...handleOAuthCallback and provider code exchange
Webhooks arrive but no orders ingestedwebhook signature validation / payload parsing / dedup
Orders sync only intermittentlypolling queue and repeat job state
Product push endpoints return accepted but no data in Shopifyprovider API/scopes/mapping failures
Unknown e-commerce provider errorsprovider value unsupported by factory
Connection shows active but no recent sync logsworker not consuming queue or no events triggering sync

2) First checks

  1. Check connection state:
curl -s "http://localhost:4000/ecommerce/connection?businessId=<businessId>" \
-H "Authorization: Bearer <app-token>"
  1. Check recent sync logs:
curl -s "http://localhost:4000/ecommerce/sync/log?businessId=<businessId>&page=1&limit=20" \
-H "Authorization: Bearer <app-token>"
  1. Validate granted scopes (debug endpoint):
curl -s "http://localhost:4000/ecommerce/debug/scopes?businessId=<businessId>" \
-H "Authorization: Bearer <app-token>"

3) OAuth and connection flow checks

Expected flow:

  1. GET /ecommerce/oauth/url
  2. provider authorization screen
  3. provider callback to GET /ecommerce/oauth/callback
  4. token exchange + webhook registration + encrypted credential persistence
  5. repeat poll job registration
  6. redirect back to PWA settings with ?connected=true

If callback returns error:

  • verify state integrity (decode base64url and confirm expected business/provider/shop fields)
  • verify provider app credentials/config
  • verify callback base URL used for webhook registration (APP_BASE_URL)

Operational note:

  • webhook registration failures are non-fatal during connect; polling fallback still runs

4) Webhook diagnostics

Route: POST /ecommerce/webhooks/shopify

Critical behavior:

  • route expects raw body buffer for HMAC verification
  • auth failure (signature / unknown shop / missing secret) returns 401
  • non-auth application errors return 200 { ok: false } intentionally (prevents retry storms)

Checklist:

  1. confirm x-shopify-shop-domain, x-shopify-hmac-sha256, x-shopify-topic headers
  2. confirm connection exists for incoming shop domain
  3. confirm webhook secret is stored/decryptable
  4. confirm payload topic is supported by adapter parser
  5. check sync log entries of type order_webhook

5) Polling diagnostics

Queue behavior from code:

  • queue: ecommerce-polling
  • repeat job name: poll
  • repeat every 15 minutes
  • repeat job id: ecommerce-poll-{businessId}

Key checks:

  1. manual enqueue:
curl -s -X POST "http://localhost:4000/ecommerce/sync/poll?businessId=<businessId>" \
-H "Authorization: Bearer <app-token>"
  1. run synchronous debug poll:
curl -s "http://localhost:4000/ecommerce/debug/poll?businessId=<businessId>" \
-H "Authorization: Bearer <app-token>"
  1. inspect sync log for order_poll and order_webhook entries

Important implementation detail:

  • startup dedup in EcommercePollingProcessor uses job.key to remove true duplicates safely

6) Product/collection sync diagnostics

Manual triggers:

  • POST /ecommerce/sync/products
  • POST /ecommerce/sync/collections

Expected behavior:

  • endpoint returns accepted response with syncLogId
  • batch loop runs paginated pushes
  • summary sync log status should be success, partial, or error

If pushes fail:

  • inspect errorDetail in sync logs
  • check token scopes (debug/scopes)
  • verify connection status and token decrypt path
  • verify product/collection data assumptions (active products, non-archived collections)

7) Known constraints

  • Factory currently supports only shopify; WooCommerce is not wired yet.
  • disconnect is idempotent: returns 204 even if no connection exists.
  • inbound order dedup relies on ingested-order guard (insertIfNew).
  • mapping and inventory deductions depend on external-to-FlowPOS product mapping accuracy.

8) Recovery playbook

Preferred order:

  1. re-check scopes and connection
  2. trigger sync/poll manually
  3. run debug/poll for immediate confirmation
  4. disconnect and reconnect OAuth if credentials or webhook state is suspect
  5. re-run product/collection sync after reconnect

Escalate to provider adapter debugging if failures persist with valid connection/scopes.