phenoml 17.0.1 → 17.2.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.
Files changed (109) hide show
  1. package/dist/cjs/BaseClient.js +2 -2
  2. package/dist/cjs/Client.d.ts +3 -0
  3. package/dist/cjs/Client.js +15 -10
  4. package/dist/cjs/api/resources/fhir2Omop/client/Client.d.ts +123 -0
  5. package/dist/cjs/api/resources/fhir2Omop/client/Client.js +211 -0
  6. package/dist/cjs/api/resources/fhir2Omop/client/index.d.ts +1 -0
  7. package/dist/cjs/api/resources/fhir2Omop/client/index.js +17 -0
  8. package/dist/cjs/api/resources/fhir2Omop/client/requests/CreateOmopRequest.d.ts +76 -0
  9. package/dist/cjs/api/resources/fhir2Omop/client/requests/CreateOmopRequest.js +3 -0
  10. package/dist/cjs/api/resources/fhir2Omop/client/requests/index.d.ts +1 -0
  11. package/dist/cjs/api/resources/fhir2Omop/client/requests/index.js +2 -0
  12. package/dist/cjs/api/resources/fhir2Omop/errors/BadRequestError.d.ts +5 -0
  13. package/dist/cjs/api/resources/fhir2Omop/errors/BadRequestError.js +54 -0
  14. package/dist/cjs/api/resources/fhir2Omop/errors/InternalServerError.d.ts +5 -0
  15. package/dist/cjs/api/resources/fhir2Omop/errors/InternalServerError.js +54 -0
  16. package/dist/cjs/api/resources/fhir2Omop/errors/UnauthorizedError.d.ts +5 -0
  17. package/dist/cjs/api/resources/fhir2Omop/errors/UnauthorizedError.js +54 -0
  18. package/dist/cjs/api/resources/fhir2Omop/errors/index.d.ts +3 -0
  19. package/dist/cjs/api/resources/fhir2Omop/errors/index.js +19 -0
  20. package/dist/cjs/api/resources/fhir2Omop/exports.d.ts +2 -0
  21. package/dist/cjs/api/resources/fhir2Omop/exports.js +21 -0
  22. package/dist/cjs/api/resources/fhir2Omop/index.d.ts +3 -0
  23. package/dist/cjs/api/resources/fhir2Omop/index.js +19 -0
  24. package/dist/cjs/api/resources/fhir2Omop/types/ConditionOccurrenceRow.d.ts +12 -0
  25. package/dist/cjs/api/resources/fhir2Omop/types/ConditionOccurrenceRow.js +3 -0
  26. package/dist/cjs/api/resources/fhir2Omop/types/CreateOmopResponse.d.ts +17 -0
  27. package/dist/cjs/api/resources/fhir2Omop/types/CreateOmopResponse.js +3 -0
  28. package/dist/cjs/api/resources/fhir2Omop/types/DroppedResource.d.ts +5 -0
  29. package/dist/cjs/api/resources/fhir2Omop/types/DroppedResource.js +3 -0
  30. package/dist/cjs/api/resources/fhir2Omop/types/DrugExposureRow.d.ts +13 -0
  31. package/dist/cjs/api/resources/fhir2Omop/types/DrugExposureRow.js +3 -0
  32. package/dist/cjs/api/resources/fhir2Omop/types/MappingReportEntry.d.ts +32 -0
  33. package/dist/cjs/api/resources/fhir2Omop/types/MappingReportEntry.js +3 -0
  34. package/dist/cjs/api/resources/fhir2Omop/types/MeasurementRow.d.ts +17 -0
  35. package/dist/cjs/api/resources/fhir2Omop/types/MeasurementRow.js +3 -0
  36. package/dist/cjs/api/resources/fhir2Omop/types/ObservationRow.d.ts +16 -0
  37. package/dist/cjs/api/resources/fhir2Omop/types/ObservationRow.js +3 -0
  38. package/dist/cjs/api/resources/fhir2Omop/types/OmopTables.d.ts +13 -0
  39. package/dist/cjs/api/resources/fhir2Omop/types/OmopTables.js +3 -0
  40. package/dist/cjs/api/resources/fhir2Omop/types/PersonRow.d.ts +14 -0
  41. package/dist/cjs/api/resources/fhir2Omop/types/PersonRow.js +3 -0
  42. package/dist/cjs/api/resources/fhir2Omop/types/ProcedureOccurrenceRow.d.ts +10 -0
  43. package/dist/cjs/api/resources/fhir2Omop/types/ProcedureOccurrenceRow.js +3 -0
  44. package/dist/cjs/api/resources/fhir2Omop/types/ScanSummary.d.ts +41 -0
  45. package/dist/cjs/api/resources/fhir2Omop/types/ScanSummary.js +3 -0
  46. package/dist/cjs/api/resources/fhir2Omop/types/VisitOccurrenceRow.d.ts +11 -0
  47. package/dist/cjs/api/resources/fhir2Omop/types/VisitOccurrenceRow.js +3 -0
  48. package/dist/cjs/api/resources/fhir2Omop/types/index.d.ts +12 -0
  49. package/dist/cjs/api/resources/fhir2Omop/types/index.js +28 -0
  50. package/dist/cjs/api/resources/index.d.ts +1 -0
  51. package/dist/cjs/api/resources/index.js +2 -1
  52. package/dist/cjs/version.d.ts +1 -1
  53. package/dist/cjs/version.js +1 -1
  54. package/dist/esm/BaseClient.mjs +2 -2
  55. package/dist/esm/Client.d.mts +3 -0
  56. package/dist/esm/Client.mjs +5 -0
  57. package/dist/esm/api/resources/fhir2Omop/client/Client.d.mts +123 -0
  58. package/dist/esm/api/resources/fhir2Omop/client/Client.mjs +174 -0
  59. package/dist/esm/api/resources/fhir2Omop/client/index.d.mts +1 -0
  60. package/dist/esm/api/resources/fhir2Omop/client/index.mjs +1 -0
  61. package/dist/esm/api/resources/fhir2Omop/client/requests/CreateOmopRequest.d.mts +76 -0
  62. package/dist/esm/api/resources/fhir2Omop/client/requests/CreateOmopRequest.mjs +2 -0
  63. package/dist/esm/api/resources/fhir2Omop/client/requests/index.d.mts +1 -0
  64. package/dist/esm/api/resources/fhir2Omop/client/requests/index.mjs +1 -0
  65. package/dist/esm/api/resources/fhir2Omop/errors/BadRequestError.d.mts +5 -0
  66. package/dist/esm/api/resources/fhir2Omop/errors/BadRequestError.mjs +17 -0
  67. package/dist/esm/api/resources/fhir2Omop/errors/InternalServerError.d.mts +5 -0
  68. package/dist/esm/api/resources/fhir2Omop/errors/InternalServerError.mjs +17 -0
  69. package/dist/esm/api/resources/fhir2Omop/errors/UnauthorizedError.d.mts +5 -0
  70. package/dist/esm/api/resources/fhir2Omop/errors/UnauthorizedError.mjs +17 -0
  71. package/dist/esm/api/resources/fhir2Omop/errors/index.d.mts +3 -0
  72. package/dist/esm/api/resources/fhir2Omop/errors/index.mjs +3 -0
  73. package/dist/esm/api/resources/fhir2Omop/exports.d.mts +2 -0
  74. package/dist/esm/api/resources/fhir2Omop/exports.mjs +3 -0
  75. package/dist/esm/api/resources/fhir2Omop/index.d.mts +3 -0
  76. package/dist/esm/api/resources/fhir2Omop/index.mjs +3 -0
  77. package/dist/esm/api/resources/fhir2Omop/types/ConditionOccurrenceRow.d.mts +12 -0
  78. package/dist/esm/api/resources/fhir2Omop/types/ConditionOccurrenceRow.mjs +2 -0
  79. package/dist/esm/api/resources/fhir2Omop/types/CreateOmopResponse.d.mts +17 -0
  80. package/dist/esm/api/resources/fhir2Omop/types/CreateOmopResponse.mjs +2 -0
  81. package/dist/esm/api/resources/fhir2Omop/types/DroppedResource.d.mts +5 -0
  82. package/dist/esm/api/resources/fhir2Omop/types/DroppedResource.mjs +2 -0
  83. package/dist/esm/api/resources/fhir2Omop/types/DrugExposureRow.d.mts +13 -0
  84. package/dist/esm/api/resources/fhir2Omop/types/DrugExposureRow.mjs +2 -0
  85. package/dist/esm/api/resources/fhir2Omop/types/MappingReportEntry.d.mts +32 -0
  86. package/dist/esm/api/resources/fhir2Omop/types/MappingReportEntry.mjs +2 -0
  87. package/dist/esm/api/resources/fhir2Omop/types/MeasurementRow.d.mts +17 -0
  88. package/dist/esm/api/resources/fhir2Omop/types/MeasurementRow.mjs +2 -0
  89. package/dist/esm/api/resources/fhir2Omop/types/ObservationRow.d.mts +16 -0
  90. package/dist/esm/api/resources/fhir2Omop/types/ObservationRow.mjs +2 -0
  91. package/dist/esm/api/resources/fhir2Omop/types/OmopTables.d.mts +13 -0
  92. package/dist/esm/api/resources/fhir2Omop/types/OmopTables.mjs +2 -0
  93. package/dist/esm/api/resources/fhir2Omop/types/PersonRow.d.mts +14 -0
  94. package/dist/esm/api/resources/fhir2Omop/types/PersonRow.mjs +2 -0
  95. package/dist/esm/api/resources/fhir2Omop/types/ProcedureOccurrenceRow.d.mts +10 -0
  96. package/dist/esm/api/resources/fhir2Omop/types/ProcedureOccurrenceRow.mjs +2 -0
  97. package/dist/esm/api/resources/fhir2Omop/types/ScanSummary.d.mts +41 -0
  98. package/dist/esm/api/resources/fhir2Omop/types/ScanSummary.mjs +2 -0
  99. package/dist/esm/api/resources/fhir2Omop/types/VisitOccurrenceRow.d.mts +11 -0
  100. package/dist/esm/api/resources/fhir2Omop/types/VisitOccurrenceRow.mjs +2 -0
  101. package/dist/esm/api/resources/fhir2Omop/types/index.d.mts +12 -0
  102. package/dist/esm/api/resources/fhir2Omop/types/index.mjs +12 -0
  103. package/dist/esm/api/resources/index.d.mts +1 -0
  104. package/dist/esm/api/resources/index.mjs +1 -0
  105. package/dist/esm/version.d.mts +1 -1
  106. package/dist/esm/version.mjs +1 -1
  107. package/openapi/openapi.json +844 -1
  108. package/package.json +15 -4
  109. package/reference.md +159 -0
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "Phenoml API",
5
- "version": "29e0b858e2cf7f5819be0c2c6a4a094c74ae1eed"
5
+ "version": "f96459701356d9f1fe1acbeab0f6f2eccc498046"
6
6
  },
