Architecture
Nexus is a Turborepo monorepo with 12 apps, 13 shared packages, and three product databases (plus Temporal’s internal store). See the System graph for the full dependency picture and the Network graph for traffic flow.
App layers
Section titled “App layers”graph TD
subgraph "Customer-facing"
SM[site-main :3000]
SS[site-shop :3010]
SH[site-hypno :3020]
end
subgraph "Staff / ops"
P[portal :3030\nadmin]
PB[portal-business :3043\nbusiness owners]
PBW[portal-business-web\nCaddy proxy]
end
subgraph "API servers"
SA[scheduler-api :4000\nFastify · tRPC · Temporal]
VS[vendure-server :3001\nNestJS GraphQL]
D[directus :8055\nHeadless CMS]
end
subgraph "Workers"
SW[scheduler-worker]
VW[vendure-worker]
end
SM & SS & SH --> SA
SM & SS & SH --> VS
SM & SS & SH --> D
P --> SA
PBW --> PB
PB --> SA
SW --> SA
VW --> VS
Subsystems
Section titled “Subsystems”Scheduler (scheduler-api + scheduler-worker)
Section titled “Scheduler (scheduler-api + scheduler-worker)”The core platform: bookings, business management, billing, provisioning, notifications, chat. Fastify + tRPC on the API side; BullMQ + Temporal for async work. Drizzle ORM on PostgreSQL (Neon).
Commerce (vendure-server + vendure-worker)
Section titled “Commerce (vendure-server + vendure-worker)”Headless commerce layer: product catalog, cart, checkout, orders. NestJS + GraphQL. TypeORM on PostgreSQL (Neon). Kept in sync with the scheduler via convergence workflows.
Content (directus)
Section titled “Content (directus)”Headless CMS for tenant content (pages, blog, media). Multi-tenancy via a custom WorkOS OIDC extension that maps WorkOS org → Directus role on login. PostgreSQL (Neon) + Cloudflare R2.
Package layers
Section titled “Package layers”| Layer | Package(s) | Consumed by |
|---|---|---|
| Contracts (source of truth) | @nexus/scheduler-contracts |
server, SDK, tRPC client |
| Public SDK | @nexus/scheduler-sdk, @nexus/vendure-sdk, @nexus/directus-sdk |
sites, business-client |
| Customer client | @nexus/business-client |
sites |
| Admin client | @nexus/scheduler-client, @nexus/scheduler-platform-client |
portals, e2e tests |
| Auth | @nexus/auth-client, @nexus/workos-auth |
portals, scheduler-api, directus |
| Events | @nexus/platform-events |
scheduler-api, workers |
| UI | @nexus/ui (shadcn + Radix + Tailwind) |
all React apps |
| Infra | @nexus/registrar, @nexus/shared-types |
scheduler-api, IaC |
Data stores
Section titled “Data stores”| Store | Provider (prod) | Provider (local) | Used by |
|---|---|---|---|
| Scheduler PostgreSQL | Neon | Docker :5434 | scheduler-api, scheduler-worker |
| Vendure PostgreSQL | Neon | Docker :5432 | vendure-server, vendure-worker |
| Directus PostgreSQL | Neon | Docker :5433 | directus |
| Temporal PostgreSQL | Railway managed | — | temporal-server |
| Redis | Railway managed | Docker :6379 | BullMQ (all), sessions, SSE bridge |
| Object storage | Cloudflare R2 | MinIO Docker :9000 | vendure (assets), directus (media), scheduler (chat) |
Two API styles in scheduler-api
Section titled “Two API styles in scheduler-api”Public / contract-first — customer-facing, slug-scoped (/api/public/:slug/*).
Zod schemas in @nexus/scheduler-contracts are the single source of truth.
A drift between client and server is a runtime 500, not a silent type mismatch.
Admin / tRPC — portal-facing (/trpc/*). End-to-end type-safe: types are
inferred from the server AppRouter, never hand-written on the client. Consumed
by both portal (via @nexus/scheduler-client) and portal-business.
Workflow orchestration
Section titled “Workflow orchestration”Long-running multi-system operations (provisioning, convergence, wipe) run as
Temporal workflows hosted on Railway. The Temporal worker is embedded in
scheduler-api. See Temporal cluster.
Infrastructure
Section titled “Infrastructure”All production services run on Railway (single environment). DNS is on
Cloudflare. Infrastructure is managed as code via Pulumi TypeScript in
infra/, with R2 as the Pulumi state backend. CI automatically runs
pulumi up on merge when infra/ changes.
See Environments concept for stack details and CI graph for the full pipeline.