mahis_emr_api_lab 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +71 -0
  4. data/Rakefile +32 -0
  5. data/app/controllers/lab/application_controller.rb +6 -0
  6. data/app/controllers/lab/labels_controller.rb +17 -0
  7. data/app/controllers/lab/orders_controller.rb +78 -0
  8. data/app/controllers/lab/reasons_for_test_controller.rb +9 -0
  9. data/app/controllers/lab/results_controller.rb +20 -0
  10. data/app/controllers/lab/specimen_types_controller.rb +15 -0
  11. data/app/controllers/lab/test_result_indicators_controller.rb +9 -0
  12. data/app/controllers/lab/test_types_controller.rb +15 -0
  13. data/app/controllers/lab/tests_controller.rb +25 -0
  14. data/app/controllers/lab/users_controller.rb +32 -0
  15. data/app/jobs/lab/application_job.rb +4 -0
  16. data/app/jobs/lab/push_order_job.rb +12 -0
  17. data/app/jobs/lab/update_patient_orders_job.rb +32 -0
  18. data/app/jobs/lab/void_order_job.rb +17 -0
  19. data/app/mailers/lab/application_mailer.rb +6 -0
  20. data/app/models/lab/application_record.rb +5 -0
  21. data/app/models/lab/lab_accession_number_counter.rb +13 -0
  22. data/app/models/lab/lab_acknowledgement.rb +6 -0
  23. data/app/models/lab/lab_encounter.rb +7 -0
  24. data/app/models/lab/lab_order.rb +58 -0
  25. data/app/models/lab/lab_result.rb +31 -0
  26. data/app/models/lab/lab_test.rb +19 -0
  27. data/app/models/lab/lims_failed_import.rb +4 -0
  28. data/app/models/lab/lims_order_mapping.rb +10 -0
  29. data/app/models/lab/order_extension.rb +14 -0
  30. data/app/serializers/lab/lab_order_serializer.rb +56 -0
  31. data/app/serializers/lab/result_serializer.rb +36 -0
  32. data/app/serializers/lab/test_serializer.rb +52 -0
  33. data/app/services/lab/accession_number_service.rb +77 -0
  34. data/app/services/lab/acknowledgement_service.rb +47 -0
  35. data/app/services/lab/concepts_service.rb +82 -0
  36. data/app/services/lab/json_web_token_service.rb +20 -0
  37. data/app/services/lab/labelling_service/order_label.rb +106 -0
  38. data/app/services/lab/lims/acknowledgement_serializer.rb +29 -0
  39. data/app/services/lab/lims/acknowledgement_worker.rb +37 -0
  40. data/app/services/lab/lims/api/blackhole_api.rb +21 -0
  41. data/app/services/lab/lims/api/couchdb_api.rb +53 -0
  42. data/app/services/lab/lims/api/mysql_api.rb +316 -0
  43. data/app/services/lab/lims/api/rest_api.rb +434 -0
  44. data/app/services/lab/lims/api/ws_api.rb +121 -0
  45. data/app/services/lab/lims/api_factory.rb +19 -0
  46. data/app/services/lab/lims/config.rb +105 -0
  47. data/app/services/lab/lims/exceptions.rb +11 -0
  48. data/app/services/lab/lims/migrator.rb +216 -0
  49. data/app/services/lab/lims/order_dto.rb +105 -0
  50. data/app/services/lab/lims/order_serializer.rb +251 -0
  51. data/app/services/lab/lims/pull_worker.rb +314 -0
  52. data/app/services/lab/lims/push_worker.rb +152 -0
  53. data/app/services/lab/lims/utils.rb +91 -0
  54. data/app/services/lab/lims/worker.rb +94 -0
  55. data/app/services/lab/metadata.rb +26 -0
  56. data/app/services/lab/notification_service.rb +72 -0
  57. data/app/services/lab/orders_search_service.rb +72 -0
  58. data/app/services/lab/orders_service.rb +330 -0
  59. data/app/services/lab/results_service.rb +166 -0
  60. data/app/services/lab/tests_service.rb +105 -0
  61. data/app/services/lab/user_service.rb +62 -0
  62. data/config/routes.rb +28 -0
  63. data/db/migrate/20210126092910_create_lab_lab_accession_number_counters.rb +12 -0
  64. data/db/migrate/20210310115457_create_lab_lims_order_mappings.rb +15 -0
  65. data/db/migrate/20210323080140_change_lims_id_to_string_in_lims_order_mapping.rb +15 -0
  66. data/db/migrate/20210326195504_add_order_revision_to_lims_order_mapping.rb +5 -0
  67. data/db/migrate/20210407071728_create_lab_lims_failed_imports.rb +19 -0
  68. data/db/migrate/20210610095024_fix_numeric_results_value_type.rb +20 -0
  69. data/db/migrate/20210807111531_add_default_to_lims_order_mapping.rb +7 -0
  70. data/lib/auto12epl.rb +201 -0
  71. data/lib/couch_bum/couch_bum.rb +92 -0
  72. data/lib/generators/lab/install/USAGE +9 -0
  73. data/lib/generators/lab/install/install_generator.rb +19 -0
  74. data/lib/generators/lab/install/templates/rswag-ui-lab.rb +5 -0
  75. data/lib/generators/lab/install/templates/start_worker.rb +32 -0
  76. data/lib/generators/lab/install/templates/swagger.yaml +714 -0
  77. data/lib/lab/engine.rb +13 -0
  78. data/lib/lab/version.rb +5 -0
  79. data/lib/logger_multiplexor.rb +38 -0
  80. data/lib/mahis_emr_api_lab.rb +6 -0
  81. data/lib/tasks/lab_tasks.rake +25 -0
  82. data/lib/tasks/loaders/data/reasons-for-test.csv +7 -0
  83. data/lib/tasks/loaders/data/test-measures.csv +225 -0
  84. data/lib/tasks/loaders/data/tests.csv +161 -0
  85. data/lib/tasks/loaders/loader_mixin.rb +53 -0
  86. data/lib/tasks/loaders/metadata_loader.rb +26 -0
  87. data/lib/tasks/loaders/reasons_for_test_loader.rb +23 -0
  88. data/lib/tasks/loaders/specimens_loader.rb +65 -0
  89. data/lib/tasks/loaders/test_result_indicators_loader.rb +54 -0
  90. metadata +331 -0
