dhti-cli 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,6 @@ services:
12
12
  - "80:80"
13
13
  - "9001:80"
14
14
 
15
-
16
15
  frontend:
17
16
  image: openmrs/openmrs-reference-application-3-frontend:3.0.0-beta.17
18
17
  # image: openmrs/openmrs-reference-application-3-frontend:${TAG:-3.0.0-beta.17} # dev3, qa, demo, 3.0.0-beta.18
@@ -59,7 +58,7 @@ services:
59
58
  restart: "unless-stopped"
60
59
  command: "mysqld --character-set-server=utf8 --collation-server=utf8_general_ci"
61
60
  healthcheck:
62
- test: "mysql --user=${OMRS_DB_USER:-openmrs} --password=${OMRS_DB_PASSWORD:-openmrs} --execute \"SHOW DATABASES;\""
61
+ test: 'mysql --user=${OMRS_DB_USER:-openmrs} --password=${OMRS_DB_PASSWORD:-openmrs} --execute "SHOW DATABASES;"'
63
62
  interval: 3s
64
63
  timeout: 1s
65
64
  retries: 5
@@ -78,11 +77,15 @@ services:
78
77
  - "8001:8001"
79
78
  restart: "unless-stopped"
80
79
  environment:
81
- - OLLAMA_SERVER_URL==http://ollama:11434
80
+ - OLLAMA_SERVER_URL=http://ollama:11434
82
81
  - OLLAMA_WEBUI=http://ollama-webui:8080
83
82
  - LANGFUSE_HOST=http://langfuse:3000
84
- - LANGFUSE_PUBLIC_KEY=pk-lf-abcd
85
- - LANGFUSE_SECRET_KEY=sk-lf-abcd
83
+ - LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY:-pk-lf-abcd}
84
+ - LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY:-sk-lf-abcd}
85
+ - GOOGLE_API_KEY=${GOOGLE_API_KEY:-google-api-key}
86
+ - OPENAI_API_KEY=${OPENAI_API_KEY:-openai-api-key}
87
+ - OPENAI_API_BASE=${OPENAI_API_BASE:-https://openrouter.ai/api/v1}
88
+ - OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-openrouter-api-key}
86
89
 
87
90
  ollama:
88
91
  image: ollama/ollama:latest
@@ -105,7 +108,7 @@ services:
105
108
  ports:
106
109
  - 8080:8080
107
110
  environment:
108
- - '/ollama/api=http://ollama:11434/api'
111
+ - "/ollama/api=http://ollama:11434/api"
109
112
  extra_hosts:
110
113
  - host.docker.internal:host-gateway
111
114
  restart: unless-stopped
@@ -118,19 +121,19 @@ services:
118
121
  depends_on:
119
122
  - postgres-db
120
123
  environment:
121
- - "spring.datasource.url=jdbc:postgresql://postgres-db:5432/postgres"
122
- - "spring.datasource.username=postgres"
123
- - "spring.datasource.password=postgres"
124
- - "spring.datasource.driverClassName=org.postgresql.Driver"
125
- - "spring.jpa.properties.hibernate.dialect=ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect"
126
- - "hapi.fhir.fhir_version=R4"
127
- - "hapi.fhir.cors.allowed-origins=*"
128
- - "hapi.fhir.cors.allowCredentials=true"
129
- - "hapi.fhir.bulkdata.enabled=true"
130
- - "hapi.fhir.bulk_export_enabled=true"
131
- - "hapi.fhir.bulk_import_enabled=true"
132
- - "hapi.fhir.enforce_referential_integrity_on_write=false"
133
- - "hapi.fhir.enforce_referential_integrity_on_delete=false"
124
+ - "spring.datasource.url=jdbc:postgresql://postgres-db:5432/postgres"
125
+ - "spring.datasource.username=postgres"
126
+ - "spring.datasource.password=postgres"
127
+ - "spring.datasource.driverClassName=org.postgresql.Driver"
128
+ - "spring.jpa.properties.hibernate.dialect=ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect"
129
+ - "hapi.fhir.fhir_version=R4"
130
+ - "hapi.fhir.cors.allowed-origins=*"
131
+ - "hapi.fhir.cors.allowCredentials=true"
132
+ - "hapi.fhir.bulkdata.enabled=true"
133
+ - "hapi.fhir.bulk_export_enabled=true"
134
+ - "hapi.fhir.bulk_import_enabled=true"
135
+ - "hapi.fhir.enforce_referential_integrity_on_write=false"
136
+ - "hapi.fhir.enforce_referential_integrity_on_delete=false"
134
137
 
