@openhi/constructs 0.0.141 → 0.0.143

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.
@@ -9399,206 +9399,6 @@ async function listAllergyIntolerancesOperation(params) {
9399
9399
  );
9400
9400
  }
9401
9401
 
9402
- // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-list-route.ts
9403
- async function listAllergyIntolerancesRoute(req, res) {
9404
- return handleListRoute({
9405
- req,
9406
- res,
9407
- basePath: BASE_PATH.ALLERGYINTOLERANCE,
9408
- listOperation: listAllergyIntolerancesOperation,
9409
- errorLogContext: "GET /AllergyIntolerance list error:"
9410
- });
9411
- }
9412
-
9413
- // src/data/operations/data/allergyintolerance/allergyintolerance-update-operation.ts
9414
- async function updateAllergyIntoleranceOperation(params) {
9415
- const { context, id, body, tableName } = params;
9416
- const { tenantId, workspaceId, date, actorId, actorName } = context;
9417
- const service = getDynamoDataService(tableName);
9418
- return updateDataEntityById(
9419
- service.entities.allergyintolerance,
9420
- tenantId,
9421
- workspaceId,
9422
- id,
9423
- "AllergyIntolerance",
9424
- context,
9425
- (existingResourceStr) => buildUpdatedResourceWithAudit(
9426
- body,
9427
- id,
9428
- date,
9429
- actorId,
9430
- actorName,
9431
- existingResourceStr,
9432
- "AllergyIntolerance"
9433
- )
9434
- );
9435
- }
9436
-
9437
- // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-update-route.ts
9438
- async function updateAllergyIntoleranceRoute(req, res) {
9439
- const bodyResult = requireJsonBodyAs(req, res);
9440
- if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
9441
- const id = String(req.params.id);
9442
- const ctx = req.openhiContext;
9443
- const body = bodyResult.body;
9444
- const resource = {
9445
- ...body,
9446
- resourceType: "AllergyIntolerance",
9447
- id
9448
- };
9449
- try {
9450
- const result = await updateAllergyIntoleranceOperation({
9451
- context: ctx,
9452
- id,
9453
- body: resource
9454
- });
9455
- return res.json(result.resource);
9456
- } catch (err) {
9457
- const status = domainErrorToHttpStatus(err);
9458
- if (status === 404) {
9459
- const diagnostics = err instanceof NotFoundError ? err.message : `AllergyIntolerance ${id} not found`;
9460
- return sendOperationOutcome404(res, diagnostics);
9461
- }
9462
- return sendOperationOutcome500(res, err, "PUT AllergyIntolerance error:");
9463
- }
9464
- }
9465
-
9466
- // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance.ts
9467
- var router13 = import_express13.default.Router();
9468
- router13.get("/", listAllergyIntolerancesRoute);
9469
- router13.get("/:id", getAllergyIntoleranceByIdRoute);
9470
- router13.post("/", createAllergyIntoleranceRoute);
9471
- router13.put("/:id", updateAllergyIntoleranceRoute);
9472
- router13.delete("/:id", deleteAllergyIntoleranceRoute);
9473
-
9474
- // src/data/rest-api/routes/data/appointment/appointment.ts
9475
- var import_express14 = __toESM(require("express"));
9476
-
9477
- // src/data/operations/data/appointment/appointment-create-operation.ts
9478
- var import_ulid6 = require("ulid");
9479
- async function createAppointmentOperation(params) {
9480
- const { context, body, tableName } = params;
9481
- const { tenantId, workspaceId, date, actorId, actorName } = context;
9482
- const id = body.id ?? (0, import_ulid6.ulid)();
9483
- const meta = {
9484
- ...body.meta ?? {},
9485
- lastUpdated: date,
9486
- versionId: "1"
9487
- };
9488
- const resourceWithAudit = {
9489
- ...body,
9490
- resourceType: "Appointment",
9491
- id,
9492
- meta: mergeAuditIntoMeta(meta, {
9493
- createdDate: date,
9494
- createdById: actorId,
9495
- createdByName: actorName,
9496
- modifiedDate: date,
9497
- modifiedById: actorId,
9498
- modifiedByName: actorName
9499
- })
9500
- };
9501
- const service = getDynamoDataService(tableName);
9502
- return createDataEntityRecord(
9503
- service.entities.appointment,
9504
- tenantId,
9505
- workspaceId,
9506
- id,
9507
- resourceWithAudit,
9508
- date
9509
- );
9510
- }
9511
-
9512
- // src/data/rest-api/routes/data/appointment/appointment-create-route.ts
9513
- async function createAppointmentRoute(req, res) {
9514
- const bodyResult = requireJsonBodyAs(req, res);
9515
- if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
9516
- const ctx = req.openhiContext;
9517
- const body = bodyResult.body;
9518
- const resource = {
9519
- ...body,
9520
- resourceType: "Appointment"
9521
- };
9522
- try {
9523
- const result = await createAppointmentOperation({
9524
- context: ctx,
9525
- body: resource
9526
- });
9527
- return res.status(201).location(`${BASE_PATH.APPOINTMENT}/${result.id}`).json(result.resource);
9528
- } catch (err) {
9529
- return sendOperationOutcome500(res, err, "POST Appointment error:");
9530
- }
9531
- }
9532
-
9533
- // src/data/operations/data/appointment/appointment-delete-operation.ts
9534
- async function deleteAppointmentOperation(params) {
9535
- const { context, id, tableName } = params;
9536
- const { tenantId, workspaceId } = context;
9537
- const service = getDynamoDataService(tableName);
9538
- await deleteDataEntityById(
9539
- service.entities.appointment,
9540
- tenantId,
9541
- workspaceId,
9542
- id
9543
- );
9544
- }
9545
-
9546
- // src/data/rest-api/routes/data/appointment/appointment-delete-route.ts
9547
- async function deleteAppointmentRoute(req, res) {
9548
- const id = String(req.params.id);
9549
- const ctx = req.openhiContext;
9550
- try {
9551
- await deleteAppointmentOperation({ context: ctx, id });
9552
- return res.status(204).send();
9553
- } catch (err) {
9554
- return sendOperationOutcome500(res, err, "DELETE Appointment error:");
9555
- }
9556
- }
9557
-
9558
- // src/data/operations/data/appointment/appointment-get-by-id-operation.ts
9559
- async function getAppointmentByIdOperation(params) {
9560
- const { context, id, tableName } = params;
9561
- const { tenantId, workspaceId } = context;
9562
- const service = getDynamoDataService(tableName);
9563
- return getDataEntityById(
9564
- service.entities.appointment,
9565
- tenantId,
9566
- workspaceId,
9567
- id,
9568
- "Appointment"
9569
- );
9570
- }
9571
-
9572
- // src/data/rest-api/routes/data/appointment/appointment-get-by-id-route.ts
9573
- async function getAppointmentByIdRoute(req, res) {
9574
- const id = String(req.params.id);
9575
- const ctx = req.openhiContext;
9576
- try {
9577
- const result = await getAppointmentByIdOperation({ context: ctx, id });
9578
- return res.json(result.resource);
9579
- } catch (err) {
9580
- const status = domainErrorToHttpStatus(err);
9581
- if (status === 404) {
9582
- const diagnostics = err instanceof NotFoundError ? err.message : `Appointment ${id} not found`;
9583
- return sendOperationOutcome404(res, diagnostics);
9584
- }
9585
- return sendOperationOutcome500(res, err, "GET Appointment error:");
9586
- }
9587
- }
9588
-
9589
- // src/data/operations/data/appointment/appointment-list-operation.ts
9590
- async function listAppointmentsOperation(params) {
9591
- const { context, tableName, mode } = params;
9592
- const { tenantId, workspaceId } = context;
9593
- const service = getDynamoDataService(tableName);
9594
- return listDataEntitiesByWorkspace(
9595
- service.entities.appointment,
9596
- tenantId,
9597
- workspaceId,
9598
- mode
9599
- );
9600
- }
9601
-
9602
9402
  // src/data/search/engine/reference-predicate.ts
