phenoml 17.2.0 → 17.3.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 (41) hide show
  1. package/dist/cjs/BaseClient.js +2 -2
  2. package/dist/cjs/api/resources/fhir2Omop/client/Client.d.ts +15 -21
  3. package/dist/cjs/api/resources/fhir2Omop/client/Client.js +17 -21
  4. package/dist/cjs/api/resources/fhir2Omop/errors/ServiceUnavailableError.d.ts +5 -0
  5. package/dist/cjs/api/resources/fhir2Omop/errors/ServiceUnavailableError.js +54 -0
  6. package/dist/cjs/api/resources/fhir2Omop/errors/index.d.ts +1 -0
  7. package/dist/cjs/api/resources/fhir2Omop/errors/index.js +1 -0
  8. package/dist/cjs/api/resources/fhir2Omop/types/CreateOmopResponse.d.ts +10 -10
  9. package/dist/cjs/api/resources/fhir2Omop/types/MappingEntry.d.ts +37 -0
  10. package/dist/cjs/api/resources/fhir2Omop/types/Summary.d.ts +15 -0
  11. package/dist/cjs/api/resources/fhir2Omop/types/index.d.ts +2 -2
  12. package/dist/cjs/api/resources/fhir2Omop/types/index.js +2 -2
  13. package/dist/cjs/core/fetcher/signals.js +9 -1
  14. package/dist/cjs/version.d.ts +1 -1
  15. package/dist/cjs/version.js +1 -1
  16. package/dist/esm/BaseClient.mjs +2 -2
  17. package/dist/esm/api/resources/fhir2Omop/client/Client.d.mts +15 -21
  18. package/dist/esm/api/resources/fhir2Omop/client/Client.mjs +17 -21
  19. package/dist/esm/api/resources/fhir2Omop/errors/ServiceUnavailableError.d.mts +5 -0
  20. package/dist/esm/api/resources/fhir2Omop/errors/ServiceUnavailableError.mjs +17 -0
  21. package/dist/esm/api/resources/fhir2Omop/errors/index.d.mts +1 -0
  22. package/dist/esm/api/resources/fhir2Omop/errors/index.mjs +1 -0
  23. package/dist/esm/api/resources/fhir2Omop/types/CreateOmopResponse.d.mts +10 -10
  24. package/dist/esm/api/resources/fhir2Omop/types/MappingEntry.d.mts +37 -0
  25. package/dist/esm/api/resources/fhir2Omop/types/Summary.d.mts +15 -0
  26. package/dist/esm/api/resources/fhir2Omop/types/index.d.mts +2 -2
  27. package/dist/esm/api/resources/fhir2Omop/types/index.mjs +2 -2
  28. package/dist/esm/core/fetcher/signals.mjs +9 -1
  29. package/dist/esm/version.d.mts +1 -1
  30. package/dist/esm/version.mjs +1 -1
  31. package/openapi/openapi.json +57 -187
  32. package/package.json +1 -1
  33. package/reference.md +15 -22
  34. package/dist/cjs/api/resources/fhir2Omop/types/MappingReportEntry.d.ts +0 -32
  35. package/dist/cjs/api/resources/fhir2Omop/types/ScanSummary.d.ts +0 -41
  36. package/dist/esm/api/resources/fhir2Omop/types/MappingReportEntry.d.mts +0 -32
  37. package/dist/esm/api/resources/fhir2Omop/types/ScanSummary.d.mts +0 -41
  38. /package/dist/cjs/api/resources/fhir2Omop/types/{MappingReportEntry.js → MappingEntry.js} +0 -0
  39. /package/dist/cjs/api/resources/fhir2Omop/types/{ScanSummary.js → Summary.js} +0 -0
  40. /package/dist/esm/api/resources/fhir2Omop/types/{MappingReportEntry.mjs → MappingEntry.mjs} +0 -0
  41. /package/dist/esm/api/resources/fhir2Omop/types/{ScanSummary.mjs → Summary.mjs} +0 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The request's data-quality headline: how the coded concepts split across
3
+ * resolution outcomes, and the share that was not already in a target
4
+ * standard vocabulary.
5
+ */
6
+ export interface Summary {
7
+ /** Codings already a standard OMOP concept. */
8
+ codes_already_standard?: number | undefined;
9
+ /** Codings mapped or suggested to a standard concept (MAPPED or UNCHECKED). */
10
+ codes_normalized?: number | undefined;
11
+ /** Codings with no standard concept found. */
12
+ codes_unmapped?: number | undefined;
13
+ /** Share of coded concepts not already standard ((normalized + unmapped) / total). */
14
+ off_vocab_rate?: number | undefined;
15
+ }
@@ -2,11 +2,11 @@ export * from "./ConditionOccurrenceRow.mjs";
2
2
  export * from "./CreateOmopResponse.mjs";