135
138
  mcp-fhir:
136
139
  image: beapen/fhir-mcp-server:4.0
@@ -173,7 +176,7 @@ services:
173
176
  - LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
174
177
 
175
178
  postgres-db:
176
- image: postgres
179
+ image: postgres:17
177
180
  restart: "unless-stopped"
178
181
  environment:
179
182
  - POSTGRES_USER=postgres
@@ -183,6 +186,12 @@ services:
183
186
  - 5432:5432
184
187
  volumes:
185
188
  - postgres-db:/var/lib/postgresql/data
189
+ healthcheck:
190
+ test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
191
+ interval: 10s
192
+ timeout: 5s
193
+ retries: 5
194
+ start_period: 10s
186
195
 
187
196
  redis:
188
197
  image: redislabs/redisearch:2.8.8
@@ -191,6 +200,12 @@ services:
191
200
  restart: "unless-stopped"
192
201
  volumes:
193
202
  - redis-db:/data
203
+ healthcheck:
204
+ test: ["CMD", "redis-cli", "ping"]
205
+ interval: 10s
206
+ timeout: 5s
207
+ retries: 3
208
+ start_period: 10s
194
209
 
195
210
  redis-commander:
196
211
  image: rediscommander/redis-commander:latest
@@ -234,14 +249,111 @@ services:
234
249
  - "3000:3000"
235
250
  # environment:
236
251
  # - MCPX_PORT=9000
237
- # - MCPX_SERVER_URL="http://10.0.0.211:9000"
252
+ # - MCPX_SERVER_URL="http://localhost:9000"
238
253
  # - VITE_MCPX_SERVER_PORT=9000
239
- # - VITE_MCPX_SERVER_URL="http://10.0.0.211:9000"
254
+ # - VITE_MCPX_SERVER_URL="http://localhost:9000"
240
255
  restart: unless-stopped
241
256
  volumes:
242
257
  - mcpx-config:/lunar/packages/mcpx-server/config
243
258
  privileged: true
244
259
 
