Skip to content

Configuration

1. Environment Variables

Core keys from EnvironmentKeys (@nx/core + @venizia/ignis); commerce adds BullMQ Redis keys in src/common/environments.ts. Read via applicationEnvironment.get<T>(key).

Core runtime

NameTypeDefaultRequiredDescription
APP_ENV_PORTnumber3000HTTP listen port (container)
APP_ENV_HOSTstring0.0.0.0Bind address
APP_ENV_BASE_PATHstring/v1/api/commerceRoute prefix
APP_ENV_NODE_IDnumberSnowflake worker ID — must be 2
APP_ENV_WORKERScsv|ALLEnables SyncProductWorker (+ CDC consumer in WORKER role)
RUN_MODEmigrate|servermigrate switches to migration entry

Database

NameTypeDefaultRequiredDescription
APP_ENV_DB_URLstringPostgreSQL connection URL

Cache / authorization Redis

NameTypeDefaultRequiredDescription
APP_ENV_REDIS_*Cache Redis (useCacheRedis); also authorization Redis (getAuthorizationRedisConnection) and footer-summary cache

BullMQ Redis (separate connection)

NameTypeDefaultRequiredDescription
APP_ENV_BULLMQ_REDIS_MODEsingle|clustersingleConnection mode
APP_ENV_BULLMQ_REDIS_HOSTstringlocalhostSingle-mode host
APP_ENV_BULLMQ_REDIS_PORTnumber6379
APP_ENV_BULLMQ_REDIS_PASSWORDstring
APP_ENV_BULLMQ_REDIS_DATABASEnumber0
APP_ENV_BULLMQ_REDIS_MAX_RETRYnumber5
APP_ENV_BULLMQ_REDIS_CLUSTER_NODESstringclusterRequired when mode=cluster
APP_ENV_BULLMQ_WORKER_CONCURRENCYnumber1SyncProductWorker concurrency

WebSocket Redis

NameTypeDefaultRequiredDescription
APP_ENV_WEBSOCKET_REDIS_MODEsingle|clustersingle
APP_ENV_WEBSOCKET_REDIS_HOST/PORT/PASSWORD/DB/MAX_RETRYhost localhost, port 6379, db 0, retry 5Single-mode WebSocketEmitter connection
APP_ENV_WEBSOCKET_REDIS_CLUSTER_NODESstringclusterRequired when mode=cluster

Kafka (producer-only)

NameTypeDefaultRequiredDescription
APP_ENV_KAFKA_BROKERScsvComma-separated broker list (empty ⇒ no brokers)
APP_ENV_KAFKA_CLIENT_IDstringSVC-00020-COMMERCE_PRODUCERProducer client id
APP_ENV_KAFKA_SASL_ENABLE'true'|'false'falseToggle SASL
APP_ENV_KAFKA_SASL_MECHANISM/USERNAME/PASSWORDstringNAWhen SASL enabled

Producer config: requestTimeout 60_000ms, connectTimeout 30_000ms, JSON value serializer. The producer is bound but not invoked in src/.

Security / integrations

NameTypeDefaultRequiredDescription
APP_ENV_APPLICATION_SECRETstring✓ (for provider integrations)AES-256-GCM key for EncryptService
APP_ENV_JWKS_URLurlIdentity JWKS endpoint
APP_ENV_BASIC_AUTH_*stringService-to-service basic creds

Search/asset components (@nx/search, @nx/asset) read their own env (Typesense nodes, Minio endpoint/keys, embedding config) — see those packages.

2. Feature Flags

No global feature flags. Runtime behavior is gated by:

GateMechanism
Worker / CDC enablementAPP_ENV_WORKERS (SyncProductWorker; CDC consumer in WORKER role)
Per-merchant strictCategoryDeletion / cascade flagsDeletionPolicyService (per-merchant policy)
Product sync to extra merchantspresence of merchantIds[] / syncMerchantIds in aggregate request

3. Seeded Data

Migration processes in src/migrations/processes/. Run on bootstrap (prestartbun run rebuildmigrate.ts); per-dev via bun run migrate:dev.

ProcessSeeds / backfills
commerce-0002-seed-permissionsRBAC permission catalogue
commerce-0003-seed-typesense-embedding-configsSemantic-search embedding configs
commerce-0005-seed-default-finance-accountsSystem default finance accounts config
commerce-0006-seed-merchant-fnb-sectorsFnB sector taxonomy
commerce-0007-seed-category-templatesSYSTEM category templates
commerce-0008-seed-search-pipeline-configSearch pipeline config
commerce-0009-seed-role-permissionsRole→permission grants
commerce-0010-seed-guest-permissionsGuest-role permissions
commerce-0011-backfill-merchant-onboardingBackfill metadata.onboarding flags

4. Configuration Storage (Configuration table)

KindEncryptionScope key
Provider-integration credentialsAES-256-GCM (EncryptService)(group, code, principalId, principalType, environment)
System configs (finance accounts, category templates, search pipeline)group=SYSTEM, principalId/Type=null

Credential code format: {type}:{provider}:{credentialAction}:{credentialType}. Responses return a masked display value; getDecryptedCredential is internal-only (never exposed via controller).

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.