3
3
  export * from "./DroppedResource.mjs";
4
4
  export * from "./DrugExposureRow.mjs";
5
- export * from "./MappingReportEntry.mjs";
5
+ export * from "./MappingEntry.mjs";
6
6
  export * from "./MeasurementRow.mjs";
7
7
  export * from "./ObservationRow.mjs";
8
8
  export * from "./OmopTables.mjs";
9
9
  export * from "./PersonRow.mjs";
10
10
  export * from "./ProcedureOccurrenceRow.mjs";
11
- export * from "./ScanSummary.mjs";
11
+ export * from "./Summary.mjs";
12
12
  export * from "./VisitOccurrenceRow.mjs";
@@ -2,11 +2,11 @@ export * from "./ConditionOccurrenceRow.mjs";
2
2
  export * from "./CreateOmopResponse.mjs";
3
3
  export * from "./DroppedResource.mjs";
4
4
  export * from "./DrugExposureRow.mjs";
5
- export * from "./MappingReportEntry.mjs";
5
+ export * from "./MappingEntry.mjs";
6
6
  export * from "./MeasurementRow.mjs";
7
7
  export * from "./ObservationRow.mjs";
8
8
  export * from "./OmopTables.mjs";
9
9
  export * from "./PersonRow.mjs";
10
10
  export * from "./ProcedureOccurrenceRow.mjs";
11
- export * from "./ScanSummary.mjs";
11
+ export * from "./Summary.mjs";
12
12
  export * from "./VisitOccurrenceRow.mjs";
@@ -10,11 +10,19 @@ export function anySignal(...args) {
10
10
  for (const signal of signals) {
11
11
  if (signal.aborted) {
12
12
  controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason);
13
- break;
13
+ return controller.signal;
14
14
  }
15
15
  signal.addEventListener("abort", () => controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason), {
16
16
  signal: controller.signal,
17
17
  });
18
+ // Re-check after adding listener: the signal may have aborted
19
+ // between the initial `signal.aborted` check and the `addEventListener`
20
+ // call above. If it did, the abort event was already dispatched and
21
+ // the listener will never fire — we must manually abort.
22
+ if (signal.aborted) {
23
+ controller.abort(signal === null || signal === void 0 ? void 0 : signal.reason);
24
+ return controller.signal;
25
+ }
18
26
  }
19
27
  return controller.signal;
20
28
  }
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "17.2.0";
1
+ export declare const SDK_VERSION = "17.3.0";
@@ -1 +1 @@
1
- export const SDK_VERSION = "17.2.0";
1
+ export const SDK_VERSION = "17.3.0";
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "Phenoml API",
5
- "version": "f96459701356d9f1fe1acbeab0f6f2eccc498046"
5
+ "version": "5084e3096e5bd89bf2e86ea44d96e3407f6f5c6b"
6
6
  },
