Run it locally

Getting Inbox up on your machine is five commands. Two of them are the ones people skip, and both fail in ways that do not name the real cause — read the gotchas below before you debug anything.

Prerequisites

First run

# 1. Install
yarn install

# 2. Build the workspace packages FIRST.
#    Skip this and the service dies with: Cannot find module '@~inbox/types'
yarn build

# 3. Create the database (once)
createdb axis_inbox

# 4. Apply migrations
yarn prisma migrate dev --schema apps/service/prisma/schema.prisma

If Prisma complains that PrismaClientKnownRequestError does not exist on type 'typeof Prisma', the generated client is stale: run yarn prisma generate, then rebuild.

Migrations are hand-managed from a baseline. Use prisma migrate devnever db push, which desyncs the migration history.

Required environment

Two variables are hard requirements, checked at boot by loadConfig:

Variable Requirement
INBOX_KEK 32 bytes / 64 hex characters. The key-encryption key for provider credentials at rest.
INBOX_REALTIME_JWT_SECRET At least 32 characters. Signs short-lived realtime tokens.

Anything shorter throws at startup with an explicit message. Beyond those, INBOX_DATABASE_URL, INBOX_REDIS_URL and INBOX_PORT (default 3000) select the backing stores and the listen port; the service's local development port is 6979 in the checked-in setup.

The gotcha that costs the most time

Nothing in the application loads .env. dotenv is a devDependency that is never imported. The start scripts pass Node's own flag instead:

"start":      "nest start --env-file ../../.env",
"start:dev":  "nest start --watch --env-file ../../.env",
"start:prod": "node --env-file-if-exists=../../.env dist/main"

Two consequences. First, ../../.env resolves from apps/service/, so the file lives at the repo root; putting it in apps/service/.env loads nothing. Second, running nest start directly, without the flag, dies with Missing required env var INBOX_KEK — which reads like a missing variable rather than a missing loader.

start:prod and the scripts use --env-file-if-exists so CI and production, where configuration comes from the real environment, do not fail on an absent file.

Start it

cd apps/service && yarn start:dev     # watch mode

or from the repo root:

yarn dev

Smoke tests

curl -s localhost:6979/v1/ping
# → { "ok": true }

curl -s localhost:6979/v1/health

GET /v1/ping and GET /v1/health are both public. Health reports which backends are wired:

{
  "status": "ok",
  "env": "development",
  "backends": { "database": true, "redis": true, "aggregator": true }
}

If database is false, stop and fix it. INBOX_DATABASE_URL did not reach the process, and common/persistence.ts silently falls back to in-memory stores. The service boots, accepts writes, answers reads within a single run — and persists nothing. There is no error, only data that is gone after a restart. The same env-driven fallback applies to the Redis-backed queues.

Once you have a credential and a tenant, confirm the whole auth chain:

curl -s -H "authorization: Bearer $KEY" -H "x-axis-tenant: ws_<userGroupId>" \
  localhost:6979/v1/whoami
# → { "data": { "appId": "…", "mode": "bearer", "scopes": [...], "tenantId": "…" } }

whoami is the one call that tells you what the service thinks you are. See Connect an app for getting $KEY.

Stopping it

pkill -f 'dist/main'

Target the server process, not the watcher. pkill -f 'nest start' kills the CLI wrapper and leaves the re-parented child holding the port, which then blocks the next start with EADDRINUSE.

Gotcha table

Symptom Cause
Missing required env var INBOX_KEK .env not loaded — use the yarn scripts, or pass --env-file ../../.env
Cannot find module '@~inbox/types' Workspace packages not built — yarn build at the root
health.backends.database = false INBOX_DATABASE_URL absent, silent in-memory fallback
EADDRINUSE on the service port Orphaned dist/main from a previous run
INBOX_SKIP_AUTH appears to be ignored Honoured only when the env is exactly development
Data disappears between restarts See database: false above