7
7
  "x-services": [
8
8
  {
@@ -26,6 +26,13 @@
26
26
  "iconHint": "fhir2summary",
27
27
  "status": "beta"
28
28
  },
29
+ {
30
+ "id": "fhir2omop",
31
+ "name": "FHIR2OMOP",
32
+ "description": "Map FHIR R4 resources and bundles into OMOP Common Data Model (CDM v5.4) tables.",
33
+ "iconHint": "fhir2omop",
34
+ "status": "alpha"
35
+ },
29
36
  {
30
37
  "id": "agent",
31
38
  "name": "Agent",
@@ -3010,6 +3017,319 @@
3010
3017
  "x-service": "construe"
3011
3018
  }
3012
3019
  },
3020
+ "/fhir2omop/create": {
3021
+ "post": {
3022
+ "operationId": "fhir2omop_create",
3023
+ "summary": "Map FHIR resources to OMOP CDM v5.4",
3024
+ "description": "Shapes a FHIR R4 resource or Bundle into OMOP Common Data Model v5.4 rows\n(person, visit_occurrence, condition_occurrence, drug_exposure,\nprocedure_occurrence, measurement, observation).\n\n**Two resolution modes, reported in `mode`.** `mode` reflects which\nresolver is wired, not the path an individual coding took. With a\nconcept-resolver configured (the default), `mode` is `\"resolved\"` and the\nresource's primary clinical coding is resolved to a real OMOP `concept_id`;\nwith no resolver configured, `mode` is `\"structural\"` and every clinical\nand source `concept_id` is `0`. In `\"resolved\"` mode individual codings can\nstill land at `concept_id` `0` without changing the mode: a coding the\nservice finds no match for is `UNMAPPED`, and a coding that fell back to the\nstructural tier (the resolver was briefly unavailable, or the resource was\ntext-only) is surfaced in `scan_summary` (`concept_resolver_note`,\n`construe_resolutions`). A `concept_id` of `0` is \"no matching concept\" per\nOMOP semantics, deliberately not omitted. Only the primary clinical coding\nis resolved \u2014 `gender`/`race`/`ethnicity`/`visit`/`value`/`unit`\n`concept_id`s are always `0`.\n\nIn every mode each `*_source_value` carries the verbatim FHIR coding\n(`system#code`), `*_type_concept_id` is set to `32817` (EHR), and the\nresponse `report` lists one Usagi-shaped entry per source coding describing\nhow it resolved (`ALREADY_STANDARD`, `MAPPED`, an `UNCHECKED` suggestion,\nor `UNMAPPED`).\n\nMedication codes are resolved whether they appear inline\n(`medicationCodeableConcept`) or via a `medicationReference` to a contained,\nrelative (`Type/id`), or bundle-entry (`urn:uuid`) `Medication` resource.\nResources that cannot be shaped into a row \u2014 a medication with no usable\ncode, resolvable reference, or display, or any clinical resource whose\nsubject/patient reference cannot be tied to a person \u2014 are reported under\n`scan_summary.dropped_resources` rather than emitted as blank rows. The\nbundle must contain at least one Patient resource.\n",
3025
+ "requestBody": {
3026
+ "required": true,
3027
+ "content": {
3028
+ "application/json": {
3029
+ "schema": {
3030
+ "$ref": "#/components/schemas/fhir2omop_CreateOmopRequest"
3031
+ },
3032
+ "examples": {
3033
+ "bundle_with_medication": {
3034
+ "summary": "Bundle with a referenced medication",
3035
+ "description": "Patient, Condition, and a MedicationRequest whose drug code lives in a contained Medication resource.",
3036
+ "value": {
3037
+ "fhir_resources": {
3038
+ "resourceType": "Bundle",
3039
+ "type": "collection",
3040
+ "entry": [
3041
+ {
3042
+ "resource": {
3043
+ "resourceType": "Patient",
3044
+ "id": "patient-1",
3045
+ "gender": "female",
3046
+ "birthDate": "1985-07-22"
3047
+ }
3048
+ },
3049
+ {
3050
+ "resource": {
3051
+ "resourceType": "Condition",
3052
+ "id": "condition-1",
3053
+ "subject": {
3054
+ "reference": "Patient/patient-1"
3055
+ },
3056
+ "code": {
3057
+ "coding": [
3058
+ {
3059
+ "system": "http://snomed.info/sct",
3060
+ "code": "44054006",
3061
+ "display": "Type 2 diabetes mellitus"
3062
+ }
3063
+ ]
3064
+ },
3065
+ "onsetDateTime": "2024-01-15"
3066
+ }
3067
+ },
3068
+ {
3069
+ "resource": {
3070
+ "resourceType": "MedicationRequest",
3071
+ "id": "medreq-1",
3072
+ "status": "active",
3073
+ "subject": {
3074
+ "reference": "Patient/patient-1"
3075
+ },
3076
+ "medicationReference": {
3077
+ "reference": "#med0"
3078
+ },
3079
+ "authoredOn": "2024-01-16",
3080
+ "contained": [
3081
+ {
3082
+ "resourceType": "Medication",
3083
+ "id": "med0",
3084
+ "code": {
3085
+ "coding": [
3086
+ {
3087
+ "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
3088
+ "code": "860975",
3089
+ "display": "metformin hydrochloride 500 MG"
3090
+ }
3091
+ ]
3092
+ }
3093
+ }
3094
+ ]
3095
+ }
3096
+ }
3097
+ ]
3098
+ }
3099
+ }
3100
+ }
3101
+ }
3102
+ }
3103
+ }
3104
+ },
3105
+ "responses": {
3106
+ "200": {
3107
+ "description": "FHIR resources mapped to OMOP CDM v5.4",
3108
+ "content": {
3109
+ "application/json": {
3110
+ "schema": {
3111
+ "$ref": "#/components/schemas/fhir2omop_CreateOmopResponse"
3112
+ },
3113
+ "examples": {
3114
+ "resolved_mapping": {
3115
+ "summary": "Resolved mapping result (default)",
3116
+ "description": "Same bundle with `concept_id`s filled by the concept-resolver\nservice. Both source codes are already standard, so each carries\nits own OMOP `concept_id` with `ALREADY_STANDARD` status;\n`target_code` is omitted because the service returns the standard\nconcept's id, name, and vocabulary rather than its `concept_code`.\nIllustrative `concept_id` values.\n",
3117
+ "value": {
3118
+ "success": true,
3119
+ "message": "FHIR resources mapped to OMOP CDM v5.4 with vocabulary concept resolution",
3120
+ "mode": "resolved",
3121
+ "tables": {
3122
+ "person": [
3123
+ {
3124
+ "person_id": 1,
3125
+ "gender_concept_id": 0,
3126
+ "year_of_birth": 1985,
3127
+ "month_of_birth": 7,
3128
+ "day_of_birth": 22,
3129
+ "birth_datetime": "1985-07-22",
3130
+ "race_concept_id": 0,
3131
+ "ethnicity_concept_id": 0,
3132
+ "person_source_value": "patient-1",
3133
+ "gender_source_value": "female"
3134
+ }
3135
+ ],
3136
+ "condition_occurrence": [
3137
+ {
3138
+ "condition_occurrence_id": 1,
3139
+ "person_id": 1,
3140
+ "condition_concept_id": 201826,
3141
+ "condition_start_date": "2024-01-15",
3142
+ "condition_start_datetime": "2024-01-15",
3143
+ "condition_type_concept_id": 32817,
3144
+ "condition_source_value": "http://snomed.info/sct#44054006",
3145
+ "condition_source_concept_id": 201826
3146
+ }
3147
+ ],
3148
+ "drug_exposure": [
3149
+ {
3150
+ "drug_exposure_id": 1,
3151
+ "person_id": 1,
3152
+ "drug_concept_id": 40163924,
3153
+ "drug_exposure_start_date": "2024-01-16",
3154
+ "drug_exposure_start_datetime": "2024-01-16",
3155
+ "drug_type_concept_id": 32817,
3156
+ "drug_source_value": "http://www.nlm.nih.gov/research/umls/rxnorm#860975",
3157
+ "drug_source_concept_id": 40163924
3158
+ }
3159
+ ]
3160
+ },
3161
+ "report": [
3162
+ {
3163
+ "resource_type": "Condition",
3164
+ "resource_id": "condition-1",
3165
+ "omop_table": "condition_occurrence",
3166
+ "source_system": "http://snomed.info/sct",
3167
+ "source_code": "44054006",
3168
+ "source_name": "Type 2 diabetes mellitus",
3169
+ "target_vocabulary": "SNOMED",
3170
+ "target_name": "Type 2 diabetes mellitus",
3171
+ "mapping_status": "ALREADY_STANDARD"
3172
+ },
3173
+ {
3174
+ "resource_type": "MedicationRequest",
3175
+ "resource_id": "medreq-1",
3176
+ "omop_table": "drug_exposure",
3177
+ "source_system": "http://www.nlm.nih.gov/research/umls/rxnorm",
3178
+ "source_code": "860975",
3179
+ "source_name": "metformin hydrochloride 500 MG",
3180
+ "target_vocabulary": "RXNORM",
3181
+ "target_name": "metformin hydrochloride 500 MG",
3182
+ "mapping_status": "ALREADY_STANDARD"
3183
+ }
3184
+ ],
3185
+ "scan_summary": {
3186
+ "total_resources": 3,
3187
+ "resource_counts": {
3188
+ "Patient": 1,
3189
+ "Condition": 1,
3190
+ "MedicationRequest": 1
3191
+ },
3192
+ "tables_populated": {
3193
+ "person": 1,
3194
+ "condition_occurrence": 1,
3195
+ "drug_exposure": 1
3196
+ },
3197
+ "coding_systems": {
3198
+ "http://snomed.info/sct": 1,
3199
+ "http://www.nlm.nih.gov/research/umls/rxnorm": 1
3200
+ },
3201
+ "codes_already_standard": 2,
3202
+ "codes_normalized": 0,
3203
+ "codes_unmapped": 0,
3204
+ "off_vocab_rate": 0,
3205
+ "resolved_vocab_version": "v20240229"
3206
+ }
3207
+ }
3208
+ },
3209
+ "structural_mapping": {
3210
+ "summary": "Structural mapping result (fallback / no resolver configured)",
3211
+ "value": {
3212
+ "success": true,
3213
+ "message": "FHIR resources mapped to OMOP CDM v5.4 (structural; concept_ids pending vocabulary crosswalk)",
3214
+ "mode": "structural",
3215
+ "tables": {
3216
+ "person": [
3217
+ {
3218
+ "person_id": 1,
3219
+ "gender_concept_id": 0,
3220
+ "year_of_birth": 1985,
3221
+ "month_of_birth": 7,
3222
+ "day_of_birth": 22,
3223
+ "birth_datetime": "1985-07-22",
3224
+ "race_concept_id": 0,
3225
+ "ethnicity_concept_id": 0,
3226
+ "person_source_value": "patient-1",
3227
+ "gender_source_value": "female"
3228
+ }
3229
+ ],
3230
+ "condition_occurrence": [
3231
+ {
3232
+ "condition_occurrence_id": 1,
3233
+ "person_id": 1,
3234
+ "condition_concept_id": 0,
3235
+ "condition_start_date": "2024-01-15",
3236
+ "condition_start_datetime": "2024-01-15",
3237
+ "condition_type_concept_id": 32817,
3238
+ "condition_source_value": "http://snomed.info/sct#44054006",
3239
+ "condition_source_concept_id": 0
3240
+ }
3241
+ ],
3242
+ "drug_exposure": [
3243
+ {
3244
+ "drug_exposure_id": 1,
3245
+ "person_id": 1,
3246
+ "drug_concept_id": 0,
3247
+ "drug_exposure_start_date": "2024-01-16",
3248
+ "drug_exposure_start_datetime": "2024-01-16",
3249
+ "drug_type_concept_id": 32817,
3250
+ "drug_source_value": "http://www.nlm.nih.gov/research/umls/rxnorm#860975",
3251
+ "drug_source_concept_id": 0
3252
+ }
3253
+ ]
3254
+ },
3255
+ "report": [
3256
+ {
3257
+ "resource_type": "Condition",
3258
+ "resource_id": "condition-1",
3259
+ "omop_table": "condition_occurrence",
3260
+ "source_system": "http://snomed.info/sct",
3261
+ "source_code": "44054006",
3262
+ "source_name": "Type 2 diabetes mellitus",
3263
+ "target_vocabulary": "SNOMED",
3264
+ "target_code": "44054006",
3265
+ "target_name": "Type 2 diabetes mellitus",
3266
+ "mapping_status": "ALREADY_STANDARD"
3267
+ },
3268
+ {
3269
+ "resource_type": "MedicationRequest",
3270
+ "resource_id": "medreq-1",
3271
+ "omop_table": "drug_exposure",
3272
+ "source_system": "http://www.nlm.nih.gov/research/umls/rxnorm",
3273
+ "source_code": "860975",
3274
+ "source_name": "metformin hydrochloride 500 MG",
3275
+ "target_vocabulary": "RXNORM",
3276
+ "target_code": "860975",
3277
+ "target_name": "metformin hydrochloride 500 MG",
3278
+ "mapping_status": "ALREADY_STANDARD"
3279
+ }
3280
+ ],
3281
+ "scan_summary": {
3282
+ "total_resources": 3,
3283
+ "resource_counts": {
3284
+ "Patient": 1,
3285
+ "Condition": 1,
3286
+ "MedicationRequest": 1
3287
+ },
3288
+ "tables_populated": {
3289
+ "person": 1,
3290
+ "condition_occurrence": 1,
3291
+ "drug_exposure": 1
3292
+ },
3293
+ "coding_systems": {
3294
+ "http://snomed.info/sct": 1,
3295
+ "http://www.nlm.nih.gov/research/umls/rxnorm": 1
3296
+ },
3297
+ "codes_already_standard": 2,
3298
+ "codes_normalized": 0,
3299
+ "codes_unmapped": 0,
3300
+ "off_vocab_rate": 0
3301
+ }
3302
+ }
3303
+ }
3304
+ }
3305
+ }
3306
+ }
3307
+ },
3308
+ "400": {
3309
+ "description": "Bad request - invalid input. Possible reasons:\n- Invalid FHIR input (missing or non-Bundle/non-resource payload)\n- No Patient resource found (OMOP requires at least one person)\n",
3310
+ "content": {
3311
+ "application/json": {
3312
+ "schema": {
3313
+ "$ref": "#/components/schemas/fhir2omop_CreateOmopResponse"
3314
+ }
3315
+ }
3316
+ }
3317
+ },
3318
+ "401": {
3319
+ "description": "Unauthorized"
3320
+ },
3321
+ "500": {
3322
+ "description": "Internal server error"
3323
+ }
3324
+ },
3325
+ "security": [
3326
+ {
3327
+ "bearerAuth": []
3328
+ }
3329
+ ],
3330
+ "x-service": "fhir2omop"
3331
+ }
3332
+ },
3013
3333
  "/fhir-provider/{fhir_provider_id}/fhir/{fhir_path}": {
3014
3334
  "get": {
3015
3335
  "summary": "Read or search FHIR resources",
@@ -8312,6 +8632,529 @@
8312
8632
  }
8313
8633
  }
