Architecture Overview
High-level system design of the NexusCommerce multi-marketplace platform.
Overview
NexusCommerce is a multi-tenant SaaS platform built on a microservices-adjacent architecture. The system is divided into five primary layers: the Next.js frontend, the NestJS API gateway, the Python AI worker fleet, the Supabase data platform, and the ClickHouse analytics engine. These layers communicate via HTTP, real-time subscriptions, and a Redis-backed job queue.
Key Concepts
Multi-tenancy — Every data table has a tenant_id column. Supabase Row Level Security (RLS) policies ensure that no query can return data from a different tenant. The tenant_id is extracted from the Supabase JWT on every API request and propagated through all service calls.
Adapter Pattern — Marketplace integrations are isolated in the packages/marketplace-adapters package. Each adapter implements a common interface, making it straightforward to add new marketplace support without changing the core platform.
Event-Driven Sync — Marketplace data flows into NexusCommerce through two mechanisms: scheduled polling (adapters run on configurable intervals) and webhook push (for marketplaces that support it). Events are normalized and upserted into Supabase.
AI Worker Pattern — Computationally intensive AI tasks are offloaded to the Python FastAPI worker fleet. The NestJS API dispatches jobs to a Bull/BullMQ queue; workers pick up jobs, execute them, and write results back to Supabase. The NestJS API polls job status and notifies the frontend via Supabase Realtime.
Getting Started
For a self-hosted deployment, see Installation. For cloud-hosted, see Quick Start.
Features
System Diagram
Browser
│
▼
Next.js 15 (apps/web) ─── Supabase Auth (JWT)
│ │
│ REST API calls │
▼ ▼
NestJS 11 API (apps/api) ─── Supabase DB (PostgreSQL + RLS)
│ │ │
│ AI jobs │ Adapter sync │ ETL
▼ ▼ ▼
Python FastAPI Marketplace ClickHouse
Workers APIs (7x) Analytics DB
(services/workers)Monorepo Structure
NexusCommerce is organized as a pnpm workspace monorepo managed by Turborepo:
apps/
web/ Next.js 15 frontend
api/ NestJS 11 API
docs/ This documentation site
packages/
ui/ Shared shadcn/ui components
shared-types/ Shared TypeScript types
marketplace-adapters/ All 7 marketplace adapters
supabase-client/ Shared Supabase client
services/
clickhouse/ Schema, migrations, materialized views
workers/ Python FastAPI AI worker fleetData Flow: Order Ingestion
- Adapter polls marketplace order API (or receives webhook)
- Adapter normalizes order to NexusCommerce schema
- API upserts order to
orderstable in Supabase - Supabase triggers an ETL function that writes the order to ClickHouse
- Dashboard stat cards update on next refresh cycle (Supabase Realtime or polling)
Data Flow: AI Job Execution
- User triggers job (or FlowForge schedule fires)
- NestJS API creates a job record in Supabase and enqueues it in BullMQ (Redis)
- Python worker picks up the job from the queue
- Worker executes the job (calls OpenAI, queries Supabase, reads competitor data)
- Worker writes results to Supabase (recommendations, classifications, scores)
- Worker marks the job as
completedin the job record - NestJS API detects completion (polling or Supabase Realtime)
- Frontend updates (via Supabase Realtime subscription or page refresh)
Authentication Architecture
All authentication is handled by Supabase Auth:
- User login — Supabase Auth issues a JWT with the user's ID and tenant ID in the claims
- API requests — The NestJS
AuthGuardvalidates the JWT signature and extracts the tenant ID - API keys — Stored in Supabase; validated by the NestJS API on each request (hashed, never stored in plaintext)
- RLS — PostgreSQL RLS policies use the JWT's
tenant_idclaim to filter all queries
Marketplace Adapter Execution
Adapters run within the NestJS API process (not as separate services). A scheduler service (using @nestjs/schedule) triggers adapter sync cycles on the configured interval per connection. Each sync cycle is executed in a separate async context.
For webhook-based adapters (Shopify, eBay, Bol.com), the NestJS API exposes webhook endpoints that immediately process incoming events without waiting for the polling cycle.
Configuration
Key environment variables governing the architecture:
| Variable | Service | Description |
|---|---|---|
SUPABASE_URL | API, Web | Supabase project URL |
SUPABASE_SERVICE_ROLE_KEY | API | Supabase service role key (bypasses RLS for admin operations) |
REDIS_URL | API, Workers | Redis connection string for BullMQ |
WORKER_URL | API | Python worker fleet base URL |
CLICKHOUSE_HOST | API, Workers | ClickHouse server host |
NEXT_PUBLIC_API_URL | Web | API base URL (public, used in browser) |