commerce-integration-api
privateA backend service that centralizes back-office automation for a consumer goods brand. It exposes authenticated HTTP and webhook endpoints and offloads long-running work to Redis-backed BullMQ queues, synchronizing data between Shopify storefronts and a NetSuite ERP.
TypeScriptNode.jsExpressBullMQRedisShopify Admin GraphQL APINetSuite RESTlets (OAuth 1.0a)PuppeteerPassport (Google OAuth)WinstonSentryDockerAWS ECRAWS EC2
Containerized Deployment
- Ships as a Docker image built for linux/amd64 and published to a private AWS ECR registry
- Bundles a headless Chromium runtime so document rendering works in production
Express API Layer
- Routes are grouped by business domain and registered through a central router module
- Each domain exposes both a synchronous endpoint and a queue-backed endpoint so callers can choose immediate or deferred processing
- Hardened with Helmet CSP, CORS, no-index headers, disabled framework fingerprinting, and a JSON body parser that preserves the raw payload for signature checks
Authentication & Request Verification
- Google OAuth via Passport with a server-side email allowlist gates access to the internal admin dashboard
- Shopify webhooks are verified with HMAC-SHA256 signatures computed over the raw request body, per storefront
- Internal service calls use a shared-secret HMAC header, and ERP calls are signed with OAuth 1.0a token-based authentication
Job Queues & Workers
- Domain-isolated BullMQ queues backed by Redis
- Workers run in sandboxed processor files with exponential backoff, bounded retries, and automatic cleanup of completed and failed jobs
- A Bull Board dashboard mounted behind OAuth provides job inspection, progress, and per-job logs
Shopify Integration
- Typed GraphQL operations generated from the Shopify Admin schema via GraphQL Code Generator
- Inventory level webhooks trigger a job that evaluates variant stock at the primary warehouse and tags products as in or out of stock
- Separate credential sets and webhook secrets isolate the retail and wholesale storefronts
NetSuite ERP Integration
- A single signed request helper fans out to purpose-specific RESTlet endpoints resolved by event type
- Handles wholesale lead creation, customer search, case creation, and file attachments
- Supports parallel production and sandbox credential sets for safe integration testing
Observability & Operations
- Sentry captures exceptions and performance profiles, with source maps uploaded during production builds
- Winston with daily log rotation writes separate application and HTTP access logs to a persisted volume
- Uptime and status endpoints plus graceful SIGINT/SIGTERM shutdown handling
- # Why queue the work instead of handling it inline?
- Shopify webhooks and ERP RESTlets impose strict timeouts and governance limits, and several workflows fan out into hundreds of paginated API calls. Pushing this work onto BullMQ lets endpoints acknowledge immediately, gives every task retries with exponential backoff, and keeps a slow integration from blocking the request thread.
- # Why one service with domain-isolated queues?
- The business domains share the same auth, logging, and integration primitives, so a single deployable avoids duplicating that plumbing. Separate queues and workers per domain still keep failure and backpressure contained — a stalled batch job cannot starve inventory tagging.
- # Why treat the ERP as the system of record?
- Customer, lead, and case data is written directly into NetSuite rather than a local database, so the ERP remains the single source of truth. The service stays stateless apart from Redis job state, which keeps deployments and rollbacks simple.
- # How is untrusted input verified?
- The JSON parser retains the raw request body so inbound Shopify webhooks and internal calls can be validated with HMAC-SHA256 signature comparisons before any handler runs. Outbound ERP requests are signed with OAuth 1.0a, and all credentials are injected as environment configuration rather than committed.