260
+ # Medplum server container
261
+ medplum-server:
262
+ image: medplum/medplum-server:latest
263
+ restart: always
264
+ depends_on:
265
+ postgres-db:
266
+ condition: service_healthy
267
+ redis:
268
+ condition: service_healthy
269
+ ports:
270
+ - "8103:8103"
271
+ volumes:
272
+ # Conditionally define a volume for a `medplum.config.json` if one is specified by the MEDPLUM_CONFIG_PATH env var
273
+ - ${MEDPLUM_CONFIG_PATH:-./medplum.config.json}:/usr/src/medplum/packages/server/medplum.config.json
274
+ entrypoint: >
275
+ sh -c "
276
+ if [ -n '${MEDPLUM_CONFIG_PATH}' ]; then
277
+ echo 'Config file found, running with custom config'
278
+ node --require ./packages/server/dist/otel/instrumentation.js packages/server/dist/index.js file:/usr/src/medplum/packages/server/medplum.config.json
279
+ else
280
+ echo 'No config file found, running with default env settings'
281
+ node --require ./packages/server/dist/otel/instrumentation.js packages/server/dist/index.js env
282
+ fi
283
+ "
284
+ environment:
285
+ MEDPLUM_PORT: 8103
286
+ MEDPLUM_BASE_URL: "http://localhost:8103/"
287
+ MEDPLUM_APP_BASE_URL: "http://localhost:3103/"
288
+ MEDPLUM_STORAGE_BASE_URL: "http://localhost:8103/storage/"
289
+
290
+ MEDPLUM_DATABASE_HOST: "postgres-db"
291
+ MEDPLUM_DATABASE_PORT: 5432
292
+ MEDPLUM_DATABASE_DBNAME: "postgres"
293
+ MEDPLUM_DATABASE_USERNAME: "postgres"
294
+ MEDPLUM_DATABASE_PASSWORD: "postgres"
295
+
296
+ MEDPLUM_REDIS_HOST: "redis"
297
+ MEDPLUM_REDIS_PORT: 6379
298
+ # MEDPLUM_REDIS_PASSWORD: 'medplum'
299
+
300
+ MEDPLUM_BINARY_STORAGE: "file:./binary/"
301
+ MEDPLUM_SUPPORT_EMAIL: '\"Medplum\" <support@medplum.com>'
302
+ MEDPLUM_GOOGLE_CLIENT_ID: "397236612778-c0b5tnjv98frbo1tfuuha5vkme3cmq4s.apps.googleusercontent.com"
303
+ MEDPLUM_GOOGLE_CLIENT_SECRET: ""
304
+ MEDPLUM_RECAPTCHA_SITE_KEY: "6LfHdsYdAAAAAC0uLnnRrDrhcXnziiUwKd8VtLNq"
305
+ MEDPLUM_RECAPTCHA_SECRET_KEY: "6LfHdsYdAAAAAH9dN154jbJ3zpQife3xaiTvPChL"
306
+ MEDPLUM_MAX_JSON_SIZE: "1mb"
307
+ MEDPLUM_MAX_BATCH_SIZE: "50mb"
308
+ MEDPLUM_BOT_LAMBDA_ROLE_ARN: ""
309
+ MEDPLUM_BOT_LAMBDA_LAYER_NAME: "medplum-bot-layer"
310
+ MEDPLUM_VM_CONTEXT_BOTS_ENABLED: "true"
311
+ MEDPLUM_DEFAULT_BOT_RUNTIME_VERSION: "vmcontext"
312
+ MEDPLUM_ALLOWED_ORIGINS: "*"
313
+ MEDPLUM_INTROSPECTION_ENABLED: "true"
314
+ MEDPLUM_SHUTDOWN_TIMEOUT_MILLISECONDS: 30000
315
+
316
+ healthcheck:
317
+ test:
318
+ # We use Node's fetch for healthcheck because this image doesn't have a curl or wget installed
319
+ [
320
+ "CMD",
321
+ "node",
322
+ "-e",
323
+ 'fetch("http://localhost:8103/healthcheck").then(r => r.json()).then(console.log).catch(() => { process.exit(1); })',
324
+ ]
325
+ interval: 30s
326
+ timeout: 10s
327
+ retries: 5
328
+
329
+ # Medplum app container (web UI)
330
+ medplum-app:
331
+ image: medplum/medplum-app:latest
332
+ restart: always
333
+ # depends_on:
334
+ # medplum-server:
335
+ # condition: service_healthy
336
+ ports:
337
+ - "3103:3000"
338
+ healthcheck:
339
+ test: ["CMD", "curl", "-f", "http://localhost:3103"]
340
+ interval: 10s
341
+ timeout: 5s
342
+ retries: 5
343
+
344
+ mpclient:
345
+ image: beapen/mpclient:15.0
346
+ ports:
347
+ - "8111:8111"
348
+ restart: "unless-stopped"
349
+ environment:
350
+ - PORT=8111
351
+ - MPCLIENT_BASE_URL=http://localhost:8111
352
+ - MEDPLUM_TOKEN_URL=http://medplum-server:8103/oauth2/token
353
+ - MEDPLUM_CLIENT_ID=client-id
354
+ - MEDPLUM_CLIENT_SECRET=secret
355
+ depends_on:
356
+ - medplum-server
245
357
 
246
358
  volumes:
247
359
  openmrs-data: ~
