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.laboratorylicense
5. Common Commands
| Command | Description |
|---|---|
pnpm dev | Start with hot reload |
pnpm test:unit | Run unit tests |
pnpm test:integration | Run integration tests (requires docker) |
pnpm drizzle-kit generate | Generate migration from schema changes |
pnpm drizzle-kit migrate | Apply pending migrations |
pnpm seed:catalog | Load 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