Skip to content

Developer Getting Started

This guide gets you from zero to running your first BANA backend service locally.

Prerequisites

ToolVersionPurpose
Bun>= 1.3.8Runtime, package manager, test runner
PostgreSQL>= 14Primary database
Redis>= 7Cache, pub/sub, BullMQ job queues
S3-compatible storageAsset storage (MinIO for local dev)
Typesense>= 0.25Full-text search
GitVersion control
glabGitLab CLI for MRs (optional but recommended)

For POS desktop development only:

Clone & Install

bash
git clone ssh://git@git.nexpando.com:2268/eventry/nx-seller.git
cd nx-seller
make install        # bun install + gateway portal install
make setup-tools    # configure git to use .githooks/

make install runs bun install at the workspace root plus a separate install for the gateway portal. make setup-tools sets core.hooksPath so the project's pre-commit hooks run on every commit.

Local Infrastructure

Start all dependencies using Docker Compose from the dev deployment directory:

bash
cd infrastructure/deployments/develop

# Core dependencies (PostgreSQL, Redis, Kafka, Typesense, MinIO)
docker compose -f services/docker-compose.yml up -d

# CDC pipeline (Debezium: PostgreSQL -> Kafka -> Typesense)
docker compose -f cdc/docker-compose.yml up -d

Create the database:

bash
psql -h localhost -U postgres -c "CREATE DATABASE nx_seller;"

Configure Environment

Each backend package uses dotenv-flow. Copy the example file to create your local config:

bash
cp packages/identity/.env.development.example packages/identity/.env.development
cp packages/commerce/.env.development.example packages/commerce/.env.development
# repeat for each package you need to run

At minimum, verify these values in each .env.development:

VariableWhat to check
APP_ENV_POSTGRES_*Points to your local PostgreSQL
APP_ENV_CACHE_REDIS_*Points to your local Redis
APP_ENV_SERVER_PORTNo port conflicts between services
APP_ENV_IDENTITY_SERVICE_BASE_URLPoints to your running identity service

See Environment Reference for the complete variable catalog.

Build

The monorepo has a strict build order because packages depend on each other. The Makefile handles this:

bash
make build    # builds everything in the correct dependency order

This runs build-3rd (third-party integrations) then build-packages (all backend packages) in the dependency order:

core → asset, search, identity, inventory, finance, ledger, pricing, taxation, outreach, signal, sale
     → commerce (depends on asset + search)
     → payment (depends on core + mq-pay)

To build a single package (with its dependencies):

bash
make identity    # builds core → mq-sms → identity
make commerce    # builds core → asset → search → commerce

Always use make or bun run rebuild

Never run tsc or npx directly. The build scripts handle path alias resolution (tsc-alias) that raw TypeScript compilation misses.

Run Migrations

Migrations are run per-package. The core package owns the shared database schemas:

bash
# 1. Core schemas first (public, pricing, allocation, sale, inventory, finance, payment)
make db-migrate-all

# 2. Per-package seed data (permissions, default configs)
cd packages/identity && bun run migrate:dev
cd ../commerce && bun run migrate:dev
cd ../sale && bun run migrate:dev
# ... repeat for each package you need

Or migrate a specific schema:

bash
make db-migrate schema=public
make db-migrate schema=pricing
make db-migrate schema=inventory

Run Your First Service

Identity is the best starting point — all other services depend on it for JWT verification.

bash
make dev-identity

This starts the identity service on port 31010. Verify it's running:

bash
curl http://localhost:31010/v1/api/identity/health
# Should return { "status": "ok" }

curl http://localhost:31010/v1/api/identity/jw-certs
# Should return the JWKS public keys

Then start other services as needed:

bash
make dev-commerce    # port 31020
make dev-sale        # port 31030
make dev-finance     # port 31040
make dev-pricing     # port 31070

Each service exposes a Swagger UI at its base URL (e.g., http://localhost:31020/v1/api/commerce).

Service Registry

ServiceCodePortSnowflake IDBase Path
identitySVC-00010310101/v1/api/identity
commerceSVC-00020310202/v1/api/commerce
saleSVC-00030310303/v1/api/sale
financeSVC-00040310404/v1/api/finance
inventorySVC-00050310505/v1/api/inventory
ledgerSVC-00060310606/v1/api/ledger
pricingSVC-00070310707/v1/api/pricing
paymentSVC-00080310808/v1/api/payment
signalSVC-00090310909/v1/api/signal
outreachSVC-001003111010/v1/api/outreach
licensingSVC-001103112011/v1/api/licensing
taxationSVC-001303113013/v1/api/taxation

Run Frontend Apps

bash
make dev-client      # Admin dashboard — http://localhost:5173
make dev-bo          # Back office — http://localhost:5174
make dev-overture    # Marketing site — http://localhost:4321
make dev-wiki        # This documentation — http://localhost:5175

The POS desktop app requires Tauri:

bash
cd apps/sale-main
cargo tauri dev

Run Tests

bash
# Per-package unit tests (no DB required)
cd packages/licensing
bun run test:unit

# Per-package full test suite (may need .env.test + DB)
bun run test

Run Linting

bash
make lint            # lint everything (apps + packages + third-parties + docs)
make lint-identity   # lint a single package
make lint-app-client # lint a single app

Zero lint errors

Lint errors are a hard gate — every commit and MR must pass make lint with zero errors. Run bun run lint:fix in the affected package to auto-fix most issues.

Common Scripts (Per Package)

Every backend package has the same script interface:

ScriptPurpose
bun run rebuildClean + compile (always use this)
bun run server:devDev server with .env.development
bun run server:localDev server with .env.local
bun run migrate:devRun migrations
bun run testFull test suite
bun run test:unitUnit tests only (if configured)
bun run lint:fixESLint + Prettier auto-fix

Next Steps

TopicPage
All Makefile targetsBuild System
Environment variablesEnvironment Reference
Git workflow & MRsGit Workflow
IGNIS framework patternsIGNIS Patterns
Backend packagesPackages Overview
Frontend appsApps Overview

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.