@@ -253,4 +365,4 @@ volumes:
253
365
  ollama-code: ~
254
366
  ollama-root: ~
255
367
  ollama-webui: ~
256
- mcpx-config: ~
368
+ mcpx-config: ~
@@ -457,6 +457,14 @@
457
457
  "name": "dry-run",
458
458
  "allowNo": false,
459
459
  "type": "boolean"
460
+ },
461
+ "token": {
462
+ "char": "t",
463
+ "description": "Bearer token for authentication (optional)",
464
+ "name": "token",
465
+ "hasDynamicHelp": false,
466
+ "multiple": false,
467
+ "type": "option"
460
468
  }
461
469
  },
462
470
  "hasDynamicHelp": false,
@@ -474,6 +482,173 @@
474
482
  "mimic.js"
475
483
  ]
476
484
  },
485
+ "synthea": {
486
+ "aliases": [],
487
+ "args": {
488
+ "subcommand": {
489
+ "description": "Subcommand to execute: install, generate, upload, delete, download",
490
+ "name": "subcommand",
491
+ "options": [
492
+ "install",
493
+ "generate",
494
+ "upload",
495
+ "delete",
496
+ "download"
497
+ ],
498
+ "required": true
499
+ }
500
+ },
501
+ "description": "Manage Synthea synthetic FHIR data generation",
502
+ "examples": [
503
+ "<%= config.bin %> <%= command.id %> install",
504
+ "<%= config.bin %> <%= command.id %> generate -p 10",
505
+ "<%= config.bin %> <%= command.id %> upload -e http://fhir:8005/baseR4",
506
+ "<%= config.bin %> <%= command.id %> delete",
507
+ "<%= config.bin %> <%= command.id %> download --covid19"
508
+ ],
509
+ "flags": {
510
+ "age": {
511
+ "char": "a",
512
+ "description": "Generate patients with specific age range (e.g., \"0-18\" for pediatric)",
513
+ "name": "age",
514
+ "hasDynamicHelp": false,
515
+ "multiple": false,
516
+ "type": "option"
517
+ },
518
+ "city": {
519
+ "char": "c",
520
+ "description": "City for patient generation",
521
+ "name": "city",
522
+ "hasDynamicHelp": false,
523
+ "multiple": false,
524
+ "type": "option"
525
+ },
526
+ "covid19": {
527
+ "description": "Download COVID-19 dataset (1k patients)",
528
+ "name": "covid19",
529
+ "allowNo": false,
530
+ "type": "boolean"
531
+ },
532
+ "covid19_10k": {
533
+ "description": "Download COVID-19 dataset (10k patients)",
534
+ "name": "covid19_10k",
535
+ "allowNo": false,
536
+ "type": "boolean"
537
+ },
538
+ "covid19_csv": {
539
+ "description": "Download COVID-19 CSV dataset (1k patients)",
540
+ "name": "covid19_csv",
541
+ "allowNo": false,
542
+ "type": "boolean"
543
+ },
544
+ "covid19_csv_10k": {
545
+ "description": "Download COVID-19 CSV dataset (10k patients)",
546
+ "name": "covid19_csv_10k",
547
+ "allowNo": false,
548
+ "type": "boolean"
549
+ },
550
+ "dry-run": {
551
+ "description": "Show what changes would be made without actually making them",
552
+ "name": "dry-run",
553
+ "allowNo": false,
554
+ "type": "boolean"
555
+ },
556
+ "endpoint": {
557
+ "char": "e",
558
+ "description": "FHIR server endpoint URL",
559
+ "name": "endpoint",
560
+ "default": "http://fhir:8005/baseR4",
561
+ "hasDynamicHelp": false,
562
+ "multiple": false,
563
+ "type": "option"
564
+ },
565
+ "gender": {
566
+ "char": "g",
567
+ "description": "Generate patients of specific gender (M or F)",
568
+ "name": "gender",
569
+ "hasDynamicHelp": false,
570
+ "multiple": false,
571
+ "options": [
572
+ "M",
573
+ "F"
574
+ ],
575
+ "type": "option"
576
+ },
577
+ "population": {
578
+ "char": "p",
579
+ "description": "Number of patients to generate",
580
+ "name": "population",
581
+ "default": 1,
582
+ "hasDynamicHelp": false,
583
+ "multiple": false,
584
+ "type": "option"
585
+ },
586
+ "seed": {
587
+ "char": "s",
588
+ "description": "Random seed for reproducible generation",
589
+ "name": "seed",
590
+ "hasDynamicHelp": false,
591
+ "multiple": false,
592
+ "type": "option"
593
+ },
594
+ "state": {
595
+ "description": "State for patient generation (default: Massachusetts)",
596
+ "name": "state",
597
+ "hasDynamicHelp": false,
598
+ "multiple": false,
599
+ "type": "option"
600
+ },
601
+ "synthea_sample_data_csv_latest": {
602
+ "description": "Download latest CSV sample data",
603
+ "name": "synthea_sample_data_csv_latest",
604
+ "allowNo": false,
605
+ "type": "boolean"
606
+ },
607
+ "synthea_sample_data_fhir_latest": {
608
+ "description": "Download latest FHIR sample data",
609
+ "name": "synthea_sample_data_fhir_latest",
610
+ "allowNo": false,
611
+ "type": "boolean"
612
+ },
613
+ "synthea_sample_data_fhir_stu3_latest": {
614
+ "description": "Download latest FHIR STU3 sample data",
615
+ "name": "synthea_sample_data_fhir_stu3_latest",
616
+ "allowNo": false,
617
+ "type": "boolean"
618
+ },
619
+ "token": {
620
+ "char": "t",
621
+ "description": "Bearer token for FHIR server authentication",
622
+ "name": "token",
623
+ "hasDynamicHelp": false,
624
+ "multiple": false,
625
+ "type": "option"
626
+ },
627
+ "workdir": {
628
+ "char": "w",
629
+ "description": "Working directory for Synthea files",
630
+ "name": "workdir",
631
+ "default": "/home/runner/dhti",
632
+ "hasDynamicHelp": false,
633
+ "multiple": false,
634
+ "type": "option"
635
+ }
636
+ },
637
+ "hasDynamicHelp": false,
638
+ "hiddenAliases": [],
639
+ "id": "synthea",
640
+ "pluginAlias": "dhti-cli",
641
+ "pluginName": "dhti-cli",
642
+ "pluginType": "core",
643
+ "strict": true,
644
+ "enableJsonFlag": false,
645
+ "isESM": true,
646
+ "relativePath": [
647
+ "dist",
648
+ "commands",
649
+ "synthea.js"
650
+ ]
651
+ },
477
652
  "synthetic": {
478
653
  "aliases": [],
479
654
  "args": {
@@ -566,5 +741,5 @@
566
741
  ]
567
742
  }
568
743
  },
569
- "version": "0.5.0"
744
+ "version": "0.7.0"
570
745
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dhti-cli",
3
3
  "description": "DHTI CLI",
4
- "version": "0.5.0",
4
+ "version": "0.7.0",
5
5
  "author": "Bell Eapen",
6
6
  "bin": {
7
7
  "dhti-cli": "bin/run.js"
@@ -83,7 +83,8 @@
83
83
  "postpack": "shx rm -f oclif.manifest.json",
84
84
  "posttest": "echo 'npm run lint'",
85
85
  "prepack": "npx oclif manifest && npx oclif readme --readme-path notes/README.md",
86
- "test": "mocha --forbid-only \"test/**/*.test.ts\"",
86
+ "test": "mocha --forbid-only \"test/**/*.test.ts\" --exclude \"test/e2e/**/*.test.ts\"",
87
+ "test-e2e": "mocha --forbid-only \"test/**/*.test.ts\"",
87
88
  "readme": "npx oclif readme --readme-path notes/README.md && git add notes/README.md",
88
89
  "docs": "typedoc --exclude src/tool.ts --html docs src"
89
90
  },