Skip to main content

Laboratory Service — Local Dev Setup

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


1. Prerequisites

  • Docker Desktop ≥ 4.x
  • Node 22 + pnpm 9
  • Keycloak local instance (shared dev realm)

2. docker-compose recipe

# infra/docker-compose.laboratory.yml (extend from root compose)
services:
laboratory-db:
image: postgres:16
environment:
POSTGRES_DB: laboratory
POSTGRES_USER: lab_user
POSTGRES_PASSWORD: lab_pass
ports:
- "5438:5432"
volumes:
- laboratory-db-data:/var/lib/postgresql/data

laboratory-service:
build:
context: .
dockerfile: services/laboratory-service/Dockerfile.dev
environment:
DATABASE_URL: postgresql://lab_user:lab_pass@laboratory-db:5432/laboratory
NATS_URL: nats://nats:4222
KEYCLOAK_JWKS_URI: http://keycloak:8080/realms/ghasi/protocol/openid-connect/certs
FHIR_GATEWAY_URL: http://interop-service:3000
TERMINOLOGY_SERVICE_URL: http://terminology-service:3000
MODULE_LICENSE_KEY: dev-diag-laboratory
ports:
- "3008:3000"
depends_on:
- laboratory-db

volumes:
laboratory-db-data:

3. Initial Setup

# Install dependencies
pnpm install

# Run DB migrations
pnpm --filter @ghasi/laboratory-service drizzle-kit migrate

# Seed test catalog with common LOINC codes
pnpm --filter @ghasi/laboratory-service seed:catalog

# Start in dev mode (hot reload)
pnpm --filter @ghasi/laboratory-service dev

4. Seed Data

The seed script (src/infrastructure/seeds/catalog.seed.ts) loads:

  • 20 common LOINC codes (CBC, metabolic panel, lipid panel)
  • 2 sample critical value policies (potassium, sodium)
  • 1 sample tenant with diag.laboratory license

5. Common Commands

CommandDescription
pnpm devStart with hot reload
pnpm test:unitRun unit tests
pnpm test:integrationRun integration tests (requires docker)
pnpm drizzle-kit generateGenerate migration from schema changes
pnpm drizzle-kit migrateApply pending migrations
pnpm seed:catalogLoad sample test catalog

6. Testing Against a Sample ORU

Use the included sample HL7 v2 ORU file to simulate external analyzer input:

# Send sample ORU through interop-service (local)
curl -X POST http://localhost:3009/v1/interop/hl7v2/inbound \
-H "Content-Type: text/plain" \
--data-binary @test/fixtures/sample-oru-r01.hl7