NexSEND is a notification platform for managed email delivery, domain verification, and service-key based API access.
Built and maintained by NexMUN.
apps/backend/: NestJS API, queue workers, domain/email/services management, CLI utilitiesapps/frontend/: Next.js admin GUI for organizations, service keys, and domain operationsscripts/: workspace helpers (for example frontend runner)
- Production runtime is currently Amazon SES only.
- The code structure is provider-extensible (interface + factory pattern), but non-SES providers are not active runtime modes today.
Do not document or advertise multi-provider runtime support as currently enabled.
This README is the single source of truth for:
- New developers (local setup and running everything)
- Production operators (configuration + release checks)
- API integrators (service-key creation and usage)
- Node.js 20+
- Bun 1.2+
- PostgreSQL
- Redis
- AWS credentials (for SES path validation)
# repo root (installs everything via Bun workspaces)
bun installcd apps/backend
cp .env.example .envMinimum local variables to verify before running:
DATABASE_URLREDIS_URLEMAIL_PROVIDER=SESAWS_REGIONAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYFRONTEND_URL=http://localhost:3000ADMIN_ALLOWED_ORIGINS=http://localhost:3000ADMIN_SETUP_TOKEN(optional in dev, required in prod)
cd apps/backend
bun run prisma:generate
bun run prisma:migrate:devcd apps/backend
bun run start:devBackend default API base: http://localhost:8001/api
From repo root (recommended):
# dev on default port 3000
bun run frontend:dev
# dev on specific port
bun run frontend:dev:port -- --port=3100
# production build for GUI
bun run frontend:build
# start built GUI
bun run frontend:start -- --port=3000Direct frontend commands:
cd apps/frontend
bun run dev
bun run build
bun run startThe root scripts call scripts/frontend-runner.mjs and forward the port to Next.js.
/setup: one-time bootstrap admin creation/login: admin session login/dashboard: organizations, service keys, domains
Important:
- In production, setup requires
ADMIN_SETUP_TOKENand headerx-admin-setup-token. - Admin session uses secure cookie auth + origin checks (
FRONTEND_URL/ADMIN_ALLOWED_ORIGINS).
Backend CLI is production-oriented for service key operations and verification.
cd apps/backend
bun run cli
bun run cli -- help
bun run cli -- capabilities
bun run cli -- create-service-key
bun run cli -- create-service-key --preset=main-backend
bun run cli -- verify-productionBun shortcuts:
cd apps/backend
bun run service-key:create
bun run service-key:create-main
bun run verify:production- Operator creates a key via CLI (
create-service-key). - Securely store returned
X-Service-Key(one-time display). - Use key in requests via
X-Service-Keyheader. - Use dashboard or CLI to rotate/regenerate when needed.
Run these before shipping:
# backend
cd apps/backend
bun run build
bun run test
# frontend
cd ../frontend
bun run lint
bun run buildbun run test (from apps/backend) currently runs:
- SES production-readiness verification
- Admin dashboard readiness verification (auth lifecycle, origin policy, contract checks)
NODE_ENV=productionEMAIL_PROVIDER=SES- valid AWS SES credentials + region
- valid DB + Redis connectivity
- explicit admin origin allowlist:
FRONTEND_URLADMIN_ALLOWED_ORIGINS
ADMIN_SETUP_TOKENset to a strong random token
- Build + tests green (
backend,frontend) - SES credentials path validated
- Domain verification flow validated
- Queue processing validated
- Health endpoint validated (
/api/health) - Service keys provisioned and vaulted securely
See also: apps/backend/PUBLIC_LAUNCH_CHECKLIST.md.
Core backend modules:
admin-auth: bootstrap/login/session cookie auth for admin GUIadmin: dashboard-facing management endpointsorganization: org managementservice-key: API key lifecycle and permissionsdomain: DNS + verification lifecycleemail: send path + provider factory + queue processor
flowchart LR
U[Admin User] --> FE[Frontend UI]
FE --> API[Backend API]
API --> PG[(PostgreSQL)]
API --> RD[(Redis)]
API --> SES[Amazon SES]
API --> DNS[DNS Providers]
subgraph Backend Modules
AA[admin-auth]
AD[admin]
ORG[organization]
SK[service-key]
DM[domain]
EM[email]
end
API --- AA
API --- AD
API --- ORG
API --- SK
API --- DM
API --- EM
Infra notes:
- Frontend UI: Next.js app (
/setup,/login,/dashboard) - Backend API: NestJS at
http://localhost:8001/api - Data/services: PostgreSQL, Redis, Amazon SES, DNS providers
High-level flow:
- Admin signs in via GUI
- Admin manages orgs, keys, domains
- Integrator sends requests with service key
- Backend validates key and queues work
- Worker processes email using SES provider
flowchart TD
REQ["Send API request"] --> CTRL["NestJS
email.controller"]
CTRL --> SVC["NestJS
email.service"]
SVC --> Q[(Redis Bull queue: email)]
Q --> PROC["NestJS
email.processor"]
PROC --> SEND[sendDirectEmail]
SEND --> ROUTE["Provider route
policy"]
ROUTE --> FACT[EmailProviderFactory]
FACT --> IFACE[IEmailProvider]
IFACE --> P1[Primary]
IFACE --> P2[Fallback 1]
IFACE --> P3[Fallback 2]
P1 --> T1{Success}
T1 -->|yes| OK["SENT +
EmailEvent"]
T1 -->|no| P2
P2 --> T2{Success}
T2 -->|yes| OK
T2 -->|no| P3
P3 --> T3{Success}
T3 -->|yes| OK
T3 -->|no| FAIL["FAILED +
EmailEvent"]
subgraph PROVIDERS[Example providers]
SESP["SESProvider
active today"]
SGP["SendGridProvider
future"]
MGP["MailgunProvider
future"]
end
P1 --> SESP
P2 --> SGP
P3 --> MGP
SESP --> SESAPI[Amazon SES]
SVC --> DB[(PostgreSQL EmailJob + EmailEvent)]
SEND --> DB
classDef compact font-size:11px;
class REQ,CTRL,SVC,Q,PROC,SEND,ROUTE,FACT,IFACE,P1,P2,P3,T1,T2,T3,OK,FAIL,SESP,SGP,MGP,DB compact;
Diagram legend:
REQ-> APIsend/send-bulkrequest entrySVC-> createsEmailJoband enqueues work in Redis Bull queueQ/PROC-> Redis/Bull queue processing path in NestJS workerROUTE-> provider selection policy (org + service key + config)FACT/IFACE-> factory +IEmailProviderabstractionP1/P2/P3-> primary and fallback provider attemptsDB-> PostgreSQL records (EmailJob,EmailEvent)
Flow notes:
- Route policy = org + service-key + config/health rules
- Provider factory = resolves provider order
- Current runtime = SES only
- Future runtime = primary + fallback providers
- Email queue = Bull queue (
email)
Provider-extensibility notes:
- Interface:
apps/backend/src/modules/email/interfaces/email-provider.interface.ts - Factory:
apps/backend/src/modules/email/factories/email-provider.factory.ts - Active runtime provider today: SES only
- Multi-provider support model (future): add additional
IEmailProviderimplementations, register them in factory, and resolve primary/fallback route per request
Canonical product name in docs/UI: NexSEND
Attribution text where needed: by NexMUN linking to https://nexmun.in.
To rename visible GUI brand/title strings, update:
apps/frontend/app/layout.tsx(metadata title/description)apps/frontend/app/dashboard/page.tsx(header title/subtitle)- any additional labels in
apps/frontend/app/*orapps/frontend/components/*
After renaming:
cd apps/frontend
bun run lint
bun run build- Ensure backend is running on
:8001 - Set
NEXT_PUBLIC_BACKEND_URLif not using defaulthttp://localhost:8001/api - Verify CORS origins in backend env
- Confirm
FRONTEND_URLandADMIN_ALLOWED_ORIGINS - In production, ensure HTTPS and
securecookie-compatible environment
- In production, verify
ADMIN_SETUP_TOKENis set - Send
x-admin-setup-tokenheader with matching value
- Check AWS credentials and region
- Re-run
cd apps/backend && bun run verify:production
Use this README as the primary source; use these for depth:
- Backend CLI details:
apps/backend/CLI.md - Backend service overview:
apps/backend/docs/README.md - Launch checklist:
apps/backend/PUBLIC_LAUNCH_CHECKLIST.md - API integration details:
apps/backend/docs/BACKEND_INTEGRATION_GUIDE.md - Service key API details:
apps/backend/docs/SERVICE_KEY_MANAGEMENT_API.md
Licensed under MIT. See LICENSE.
NexSEND by NexMUN