Skip to main content

Billing Service — Local Dev Setup

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template

1. Prereqs

ToolVersion
Node.js22.x LTS
pnpm9.x
Docker + Docker Compose24+
psql client16
nats-clilatest

2. Bootstrap

# From application monorepo root (D:\GhasiTech\Ghasi-edTech for edTech; Ghasi-eHealth app repo when created)
pnpm install
pnpm --filter @ghasi/service-billing build

3. docker-compose (dev stack)

# infra/dev/billing/docker-compose.yml
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: dev
POSTGRES_DB: billing_dev
ports: ["5435:5432"]
nats:
image: nats:2.10-alpine
command: ["-js"]
ports: ["4222:4222", "8222:8222"]
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: dev
MINIO_ROOT_PASSWORD: devdevdev
ports: ["9000:9000", "9001:9001"]
redis:
image: redis:7-alpine
ports: ["6380:6379"]
docker compose -f infra/dev/billing/docker-compose.yml up -d

4. Env (.env.local)

PORT=3035
NODE_ENV=development
DATABASE_URL=postgres://postgres:dev@localhost:5435/billing_dev
NATS_URL=nats://localhost:4222
REDIS_URL=redis://localhost:6380
JWKS_URL=http://localhost:3010/.well-known/jwks.json
TENANT_SERVICE_URL=http://localhost:3011
TERMINOLOGY_SERVICE_URL=http://localhost:3012
FHIR_GATEWAY_URL=http://localhost:3020
OBJECT_STORE_ENDPOINT=http://localhost:9000
OBJECT_STORE_BUCKET=billing-dev
OBJECT_STORE_ACCESS_KEY=dev
OBJECT_STORE_SECRET_KEY=devdevdev
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
LOG_LEVEL=debug

5. Run

pnpm --filter @ghasi/service-billing drizzle:migrate
pnpm --filter @ghasi/service-billing seed
pnpm --filter @ghasi/service-billing dev

The seed script loads one tenant (ten_dev), one facility (fac_dev), a published price list, one tax rule, one patient account, and a dummy encounter.

6. Common commands

CommandPurpose
pnpm --filter @ghasi/service-billing testUnit tests
pnpm --filter @ghasi/service-billing test:integrationIntegration (requires docker stack)
pnpm --filter @ghasi/service-billing test:e2eE2E revenue cycle
pnpm --filter @ghasi/service-billing typechecktsc --noEmit
pnpm --filter @ghasi/service-billing lintESLint with import-restriction
pnpm --filter @ghasi/service-billing drizzle:generateGenerate migration
pnpm --filter @ghasi/service-billing seed:resetReset and reseed dev DB

7. Smoke test

# Capture charge
TOKEN=$(./scripts/dev-token.sh ten_dev billing_clerk)
curl -sS -X POST http://localhost:3035/charges \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"patientId":"pat_dev_001",
"encounterId":"enc_dev_001",
"facilityId":"fac_dev",
"serviceDate":"2026-04-17",
"items":[{"code":{"system":"CPT","code":"99213"},"units":1,"modifiers":[]}]
}' | jq

# Post payment
curl -sS -X POST http://localhost:3035/payments \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"accountId":"acc_dev_001","method":"CASH","amount":{"currency":"AFN","minor_units":250000}}' | jq

8. Tearing down

docker compose -f infra/dev/billing/docker-compose.yml down -v