Microservices Overview
The primebrick-us-v3 repository contains the distributed microservices that
make up the Primebrick v3 backend. Each microservice is a self-contained
sub-folder with its own src/, package.json, Dockerfile, db-meta/, and
terraform/ configuration.
Tech stack
- Runtime: Bun (dev with
--hotreload, prod withbun dist/index.js) - Language: TypeScript® (strict mode)
- HTTP: Node.js® HTTP server via
@primebrick/sdk'screateHttpServer - Messaging: NATS™ (via
@primebrick/sdk'sNatsClient) - Database: PostgreSQL® (via
@primebrick/dal-pg) - Package manager: pnpm
- Templates: Handlebars (where applicable)
Service catalog
| Service | Code | Port | Description |
|---|---|---|---|
| EmailSender | emailsender | 3003 | Email provider configuration, template rendering, and email dispatch via Brevo™ |
| AI | ai | 3004 | AI assistant — chat streaming (SSE), conversation lifecycle, docs knowledge-base search, embeddings, ai_model/ai_cerebellum entity catalog |
| Webhook | webhook | 3005 | Inbound webhook ingress — forwards requests verbatim to the target microservice via JetStream, registry-driven routing |
| JobHandler | job | 3006 | Job scheduling, governance, and execution observability — NATS JetStream native scheduler, business job_rules, run history |
| CRM | crm | 3007 | CRM module — module-ownership case study: nav, route census and translations declared at service registration |
Port source of truth: ports are seeded in each service's own
db-meta/patches/(config_entrieskeyhttp_port) — the table above mirrors those seeds. There is no env var or config file for ports.
New microservices are added as new top-level sub-folders. Each must contain
a package.json with a name starting with primebrick- and a src/index.ts
entry point.
Architecture at a glance
The Backend (BE) acts as the API gateway. The Frontend (FE) never calls
microservices directly — all HTTP traffic goes through the BE's
/ws/:serviceCode/* proxy. Inter-service async communication uses NATS™
subjects.
Quick start
Each microservice is a self-contained sub-folder with its own package.json,
src/, Dockerfile, db-meta/, and terraform/. To run EmailSender
locally:
Code
The microservice reads its NATS™ URL, HTTP port, and service code from the
config_entries table at startup via the SDK's ConfigLoader — not from env vars.
The only required env vars are DATABASE_URL and DATABASE_SCHEMA (the
service's owned PG schema — closed-set validated by assertDbEnv()).
To verify the service is running:
Code
From the Frontend, the same service is reached through the BE proxy:
Code
To apply database migrations for a microservice:
Code
Next steps
- Architecture — NATS™ bus, BE proxy, SDK lifecycle
- Conventions — API path conventions, data model rules
- EmailSender — Email sending microservice