9603
9403
  function buildOpenHiResourceUrn(opts) {
9604
9404
  return `urn:ohi:${opts.tenantId}:${opts.workspaceId}:${opts.resourceType}:${opts.resourceId}`;
@@ -10252,6 +10052,30 @@ async function genericSearchOperation(params) {
10252
10052
  return { entries, total: entries.length };
10253
10053
  }
10254
10054
 
10055
+ // src/data/search/registry/allergyintolerance-search-parameters.ts
10056
+ var ALLERGYINTOLERANCE_SEARCH_PARAMETERS = [
10057
+ {
10058
+ code: "clinical-status",
10059
+ type: "token",
10060
+ jsonbPath: "$.clinicalStatus"
10061
+ },
10062
+ {
10063
+ code: "verification-status",
10064
+ type: "token",
10065
+ jsonbPath: "$.verificationStatus"
10066
+ },
10067
+ { code: "type", type: "token", jsonbPath: "$.type" },
10068
+ { code: "category", type: "token", jsonbPath: "$.category[*]" },
10069
+ { code: "criticality", type: "token", jsonbPath: "$.criticality" },
10070
+ { code: "code", type: "token", jsonbPath: "$.code" },
10071
+ { code: "patient", type: "reference", jsonbPath: "$.patient" },
10072
+ { code: "recorder", type: "reference", jsonbPath: "$.recorder" },
10073
+ { code: "asserter", type: "reference", jsonbPath: "$.asserter" },
10074
+ { code: "date", type: "date", jsonbPath: "$.recordedDate" },
10075
+ { code: "last-date", type: "date", jsonbPath: "$.lastOccurrence" },
10076
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
10077
+ ];
10078
+
10255
10079
  // src/data/search/registry/appointment-search-parameters.ts
10256
10080
  var APPOINTMENT_SEARCH_PARAMETERS = [
10257
10081
  { code: "status", type: "token", jsonbPath: "$.status" },
@@ -10286,6 +10110,32 @@ var APPOINTMENT_SEARCH_PARAMETERS = [
10286
10110
  { code: "slot", type: "reference", jsonbPath: "$.slot[*]" }
10287
10111
  ];
10288
10112
 
10113
+ // src/data/search/registry/condition-search-parameters.ts
10114
+ var CONDITION_SEARCH_PARAMETERS = [
10115
+ {
10116
+ code: "clinical-status",
10117
+ type: "token",
10118
+ jsonbPath: "$.clinicalStatus"
10119
+ },
10120
+ {
10121
+ code: "verification-status",
10122
+ type: "token",
10123
+ jsonbPath: "$.verificationStatus"
10124
+ },
10125
+ { code: "category", type: "token", jsonbPath: "$.category[*]" },
10126
+ { code: "severity", type: "token", jsonbPath: "$.severity" },
10127
+ { code: "code", type: "token", jsonbPath: "$.code" },
10128
+ { code: "subject", type: "reference", jsonbPath: "$.subject" },
10129
+ { code: "patient", type: "reference", jsonbPath: "$.subject" },
10130
+ { code: "encounter", type: "reference", jsonbPath: "$.encounter" },
10131
+ { code: "asserter", type: "reference", jsonbPath: "$.asserter" },
10132
+ { code: "recorder", type: "reference", jsonbPath: "$.recorder" },
10133
+ { code: "onset-date", type: "date", jsonbPath: "$.onsetDateTime" },
10134
+ { code: "recorded-date", type: "date", jsonbPath: "$.recordedDate" },
10135
+ { code: "body-site", type: "token", jsonbPath: "$.bodySite[*]" },
10136
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
10137
+ ];
10138
+
10289
10139
  // src/data/search/registry/encounter-search-parameters.ts
10290
10140
  var ENCOUNTER_SEARCH_PARAMETERS = [
10291
10141
  { code: "status", type: "token", jsonbPath: "$.status" },
@@ -10312,6 +10162,17 @@ var ENCOUNTER_SEARCH_PARAMETERS = [
10312
10162
  }
10313
10163
  ];
10314
10164
 
10165
+ // src/data/search/registry/familymemberhistory-search-parameters.ts
10166
+ var FAMILYMEMBERHISTORY_SEARCH_PARAMETERS = [
10167
+ { code: "status", type: "token", jsonbPath: "$.status" },
10168
+ { code: "relationship", type: "token", jsonbPath: "$.relationship" },
10169
+ { code: "sex", type: "token", jsonbPath: "$.sex" },
10170
+ { code: "patient", type: "reference", jsonbPath: "$.patient" },
10171
+ { code: "date", type: "date", jsonbPath: "$.date" },
10172
+ { code: "code", type: "token", jsonbPath: "$.condition[*]" },
10173
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
10174
+ ];
10175
+
10315
10176
  // src/data/search/registry/observation-search-parameters.ts
10316
10177
  var OBSERVATION_SEARCH_PARAMETERS = [
10317
10178
  { code: "status", type: "token", jsonbPath: "$.status" },
@@ -10333,108 +10194,415 @@ var OBSERVATION_SEARCH_PARAMETERS = [
10333
10194
  { code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" }
10334
10195
  ];
10335
10196
 
10336
- // src/data/search/registry/patient-search-parameters.ts
10337
- var PATIENT_SEARCH_PARAMETERS = [
10338
- { code: "gender", type: "token", jsonbPath: "$.gender" },
10339
- { code: "identifier", type: "token", jsonbPath: "$.identifier[*].value" },
10340
- { code: "birthdate", type: "date", jsonbPath: "$.birthDate" },
10341
- {
10342
- code: "name",
10343
- type: "string",
10344
- jsonbPath: "$.name[*].text",
10345
- modifiers: ["exact", "contains", "missing", "not"]
10346
- },
10347
- {
10348
- code: "family",
10349
- type: "string",
10350
- jsonbPath: "$.name[*].family",
10351
- modifiers: ["exact", "contains", "missing", "not"]
10352
- },
10353
- {
10354
- code: "given",
10355
- type: "string",
10356
- jsonbPath: "$.name[*].given",
10357
- modifiers: ["exact", "contains", "missing", "not"]
10358
- },
10359
- { code: "active", type: "token", jsonbPath: "$.active" },
10360
- { code: "deceased", type: "token", jsonbPath: "$.deceasedBoolean" },
10361
- {
10362
- code: "general-practitioner",
10363
- type: "reference",
10364
- jsonbPath: "$.generalPractitioner[*]"
10365
- },
10366
- {
10367
- code: "organization",
10368
- type: "reference",
10369
- jsonbPath: "$.managingOrganization"
10197
+ // src/data/search/registry/patient-search-parameters.ts
10198
+ var PATIENT_SEARCH_PARAMETERS = [
10199
+ { code: "gender", type: "token", jsonbPath: "$.gender" },
10200
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*].value" },
10201
+ { code: "birthdate", type: "date", jsonbPath: "$.birthDate" },
10202
+ {
10203
+ code: "name",
10204
+ type: "string",
10205
+ jsonbPath: "$.name[*].text",
10206
+ modifiers: ["exact", "contains", "missing", "not"]
10207
+ },
10208
+ {
10209
+ code: "family",
10210
+ type: "string",
10211
+ jsonbPath: "$.name[*].family",
10212
+ modifiers: ["exact", "contains", "missing", "not"]
10213
+ },
10214
+ {
10215
+ code: "given",
10216
+ type: "string",
10217
+ jsonbPath: "$.name[*].given",
10218
+ modifiers: ["exact", "contains", "missing", "not"]
10219
+ },
10220
+ { code: "active", type: "token", jsonbPath: "$.active" },
10221
+ { code: "deceased", type: "token", jsonbPath: "$.deceasedBoolean" },
10222
+ {
10223
+ code: "general-practitioner",
10224
+ type: "reference",
10225
+ jsonbPath: "$.generalPractitioner[*]"
10226
+ },
10227
+ {
10228
+ code: "organization",
10229
+ type: "reference",
10230
+ jsonbPath: "$.managingOrganization"
10231
+ }
10232
+ ];
10233
+
10234
+ // src/data/search/registry/procedure-search-parameters.ts
10235
+ var PROCEDURE_SEARCH_PARAMETERS = [
10236
+ { code: "status", type: "token", jsonbPath: "$.status" },
10237
+ { code: "category", type: "token", jsonbPath: "$.category" },
10238
+ { code: "code", type: "token", jsonbPath: "$.code" },
10239
+ { code: "subject", type: "reference", jsonbPath: "$.subject" },
10240
+ { code: "patient", type: "reference", jsonbPath: "$.subject" },
10241
+ { code: "encounter", type: "reference", jsonbPath: "$.encounter" },
10242
+ {
10243
+ code: "performer",
10244
+ type: "reference",
10245
+ jsonbPath: "$.performer[*].actor"
10246
+ },
10247
+ { code: "date", type: "date", jsonbPath: "$.performedDateTime" },
10248
+ { code: "location", type: "reference", jsonbPath: "$.location" },
10249
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
10250
+ { code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
10251
+ { code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" },
10252
+ { code: "reason-code", type: "token", jsonbPath: "$.reasonCode[*]" },
10253
+ {
10254
+ code: "reason-reference",
10255
+ type: "reference",
10256
+ jsonbPath: "$.reasonReference[*]"
10257
+ }
10258
+ ];
10259
+
10260
+ // src/data/search/registry/resolver.ts
10261
+ var STATIC_SEARCH_PARAMETER_MAP = {
10262
+ AllergyIntolerance: ALLERGYINTOLERANCE_SEARCH_PARAMETERS,
10263
+ Appointment: APPOINTMENT_SEARCH_PARAMETERS,
10264
+ Condition: CONDITION_SEARCH_PARAMETERS,
10265
+ Encounter: ENCOUNTER_SEARCH_PARAMETERS,
10266
+ FamilyMemberHistory: FAMILYMEMBERHISTORY_SEARCH_PARAMETERS,
10267
+ Observation: OBSERVATION_SEARCH_PARAMETERS,
10268
+ Patient: PATIENT_SEARCH_PARAMETERS,
10269
+ Procedure: PROCEDURE_SEARCH_PARAMETERS
10270
+ };
10271
+ var defaultSearchParameterResolver = (resourceType, _tenantId) => STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
10272
+ function getRegisteredSearchParameters(resourceType) {
10273
+ return STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
10274
+ }
10275
+
10276
+ // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-list-route.ts
10277
+ var ALLERGYINTOLERANCE_RESOURCE_TYPE = "AllergyIntolerance";
10278
+ function stripModifier(key) {
10279
+ const idx = key.indexOf(":");
10280
+ return idx === -1 ? key : key.slice(0, idx);
10281
+ }
10282
+ function isResultParameter(key) {
10283
+ return key.startsWith("_");
10284
+ }
10285
+ function sendInvalidSearch400(res, diagnostics) {
10286
+ return res.status(400).json({
10287
+ resourceType: "OperationOutcome",
10288
+ issue: [{ severity: "error", code: "invalid", diagnostics }]
10289
+ });
10290
+ }
10291
+ function extractSearchParamKeys(query) {
10292
+ const out = [];
10293
+ for (const rawKey of Object.keys(query)) {
10294
+ if (isResultParameter(rawKey)) {
10295
+ continue;
10296
+ }
10297
+ out.push({ rawKey, code: stripModifier(rawKey) });
10298
+ }
10299
+ return out;
10300
+ }
10301
+ function buildUnknownParamDiagnostics(unknownCodes) {
10302
+ const validCodes = getRegisteredSearchParameters(
10303
+ ALLERGYINTOLERANCE_RESOURCE_TYPE
10304
+ ).map((p) => p.code).sort().join(", ");
10305
+ const codes = unknownCodes.join(", ");
10306
+ const isPlural = unknownCodes.length !== 1;
10307
+ return [
10308
+ `Unknown search ${isPlural ? "parameters" : "parameter"} for AllergyIntolerance: ${codes}.`,
10309
+ `Valid codes: ${validCodes}.`
10310
+ ].join(" ");
10311
+ }
10312
+ function findMalformedReference(query, searchParamKeys) {
10313
+ const referenceCodes = new Set(
10314
+ getRegisteredSearchParameters(ALLERGYINTOLERANCE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
10315
+ );
10316
+ for (const { rawKey, code } of searchParamKeys) {
10317
+ if (!referenceCodes.has(code)) {
10318
+ continue;
10319
+ }
10320
+ const raw = query[rawKey];
10321
+ const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
10322
+ for (const v of values) {
10323
+ const trimmed = v.trim();
10324
+ if (trimmed.length === 0) {
10325
+ continue;
10326
+ }
10327
+ if (parseTypedReference(trimmed) === void 0) {
10328
+ return { rawKey, value: trimmed };
10329
+ }
10330
+ }
10331
+ }
10332
+ return void 0;
10333
+ }
10334
+ async function listAllergyIntolerancesRoute(req, res) {
10335
+ const searchParamKeys = extractSearchParamKeys(
10336
+ req.query
10337
+ );
10338
+ if (searchParamKeys.length === 0) {
10339
+ return handleListRoute({
10340
+ req,
10341
+ res,
10342
+ basePath: BASE_PATH.ALLERGYINTOLERANCE,
10343
+ listOperation: listAllergyIntolerancesOperation,
10344
+ errorLogContext: "GET /AllergyIntolerance list error:"
10345
+ });
10346
+ }
10347
+ const registered = getRegisteredSearchParameters(
10348
+ ALLERGYINTOLERANCE_RESOURCE_TYPE
10349
+ );
10350
+ const validCodes = new Set(registered.map((p) => p.code));
10351
+ const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
10352
+ if (unknownCodes.length > 0) {
10353
+ return sendInvalidSearch400(
10354
+ res,
10355
+ buildUnknownParamDiagnostics([...new Set(unknownCodes)])
10356
+ );
10357
+ }
10358
+ const malformedRef = findMalformedReference(
10359
+ req.query,
10360
+ searchParamKeys
10361
+ );
10362
+ if (malformedRef !== void 0) {
10363
+ return sendInvalidSearch400(
10364
+ res,
10365
+ `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
10366
+ );
10367
+ }
10368
+ const ctx = req.openhiContext;
10369
+ try {
10370
+ const result = await genericSearchOperation({
10371
+ resourceType: ALLERGYINTOLERANCE_RESOURCE_TYPE,
10372
+ tenantId: ctx.tenantId,
10373
+ workspaceId: ctx.workspaceId,
10374
+ query: req.query,
10375
+ resolver: defaultSearchParameterResolver
10376
+ });
10377
+ const bundle = buildSearchsetBundle(
10378
+ BASE_PATH.ALLERGYINTOLERANCE,
10379
+ result.entries
10380
+ );
10381
+ return res.json(bundle);
10382
+ } catch (err) {
10383
+ return sendOperationOutcome500(
10384
+ res,
10385
+ err,
10386
+ "GET /AllergyIntolerance search error:"
10387
+ );
10388
+ }
10389
+ }
10390
+
10391
+ // src/data/operations/data/allergyintolerance/allergyintolerance-update-operation.ts
10392
+ async function updateAllergyIntoleranceOperation(params) {
10393
+ const { context, id, body, tableName } = params;
10394
+ const { tenantId, workspaceId, date, actorId, actorName } = context;
10395
+ const service = getDynamoDataService(tableName);
10396
+ return updateDataEntityById(
10397
+ service.entities.allergyintolerance,
10398
+ tenantId,
10399
+ workspaceId,
10400
+ id,
10401
+ "AllergyIntolerance",
10402
+ context,
10403
+ (existingResourceStr) => buildUpdatedResourceWithAudit(
10404
+ body,
10405
+ id,
10406
+ date,
10407
+ actorId,
10408
+ actorName,
10409
+ existingResourceStr,
10410
+ "AllergyIntolerance"
10411
+ )
10412
+ );
10413
+ }
10414
+
10415
+ // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-update-route.ts
10416
+ async function updateAllergyIntoleranceRoute(req, res) {
10417
+ const bodyResult = requireJsonBodyAs(req, res);
10418
+ if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
10419
+ const id = String(req.params.id);
10420
+ const ctx = req.openhiContext;
10421
+ const body = bodyResult.body;
10422
+ const resource = {
10423
+ ...body,
10424
+ resourceType: "AllergyIntolerance",
10425
+ id
10426
+ };
10427
+ try {
10428
+ const result = await updateAllergyIntoleranceOperation({
10429
+ context: ctx,
10430
+ id,
10431
+ body: resource
10432
+ });
10433
+ return res.json(result.resource);
10434
+ } catch (err) {
10435
+ const status = domainErrorToHttpStatus(err);
10436
+ if (status === 404) {
10437
+ const diagnostics = err instanceof NotFoundError ? err.message : `AllergyIntolerance ${id} not found`;
10438
+ return sendOperationOutcome404(res, diagnostics);
10439
+ }
10440
+ return sendOperationOutcome500(res, err, "PUT AllergyIntolerance error:");
10441
+ }
10442
+ }
10443
+
10444
+ // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance.ts
10445
+ var router13 = import_express13.default.Router();
10446
+ router13.get("/", listAllergyIntolerancesRoute);
10447
+ router13.get("/:id", getAllergyIntoleranceByIdRoute);
10448
+ router13.post("/", createAllergyIntoleranceRoute);
10449
+ router13.put("/:id", updateAllergyIntoleranceRoute);
10450
+ router13.delete("/:id", deleteAllergyIntoleranceRoute);
10451
+
10452
+ // src/data/rest-api/routes/data/appointment/appointment.ts
10453
+ var import_express14 = __toESM(require("express"));
10454
+
10455
+ // src/data/operations/data/appointment/appointment-create-operation.ts
10456
+ var import_ulid6 = require("ulid");
10457
+ async function createAppointmentOperation(params) {
10458
+ const { context, body, tableName } = params;
10459
+ const { tenantId, workspaceId, date, actorId, actorName } = context;
10460
+ const id = body.id ?? (0, import_ulid6.ulid)();
10461
+ const meta = {
10462
+ ...body.meta ?? {},
10463
+ lastUpdated: date,
10464
+ versionId: "1"
10465
+ };
10466
+ const resourceWithAudit = {
10467
+ ...body,
10468
+ resourceType: "Appointment",
10469
+ id,
10470
+ meta: mergeAuditIntoMeta(meta, {
10471
+ createdDate: date,
10472
+ createdById: actorId,
10473
+ createdByName: actorName,
10474
+ modifiedDate: date,
10475
+ modifiedById: actorId,
10476
+ modifiedByName: actorName
10477
+ })
10478
+ };
10479
+ const service = getDynamoDataService(tableName);
10480
+ return createDataEntityRecord(
10481
+ service.entities.appointment,
10482
+ tenantId,
10483
+ workspaceId,
10484
+ id,
10485
+ resourceWithAudit,
10486
+ date
10487
+ );
10488
+ }
10489
+
10490
+ // src/data/rest-api/routes/data/appointment/appointment-create-route.ts
10491
+ async function createAppointmentRoute(req, res) {
10492
+ const bodyResult = requireJsonBodyAs(req, res);
10493
+ if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
10494
+ const ctx = req.openhiContext;
10495
+ const body = bodyResult.body;
10496
+ const resource = {
10497
+ ...body,
10498
+ resourceType: "Appointment"
10499
+ };
10500
+ try {
10501
+ const result = await createAppointmentOperation({
10502
+ context: ctx,
10503
+ body: resource
10504
+ });
10505
+ return res.status(201).location(`${BASE_PATH.APPOINTMENT}/${result.id}`).json(result.resource);
10506
+ } catch (err) {
10507
+ return sendOperationOutcome500(res, err, "POST Appointment error:");
10508
+ }
10509
+ }
10510
+
10511
+ // src/data/operations/data/appointment/appointment-delete-operation.ts
10512
+ async function deleteAppointmentOperation(params) {
10513
+ const { context, id, tableName } = params;
10514
+ const { tenantId, workspaceId } = context;
10515
+ const service = getDynamoDataService(tableName);
10516
+ await deleteDataEntityById(
10517
+ service.entities.appointment,
10518
+ tenantId,
10519
+ workspaceId,
10520
+ id
10521
+ );
10522
+ }
10523
+
10524
+ // src/data/rest-api/routes/data/appointment/appointment-delete-route.ts
10525
+ async function deleteAppointmentRoute(req, res) {
10526
+ const id = String(req.params.id);
10527
+ const ctx = req.openhiContext;
10528
+ try {
10529
+ await deleteAppointmentOperation({ context: ctx, id });
10530
+ return res.status(204).send();
10531
+ } catch (err) {
10532
+ return sendOperationOutcome500(res, err, "DELETE Appointment error:");
10370
10533
  }
10371
- ];
10534
+ }
10372
10535
 
10373
- // src/data/search/registry/procedure-search-parameters.ts
10374
- var PROCEDURE_SEARCH_PARAMETERS = [
10375
- { code: "status", type: "token", jsonbPath: "$.status" },
10376
- { code: "category", type: "token", jsonbPath: "$.category" },
10377
- { code: "code", type: "token", jsonbPath: "$.code" },
10378
- { code: "subject", type: "reference", jsonbPath: "$.subject" },
10379
- { code: "patient", type: "reference", jsonbPath: "$.subject" },
10380
- { code: "encounter", type: "reference", jsonbPath: "$.encounter" },
10381
- {
10382
- code: "performer",
10383
- type: "reference",
10384
- jsonbPath: "$.performer[*].actor"
10385
- },
10386
- { code: "date", type: "date", jsonbPath: "$.performedDateTime" },
10387
- { code: "location", type: "reference", jsonbPath: "$.location" },
10388
- { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
10389
- { code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
10390
- { code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" },
10391
- { code: "reason-code", type: "token", jsonbPath: "$.reasonCode[*]" },
10392
- {
10393
- code: "reason-reference",
10394
- type: "reference",
10395
- jsonbPath: "$.reasonReference[*]"
10536
+ // src/data/operations/data/appointment/appointment-get-by-id-operation.ts
10537
+ async function getAppointmentByIdOperation(params) {
10538
+ const { context, id, tableName } = params;
10539
+ const { tenantId, workspaceId } = context;
10540
+ const service = getDynamoDataService(tableName);
10541
+ return getDataEntityById(
10542
+ service.entities.appointment,
10543
+ tenantId,
10544
+ workspaceId,
10545
+ id,
10546
+ "Appointment"
10547
+ );
10548
+ }
10549
+
10550
+ // src/data/rest-api/routes/data/appointment/appointment-get-by-id-route.ts
10551
+ async function getAppointmentByIdRoute(req, res) {
10552
+ const id = String(req.params.id);
10553
+ const ctx = req.openhiContext;
10554
+ try {
10555
+ const result = await getAppointmentByIdOperation({ context: ctx, id });
10556
+ return res.json(result.resource);
10557
+ } catch (err) {
10558
+ const status = domainErrorToHttpStatus(err);
10559
+ if (status === 404) {
10560
+ const diagnostics = err instanceof NotFoundError ? err.message : `Appointment ${id} not found`;
10561
+ return sendOperationOutcome404(res, diagnostics);
10562
+ }
10563
+ return sendOperationOutcome500(res, err, "GET Appointment error:");
10396
10564
  }
10397
- ];
10565
+ }
10398
10566
 
10399
- // src/data/search/registry/resolver.ts
10400
- var STATIC_SEARCH_PARAMETER_MAP = {
10401
- Appointment: APPOINTMENT_SEARCH_PARAMETERS,
10402
- Encounter: ENCOUNTER_SEARCH_PARAMETERS,
10403
- Observation: OBSERVATION_SEARCH_PARAMETERS,
10404
- Patient: PATIENT_SEARCH_PARAMETERS,
10405
- Procedure: PROCEDURE_SEARCH_PARAMETERS
10406
- };
10407
- var defaultSearchParameterResolver = (resourceType, _tenantId) => STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
10408
- function getRegisteredSearchParameters(resourceType) {
10409
- return STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
10567
+ // src/data/operations/data/appointment/appointment-list-operation.ts
10568
+ async function listAppointmentsOperation(params) {
10569
+ const { context, tableName, mode } = params;
10570
+ const { tenantId, workspaceId } = context;
10571
+ const service = getDynamoDataService(tableName);
10572
+ return listDataEntitiesByWorkspace(
10573
+ service.entities.appointment,
10574
+ tenantId,
10575
+ workspaceId,
10576
+ mode
10577
+ );
10410
10578
  }
10411
10579
 
10412
10580
  // src/data/rest-api/routes/data/appointment/appointment-list-route.ts
10413
10581
  var APPOINTMENT_RESOURCE_TYPE = "Appointment";
10414
- function stripModifier(key) {
10582
+ function stripModifier2(key) {
10415
10583
  const idx = key.indexOf(":");
10416
10584
  return idx === -1 ? key : key.slice(0, idx);
10417
10585
  }
10418
- function isResultParameter(key) {
10586
+ function isResultParameter2(key) {
10419
10587
  return key.startsWith("_");
10420
10588
  }
10421
- function sendInvalidSearch400(res, diagnostics) {
10589
+ function sendInvalidSearch4002(res, diagnostics) {
10422
10590
  return res.status(400).json({
10423
10591
  resourceType: "OperationOutcome",
10424
10592
  issue: [{ severity: "error", code: "invalid", diagnostics }]
10425
10593
  });
10426
10594
  }
10427
- function extractSearchParamKeys(query) {
10595
+ function extractSearchParamKeys2(query) {
10428
10596
  const out = [];
10429
10597
  for (const rawKey of Object.keys(query)) {
10430
- if (isResultParameter(rawKey)) {
10598
+ if (isResultParameter2(rawKey)) {
10431
10599
  continue;
10432
10600
  }
10433
- out.push({ rawKey, code: stripModifier(rawKey) });
10601
+ out.push({ rawKey, code: stripModifier2(rawKey) });
10434
10602
  }
10435
10603
  return out;
10436
10604
  }
10437
- function buildUnknownParamDiagnostics(unknownCodes) {
10605
+ function buildUnknownParamDiagnostics2(unknownCodes) {
10438
10606
  const validCodes = getRegisteredSearchParameters(APPOINTMENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
10439
10607
  const codes = unknownCodes.join(", ");
10440
10608
  const isPlural = unknownCodes.length !== 1;
@@ -10443,7 +10611,7 @@ function buildUnknownParamDiagnostics(unknownCodes) {
10443
10611
  `Valid codes: ${validCodes}.`
10444
10612
  ].join(" ");
10445
10613
  }
10446
- function findMalformedReference(query, searchParamKeys) {
10614
+ function findMalformedReference2(query, searchParamKeys) {
10447
10615
  const referenceCodes = new Set(
10448
10616
  getRegisteredSearchParameters(APPOINTMENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
10449
10617
  );
@@ -10466,7 +10634,7 @@ function findMalformedReference(query, searchParamKeys) {
10466
10634
  return void 0;
10467
10635
  }
10468
10636
  async function listAppointmentsRoute(req, res) {
10469
- const searchParamKeys = extractSearchParamKeys(
10637
+ const searchParamKeys = extractSearchParamKeys2(
10470
10638
  req.query
10471
10639
  );
10472
10640
  if (searchParamKeys.length === 0) {
@@ -10482,17 +10650,17 @@ async function listAppointmentsRoute(req, res) {
10482
10650
  const validCodes = new Set(registered.map((p) => p.code));
10483
10651
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
10484
10652
  if (unknownCodes.length > 0) {
10485
- return sendInvalidSearch400(
10653
+ return sendInvalidSearch4002(
10486
10654
  res,
10487
- buildUnknownParamDiagnostics([...new Set(unknownCodes)])
10655
+ buildUnknownParamDiagnostics2([...new Set(unknownCodes)])
10488
10656
  );
10489
10657
  }
10490
- const malformedRef = findMalformedReference(
10658
+ const malformedRef = findMalformedReference2(
10491
10659
  req.query,
10492
10660
  searchParamKeys
10493
10661
  );
10494
10662
  if (malformedRef !== void 0) {
10495
- return sendInvalidSearch400(
10663
+ return sendInvalidSearch4002(
10496
10664
  res,
10497
10665
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
10498
10666
  );
@@ -14738,62 +14906,155 @@ async function deleteConditionRoute(req, res) {
14738
14906
  return sendOperationOutcome500(res, err, "DELETE Condition error:");
14739
14907
  }
14740
14908
  }
14741
-
14742
- // src/data/operations/data/condition/condition-get-by-id-operation.ts
14743
- async function getConditionByIdOperation(params) {
14744
- const { context, id, tableName } = params;
14745
- const { tenantId, workspaceId } = context;
14746
- const service = getDynamoDataService(tableName);
14747
- return getDataEntityById(
14748
- service.entities.condition,
14749
- tenantId,
14750
- workspaceId,
14751
- id,
14752
- "Condition"
14909
+
14910
+ // src/data/operations/data/condition/condition-get-by-id-operation.ts
14911
+ async function getConditionByIdOperation(params) {
14912
+ const { context, id, tableName } = params;
14913
+ const { tenantId, workspaceId } = context;
14914
+ const service = getDynamoDataService(tableName);
14915
+ return getDataEntityById(
14916
+ service.entities.condition,
14917
+ tenantId,
14918
+ workspaceId,
14919
+ id,
14920
+ "Condition"
14921
+ );
14922
+ }
14923
+
14924
+ // src/data/rest-api/routes/data/condition/condition-get-by-id-route.ts
14925
+ async function getConditionByIdRoute(req, res) {
14926
+ const id = String(req.params.id);
14927
+ const ctx = req.openhiContext;
14928
+ try {
14929
+ const result = await getConditionByIdOperation({ context: ctx, id });
14930
+ return res.json(result.resource);
14931
+ } catch (err) {
14932
+ const status = domainErrorToHttpStatus(err);
14933
+ if (status === 404) {
14934
+ const diagnostics = err instanceof NotFoundError ? err.message : `Condition ${id} not found`;
14935
+ return sendOperationOutcome404(res, diagnostics);
14936
+ }
14937
+ return sendOperationOutcome500(res, err, "GET Condition error:");
14938
+ }
14939
+ }
14940
+
14941
+ // src/data/operations/data/condition/condition-list-operation.ts
14942
+ async function listConditionsOperation(params) {
14943
+ const { context, tableName, mode } = params;
14944
+ const { tenantId, workspaceId } = context;
14945
+ const service = getDynamoDataService(tableName);
14946
+ return listDataEntitiesByWorkspace(
14947
+ service.entities.condition,
14948
+ tenantId,
14949
+ workspaceId,
14950
+ mode
14951
+ );
14952
+ }
14953
+
14954
+ // src/data/rest-api/routes/data/condition/condition-list-route.ts
14955
+ var CONDITION_RESOURCE_TYPE = "Condition";
14956
+ function stripModifier3(key) {
14957
+ const idx = key.indexOf(":");
14958
+ return idx === -1 ? key : key.slice(0, idx);
14959
+ }
14960
+ function isResultParameter3(key) {
14961
+ return key.startsWith("_");
14962
+ }
14963
+ function sendInvalidSearch4003(res, diagnostics) {
14964
+ return res.status(400).json({
14965
+ resourceType: "OperationOutcome",
14966
+ issue: [{ severity: "error", code: "invalid", diagnostics }]
14967
+ });
14968
+ }
14969
+ function extractSearchParamKeys3(query) {
14970
+ const out = [];
14971
+ for (const rawKey of Object.keys(query)) {
14972
+ if (isResultParameter3(rawKey)) {
14973
+ continue;
14974
+ }
14975
+ out.push({ rawKey, code: stripModifier3(rawKey) });
14976
+ }
14977
+ return out;
14978
+ }
14979
+ function buildUnknownParamDiagnostics3(unknownCodes) {
14980
+ const validCodes = getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
14981
+ const codes = unknownCodes.join(", ");
14982
+ const isPlural = unknownCodes.length !== 1;
14983
+ return [
14984
+ `Unknown search ${isPlural ? "parameters" : "parameter"} for Condition: ${codes}.`,
14985
+ `Valid codes: ${validCodes}.`
14986
+ ].join(" ");
14987
+ }
14988
+ function findMalformedReference3(query, searchParamKeys) {
14989
+ const referenceCodes = new Set(
14990
+ getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
14991
+ );
14992
+ for (const { rawKey, code } of searchParamKeys) {
14993
+ if (!referenceCodes.has(code)) {
14994
+ continue;
14995
+ }
14996
+ const raw = query[rawKey];
14997
+ const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
14998
+ for (const v of values) {
14999
+ const trimmed = v.trim();
15000
+ if (trimmed.length === 0) {
15001
+ continue;
15002
+ }
15003
+ if (parseTypedReference(trimmed) === void 0) {
15004
+ return { rawKey, value: trimmed };
15005
+ }
15006
+ }
15007
+ }
15008
+ return void 0;
15009
+ }
15010
+ async function listConditionsRoute(req, res) {
15011
+ const searchParamKeys = extractSearchParamKeys3(
15012
+ req.query
14753
15013
  );
14754
- }
14755
-
14756
- // src/data/rest-api/routes/data/condition/condition-get-by-id-route.ts
14757
- async function getConditionByIdRoute(req, res) {
14758
- const id = String(req.params.id);
15014
+ if (searchParamKeys.length === 0) {
15015
+ return handleListRoute({
15016
+ req,
15017
+ res,
15018
+ basePath: BASE_PATH.CONDITION,
15019
+ listOperation: listConditionsOperation,
15020
+ errorLogContext: "GET /Condition list error:"
15021
+ });
15022
+ }
15023
+ const registered = getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE);
15024
+ const validCodes = new Set(registered.map((p) => p.code));
15025
+ const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
15026
+ if (unknownCodes.length > 0) {
15027
+ return sendInvalidSearch4003(
15028
+ res,
15029
+ buildUnknownParamDiagnostics3([...new Set(unknownCodes)])
15030
+ );
15031
+ }
15032
+ const malformedRef = findMalformedReference3(
15033
+ req.query,
15034
+ searchParamKeys
15035
+ );
15036
+ if (malformedRef !== void 0) {
15037
+ return sendInvalidSearch4003(
15038
+ res,
15039
+ `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
15040
+ );
15041
+ }
14759
15042
  const ctx = req.openhiContext;
14760
15043
  try {
14761
- const result = await getConditionByIdOperation({ context: ctx, id });
14762
- return res.json(result.resource);
15044
+ const result = await genericSearchOperation({
15045
+ resourceType: CONDITION_RESOURCE_TYPE,
15046
+ tenantId: ctx.tenantId,
15047
+ workspaceId: ctx.workspaceId,
15048
+ query: req.query,
15049
+ resolver: defaultSearchParameterResolver
15050
+ });
15051
+ const bundle = buildSearchsetBundle(BASE_PATH.CONDITION, result.entries);
15052
+ return res.json(bundle);
14763
15053
  } catch (err) {
14764
- const status = domainErrorToHttpStatus(err);
14765
- if (status === 404) {
14766
- const diagnostics = err instanceof NotFoundError ? err.message : `Condition ${id} not found`;
14767
- return sendOperationOutcome404(res, diagnostics);
14768
- }
14769
- return sendOperationOutcome500(res, err, "GET Condition error:");
15054
+ return sendOperationOutcome500(res, err, "GET /Condition search error:");
14770
15055
  }
14771
15056
  }
14772
15057
 
14773
- // src/data/operations/data/condition/condition-list-operation.ts
14774
- async function listConditionsOperation(params) {
14775
- const { context, tableName, mode } = params;
14776
- const { tenantId, workspaceId } = context;
14777
- const service = getDynamoDataService(tableName);
14778
- return listDataEntitiesByWorkspace(
14779
- service.entities.condition,
14780
- tenantId,
14781
- workspaceId,
14782
- mode
14783
- );
14784
- }
14785
-
14786
- // src/data/rest-api/routes/data/condition/condition-list-route.ts
14787
- async function listConditionsRoute(req, res) {
14788
- return handleListRoute({
14789
- req,
14790
- res,
14791
- basePath: BASE_PATH.CONDITION,
14792
- listOperation: listConditionsOperation,
14793
- errorLogContext: "GET /Condition list error:"
14794
- });
14795
- }
14796
-
14797
15058
  // src/data/operations/data/condition/condition-update-operation.ts
14798
15059
  async function updateConditionOperation(params) {
14799
15060
  const { context, id, body, tableName } = params;
@@ -18055,30 +18316,30 @@ async function listEncountersOperation(params) {
18055
18316
 
18056
18317
  // src/data/rest-api/routes/data/encounter/encounter-list-route.ts
18057
18318
  var ENCOUNTER_RESOURCE_TYPE = "Encounter";
18058
- function stripModifier2(key) {
18319
+ function stripModifier4(key) {
18059
18320
  const idx = key.indexOf(":");
18060
18321
  return idx === -1 ? key : key.slice(0, idx);
18061
18322
  }
18062
- function isResultParameter2(key) {
18323
+ function isResultParameter4(key) {
18063
18324
  return key.startsWith("_");
18064
18325
  }
18065
- function sendInvalidSearch4002(res, diagnostics) {
18326
+ function sendInvalidSearch4004(res, diagnostics) {
18066
18327
  return res.status(400).json({
18067
18328
  resourceType: "OperationOutcome",
18068
18329
  issue: [{ severity: "error", code: "invalid", diagnostics }]
18069
18330
  });
18070
18331
  }
18071
- function extractSearchParamKeys2(query) {
18332
+ function extractSearchParamKeys4(query) {
18072
18333
  const out = [];
18073
18334
  for (const rawKey of Object.keys(query)) {
18074
- if (isResultParameter2(rawKey)) {
18335
+ if (isResultParameter4(rawKey)) {
18075
18336
  continue;
18076
18337
  }
18077
- out.push({ rawKey, code: stripModifier2(rawKey) });
18338
+ out.push({ rawKey, code: stripModifier4(rawKey) });
18078
18339
  }
18079
18340
  return out;
18080
18341
  }
18081
- function buildUnknownParamDiagnostics2(unknownCodes) {
18342
+ function buildUnknownParamDiagnostics4(unknownCodes) {
18082
18343
  const validCodes = getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
18083
18344
  const codes = unknownCodes.join(", ");
18084
18345
  const isPlural = unknownCodes.length !== 1;
@@ -18087,7 +18348,7 @@ function buildUnknownParamDiagnostics2(unknownCodes) {
18087
18348
  `Valid codes: ${validCodes}.`
18088
18349
  ].join(" ");
18089
18350
  }
18090
- function findMalformedReference2(query, searchParamKeys) {
18351
+ function findMalformedReference4(query, searchParamKeys) {
18091
18352
  const referenceCodes = new Set(
18092
18353
  getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
18093
18354
  );
@@ -18110,7 +18371,7 @@ function findMalformedReference2(query, searchParamKeys) {
18110
18371
  return void 0;
18111
18372
  }
18112
18373
  async function listEncountersRoute(req, res) {
18113
- const searchParamKeys = extractSearchParamKeys2(
18374
+ const searchParamKeys = extractSearchParamKeys4(
18114
18375
  req.query
18115
18376
  );
18116
18377
  if (searchParamKeys.length === 0) {
@@ -18126,17 +18387,17 @@ async function listEncountersRoute(req, res) {
18126
18387
  const validCodes = new Set(registered.map((p) => p.code));
18127
18388
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
18128
18389
  if (unknownCodes.length > 0) {
18129
- return sendInvalidSearch4002(
18390
+ return sendInvalidSearch4004(
18130
18391
  res,
18131
- buildUnknownParamDiagnostics2([...new Set(unknownCodes)])
18392
+ buildUnknownParamDiagnostics4([...new Set(unknownCodes)])
18132
18393
  );
18133
18394
  }
18134
- const malformedRef = findMalformedReference2(
18395
+ const malformedRef = findMalformedReference4(
18135
18396
  req.query,
18136
18397
  searchParamKeys
18137
18398
  );
18138
18399
  if (malformedRef !== void 0) {
18139
- return sendInvalidSearch4002(
18400
+ return sendInvalidSearch4004(
18140
18401
  res,
18141
18402
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
18142
18403
  );
@@ -20180,15 +20441,119 @@ async function listFamilyMemberHistorysOperation(params) {
20180
20441
  }
20181
20442
 
20182
20443
  // src/data/rest-api/routes/data/familymemberhistory/familymemberhistory-list-route.ts
20183
- async function listFamilyMemberHistorysRoute(req, res) {
20184
- return handleListRoute({
20185
- req,
20186
- res,
20187
- basePath: BASE_PATH.FAMILYMEMBERHISTORY,
20188
- listOperation: listFamilyMemberHistorysOperation,
20189
- errorLogContext: "GET /FamilyMemberHistory list error:"
20444
+ var FAMILYMEMBERHISTORY_RESOURCE_TYPE = "FamilyMemberHistory";
20445
+ function stripModifier5(key) {
20446
+ const idx = key.indexOf(":");
20447
+ return idx === -1 ? key : key.slice(0, idx);
20448
+ }
20449
+ function isResultParameter5(key) {
20450
+ return key.startsWith("_");
20451
+ }
20452
+ function sendInvalidSearch4005(res, diagnostics) {
20453
+ return res.status(400).json({
20454
+ resourceType: "OperationOutcome",
20455
+ issue: [{ severity: "error", code: "invalid", diagnostics }]
20190
20456
  });
20191
20457
  }
20458
+ function extractSearchParamKeys5(query) {
20459
+ const out = [];
20460
+ for (const rawKey of Object.keys(query)) {
20461
+ if (isResultParameter5(rawKey)) {
20462
+ continue;
20463
+ }
20464
+ out.push({ rawKey, code: stripModifier5(rawKey) });
20465
+ }
20466
+ return out;
20467
+ }
20468
+ function buildUnknownParamDiagnostics5(unknownCodes) {
20469
+ const validCodes = getRegisteredSearchParameters(
20470
+ FAMILYMEMBERHISTORY_RESOURCE_TYPE
20471
+ ).map((p) => p.code).sort().join(", ");
20472
+ const codes = unknownCodes.join(", ");
20473
+ const isPlural = unknownCodes.length !== 1;
20474
+ return [
20475
+ `Unknown search ${isPlural ? "parameters" : "parameter"} for FamilyMemberHistory: ${codes}.`,
20476
+ `Valid codes: ${validCodes}.`
20477
+ ].join(" ");
20478
+ }
20479
+ function findMalformedReference5(query, searchParamKeys) {
20480
+ const referenceCodes = new Set(
20481
+ getRegisteredSearchParameters(FAMILYMEMBERHISTORY_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
20482
+ );
20483
+ for (const { rawKey, code } of searchParamKeys) {
20484
+ if (!referenceCodes.has(code)) {
20485
+ continue;
20486
+ }
20487
+ const raw = query[rawKey];
20488
+ const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
20489
+ for (const v of values) {
20490
+ const trimmed = v.trim();
20491
+ if (trimmed.length === 0) {
20492
+ continue;
20493
+ }
20494
+ if (parseTypedReference(trimmed) === void 0) {
20495
+ return { rawKey, value: trimmed };
20496
+ }
20497
+ }
20498
+ }
20499
+ return void 0;
20500
+ }
20501
+ async function listFamilyMemberHistorysRoute(req, res) {
20502
+ const searchParamKeys = extractSearchParamKeys5(
20503
+ req.query
20504
+ );
20505
+ if (searchParamKeys.length === 0) {
20506
+ return handleListRoute({
20507
+ req,
20508
+ res,
20509
+ basePath: BASE_PATH.FAMILYMEMBERHISTORY,
20510
+ listOperation: listFamilyMemberHistorysOperation,
20511
+ errorLogContext: "GET /FamilyMemberHistory list error:"
20512
+ });
20513
+ }
20514
+ const registered = getRegisteredSearchParameters(
20515
+ FAMILYMEMBERHISTORY_RESOURCE_TYPE
20516
+ );
20517
+ const validCodes = new Set(registered.map((p) => p.code));
20518
+ const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
20519
+ if (unknownCodes.length > 0) {
20520
+ return sendInvalidSearch4005(
20521
+ res,
20522
+ buildUnknownParamDiagnostics5([...new Set(unknownCodes)])
20523
+ );
20524
+ }
20525
+ const malformedRef = findMalformedReference5(
20526
+ req.query,
20527
+ searchParamKeys
20528
+ );
20529
+ if (malformedRef !== void 0) {
20530
+ return sendInvalidSearch4005(
20531
+ res,
20532
+ `?${malformedRef.rawKey} must be a typed reference like "Patient/<id>"; got "${malformedRef.value}".`
20533
+ );
20534
+ }
20535
+ const ctx = req.openhiContext;
20536
+ try {
20537
+ const result = await genericSearchOperation({
20538
+ resourceType: FAMILYMEMBERHISTORY_RESOURCE_TYPE,
20539
+ tenantId: ctx.tenantId,
20540
+ workspaceId: ctx.workspaceId,
20541
+ query: req.query,
20542
+ resolver: defaultSearchParameterResolver
20543
+ });
20544
+ const bundle = buildSearchsetBundle(
20545
+ BASE_PATH.FAMILYMEMBERHISTORY,
20546
+ result.entries
20547
+ );
20548
+ return res.json(bundle);
20549
+ } catch (err) {
20550
+ return sendOperationOutcome500(
20551
+ res,
20552
+ err,
20553
+ "GET /FamilyMemberHistory search error:"
20554
+ );
20555
+ }
20556
+ }
20192
20557
 
20193
20558
  // src/data/operations/data/familymemberhistory/familymemberhistory-update-operation.ts
20194
20559
  async function updateFamilyMemberHistoryOperation(params) {
@@ -28870,30 +29235,30 @@ async function listObservationsOperation(params) {
28870
29235
 
28871
29236
  // src/data/rest-api/routes/data/observation/observation-list-route.ts
28872
29237
  var OBSERVATION_RESOURCE_TYPE = "Observation";
28873
- function stripModifier3(key) {
29238
+ function stripModifier6(key) {
28874
29239
  const idx = key.indexOf(":");
28875
29240
  return idx === -1 ? key : key.slice(0, idx);
28876
29241
  }
28877
- function isResultParameter3(key) {
29242
+ function isResultParameter6(key) {
28878
29243
  return key.startsWith("_");
28879
29244
  }
28880
- function sendInvalidSearch4003(res, diagnostics) {
29245
+ function sendInvalidSearch4006(res, diagnostics) {
28881
29246
  return res.status(400).json({
28882
29247
  resourceType: "OperationOutcome",
28883
29248
  issue: [{ severity: "error", code: "invalid", diagnostics }]
28884
29249
  });
28885
29250
  }
28886
- function extractSearchParamKeys3(query) {
29251
+ function extractSearchParamKeys6(query) {
28887
29252
  const out = [];
28888
29253
  for (const rawKey of Object.keys(query)) {
28889
- if (isResultParameter3(rawKey)) {
29254
+ if (isResultParameter6(rawKey)) {
28890
29255
  continue;
28891
29256
  }
28892
- out.push({ rawKey, code: stripModifier3(rawKey) });
29257
+ out.push({ rawKey, code: stripModifier6(rawKey) });
28893
29258
  }
28894
29259
  return out;
28895
29260
  }
28896
- function buildUnknownParamDiagnostics3(unknownCodes) {
29261
+ function buildUnknownParamDiagnostics6(unknownCodes) {
28897
29262
  const validCodes = getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
28898
29263
  const codes = unknownCodes.join(", ");
28899
29264
  const isPlural = unknownCodes.length !== 1;
@@ -28902,7 +29267,7 @@ function buildUnknownParamDiagnostics3(unknownCodes) {
28902
29267
  `Valid codes: ${validCodes}.`
28903
29268
  ].join(" ");
28904
29269
  }
28905
- function findMalformedReference3(query, searchParamKeys) {
29270
+ function findMalformedReference6(query, searchParamKeys) {
28906
29271
  const referenceCodes = new Set(
28907
29272
  getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
28908
29273
  );
@@ -28925,7 +29290,7 @@ function findMalformedReference3(query, searchParamKeys) {
28925
29290
  return void 0;
28926
29291
  }
28927
29292
  async function listObservationsRoute(req, res) {
28928
- const searchParamKeys = extractSearchParamKeys3(
29293
+ const searchParamKeys = extractSearchParamKeys6(
28929
29294
  req.query
28930
29295
  );
28931
29296
  if (searchParamKeys.length === 0) {
@@ -28941,17 +29306,17 @@ async function listObservationsRoute(req, res) {
28941
29306
  const validCodes = new Set(registered.map((p) => p.code));
28942
29307
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
28943
29308
  if (unknownCodes.length > 0) {
28944
- return sendInvalidSearch4003(
29309
+ return sendInvalidSearch4006(
28945
29310
  res,
28946
- buildUnknownParamDiagnostics3([...new Set(unknownCodes)])
29311
+ buildUnknownParamDiagnostics6([...new Set(unknownCodes)])
28947
29312
  );
28948
29313
  }
28949
- const malformedRef = findMalformedReference3(
29314
+ const malformedRef = findMalformedReference6(
28950
29315
  req.query,
28951
29316
  searchParamKeys
28952
29317
  );
28953
29318
  if (malformedRef !== void 0) {
28954
- return sendInvalidSearch4003(
29319
+ return sendInvalidSearch4006(
28955
29320
  res,
28956
29321
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
28957
29322
  );
@@ -29981,30 +30346,30 @@ async function listPatientsOperation(params) {
29981
30346
 
29982
30347
  // src/data/rest-api/routes/data/patient/patient-list-route.ts
29983
30348
  var PATIENT_RESOURCE_TYPE = "Patient";
29984
- function stripModifier4(key) {
30349
+ function stripModifier7(key) {
29985
30350
  const idx = key.indexOf(":");
29986
30351
  return idx === -1 ? key : key.slice(0, idx);
29987
30352
  }
29988
- function isResultParameter4(key) {
30353
+ function isResultParameter7(key) {
29989
30354
  return key.startsWith("_");
29990
30355
  }
29991
- function sendInvalidSearch4004(res, diagnostics) {
30356
+ function sendInvalidSearch4007(res, diagnostics) {
29992
30357
  return res.status(400).json({
29993
30358
  resourceType: "OperationOutcome",
29994
30359
  issue: [{ severity: "error", code: "invalid", diagnostics }]
29995
30360
  });
29996
30361
  }
29997
- function extractSearchParamKeys4(query) {
30362
+ function extractSearchParamKeys7(query) {
29998
30363
  const out = [];
29999
30364
  for (const rawKey of Object.keys(query)) {
30000
- if (isResultParameter4(rawKey)) {
30365
+ if (isResultParameter7(rawKey)) {
30001
30366
  continue;
30002
30367
  }
30003
- out.push({ rawKey, code: stripModifier4(rawKey) });
30368
+ out.push({ rawKey, code: stripModifier7(rawKey) });
30004
30369
  }
30005
30370
  return out;
30006
30371
  }
30007
- function buildUnknownParamDiagnostics4(unknownCodes) {
30372
+ function buildUnknownParamDiagnostics7(unknownCodes) {
30008
30373
  const validCodes = getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
30009
30374
  const codes = unknownCodes.join(", ");
30010
30375
  const isPlural = unknownCodes.length !== 1;
@@ -30013,7 +30378,7 @@ function buildUnknownParamDiagnostics4(unknownCodes) {
30013
30378
  `Valid codes: ${validCodes}.`
30014
30379
  ].join(" ");
30015
30380
  }
30016
- function findMalformedReference4(query, searchParamKeys) {
30381
+ function findMalformedReference7(query, searchParamKeys) {
30017
30382
  const referenceCodes = new Set(
30018
30383
  getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
30019
30384
  );
@@ -30036,7 +30401,7 @@ function findMalformedReference4(query, searchParamKeys) {
30036
30401
  return void 0;
30037
30402
  }
30038
30403
  async function listPatientsRoute(req, res) {
30039
- const searchParamKeys = extractSearchParamKeys4(
30404
+ const searchParamKeys = extractSearchParamKeys7(
30040
30405
  req.query
30041
30406
  );
30042
30407
  if (searchParamKeys.length === 0) {
@@ -30052,17 +30417,17 @@ async function listPatientsRoute(req, res) {
30052
30417
  const validCodes = new Set(registered.map((p) => p.code));
30053
30418
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
30054
30419
  if (unknownCodes.length > 0) {
30055
- return sendInvalidSearch4004(
30420
+ return sendInvalidSearch4007(
30056
30421
  res,
30057
- buildUnknownParamDiagnostics4([...new Set(unknownCodes)])
30422
+ buildUnknownParamDiagnostics7([...new Set(unknownCodes)])
30058
30423
  );
30059
30424
  }
30060
- const malformedRef = findMalformedReference4(
30425
+ const malformedRef = findMalformedReference7(
30061
30426
  req.query,
30062
30427
  searchParamKeys
30063
30428
  );
30064
30429
  if (malformedRef !== void 0) {
30065
- return sendInvalidSearch4004(
30430
+ return sendInvalidSearch4007(
30066
30431
  res,
30067
30432
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
30068
30433
  );
@@ -31437,30 +31802,30 @@ async function listProceduresOperation(params) {
31437
31802
 
31438
31803
  // src/data/rest-api/routes/data/procedure/procedure-list-route.ts
31439
31804
  var PROCEDURE_RESOURCE_TYPE = "Procedure";
31440
- function stripModifier5(key) {
31805
+ function stripModifier8(key) {
31441
31806
  const idx = key.indexOf(":");
31442
31807
  return idx === -1 ? key : key.slice(0, idx);
31443
31808
  }
31444
- function isResultParameter5(key) {
31809
+ function isResultParameter8(key) {
31445
31810
  return key.startsWith("_");
31446
31811
  }
31447
- function sendInvalidSearch4005(res, diagnostics) {
31812
+ function sendInvalidSearch4008(res, diagnostics) {
31448
31813
  return res.status(400).json({
31449
31814
  resourceType: "OperationOutcome",
31450
31815
  issue: [{ severity: "error", code: "invalid", diagnostics }]
31451
31816
  });
31452
31817
  }
31453
- function extractSearchParamKeys5(query) {
31818
+ function extractSearchParamKeys8(query) {
31454
31819
  const out = [];
31455
31820
  for (const rawKey of Object.keys(query)) {
31456
- if (isResultParameter5(rawKey)) {
31821
+ if (isResultParameter8(rawKey)) {
31457
31822
  continue;
31458
31823
  }
31459
- out.push({ rawKey, code: stripModifier5(rawKey) });
31824
+ out.push({ rawKey, code: stripModifier8(rawKey) });
31460
31825
  }
31461
31826
  return out;
31462
31827
  }
31463
- function buildUnknownParamDiagnostics5(unknownCodes) {
31828
+ function buildUnknownParamDiagnostics8(unknownCodes) {
31464
31829
  const validCodes = getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
31465
31830
  const codes = unknownCodes.join(", ");
31466
31831
  const isPlural = unknownCodes.length !== 1;
@@ -31469,7 +31834,7 @@ function buildUnknownParamDiagnostics5(unknownCodes) {
31469
31834
  `Valid codes: ${validCodes}.`
31470
31835
  ].join(" ");
31471
31836
  }
31472
- function findMalformedReference5(query, searchParamKeys) {
31837
+ function findMalformedReference8(query, searchParamKeys) {
31473
31838
  const referenceCodes = new Set(
31474
31839
  getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
31475
31840
  );
@@ -31492,7 +31857,7 @@ function findMalformedReference5(query, searchParamKeys) {
31492
31857
  return void 0;
31493
31858
  }
31494
31859
  async function listProceduresRoute(req, res) {
31495
- const searchParamKeys = extractSearchParamKeys5(
31860
+ const searchParamKeys = extractSearchParamKeys8(
31496
31861
  req.query
31497
31862
  );
31498
31863
  if (searchParamKeys.length === 0) {
@@ -31508,17 +31873,17 @@ async function listProceduresRoute(req, res) {
31508
31873
  const validCodes = new Set(registered.map((p) => p.code));
31509
31874
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
31510
31875
  if (unknownCodes.length > 0) {
31511
- return sendInvalidSearch4005(
31876
+ return sendInvalidSearch4008(
31512
31877
  res,
31513
- buildUnknownParamDiagnostics5([...new Set(unknownCodes)])
31878
+ buildUnknownParamDiagnostics8([...new Set(unknownCodes)])
31514
31879
  );
31515
31880
  }
31516
- const malformedRef = findMalformedReference5(
31881
+ const malformedRef = findMalformedReference8(
31517
31882
  req.query,
31518
31883
  searchParamKeys
31519
31884
  );
31520
31885
  if (malformedRef !== void 0) {
31521
- return sendInvalidSearch4005(
31886
+ return sendInvalidSearch4008(
31522
31887
  res,
31523
31888
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
31524
31889
  );
@@ -34045,7 +34410,7 @@ function singleStringQueryParam(req, name) {
34045
34410
  const trimmed = v.trim();
34046
34411
  return trimmed === "" ? void 0 : trimmed;
34047
34412
  }
34048
- function sendInvalidSearch4006(res, diagnostics) {
34413
+ function sendInvalidSearch4009(res, diagnostics) {
34049
34414
  return res.status(400).json({
34050
34415
  resourceType: "OperationOutcome",
34051
34416
  issue: [{ severity: "error", code: "invalid", diagnostics }]
@@ -34055,7 +34420,7 @@ async function listSchedulesRoute(req, res) {
34055
34420
  const actorRef = singleStringQueryParam(req, "actor");
34056
34421
  if (actorRef !== void 0) {
34057
34422
  if (parseTypedReference(actorRef) === void 0) {
34058
- return sendInvalidSearch4006(
34423
+ return sendInvalidSearch4009(
34059
34424
  res,
34060
34425
  `?actor must be a typed reference like "Practitioner/<id>"; got "${actorRef}".`
34061
34426
  );
@@ -37853,7 +38218,7 @@ function singleStringQueryParam2(req, name) {
37853
38218
  const trimmed = v.trim();
37854
38219
  return trimmed === "" ? void 0 : trimmed;
37855
38220
  }
37856
- function sendInvalidSearch4007(res, diagnostics) {
38221
+ function sendInvalidSearch40010(res, diagnostics) {
37857
38222
  return res.status(400).json({
37858
38223
  resourceType: "OperationOutcome",
37859
38224
  issue: [{ severity: "error", code: "invalid", diagnostics }]
@@ -37863,14 +38228,14 @@ async function listTasksRoute(req, res) {
37863
38228
  const ownerRef = singleStringQueryParam2(req, "owner");
37864
38229
  const requesterRef = singleStringQueryParam2(req, "requester");
37865
38230
  if (ownerRef !== void 0 && requesterRef !== void 0) {
37866
- return sendInvalidSearch4007(
38231
+ return sendInvalidSearch40010(
37867
38232
  res,
37868
38233
  "?owner= and ?requester= cannot be combined on the same request."
37869
38234
  );
37870
38235
  }
37871
38236
  if (ownerRef !== void 0) {
37872
38237
  if (parseTypedReference(ownerRef) === void 0) {
37873
- return sendInvalidSearch4007(
38238
+ return sendInvalidSearch40010(
37874
38239
  res,
37875
38240
  `?owner must be a typed reference like "Practitioner/<id>"; got "${ownerRef}".`
37876
38241
  );
@@ -37893,7 +38258,7 @@ async function listTasksRoute(req, res) {
37893
38258
  }
37894
38259
  if (requesterRef !== void 0) {
37895
38260
  if (parseTypedReference(requesterRef) === void 0) {
37896
- return sendInvalidSearch4007(
38261
+ return sendInvalidSearch40010(
37897
38262
  res,
37898
38263
  `?requester must be a typed reference like "Practitioner/<id>"; got "${requesterRef}".`
37899
38264
  );