Skip to content

Architecture

Folder map

Where things live under src/ and how they're named.

Folder Purpose Main files Naming
auth/ Auth routes and shared auth logic. Mounts strategy submodules (email-password, email-otp, sms-otp). auth.router.ts, auth.controller.ts, auth.service.ts, auth.middleware.ts, auth.helper.ts, auth.validator.ts auth.*
auth/emailPassword/ Email/password signup, login, verify-email, forgot-password. emailPassword.router.ts, .controller.ts, .service.ts, .validator.ts emailPassword.*
auth/emailOtp/ Email-OTP signup and login (send OTP, verify code). emailOtp.router.ts, .controller.ts, .service.ts, .validator.ts emailOtp.*
auth/smsOtp/ SMS-OTP login (send OTP, verify code). smsOtp.router.ts, .controller.ts, .service.ts, .validator.ts smsOtp.*
admin/ Admin API: users list/update, etc. Protected by admin role. admin.router.ts, admin.controller.ts, admin.service.ts, admin.middleware.ts, admin.validator.ts admin.*
rbac/ RBAC: apps, roles, permissions, user-role assignment. rbac.router.ts, .controller.ts, .service.ts, .validator.ts, rbac.schemas.ts, rbac.types.ts rbac.*
invitations/ Invitation CRUD and admin flows. invitations.router.ts, .controller.ts, .service.ts, .validator.ts invitations.*
lib/ App-wide infra. auth.ts (Better Auth), db.ts, openapi.ts, jaduSpineJwt.ts, verification.ts, emailAuthSession.ts No suffix rule
models/ MongoDB collection access. users.model.ts, otp.model.ts, invitations.model.ts, authAppRbac.model.ts *.model.ts
shared/ Shared utilities. sharedHelpers.ts, sharedErrors.ts, sharedConstants.ts shared*
mail/ Email sending (templates, provider). mail.service.ts, mail.provider.ts, mail.templateRenderer.ts, mail.constants.ts, mail.types.ts mail.*
sms/ SMS domain layer (provider abstraction, templates/orchestration). sms.service.ts, sms.provider.ts, sms.types.ts sms.*
thirdPartyServices/twilio/ Twilio SDK integration details used by SMS provider. twilio.service.ts twilio.*
authApps/ Auth app configs (which strategies an app uses). *.config.ts, authApps.service.ts Config + service
signUpAccess/ Sign-up gating (e.g. invite-only). signUpAccess.service.ts Service only

App bootstrap: index.ts calls createApp() from appFactory.ts. The factory connects DB, initializes Better Auth, mounts CORS, JSON, helmet, morgan, Swagger, then mounts routers: /api/auth (authRouter), /api/admin (invitations, admin, rbac). To add a new top-level area, add a router and mount it in appFactory.ts.


Request flow

How a typical API request is handled.

Path

Router → (optional middleware) → Controller → Validator → Service → Model / DB
  1. Router — Defines method and path; wraps handler with SharedHelpers.handleIfError(...).
  2. Middleware — e.g. AuthMiddleware.authenticateSession, requireStrategyForApp; runs before the controller.
  3. Controller — Thin: calls validator to parse body/query, then service, then SharedHelpers.sendResponse(res, status, message, isSuccess, data).
  4. Validator — Zod schemas; schema.parse(req.body) or similar; throws on invalid input.
  5. Service — Business logic; may use models, shared helpers, throw SharedErrors.* on failure.
  6. Model — MongoDB access via getDatabase() and collection methods.

Example

POST /api/auth/email-password/login:

  • emailPassword.router.tspost('/login', handleIfError(EmailPasswordController.login))
  • emailPassword.controller.tslogin calls validator, then EmailPasswordService.login(...), then sendResponse
  • emailPassword.validator.ts — Parses body (email, password, authAppId)
  • emailPassword.service.ts — Validates user, creates session/tokens via auth services
  • users.model.ts / auth lib — User lookup and session handling

Errors

Services throw subclasses of SharedErrors.CustomError. The handleIfError wrapper catches them and sends the appropriate status and body. See CONVENTIONS.md for response shape and error handling.


Stack and libs

Tech stack

Layer Technology
Runtime Node.js with TypeScript
Framework Express.js v5
Database MongoDB (native driver)
Auth Better Auth + JWT plugin (EdDSA), session and admin plugins
Validation Zod
API docs OpenAPI 3.0 + Swagger UI (/api-docs)

Key env vars

Defined in .env (see be/.env.example for full list).

Variable Purpose
PORT Server port (default 8084)
MONGODB_URI_JADU_AUTH MongoDB connection string
BETTER_AUTH_SECRET Secret for Better Auth (32+ chars); never commit
BETTER_AUTH_URL Base URL of this server
TRUSTED_ORIGINS Comma-separated allowed CORS origins
JADU_SPINE_JWT_SECRET Optional; for signing JaduSpine/Centrifugo tokens
SMTP_* Mail (SMTP) for verification and password-reset emails
SMS_PROVIDER, TWILIO_* SMS provider config for SMS OTP login delivery

Lib usage

  • lib/db.tsgetDatabase(), getClient(), closeDatabase(). Single shared connection; models and app use getDatabase() for collections.
  • lib/auth.ts — Better Auth config; initAuth(db, client), getAuth(). Mounted in appFactory as toNodeHandler(getAuth()) under /api/better-auth/.
  • lib/openapi.ts — Builds the OpenAPI document; feature *.openapi.ts files register paths and schemas.