Getting started

Local development setup for the INITE Billing Service. Node 22+, Docker, and an Anthropic API key (for the assistant) are expected.

The local stack

Two Node processes (backend + frontend) talk to a Dockerized Postgres and Redis, plus two external services — auth.inite.ai for identity and the Anthropic API for the AI surfaces.

1. Install

git clone [email protected]:inite-ai/inite-billing-service.git
cd inite-billing-service
npm install                    # postinstall runs prisma generate

2. Infrastructure

docker compose up -d postgres redis

This starts:

ServiceImageHost port
PostgreSQLpgvector/pgvector:pg155433
Redisredis:7-alpine6381

pgvector is required. The embeddings migration runs CREATE EXTENSION vector — a plain postgres image will fail to migrate.

3. Environment

cp env.example .env
$EDITOR .env

Key groups (see env.example for the full annotated list):

GroupVariablesNotes
CoreDATABASE_URL, REDIS_URL, PORTdefaults match docker-compose
AuthAUTH_SERVICE_URL + JWT_ISSUER (+ JWT_AUDIENCE), or JWT_SECRET in devRS256 via {AUTH_SERVICE_URL}/.well-known/jwks.json; JWT_ISSUER is the signed iss (https://auth-api.inite.ai for INITE's own Auth). Rules: Triad token contract
AnthropicANTHROPIC_API_KEY, ANTHROPIC_MODELmodel defaults to claude-sonnet-4-5
EmailRESEND_API_KEY, EMAIL_FROM, NOTIFICATIONS_EMAIL_ENABLEDemail is off by default
OutreachOUTREACH_ENABLED, OUTREACH_TRIGGERS, OUTREACH_MAX_PER_USER_7Doff by default
EmbeddingsOPENAI_API_KEY, EMBEDDINGS_ENABLEDoff by default; ILIKE fallback
RiskRISK_BLOCKING_ENABLED, RISK_* thresholdsmonitor-only by default

Payment-provider credentials are not env variables — they live in the database (payment_providers.config) and are configured through the admin UI.

4. Migrate & run

npm run prisma:migrate         # dev migration (creates/applies)
npm run start:dev              # hot-reloading backend on :3000

5. Frontend

cd frontend
npm install
npm run dev                    # Next.js on :3001

The frontend authenticates against auth.inite.ai via OAuth PKCE; locale switcher (EN/RU) sets the locale cookie which the backend captures for localized notifications.

Running tests

npm test          # spins throwaway dockerized PG (pgvector) + Redis via scripts/test.sh
npm run test:ci   # jest only — expects DATABASE_URL/REDIS_URL of a prepared test DB
npm run eval      # AI golden-dialog evals (needs ANTHROPIC_API_KEY; costs tokens)

scripts/test.sh uses host ports 5433 (postgres) and 6381 (redis). If those ports are taken on your machine, point the suite at your own containers instead:

TEST_DATABASE_URL="postgresql://postgres:postgres@localhost:<pg-port>/inite_billing_test?schema=billing" \
TEST_REDIS_URL="redis://localhost:<redis-port>" \
npx jest --forceExit --runInBand

(test/setup-e2e.ts honors TEST_DATABASE_URL / TEST_REDIS_URL overrides.)

Everyday commands

npm run start:dev            # dev server (watch)
npm run build                # compile
npm run lint                 # eslint --fix over src+test
npm run prisma:studio        # DB browser
npm run prisma:migrate       # create/apply a dev migration
npx prisma migrate deploy    # apply committed migrations (prod-style)

Troubleshooting

  • Migration fails with type "vector" does not exist — your postgres has no pgvector; use the pgvector/pgvector:pg15 image from docker-compose.
  • npm test fails to bind :5433/:6381 — another container owns the port; use the TEST_* override above.
  • Assistant returns 404 from Anthropic — check ANTHROPIC_MODEL; use the claude-sonnet-4-5 alias or a valid dated snapshot.
  • If setup breaks in any other way, file an issue — that usually means this doc is wrong.