Skip to main content

Document Service — Local Dev Setup

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


1. Prerequisites

ToolVersion
Node.js22 LTS
pnpm9.x
Docker + Docker Compose24+
AWS CLI or MinIO CLI (mc)For object storage inspection

2. docker-compose.yml (document-service dev stack)

version: "3.9"
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: ghasi_documents
POSTGRES_USER: ghasi
POSTGRES_PASSWORD: ghasi_dev
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data

minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ghasi_minio
MINIO_ROOT_PASSWORD: ghasi_minio_dev
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data

clamav:
image: clamav/clamav:latest
ports:
- "3310:3310"

nats:
image: nats:2.10-alpine
ports:
- "4222:4222"
command: --jetstream

document-service:
build:
context: .
dockerfile: Dockerfile.dev
environment:
DATABASE_URL: postgres://ghasi:ghasi_dev@postgres:5432/ghasi_documents
NATS_URL: nats://nats:4222
OBJECT_STORAGE_ENDPOINT: http://minio:9000
OBJECT_STORAGE_ACCESS_KEY: ghasi_minio
OBJECT_STORAGE_SECRET_KEY: ghasi_minio_dev
OBJECT_STORAGE_BUCKET: ghasi-documents-dev
OBJECT_STORAGE_REGION: us-east-1
CLAMAV_HOST: clamav
CLAMAV_PORT: 3310
FHIR_GATEWAY_URL: http://interop-service:3030
CONFIG_SERVICE_URL: http://config-service:3015
PORT: 3020
NODE_ENV: development
IDENTITY_JWT_ISSUER: http://keycloak:8080/realms/ghasi-dev
PRESIGNED_URL_TTL_SECONDS: 900
ports:
- "3020:3020"
depends_on:
- postgres
- minio
- clamav
- nats

volumes:
postgres_data:
minio_data:

3. Environment Variables

Copy .env.example to .env:

DATABASE_URL=postgres://ghasi:ghasi_dev@localhost:5432/ghasi_documents
NATS_URL=nats://localhost:4222
OBJECT_STORAGE_ENDPOINT=http://localhost:9000
OBJECT_STORAGE_ACCESS_KEY=ghasi_minio
OBJECT_STORAGE_SECRET_KEY=ghasi_minio_dev
OBJECT_STORAGE_BUCKET=ghasi-documents-dev
OBJECT_STORAGE_REGION=us-east-1
CLAMAV_HOST=localhost
CLAMAV_PORT=3310
FHIR_GATEWAY_URL=http://localhost:3030
CONFIG_SERVICE_URL=http://localhost:3015
PORT=3020
NODE_ENV=development
IDENTITY_JWT_ISSUER=http://localhost:8080/realms/ghasi-dev
PRESIGNED_URL_TTL_SECONDS=900
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

4. Common Commands

# Start all dependencies
docker compose up -d postgres minio clamav nats

# Create MinIO bucket
mc alias set local http://localhost:9000 ghasi_minio ghasi_minio_dev
mc mb local/ghasi-documents-dev

# Install dependencies
pnpm install

# Run database migrations
pnpm db:migrate

# Seed platform reference templates
pnpm db:seed

# Start in development mode (hot reload)
pnpm dev

# Start render worker separately
pnpm dev:worker

# Run unit tests
pnpm test:unit

# Run integration tests (requires docker compose running)
pnpm test:integration

# Run all tests
pnpm test

# Check coverage
pnpm test:coverage

# Run PDF contract tests (golden hash comparison)
pnpm test:pdf-contracts

5. Seed Data

The seed script (scripts/seed-dev.ts) creates:

Seed itemDetails
Platform reference templatesGeneral Test Requisition (platform.dms.general-lab.general-test-requisition)
Sample tenant template"Outpatient Prescription" for ten_afg_moph_001
Published versionVersion 1.0.0 of General Test Requisition
Sample render jobCompleted job for test patient

6. MinIO Console

Access MinIO admin console at http://localhost:9001 (user: ghasi_minio, password: ghasi_minio_dev) to inspect uploaded objects and quarantine bucket.


7. Testing with curl

# List templates
curl "http://localhost:3020/v1/document-templates?origin=all&status=published" \
-H "Authorization: Bearer <dev-jwt>"

# Generate a document
curl -X POST "http://localhost:3020/v1/documents/generate" \
-H "Authorization: Bearer <dev-jwt>" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"templateVersionId":"tv_seed_001","patientId":"pat_seed_001","locale":"ps-AF"}'