Patient Portal Service — Local Dev Setup
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services
1. Prerequisites
| Tool | Version |
|---|---|
| Node.js | 22.x |
| pnpm | 9.x |
| Docker Desktop | ≥ 4.30 |
| Docker Compose | ≥ 2.24 |
2. Docker Compose Stack
# docker-compose.dev.yml (patient-portal-service)
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: portal_dev
POSTGRES_USER: portal
POSTGRES_PASSWORD: portal_secret
ports:
- "5434:5432"
volumes:
- portal_pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6382:6379"
nats:
image: nats:2.10-alpine
command: ["--jetstream", "--store_dir", "/data"]
ports:
- "4225:4222"
volumes:
- portal_natsdata:/data
keycloak:
image: quay.io/keycloak/keycloak:24.0
command: start-dev
environment:
KC_DB: dev-mem
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
ports:
- "8082:8080"
volumes:
portal_pgdata:
portal_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://portal:portal_secret@localhost:5434/portal_dev
REDIS_URL=redis://localhost:6382
NATS_URL=nats://localhost:4225
KEYCLOAK_REALM_URL=http://localhost:8082/realms/portal-dev
MODULE_LICENSE_KEY=ehr.portal
AI_GATEWAY_URL=http://localhost:3099
EXPORT_STORAGE_BUCKET=portal-export-local
LOG_LEVEL=debug
4. Database Migration and Seed
# Run Drizzle migrations
pnpm db:migrate
# Seed dev data (2 tenants, sample portal accounts, sample results)
pnpm db:seed
5. Start Service
pnpm install
pnpm dev
# Service starts on http://localhost:3007
6. Keycloak Patient Realm Setup
On first run, import the dev realm:
# Import portal-dev realm (includes patient users + scopes)
docker exec -it <keycloak_container> \
/opt/keycloak/bin/kc.sh import --file /realm-exports/portal-dev-realm.json
Default dev patient credentials:
- User:
patient@dev.local/ Password:Portal123! - MFA: TOTP seed in
test/fixtures/mfa-seed.txt
7. Common Commands
| Command | Description |
|---|---|
pnpm dev | Start in watch mode |
pnpm test:unit | Run unit tests |
pnpm test:integration | Run integration tests (requires Docker) |
pnpm test:e2e | Run Playwright E2E against local stack |
pnpm db:migrate | Apply pending migrations |
pnpm db:seed | Insert dev seed data |
pnpm build | Production build |
pnpm lint | ESLint check |
pnpm type-check | TypeScript type check (no emit) |
8. Stub Upstream Services
For local development without running all upstream services, use the provided WireMock stubs:
# Start WireMock stubs for upstream services
docker run -d -p 8090:8080 \
-v $(pwd)/test/stubs:/home/wiremock \
wiremock/wiremock:3.5.2
Stubs are pre-configured for:
registration-service— patient demographicslaboratory-service— 3 released observationsscheduling-service— 2 upcoming appointmentsmedication-service— 2 active medications