8314
8634
  },
8635
+ "fhir2omop_CreateOmopRequest": {
8636
+ "type": "object",
8637
+ "required": [
8638
+ "fhir_resources"
8639
+ ],
8640
+ "properties": {
8641
+ "fhir_resources": {
8642
+ "type": "object",
8643
+ "additionalProperties": true,
8644
+ "description": "FHIR resources (single resource or Bundle). Must contain at least one\nPatient resource. Resources are mapped to OMOP rows; standalone\nMedication resources are consumed by medication references rather than\nmapped to their own table.\n"
8645
+ }
8646
+ }
8647
+ },
8648
+ "fhir2omop_CreateOmopResponse": {
8649
+ "type": "object",
8650
+ "properties": {
8651
+ "success": {
8652
+ "type": "boolean"
8653
+ },
8654
+ "message": {
8655
+ "type": "string"
8656
+ },
8657
+ "mode": {
8658
+ "type": "string",
8659
+ "description": "Resolution mode. `resolved` (default) means clinical `concept_id`s were\nfilled by the concept-resolver service; `structural` means no resolver\nwas configured, so all clinical `concept_id`s are `0`. Reflects which\nresolver is wired, not the path an individual coding took \u2014 per-coding\ndegradation is surfaced in `scan_summary`, not the mode.\n"
8660
+ },
8661
+ "tables": {
8662
+ "$ref": "#/components/schemas/fhir2omop_OmopTables"
8663
+ },
8664
+ "report": {
8665
+ "type": "array",
8666
+ "description": "One Usagi-shaped entry per source coding routed through concept resolution.",
8667
+ "items": {
8668
+ "$ref": "#/components/schemas/fhir2omop_MappingReportEntry"
8669
+ }
8670
+ },
8671
+ "scan_summary": {
8672
+ "$ref": "#/components/schemas/fhir2omop_ScanSummary"
8673
+ }
8674
+ }
8675
+ },
8676
+ "fhir2omop_OmopTables": {
8677
+ "type": "object",
8678
+ "description": "OMOP CDM v5.4 rows grouped by destination table.",
8679
+ "properties": {
8680
+ "person": {
8681
+ "type": "array",
8682
+ "items": {
8683
+ "$ref": "#/components/schemas/fhir2omop_PersonRow"
8684
+ }
8685
+ },
8686
+ "visit_occurrence": {
8687
+ "type": "array",
8688
+ "items": {
8689
+ "$ref": "#/components/schemas/fhir2omop_VisitOccurrenceRow"
8690
+ }
8691
+ },
8692
+ "condition_occurrence": {
8693
+ "type": "array",
8694
+ "items": {
8695
+ "$ref": "#/components/schemas/fhir2omop_ConditionOccurrenceRow"
8696
+ }
8697
+ },
8698
+ "drug_exposure": {
8699
+ "type": "array",
8700
+ "items": {
8701
+ "$ref": "#/components/schemas/fhir2omop_DrugExposureRow"
8702
+ }
8703
+ },
8704
+ "procedure_occurrence": {
8705
+ "type": "array",
8706
+ "items": {
8707
+ "$ref": "#/components/schemas/fhir2omop_ProcedureOccurrenceRow"
8708
+ }
8709
+ },
8710
+ "measurement": {
8711
+ "type": "array",
8712
+ "items": {
8713
+ "$ref": "#/components/schemas/fhir2omop_MeasurementRow"
8714
+ }
8715
+ },
8716
+ "observation": {
8717
+ "type": "array",
8718
+ "items": {
8719
+ "$ref": "#/components/schemas/fhir2omop_ObservationRow"
8720
+ }
8721
+ }
8722
+ }
8723
+ },
8724
+ "fhir2omop_PersonRow": {
8725
+ "type": "object",
8726
+ "properties": {
8727
+ "person_id": {
8728
+ "type": "integer",
8729
+ "format": "int64"
8730
+ },
8731
+ "gender_concept_id": {
8732
+ "type": "integer",
8733
+ "format": "int64"
8734
+ },
8735
+ "year_of_birth": {
8736
+ "type": "integer"
8737
+ },
8738
+ "month_of_birth": {
8739
+ "type": "integer"
8740
+ },
8741
+ "day_of_birth": {
8742
+ "type": "integer"
8743
+ },
8744
+ "birth_datetime": {
8745
+ "type": "string"
8746
+ },
8747
+ "race_concept_id": {
8748
+ "type": "integer",
8749
+ "format": "int64"
8750
+ },
8751
+ "ethnicity_concept_id": {
8752
+ "type": "integer",
8753
+ "format": "int64"
8754
+ },
8755
+ "person_source_value": {
8756
+ "type": "string"
8757
+ },
8758
+ "gender_source_value": {
8759
+ "type": "string"
8760
+ },
8761
+ "race_source_value": {
8762
+ "type": "string"
8763
+ },
8764
+ "ethnicity_source_value": {
8765
+ "type": "string"
8766
+ }
8767
+ }
8768
+ },
8769
+ "fhir2omop_VisitOccurrenceRow": {
8770
+ "type": "object",
8771
+ "properties": {
8772
+ "visit_occurrence_id": {
8773
+ "type": "integer",
8774
+ "format": "int64"
8775
+ },
8776
+ "person_id": {
8777
+ "type": "integer",
8778
+ "format": "int64"
8779
+ },
8780
+ "visit_concept_id": {
8781
+ "type": "integer",
8782
+ "format": "int64"
8783
+ },
8784
+ "visit_start_date": {
8785
+ "type": "string"
8786
+ },
8787
+ "visit_start_datetime": {
8788
+ "type": "string"
8789
+ },
8790
+ "visit_end_date": {
8791
+ "type": "string"
8792
+ },
8793
+ "visit_end_datetime": {
8794
+ "type": "string"
8795
+ },
8796
+ "visit_type_concept_id": {
8797
+ "type": "integer",
8798
+ "format": "int64"
8799
+ },
8800
+ "visit_source_value": {
8801
+ "type": "string"
8802
+ }
8803
+ }
8804
+ },
8805
+ "fhir2omop_ConditionOccurrenceRow": {
8806
+ "type": "object",
8807
+ "properties": {
8808
+ "condition_occurrence_id": {
8809
+ "type": "integer",
8810
+ "format": "int64"
8811
+ },
8812
+ "person_id": {
8813
+ "type": "integer",
8814
+ "format": "int64"
8815
+ },
8816
+ "condition_concept_id": {
8817
+ "type": "integer",
8818
+ "format": "int64"
8819
+ },
8820
+ "condition_start_date": {
8821
+ "type": "string"
8822
+ },
8823
+ "condition_start_datetime": {
8824
+ "type": "string"
8825
+ },
8826
+ "condition_end_date": {
8827
+ "type": "string"
8828
+ },
8829
+ "condition_type_concept_id": {
8830
+ "type": "integer",
8831
+ "format": "int64"
8832
+ },
8833
+ "condition_source_value": {
8834
+ "type": "string"
8835
+ },
8836
+ "condition_source_concept_id": {
8837
+ "type": "integer",
8838
+ "format": "int64"
8839
+ },
8840
+ "condition_status_source_value": {
8841
+ "type": "string"
8842
+ }
8843
+ }
8844
+ },
8845
+ "fhir2omop_DrugExposureRow": {
8846
+ "type": "object",
8847
+ "properties": {
8848
+ "drug_exposure_id": {
8849
+ "type": "integer",
8850
+ "format": "int64"
8851
+ },
8852
+ "person_id": {
8853
+ "type": "integer",
8854
+ "format": "int64"
8855
+ },
8856
+ "drug_concept_id": {
8857
+ "type": "integer",
8858
+ "format": "int64"
8859
+ },
8860
+ "drug_exposure_start_date": {
8861
+ "type": "string"
8862
+ },
8863
+ "drug_exposure_start_datetime": {
8864
+ "type": "string"
8865
+ },
8866
+ "drug_exposure_end_date": {
8867
+ "type": "string"
8868
+ },
8869
+ "drug_type_concept_id": {
8870
+ "type": "integer",
8871
+ "format": "int64"
8872
+ },
8873
+ "stop_reason": {
8874
+ "type": "string"
8875
+ },
8876
+ "sig": {
8877
+ "type": "string"
8878
+ },
8879
+ "drug_source_value": {
8880
+ "type": "string"
8881
+ },
8882
+ "drug_source_concept_id": {
8883
+ "type": "integer",
8884
+ "format": "int64"
8885
+ }
8886
+ }
8887
+ },
8888
+ "fhir2omop_ProcedureOccurrenceRow": {
8889
+ "type": "object",
8890
+ "properties": {
8891
+ "procedure_occurrence_id": {
8892
+ "type": "integer",
8893
+ "format": "int64"
8894
+ },
8895
+ "person_id": {
8896
+ "type": "integer",
8897
+ "format": "int64"
8898
+ },
8899
+ "procedure_concept_id": {
8900
+ "type": "integer",
8901
+ "format": "int64"
8902
+ },
8903
+ "procedure_date": {
8904
+ "type": "string"
8905
+ },
8906
+ "procedure_datetime": {
8907
+ "type": "string"
8908
+ },
8909
+ "procedure_type_concept_id": {
8910
+ "type": "integer",
8911
+ "format": "int64"
8912
+ },
8913
+ "procedure_source_value": {
8914
+ "type": "string"
8915
+ },
8916
+ "procedure_source_concept_id": {
8917
+ "type": "integer",
8918
+ "format": "int64"
8919
+ }
8920
+ }
8921
+ },
8922
+ "fhir2omop_MeasurementRow": {
8923
+ "type": "object",
8924
+ "properties": {
8925
+ "measurement_id": {
8926
+ "type": "integer",
8927
+ "format": "int64"
8928
+ },
8929
+ "person_id": {
8930
+ "type": "integer",
8931
+ "format": "int64"
8932
+ },
8933
+ "measurement_concept_id": {
8934
+ "type": "integer",
8935
+ "format": "int64"
8936
+ },
8937
+ "measurement_date": {
8938
+ "type": "string"
8939
+ },
8940
+ "measurement_datetime": {
8941
+ "type": "string"
8942
+ },
8943
+ "measurement_type_concept_id": {
8944
+ "type": "integer",
8945
+ "format": "int64"
8946
+ },
8947
+ "value_as_number": {
8948
+ "type": "number",
8949
+ "format": "double"
8950
+ },
8951
+ "value_as_concept_id": {
8952
+ "type": "integer",
8953
+ "format": "int64"
8954
+ },
8955
+ "unit_concept_id": {
8956
+ "type": "integer",
8957
+ "format": "int64"
8958
+ },
8959
+ "range_low": {
8960
+ "type": "number",
8961
+ "format": "double"
8962
+ },
8963
+ "range_high": {
8964
+ "type": "number",
8965
+ "format": "double"
8966
+ },
8967
+ "measurement_source_value": {
8968
+ "type": "string"
8969
+ },
8970
+ "measurement_source_concept_id": {
8971
+ "type": "integer",
8972
+ "format": "int64"
8973
+ },
8974
+ "unit_source_value": {
8975
+ "type": "string"
8976
+ },
8977
+ "value_source_value": {
8978
+ "type": "string"
8979
+ }
8980
+ }
8981
+ },
8982
+ "fhir2omop_ObservationRow": {
8983
+ "type": "object",
8984
+ "properties": {
8985
+ "observation_id": {
8986
+ "type": "integer",
8987
+ "format": "int64"
8988
+ },
8989
+ "person_id": {
8990
+ "type": "integer",
8991
+ "format": "int64"
8992
+ },
8993
+ "observation_concept_id": {
8994
+ "type": "integer",
8995
+ "format": "int64"
8996
+ },
8997
+ "observation_date": {
8998
+ "type": "string"
8999
+ },
9000
+ "observation_datetime": {
9001
+ "type": "string"
9002
+ },
9003
+ "observation_type_concept_id": {
9004
+ "type": "integer",
9005
+ "format": "int64"
9006
+ },
9007
+ "value_as_number": {
9008
+ "type": "number",
9009
+ "format": "double"
9010
+ },
9011
+ "value_as_string": {
9012
+ "type": "string"
9013
+ },
9014
+ "value_as_concept_id": {
9015
+ "type": "integer",
9016
+ "format": "int64"
9017
+ },
9018
+ "unit_concept_id": {
9019
+ "type": "integer",
9020
+ "format": "int64"
9021
+ },
9022
+ "observation_source_value": {
9023
+ "type": "string"
9024
+ },
9025
+ "observation_source_concept_id": {
9026
+ "type": "integer",
9027
+ "format": "int64"
9028
+ },
9029
+ "unit_source_value": {
9030
+ "type": "string"
9031
+ },
9032
+ "value_source_value": {
9033
+ "type": "string"
9034
+ }
9035
+ }
9036
+ },
9037
+ "fhir2omop_MappingReportEntry": {
9038
+ "type": "object",
9039
+ "description": "One source_to_concept_map-style mapping suggestion (Usagi-shaped).",
9040
+ "properties": {
9041
+ "resource_type": {
9042
+ "type": "string"
9043
+ },
9044
+ "resource_id": {
9045
+ "type": "string"
9046
+ },
9047
+ "omop_table": {
9048
+ "type": "string"
9049
+ },
9050
+ "source_system": {
9051
+ "type": "string"
9052
+ },
9053
+ "source_code": {
9054
+ "type": "string"
9055
+ },
9056
+ "source_name": {
9057
+ "type": "string"
9058
+ },
9059
+ "target_vocabulary": {
9060
+ "type": "string"
9061
+ },
9062
+ "target_code": {
9063
+ "type": "string",
9064
+ "description": "Standard concept code. Set when a coding is matched by the structural\n(construe) tier \u2014 an already-standard code taken verbatim, or a\nconstrue-suggested code \u2014 which is every match in structural mode and,\nin resolved mode, codings for text-only resources or ones that fell back\nwhen the resolver was unavailable. Omitted for codings resolved directly\nby the concept-resolver service, which returns the standard concept's\nid, name, and vocabulary but not its `concept_code`.\n"
9065
+ },
9066
+ "target_name": {
9067
+ "type": "string"
9068
+ },
9069
+ "mapping_status": {
9070
+ "type": "string",
9071
+ "description": "ALREADY_STANDARD (source already in the target standard vocabulary),\nMAPPED (resolved to a standard concept via the OMOP \"Maps to\" crosswalk\nor UMLS-CUI bridge; resolved mode only), UNCHECKED (an unreviewed\nconstrue suggestion; structural / fallback only), or UNMAPPED (no\ncandidate found).\n"
9072
+ },
9073
+ "note": {
9074
+ "type": "string"
9075
+ }
9076
+ }
9077
+ },
9078
+ "fhir2omop_ScanSummary": {
9079
+ "type": "object",
9080
+ "description": "White Rabbit-style aggregate profile of the mapping request.",
9081
+ "properties": {
9082
+ "total_resources": {
9083
+ "type": "integer"
9084
+ },
9085
+ "resource_counts": {
9086
+ "type": "object",
9087
+ "additionalProperties": {
9088
+ "type": "integer"
9089
+ }
9090
+ },
9091
+ "tables_populated": {
9092
+ "type": "object",
9093
+ "additionalProperties": {
9094
+ "type": "integer"
9095
+ }
9096
+ },
9097
+ "coding_systems": {
9098
+ "type": "object",
9099
+ "additionalProperties": {
9100
+ "type": "integer"
9101
+ }
9102
+ },
9103
+ "codes_already_standard": {
9104
+ "type": "integer"
9105
+ },
9106
+ "codes_normalized": {
9107
+ "type": "integer"
9108
+ },
9109
+ "codes_unmapped": {
9110
+ "type": "integer"
9111
+ },
9112
+ "off_vocab_rate": {
9113
+ "type": "number",
9114
+ "format": "double"
9115
+ },
9116
+ "dropped_resources": {
9117
+ "type": "array",
9118
+ "items": {
9119
+ "$ref": "#/components/schemas/fhir2omop_DroppedResource"
9120
+ }
9121
+ },
9122
+ "resolved_vocab_version": {
9123
+ "type": "string",
9124
+ "description": "OMOP vocabulary release the resolver mapped against (e.g. \"v20240229\").\nResolved mode only; empty when no coded concept reached the service.\n"
9125
+ },
9126
+ "concept_resolver_note": {
9127
+ "type": "string",
9128
+ "description": "Set when concept resolution was degraded \u2014 the resolver was unavailable\nfor one or more codings, whose `concept_id`s fell back to the structural\n(construe) tier. Empty when resolution was clean.\n"
9129
+ },
9130
+ "concepts_bridged": {
9131
+ "type": "integer",
9132
+ "description": "Count of `concept_id`s chosen via the lower-confidence UMLS-CUI bridge\n(no direct OMOP crosswalk existed). Resolved mode only.\n"
9133
+ },
9134
+ "concept_candidates_truncated": {
9135
+ "type": "integer",
9136
+ "description": "Count of codings whose candidate list the resolver capped, so the best\nconcept may not have been among those returned.\n"
9137
+ },
9138
+ "construe_resolutions": {
9139
+ "type": "integer",
9140
+ "description": "Count of codings resolved via the construe ML extractor \u2014 the text-only\nor availability fallback path. A non-zero value bills the construe tier.\n"
9141
+ }
9142
+ }
9143
+ },
9144
+ "fhir2omop_DroppedResource": {
9145
+ "type": "object",
9146
+ "properties": {
9147
+ "resource_type": {
9148
+ "type": "string"
9149
+ },
9150
+ "resource_id": {
9151
+ "type": "string"
9152
+ },
9153
+ "reason": {
9154
+ "type": "string"
9155
+ }
9156
+ }
9157
+ },
8315
9158
  "fhir_provider_FhirProviderCreateRequest": {
8316
9159
  "type": "object",
8317
9160
  "required": [