7
7
  "x-services": [
8
8
  {
@@ -3021,7 +3021,7 @@
3021
3021
  "post": {
3022
3022
  "operationId": "fhir2omop_create",
3023
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",
3024
+ "description": "Maps 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\nEach resource's primary clinical coding is resolved to a standard OMOP\n`concept_id`. Alongside the OMOP rows grouped by table (`tables`), the\nresponse carries `mappings` (how each source coding resolved, linked back\nto the row it produced), `dropped` (resources that could not be shaped\ninto a row), `vocab_version` (the OMOP vocabulary release codes were\nresolved against), and a small `summary` of the resolution outcomes.\n\nA `concept_id` of `0` means \"no matching standard concept\" (OMOP\nsemantics) and is reported, not omitted \u2014 a coding with no match is\n`UNMAPPED`. Only the primary clinical coding is resolved;\n`gender`/`race`/`ethnicity`/`visit`/`value`/`unit` `concept_id`s are\nalways `0`. Each `*_source_value` carries the verbatim FHIR coding\n(`system#code`), and `*_type_concept_id` is set to `32817` (EHR).\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`dropped` rather than emitted as blank rows. The\nbundle must contain at least one Patient resource.\n",
3025
3025
  "requestBody": {
3026
3026
  "required": true,
3027
3027
  "content": {
@@ -3111,13 +3111,12 @@
3111
3111
  "$ref": "#/components/schemas/fhir2omop_CreateOmopResponse"
3112
3112
  },
3113
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",
3114
+ "mapping_result": {
3115
+ "summary": "Mapping result",
3116
+ "description": "The example bundle mapped to OMOP. Both source codes are already\nstandard, so each clinical row carries its own OMOP `concept_id`\nwith `ALREADY_STANDARD` status. `target_code` is omitted for a\nresolved concept \u2014 it is identified by `target_vocabulary` and\n`target_name` (and the row's `*_concept_id`). Illustrative\n`concept_id` values.\n",
3117
3117
  "value": {
3118
3118
  "success": true,
3119
- "message": "FHIR resources mapped to OMOP CDM v5.4 with vocabulary concept resolution",
3120
- "mode": "resolved",
3119
+ "message": "FHIR resources mapped to OMOP CDM v5.4",
3121
3120
  "tables": {
3122
3121
  "person": [
3123
3122
  {
@@ -3158,11 +3157,12 @@
3158
3157
  }
3159
3158
  ]
3160
3159
  },
3161
- "report": [
3160
+ "mappings": [
3162
3161
  {
3163
3162
  "resource_type": "Condition",
3164
3163
  "resource_id": "condition-1",
3165
3164
  "omop_table": "condition_occurrence",
3165
+ "omop_id": 1,
3166
3166
  "source_system": "http://snomed.info/sct",
3167
3167
  "source_code": "44054006",
3168
3168
  "source_name": "Type 2 diabetes mellitus",
@@ -3174,6 +3174,7 @@
3174
3174
  "resource_type": "MedicationRequest",
3175
3175
  "resource_id": "medreq-1",
3176
3176
  "omop_table": "drug_exposure",
3177
+ "omop_id": 1,
3177
3178
  "source_system": "http://www.nlm.nih.gov/research/umls/rxnorm",
3178
3179
  "source_code": "860975",
3179
3180
  "source_name": "metformin hydrochloride 500 MG",
@@ -3182,118 +3183,8 @@
3182
3183
  "mapping_status": "ALREADY_STANDARD"
3183
3184
  }
3184
3185
  ],
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
- },
3186
+ "vocab_version": "v20240229",
3187
+ "summary": {
3297
3188
  "codes_already_standard": 2,
3298
3189
  "codes_normalized": 0,
3299
3190
  "codes_unmapped": 0,
@@ -3306,7 +3197,7 @@
3306
3197
  }
3307
3198
  },
3308
3199
  "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",
3200
+ "description": "Bad request - invalid input. Possible reasons:\n- Missing or malformed request body (no `fhir_resources`)\n- Invalid FHIR input (non-Bundle/non-resource payload)\n- No Patient resource found (OMOP requires at least one person)\n",
3310
3201
  "content": {
3311
3202
  "application/json": {
3312
3203
  "schema": {
@@ -3320,6 +3211,16 @@
3320
3211
  },
3321
3212
  "500": {
3322
3213
  "description": "Internal server error"
3214
+ },
3215
+ "503": {
3216
+ "description": "Service unavailable due to a server configuration error. No rows are\nreturned.\n",
3217
+ "content": {
3218
+ "application/json": {
3219
+ "schema": {
3220
+ "$ref": "#/components/schemas/fhir2omop_CreateOmopResponse"
3221
+ }
3222
+ }
3223
+ }
3323
3224
  }
3324
3225
  },
3325
3226
  "security": [
@@ -8654,22 +8555,29 @@
8654
8555
  "message": {
8655
8556
  "type": "string"
8656
8557
  },
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
8558
  "tables": {
8662
8559
  "$ref": "#/components/schemas/fhir2omop_OmopTables"
8663
8560
  },
8664
- "report": {
8561
+ "mappings": {
8562
+ "type": "array",
8563
+ "description": "One entry per source coding (or one entry for a text-only resource with no coding), describing how it resolved and linking back to the row it produced.",
8564
+ "items": {
8565
+ "$ref": "#/components/schemas/fhir2omop_MappingEntry"
8566
+ }
8567
+ },
8568
+ "dropped": {
8665
8569
  "type": "array",
8666
- "description": "One Usagi-shaped entry per source coding routed through concept resolution.",
8570
+ "description": "Resources that could not be shaped into an OMOP row (rather than emitted as blank rows).",
8667
8571
  "items": {
8668
- "$ref": "#/components/schemas/fhir2omop_MappingReportEntry"
8572
+ "$ref": "#/components/schemas/fhir2omop_DroppedResource"
8669
8573
  }
8670
8574
  },
8671
- "scan_summary": {
8672
- "$ref": "#/components/schemas/fhir2omop_ScanSummary"
8575
+ "vocab_version": {
8576
+ "type": "string",
8577
+ "description": "The OMOP vocabulary release the clinical codes were resolved against\n(e.g. \"v20240229\"), for reproducibility. Present when at least one\ncoded concept was resolved.\n"
8578
+ },
8579
+ "summary": {
8580
+ "$ref": "#/components/schemas/fhir2omop_Summary"
8673
8581
  }
8674
8582
  }
8675
8583
  },
@@ -9034,9 +8942,9 @@
9034
8942
  }
9035
8943
  }
9036
8944
  },
9037
- "fhir2omop_MappingReportEntry": {
8945
+ "fhir2omop_MappingEntry": {
9038
8946
  "type": "object",
9039
- "description": "One source_to_concept_map-style mapping suggestion (Usagi-shaped).",
8947
+ "description": "How one source coding (or a text-only resource's free text) resolved to an OMOP standard concept.",
9040
8948
  "properties": {
9041
8949
  "resource_type": {
9042
8950
  "type": "string"
@@ -9047,6 +8955,11 @@
9047
8955
  "omop_table": {
9048
8956
  "type": "string"
9049
8957
  },
8958
+ "omop_id": {
8959
+ "type": "integer",
8960
+ "format": "int64",
8961
+ "description": "The id of the OMOP row this coding produced (e.g. `condition_occurrence_id`),\nwithin `omop_table`. A resource with multiple codings yields one entry\nper coding, all sharing this id.\n"
8962
+ },
9050
8963
  "source_system": {
9051
8964
  "type": "string"
9052
8965
  },
@@ -9061,83 +8974,40 @@
9061
8974
  },
9062
8975
  "target_code": {
9063
8976
  "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"
8977
+ "description": "The standard concept's code, when present. Populated only for an\n`UNCHECKED` suggestion (where the API normalized a text-only resource\nto a suggested code); omitted for codings resolved through concept\nresolution (`ALREADY_STANDARD` / `MAPPED` / `UNMAPPED`), which are\nidentified by `target_vocabulary`, `target_name`, and the row's\n`*_concept_id` rather than by code.\n"
9065
8978
  },
9066
8979
  "target_name": {
9067
8980
  "type": "string"
9068
8981
  },
9069
8982
  "mapping_status": {
9070
8983
  "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"
8984
+ "description": "ALREADY_STANDARD (source coding is already a standard OMOP concept),\nMAPPED (source coding was mapped to a standard concept), UNCHECKED (a\nstandard code was suggested \u2014 e.g. for a text-only resource \u2014 but not\nverified against the OMOP vocabulary, so `concept_id` stays `0`), or\nUNMAPPED (no standard concept found).\n"
9072
8985
  },
9073
8986
  "note": {
9074
8987
  "type": "string"
9075
8988
  }
9076
8989
  }
9077
8990
  },
9078
- "fhir2omop_ScanSummary": {
8991
+ "fhir2omop_Summary": {
9079
8992
  "type": "object",
9080
- "description": "White Rabbit-style aggregate profile of the mapping request.",
8993
+ "description": "The request's data-quality headline: how the coded concepts split across\nresolution outcomes, and the share that was not already in a target\nstandard vocabulary.\n",
9081
8994
  "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
8995
  "codes_already_standard": {
9104
- "type": "integer"
8996
+ "type": "integer",
8997
+ "description": "Codings already a standard OMOP concept."
9105
8998
  },
9106
8999
  "codes_normalized": {
9107
- "type": "integer"
9000
+ "type": "integer",
9001
+ "description": "Codings mapped or suggested to a standard concept (MAPPED or UNCHECKED)."
9108
9002
  },
9109
9003
  "codes_unmapped": {
9110
- "type": "integer"
9004
+ "type": "integer",
9005
+ "description": "Codings with no standard concept found."
9111
9006
  },
9112
9007
  "off_vocab_rate": {
9113
9008
  "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"
9009
+ "format": "double",
9010
+ "description": "Share of coded concepts not already standard ((normalized + unmapped) / total)."
9141
9011
  }
9142
9012
  }
9143
9013
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phenoml",
3
- "version": "17.2.0",
3
+ "version": "17.3.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
package/reference.md CHANGED
@@ -2673,30 +2673,23 @@ The ID of the FHIR provider to use. Can be either:
2673
2673
  <dl>
2674
2674
  <dd>
2675
2675
 
2676
- Shapes a FHIR R4 resource or Bundle into OMOP Common Data Model v5.4 rows
2676
+ Maps a FHIR R4 resource or Bundle into OMOP Common Data Model v5.4 rows
2677
2677
  (person, visit_occurrence, condition_occurrence, drug_exposure,
2678
2678
  procedure_occurrence, measurement, observation).
2679
2679
 
2680
- **Two resolution modes, reported in `mode`.** `mode` reflects which
2681
- resolver is wired, not the path an individual coding took. With a
2682
- concept-resolver configured (the default), `mode` is `"resolved"` and the
2683
- resource's primary clinical coding is resolved to a real OMOP `concept_id`;
2684
- with no resolver configured, `mode` is `"structural"` and every clinical
2685
- and source `concept_id` is `0`. In `"resolved"` mode individual codings can
2686
- still land at `concept_id` `0` without changing the mode: a coding the
2687
- service finds no match for is `UNMAPPED`, and a coding that fell back to the
2688
- structural tier (the resolver was briefly unavailable, or the resource was
2689
- text-only) is surfaced in `scan_summary` (`concept_resolver_note`,
2690
- `construe_resolutions`). A `concept_id` of `0` is "no matching concept" per
2691
- OMOP semantics, deliberately not omitted. Only the primary clinical coding
2692
- is resolved `gender`/`race`/`ethnicity`/`visit`/`value`/`unit`
2693
- `concept_id`s are always `0`.
2694
-
2695
- In every mode each `*_source_value` carries the verbatim FHIR coding
2696
- (`system#code`), `*_type_concept_id` is set to `32817` (EHR), and the
2697
- response `report` lists one Usagi-shaped entry per source coding describing
2698
- how it resolved (`ALREADY_STANDARD`, `MAPPED`, an `UNCHECKED` suggestion,
2699
- or `UNMAPPED`).
2680
+ Each resource's primary clinical coding is resolved to a standard OMOP
2681
+ `concept_id`. Alongside the OMOP rows grouped by table (`tables`), the
2682
+ response carries `mappings` (how each source coding resolved, linked back
2683
+ to the row it produced), `dropped` (resources that could not be shaped
2684
+ into a row), `vocab_version` (the OMOP vocabulary release codes were
2685
+ resolved against), and a small `summary` of the resolution outcomes.
2686
+
2687
+ A `concept_id` of `0` means "no matching standard concept" (OMOP
2688
+ semantics) and is reported, not omitted a coding with no match is
2689
+ `UNMAPPED`. Only the primary clinical coding is resolved;
2690
+ `gender`/`race`/`ethnicity`/`visit`/`value`/`unit` `concept_id`s are
2691
+ always `0`. Each `*_source_value` carries the verbatim FHIR coding
2692
+ (`system#code`), and `*_type_concept_id` is set to `32817` (EHR).
2700
2693
 
2701
2694
  Medication codes are resolved whether they appear inline
2702
2695
  (`medicationCodeableConcept`) or via a `medicationReference` to a contained,
@@ -2704,7 +2697,7 @@ relative (`Type/id`), or bundle-entry (`urn:uuid`) `Medication` resource.
2704
2697
  Resources that cannot be shaped into a row — a medication with no usable
2705
2698
  code, resolvable reference, or display, or any clinical resource whose
2706
2699
  subject/patient reference cannot be tied to a person — are reported under
2707
- `scan_summary.dropped_resources` rather than emitted as blank rows. The
2700
+ `dropped` rather than emitted as blank rows. The
2708
2701
  bundle must contain at least one Patient resource.
2709
2702
  </dd>
2710
2703
  </dl>
@@ -1,32 +0,0 @@
1
- /**
2
- * One source_to_concept_map-style mapping suggestion (Usagi-shaped).
3
- */
4
- export interface MappingReportEntry {
5
- resource_type?: string | undefined;
6
- resource_id?: string | undefined;
7
- omop_table?: string | undefined;
8
- source_system?: string | undefined;
9
- source_code?: string | undefined;
10
- source_name?: string | undefined;
11
- target_vocabulary?: string | undefined;
12
- /**
13
- * Standard concept code. Set when a coding is matched by the structural
14
- * (construe) tier — an already-standard code taken verbatim, or a
15
- * construe-suggested code — which is every match in structural mode and,
16
- * in resolved mode, codings for text-only resources or ones that fell back
17
- * when the resolver was unavailable. Omitted for codings resolved directly
18
- * by the concept-resolver service, which returns the standard concept's
19
- * id, name, and vocabulary but not its `concept_code`.
20
- */
21
- target_code?: string | undefined;
22
- target_name?: string | undefined;
23
- /**
24
- * ALREADY_STANDARD (source already in the target standard vocabulary),
25
- * MAPPED (resolved to a standard concept via the OMOP "Maps to" crosswalk
26
- * or UMLS-CUI bridge; resolved mode only), UNCHECKED (an unreviewed
27
- * construe suggestion; structural / fallback only), or UNMAPPED (no
28
- * candidate found).
29
- */
30
- mapping_status?: string | undefined;
31
- note?: string | undefined;
32
- }
@@ -1,41 +0,0 @@
1
- import type * as phenoml from "../../../index.js";
2
- /**
3
- * White Rabbit-style aggregate profile of the mapping request.
4
- */
5
- export interface ScanSummary {
6
- total_resources?: number | undefined;
7
- resource_counts?: Record<string, number> | undefined;
8
- tables_populated?: Record<string, number> | undefined;
9
- coding_systems?: Record<string, number> | undefined;
10
- codes_already_standard?: number | undefined;
11
- codes_normalized?: number | undefined;
12
- codes_unmapped?: number | undefined;
13
- off_vocab_rate?: number | undefined;
14
- dropped_resources?: phenoml.fhir2Omop.DroppedResource[] | undefined;
15
- /**
16
- * OMOP vocabulary release the resolver mapped against (e.g. "v20240229").
17
- * Resolved mode only; empty when no coded concept reached the service.
18
- */
19
- resolved_vocab_version?: string | undefined;
20
- /**
21
- * Set when concept resolution was degraded — the resolver was unavailable
22
- * for one or more codings, whose `concept_id`s fell back to the structural
23
- * (construe) tier. Empty when resolution was clean.
24
- */
25
- concept_resolver_note?: string | undefined;
26
- /**
27
- * Count of `concept_id`s chosen via the lower-confidence UMLS-CUI bridge
28
- * (no direct OMOP crosswalk existed). Resolved mode only.
29
- */
30
- concepts_bridged?: number | undefined;
31
- /**
32
- * Count of codings whose candidate list the resolver capped, so the best
33
- * concept may not have been among those returned.
34
- */
35
- concept_candidates_truncated?: number | undefined;
36
- /**
37
- * Count of codings resolved via the construe ML extractor — the text-only
38
- * or availability fallback path. A non-zero value bills the construe tier.
39
- */
40
- construe_resolutions?: number | undefined;
41
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * One source_to_concept_map-style mapping suggestion (Usagi-shaped).
3
- */
4
- export interface MappingReportEntry {
5
- resource_type?: string | undefined;
6
- resource_id?: string | undefined;
7
- omop_table?: string | undefined;
8
- source_system?: string | undefined;
9
- source_code?: string | undefined;
10
- source_name?: string | undefined;
11
- target_vocabulary?: string | undefined;
12
- /**
13
- * Standard concept code. Set when a coding is matched by the structural
14
- * (construe) tier — an already-standard code taken verbatim, or a
15
- * construe-suggested code — which is every match in structural mode and,
16
- * in resolved mode, codings for text-only resources or ones that fell back
17
- * when the resolver was unavailable. Omitted for codings resolved directly
18
- * by the concept-resolver service, which returns the standard concept's
19
- * id, name, and vocabulary but not its `concept_code`.
20
- */
21
- target_code?: string | undefined;
22
- target_name?: string | undefined;
23
- /**
24
- * ALREADY_STANDARD (source already in the target standard vocabulary),
25
- * MAPPED (resolved to a standard concept via the OMOP "Maps to" crosswalk
26
- * or UMLS-CUI bridge; resolved mode only), UNCHECKED (an unreviewed
27
- * construe suggestion; structural / fallback only), or UNMAPPED (no
28
- * candidate found).
29
- */
30
- mapping_status?: string | undefined;
31
- note?: string | undefined;
32
- }