@@ -0,0 +1,714 @@
1
+ ---
2
+ openapi: 3.0.1
3
+ info:
4
+ title: API V1
5
+ version: v1
6
+ paths:
7
+ "/api/v1/lab/orders":
8
+ post:
9
+ summary: Create order
10
+ tags:
11
+ - Orders
12
+ description: |
13
+ Create a lab order for a test.
14
+
15
+ Broadly a lab order consists of a test type and a number of specimens.
16
+ To each specimen is assigned a tracking number which can be used
17
+ to query the status and results of the specimen.
18
+ parameters: []
19
+ security:
20
+ - api_key: []
21
+ responses:
22
+ '201':
23
+ description: Created
24
+ content:
25
+ application/json:
26
+ schema:
27
+ type: array
28
+ items:
29
+ type: object
30
+ properties:
31
+ id:
32
+ type: integer
33
+ patient_id:
34
+ type: integer
35
+ encounter_id:
36
+ type: integer
37
+ order_date:
38
+ type: string
39
+ format: datetime
40
+ accession_number:
41
+ type: string
42
+ specimen:
43
+ type: object
44
+ properties:
45
+ concept_id:
46
+ type: integer
47
+ name:
48
+ type: string
49
+ required:
50
+ - concept_id
51
+ - name
52
+ requesting_clinician:
53
+ type: string
54
+ nullable: true
55
+ target_lab:
56
+ type: string
57
+ reason_for_test:
58
+ type: object
59
+ properties:
60
+ concept_id:
61
+ type: integer
62
+ name:
63
+ type: string
64
+ required:
65
+ - concept_id
66
+ - name
67
+ tests:
68
+ type: array
69
+ items:
70
+ type: object
71
+ properties:
72
+ id:
73
+ type: integer
74
+ concept_id:
75
+ type: integer
76
+ name:
77
+ type: string
78
+ result:
79
+ type: object
80
+ nullable: true
81
+ properties:
82
+ id:
83
+ type: integer
84
+ value:
85
+ type: string
86
+ nullable: true
87
+ date:
88
+ type: string
89
+ format: datetime
90
+ nullable: true
91
+ required:
92
+ - id
93
+ - value
94
+ - date
95
+ required:
96
+ - id
97
+ - concept_id
98
+ - name
99
+ required:
100
+ - id
101
+ - specimen
102
+ - reason_for_test
103
+ - accession_number
104
+ - patient_id
105
+ - order_date
106
+ requestBody:
107
+ content:
108
+ application/json:
109
+ schema:
110
+ type: object
111
+ properties:
112
+ orders:
113
+ type: array
114
+ items:
115
+ properties:
116
+ encounter_id:
117
+ type: integer
118
+ specimen:
119
+ type: object
120
+ properties:
121
+ concept_id:
122
+ type: integer
123
+ description: Specimen type concept ID (see GET /lab/test_types)
124
+ tests:
125
+ type: array
126
+ items:
127
+ type: object
128
+ properties:
129
+ concept_id:
130
+ type: integer
131
+ description: Test type concept ID (see GET /lab/test_types)
132
+ requesting_clinician:
133
+ type: string
134
+ description: Fullname of the clinician requesting the test
135
+ (defaults to orderer)
136
+ target_lab:
137
+ type: string
138
+ reason_for_test_id:
139
+ type: string
140
+ description: One of routine, targeted, or confirmatory
141
+ required:
142
+ - encounter_id
143
+ - tests
144
+ - target_lab
145
+ - reason_for_test_id
146
+ get:
147
+ summary: Retrieve lab orders
148
+ tags:
149
+ - Orders
150
+ description: Search/retrieve for lab orders.
151
+ security:
152
+ - api_key: []
153
+ parameters:
154
+ - name: patient_id
155
+ in: query
156
+ required: false
157
+ description: Filter orders using patient_id
158
+ schema:
159
+ type: integer
160
+ - name: accession_number
161
+ in: query
162
+ required: false
163
+ description: Filter orders using sample accession number
164
+ schema:
165
+ type: integer
166
+ - name: date
167
+ in: query
168
+ required: false
169
+ description: Select results falling on a specific date
170
+ schema:
171
+ type: date
172
+ - name: status
173
+ in: query
174
+ required: false
175
+ description: 'Filter by sample status: ordered, drawn'
176
+ schema:
177
+ type: string
178
+ - name: end_date
179
+ in: query
180
+ required: false
181
+ description: Select all results before this date
182
+ schema:
183
+ type: date
184
+ responses:
185
+ '200':
186
+ description: Success
187
+ content:
188
+ application/json:
189
+ schema:
190
+ type: array
191
+ items:
192
+ type: object
193
+ properties:
194
+ id:
195
+ type: integer
196
+ patient_id:
197
+ type: integer
198
+ encounter_id:
199
+ type: integer
200
+ order_date:
201
+ type: string
202
+ format: datetime
203
+ accession_number:
204
+ type: string
205
+ specimen:
206
+ type: object
207
+ properties:
208
+ concept_id:
209
+ type: integer
210
+ name:
211
+ type: string
212
+ required:
213
+ - concept_id
214
+ - name
215
+ requesting_clinician:
216
+ type: string
217
+ nullable: true
218
+ target_lab:
219
+ type: string
220
+ reason_for_test:
221
+ type: object
222
+ properties:
223
+ concept_id:
224
+ type: integer
225
+ name:
226
+ type: string
227
+ required:
228
+ - concept_id
229
+ - name
230
+ tests:
231
+ type: array
232
+ items:
233
+ type: object
234
+ properties:
235
+ id:
236
+ type: integer
237
+ concept_id:
238
+ type: integer
239
+ name:
240
+ type: string
241
+ result:
242
+ type: object
243
+ nullable: true
244
+ properties:
245
+ id:
246
+ type: integer
247
+ value:
248
+ type: string
249
+ nullable: true
250
+ date:
251
+ type: string
252
+ format: datetime
253
+ nullable: true
254
+ required:
255
+ - id
256
+ - value
257
+ - date
258
+ required:
259
+ - id
260
+ - concept_id
261
+ - name
262
+ required:
263
+ - id
264
+ - specimen
265
+ - reason_for_test
266
+ - accession_number
267
+ - patient_id
268
+ - order_date
269
+ "/api/v1/lab/orders/{order_id}":
270
+ put:
271
+ summary: Update order
272
+ tags:
273
+ - Orders
274
+ description: Update an existing order
275
+ security:
276
+ - api_key: []
277
+ parameters:
278
+ - name: order_id
279
+ in: path
280
+ required: true
281
+ schema:
282
+ type: integer
283
+ responses:
284
+ '200':
285
+ description: Ok
286
+ content:
287
+ application/json:
288
+ schema:
289
+ type: object
290
+ properties:
291
+ type: object
292
+ properties:
293
+ id:
294
+ type: integer
295
+ patient_id:
296
+ type: integer
297
+ encounter_id:
298
+ type: integer
299
+ order_date:
300
+ type: string
301
+ format: datetime
302
+ accession_number:
303
+ type: string
304
+ specimen:
305
+ type: object
306
+ properties:
307
+ concept_id:
308
+ type: integer
309
+ name:
310
+ type: string
311
+ required:
312
+ - concept_id
313
+ - name
314
+ requesting_clinician:
315
+ type: string
316
+ nullable: true
317
+ target_lab:
318
+ type: string
319
+ reason_for_test:
320
+ type: object
321
+ properties:
322
+ concept_id:
323
+ type: integer
324
+ name:
325
+ type: string
326
+ required:
327
+ - concept_id
328
+ - name
329
+ tests:
330
+ type: array
331
+ items:
332
+ type: object
333
+ properties:
334
+ id:
335
+ type: integer
336
+ concept_id:
337
+ type: integer
338
+ name:
339
+ type: string
340
+ result:
341
+ type: object
342
+ nullable: true
343
+ properties:
344
+ id:
345
+ type: integer
346
+ value:
347
+ type: string
348
+ nullable: true
349
+ date:
350
+ type: string
351
+ format: datetime
352
+ nullable: true
353
+ required:
354
+ - id
355
+ - value
356
+ - date
357
+ required:
358
+ - id
359
+ - concept_id
360
+ - name
361
+ required:
362
+ - id
363
+ - specimen
364
+ - reason_for_test
365
+ - accession_number
366
+ - patient_id
367
+ - order_date
368
+ requestBody:
369
+ content:
370
+ application/json:
371
+ schema:
372
+ type: object
373
+ properties:
374
+ specimen:
375
+ type: object
376
+ properties:
377
+ concept_id:
378
+ type: integer
379
+ required:
380
+ - concept_id
381
+ delete:
382
+ summary: Void lab order
383
+ tags:
384
+ - Orders
385
+ description: |
386
+ Void a lab order and all it's associated records
387
+
388
+ This action voids an order, all it's linked tests and results.
389
+ security:
390
+ - api_key: []
391
+ parameters:
392
+ - name: order_id
393
+ in: path
394
+ required: true
395
+ schema:
396
+ type: integer
397
+ - name: reason
398
+ in: query
399
+ required: true
400
+ schema:
401
+ type: string
402
+ responses:
403
+ '204':
404
+ description: No Content
405
+ "/api/v1/lab/reasons_for_test":
406
+ get:
407
+ summary: Reasons for test
408
+ description: Retrieve default reasons for test concept set
409
+ tags:
410
+ - Concepts
411
+ security:
412
+ - api_key: []
413
+ responses:
414
+ '200':
415
+ description: Success
416
+ content:
417
+ application/json:
418
+ schema:
419
+ type: array
420
+ items:
421
+ type: object
422
+ properties:
423
+ concept_id:
424
+ type: integer
425
+ name:
426
+ type: string
427
+ example: Routine
428
+ required:
429
+ - concept_id
430
+ - name
431
+ "/api/v1/lab/tests/{test_id}/results":
432
+ post:
433
+ summary: Add results to order
434
+ tags:
435
+ - Results
436
+ description: Attach results to specimens on order
437
+ parameters:
438
+ - name: test_id
439
+ in: path
440
+ required: true
441
+ schema:
442
+ type: integer
443
+ security:
444
+ - api_key: []
445
+ responses:
446
+ '201':
447
+ description: Created
448
+ requestBody:
449
+ content:
450
+ application/json:
451
+ schema:
452
+ type: object
453
+ properties:
454
+ encounter_id:
455
+ type: integer
456
+ provider_id:
457
+ type: integer
458
+ date:
459
+ type: string
460
+ measures:
461
+ type: array
462
+ items:
463
+ type: object
464
+ properties:
465
+ indicator:
466
+ type: object
467
+ properties:
468
+ concept_id:
469
+ type: integer
470
+ description: Concept ID of a test result indicator for
471
+ this test (see GET /test_result_indicators)
472
+ required:
473
+ - concept_id
474
+ value:
475
+ type: string
476
+ example: LDL
477
+ value_modifier:
478
+ type: string
479
+ example: "="
480
+ value_type:
481
+ type: string
482
+ enum:
483
+ - text
484
+ - boolean
485
+ - numeric
486
+ - coded
487
+ description: Determines under what column the value is to
488
+ be saved under in the obs table (defaults to text)
489
+ example: text
490
+ required:
491
+ - indicator
492
+ - value
493
+ required:
494
+ - measures
495
+ "/api/v1/lab/specimen_types":
496
+ get:
497
+ summary: Specimen types
498
+ tags:
499
+ - Concepts
500
+ description: Retrieve all specimen types
501
+ security:
502
+ - api_key: []
503
+ parameters:
504
+ - name: test_type
505
+ in: query
506
+ required: false
507
+ description: Select specimen types having this test type only
508
+ schema:
509
+ type: string
510
+ responses:
511
+ '200':
512
+ description: Success
513
+ content:
514
+ application/json:
515
+ schema:
516
+ type: array
517
+ items:
518
+ type: object
519
+ properties:
520
+ concept_id:
521
+ type: integer
522
+ name:
523
+ type: string
524
+ required:
525
+ - concept_id
526
+ - name
527
+ "/api/v1/lab/test_result_indicators":
528
+ get:
529
+ summary: Test Result Indicators
530
+ tags:
531
+ - Concepts
532
+ description: Retrieve all result indicators for a given test
533
+ security:
534
+ - api_key: []
535
+ parameters:
536
+ - name: test_type_id
537
+ in: query
538
+ required: true
539
+ description: Concept ID for the desired test
540
+ schema:
541
+ type: integer
542
+ responses:
543
+ '200':
544
+ description: Ok
545
+ content:
546
+ application/json:
547
+ schema:
548
+ type: array
549
+ items:
550
+ type: object
551
+ properties:
552
+ concept_id:
553
+ type: integer
554
+ name:
555
+ type: string
556
+ required:
557
+ - concept_id
558
+ - name
559
+ "/api/v1/lab/test_types":
560
+ get:
561
+ summary: Test types
562
+ tags:
563
+ - Concepts
564
+ description: Retrieve all test types
565
+ security:
566
+ - api_key: []
567
+ parameters:
568
+ - name: specimen_type
569
+ in: query
570
+ required: false
571
+ description: Select test types having this specimen type only
572
+ schema:
573
+ type: string
574
+ responses:
575
+ '200':
576
+ description: Success
577
+ content:
578
+ application/json:
579
+ schema:
580
+ type: array
581
+ items:
582
+ type: object
583
+ properties:
584
+ concept_id:
585
+ type: integer
586
+ name:
587
+ type: string
588
+ required:
589
+ - concept_id
590
+ - name
591
+ "/api/v1/lab/tests":
592
+ get:
593
+ summary: Search for tests
594
+ tags:
595
+ - Tests
596
+ description: 'Search for tests by accession number, date and other parameters.
597
+
598
+ '
599
+ parameters:
600
+ - name: accession_number
601
+ in: query
602
+ required: false
603
+ schema:
604
+ type: string
605
+ - name: test_type_id
606
+ in: query
607
+ required: false
608
+ schema:
609
+ type: integer
610
+ - name: specimen_type_id
611
+ in: query
612
+ required: false
613
+ schema:
614
+ type: integer
615
+ - name: patient_id
616
+ in: query
617
+ required: false
618
+ schema:
619
+ type: integer
620
+ - name: order_date
621
+ in: query
622
+ required: false
623
+ schema:
624
+ type: boolean
625
+ responses:
626
+ '200':
627
+ description: Okay
628
+ content:
629
+ application/json:
630
+ schema:
631
+ type: array
632
+ items:
633
+ type: object
634
+ properties:
635
+ id:
636
+ type: integer
637
+ concept_id:
638
+ type: integer
639
+ name:
640
+ type: string
641
+ order:
642
+ order_id:
643
+ type: string
644
+ accession_number:
645
+ type: string
646
+ post:
647
+ summary: Add tests to an existing order
648
+ tags:
649
+ - Tests
650
+ description: |
651
+ Add tests to an existing order.
652
+
653
+ An order can be created without specifying tests.
654
+ This endpoint allows one to add tests to that order.
655
+ parameters: []
656
+ security:
657
+ - api_key: []
658
+ responses:
659
+ '201':
660
+ description: Created
661
+ content:
662
+ application/json:
663
+ schema:
664
+ type: array
665
+ items:
666
+ type: object
667
+ properties:
668
+ id:
669
+ type: integer
670
+ concept_id:
671
+ type: integer
672
+ name:
673
+ type: string
674
+ order:
675
+ order_id:
676
+ type: string
677
+ accession_number:
678
+ type: string
679
+ requestBody:
680
+ content:
681
+ application/json:
682
+ schema:
683
+ type: object
684
+ properties:
685
+ order_id:
686
+ type: integer
687
+ tests:
688
+ type: array
689
+ items:
690
+ type: object
691
+ properties:
692
+ concept_id:
693
+ type: integer
694
+ description: Test type concept ID
695
+ required:
696
+ - concept_id
697
+ required:
698
+ - order_id
699
+ - tests
700
+ servers:
701
+ - url: http://{defaultHost}
702
+ variables:
703
+ defaultHost:
704
+ default: localhost:3000
705
+ components:
706
+ securitySchemes:
707
+ api_key:
708
+ type: apiKey
709
+ name: Authorization
710
+ in: header
711
+ bearer:
712
+ type: bearer
713
+ name: Authorization
714
+ in: header
data/lib/lab/engine.rb ADDED
@@ -0,0 +1,13 @@
1
+ if Rails.env == 'test'
2
+ require 'rswag/ui'
3
+ require 'rswag/api'
4
+ end
5
+
6
+ class Lab::Engine < ::Rails::Engine
7
+ isolate_namespace Lab
8
+ config.generators.api_only = true
9
+
10
+ config.generators do |g|
11
+ g.test_framework :rspec
12
+ end
13
+ end