Skip to main content

Terminology Service — Local Dev Setup

Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services

1. Prerequisites

ToolVersion
Node.js22.x
pnpm9.x
Docker Desktop≥ 4.30
Docker Compose≥ 2.24

2. Docker Compose Stack

# docker-compose.dev.yml (terminology-service)
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: terminology_dev
POSTGRES_USER: terminology
POSTGRES_PASSWORD: term_secret
ports:
- "5435:5432"
volumes:
- term_pgdata:/var/lib/postgresql/data

redis:
image: redis:7-alpine
ports:
- "6383:6379"

nats:
image: nats:2.10-alpine
command: ["--jetstream", "--store_dir", "/data"]
ports:
- "4226:4222"
volumes:
- term_natsdata:/data

volumes:
term_pgdata:
term_natsdata:

Start: docker compose -f docker-compose.dev.yml up -d


3. Environment Setup

cp .env.example .env

.env.example values for local dev:

DATABASE_URL=postgresql://terminology:term_secret@localhost:5435/terminology_dev
REDIS_URL=redis://localhost:6383
NATS_URL=nats://localhost:4226
KEYCLOAK_REALM_URL=http://localhost:8080/realms/ehealth-dev
IMPORT_ENABLED=true
CACHE_TTL_LOOKUP_SECONDS=3600
CACHE_TTL_EXPAND_SECONDS=300
MAX_EXPANSION_SIZE=500
LOG_LEVEL=debug

4. Database Migration and Seed

# Run Drizzle migrations
pnpm db:migrate

# Seed dev data (sample LOINC, SNOMED, RxNorm, ICD-10 concepts; drug interactions; value sets)
pnpm db:seed

The seed script loads a curated subset (~5,000 concepts) from test/fixtures/terminology-seed.csv. This is a non-licensed synthetic set suitable for development and testing. Production requires a licensed ETL run.


5. Start Service

pnpm install
pnpm dev
# Service starts on http://localhost:3008

6. Test the API

# Search for glucose
curl "http://localhost:3008/v1/terminology/search?system=http://loinc.org&query=glucose" \
-H "Authorization: Bearer $(pnpm get-dev-token)"

# Lookup a specific LOINC code
curl "http://localhost:3008/v1/terminology/lookup?system=http://loinc.org&code=2345-7" \
-H "Authorization: Bearer $(pnpm get-dev-token)"

# FHIR CodeSystem $lookup
curl -X POST "http://localhost:3008/fhir/R4/CodeSystem/\$lookup" \
-H "Content-Type: application/fhir+json" \
-H "Authorization: Bearer $(pnpm get-dev-token)" \
-d '{"resourceType":"Parameters","parameter":[{"name":"system","valueUri":"http://loinc.org"},{"name":"code","valueCode":"2345-7"}]}'

7. Loading Test Terminology Data

# Import from CSV using admin endpoint (IMPORT_ENABLED=true required)
curl -X POST "http://localhost:3008/internal/terminology/import" \
-H "Content-Type: multipart/form-data" \
-F "file=@test/fixtures/terminology-seed.csv"

8. Common Commands

CommandDescription
pnpm devStart in watch mode
pnpm test:unitRun unit tests
pnpm test:integrationRun integration tests (requires Docker)
pnpm db:migrateApply pending migrations
pnpm db:seedInsert dev seed concepts
pnpm buildProduction build
pnpm lintESLint check
pnpm type-checkTypeScript type check