@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.
@@ -5205,206 +5205,6 @@ async function listAllergyIntolerancesOperation(params) {
5205
5205
  );
5206
5206
  }
5207
5207
 
5208
- // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-list-route.ts
5209
- async function listAllergyIntolerancesRoute(req, res) {
5210
- return handleListRoute({
5211
- req,
5212
- res,
5213
- basePath: BASE_PATH.ALLERGYINTOLERANCE,
5214
- listOperation: listAllergyIntolerancesOperation,
5215
- errorLogContext: "GET /AllergyIntolerance list error:"
5216
- });
5217
- }
5218
-
5219
- // src/data/operations/data/allergyintolerance/allergyintolerance-update-operation.ts
5220
- async function updateAllergyIntoleranceOperation(params) {
5221
- const { context, id, body, tableName } = params;
5222
- const { tenantId, workspaceId, date, actorId, actorName } = context;
5223
- const service = getDynamoDataService(tableName);
5224
- return updateDataEntityById(
5225
- service.entities.allergyintolerance,
5226
- tenantId,
5227
- workspaceId,
5228
- id,
5229
- "AllergyIntolerance",
5230
- context,
5231
- (existingResourceStr) => buildUpdatedResourceWithAudit(
5232
- body,
5233
- id,
5234
- date,
5235
- actorId,
5236
- actorName,
5237
- existingResourceStr,
5238
- "AllergyIntolerance"
5239
- )
5240
- );
5241
- }
5242
-
5243
- // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-update-route.ts
5244
- async function updateAllergyIntoleranceRoute(req, res) {
5245
- const bodyResult = requireJsonBodyAs(req, res);
5246
- if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
5247
- const id = String(req.params.id);
5248
- const ctx = req.openhiContext;
5249
- const body = bodyResult.body;
5250
- const resource = {
5251
- ...body,
5252
- resourceType: "AllergyIntolerance",
5253
- id
5254
- };
5255
- try {
5256
- const result = await updateAllergyIntoleranceOperation({
5257
- context: ctx,
5258
- id,
5259
- body: resource
5260
- });
5261
- return res.json(result.resource);
5262
- } catch (err) {
5263
- const status = domainErrorToHttpStatus(err);
5264
- if (status === 404) {
5265
- const diagnostics = err instanceof NotFoundError ? err.message : `AllergyIntolerance ${id} not found`;
5266
- return sendOperationOutcome404(res, diagnostics);
5267
- }
5268
- return sendOperationOutcome500(res, err, "PUT AllergyIntolerance error:");
5269
- }
5270
- }
5271
-
5272
- // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance.ts
5273
- var router13 = express13.Router();
5274
- router13.get("/", listAllergyIntolerancesRoute);
5275
- router13.get("/:id", getAllergyIntoleranceByIdRoute);
5276
- router13.post("/", createAllergyIntoleranceRoute);
5277
- router13.put("/:id", updateAllergyIntoleranceRoute);
5278
- router13.delete("/:id", deleteAllergyIntoleranceRoute);
5279
-
5280
- // src/data/rest-api/routes/data/appointment/appointment.ts
5281
- import express14 from "express";
5282
-
5283
- // src/data/operations/data/appointment/appointment-create-operation.ts
5284
- import { ulid as ulid5 } from "ulid";
5285
- async function createAppointmentOperation(params) {
5286
- const { context, body, tableName } = params;
5287
- const { tenantId, workspaceId, date, actorId, actorName } = context;
5288
- const id = body.id ?? ulid5();
5289
- const meta = {
5290
- ...body.meta ?? {},
5291
- lastUpdated: date,
5292
- versionId: "1"
5293
- };
5294
- const resourceWithAudit = {
5295
- ...body,
5296
- resourceType: "Appointment",
5297
- id,
5298
- meta: mergeAuditIntoMeta(meta, {
5299
- createdDate: date,
5300
- createdById: actorId,
5301
- createdByName: actorName,
5302
- modifiedDate: date,
5303
- modifiedById: actorId,
5304
- modifiedByName: actorName
5305
- })
5306
- };
5307
- const service = getDynamoDataService(tableName);
5308
- return createDataEntityRecord(
5309
- service.entities.appointment,
5310
- tenantId,
5311
- workspaceId,
5312
- id,
5313
- resourceWithAudit,
5314
- date
5315
- );
5316
- }
5317
-
5318
- // src/data/rest-api/routes/data/appointment/appointment-create-route.ts
5319
- async function createAppointmentRoute(req, res) {
5320
- const bodyResult = requireJsonBodyAs(req, res);
5321
- if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
5322
- const ctx = req.openhiContext;
5323
- const body = bodyResult.body;
5324
- const resource = {
5325
- ...body,
5326
- resourceType: "Appointment"
5327
- };
5328
- try {
5329
- const result = await createAppointmentOperation({
5330
- context: ctx,
5331
- body: resource
5332
- });
5333
- return res.status(201).location(`${BASE_PATH.APPOINTMENT}/${result.id}`).json(result.resource);
5334
- } catch (err) {
5335
- return sendOperationOutcome500(res, err, "POST Appointment error:");
5336
- }
5337
- }
5338
-
5339
- // src/data/operations/data/appointment/appointment-delete-operation.ts
5340
- async function deleteAppointmentOperation(params) {
5341
- const { context, id, tableName } = params;
5342
- const { tenantId, workspaceId } = context;
5343
- const service = getDynamoDataService(tableName);
5344
- await deleteDataEntityById(
5345
- service.entities.appointment,
5346
- tenantId,
5347
- workspaceId,
5348
- id
5349
- );
5350
- }
5351
-
5352
- // src/data/rest-api/routes/data/appointment/appointment-delete-route.ts
5353
- async function deleteAppointmentRoute(req, res) {
5354
- const id = String(req.params.id);
5355
- const ctx = req.openhiContext;
5356
- try {
5357
- await deleteAppointmentOperation({ context: ctx, id });
5358
- return res.status(204).send();
5359
- } catch (err) {
5360
- return sendOperationOutcome500(res, err, "DELETE Appointment error:");
5361
- }
5362
- }
5363
-
5364
- // src/data/operations/data/appointment/appointment-get-by-id-operation.ts
5365
- async function getAppointmentByIdOperation(params) {
5366
- const { context, id, tableName } = params;
5367
- const { tenantId, workspaceId } = context;
5368
- const service = getDynamoDataService(tableName);
5369
- return getDataEntityById(
5370
- service.entities.appointment,
5371
- tenantId,
5372
- workspaceId,
5373
- id,
5374
- "Appointment"
5375
- );
5376
- }
5377
-
5378
- // src/data/rest-api/routes/data/appointment/appointment-get-by-id-route.ts
5379
- async function getAppointmentByIdRoute(req, res) {
5380
- const id = String(req.params.id);
5381
- const ctx = req.openhiContext;
5382
- try {
5383
- const result = await getAppointmentByIdOperation({ context: ctx, id });
5384
- return res.json(result.resource);
5385
- } catch (err) {
5386
- const status = domainErrorToHttpStatus(err);
5387
- if (status === 404) {
5388
- const diagnostics = err instanceof NotFoundError ? err.message : `Appointment ${id} not found`;
5389
- return sendOperationOutcome404(res, diagnostics);
5390
- }
5391
- return sendOperationOutcome500(res, err, "GET Appointment error:");
5392
- }
5393
- }
5394
-
5395
- // src/data/operations/data/appointment/appointment-list-operation.ts
5396
- async function listAppointmentsOperation(params) {
5397
- const { context, tableName, mode } = params;
5398
- const { tenantId, workspaceId } = context;
5399
- const service = getDynamoDataService(tableName);
5400
- return listDataEntitiesByWorkspace(
5401
- service.entities.appointment,
5402
- tenantId,
5403
- workspaceId,
5404
- mode
5405
- );
5406
- }
5407
-
5408
5208
  // src/data/search/engine/reference-predicate.ts
5409
5209
  function buildOpenHiResourceUrn(opts) {
5410
5210
  return `urn:ohi:${opts.tenantId}:${opts.workspaceId}:${opts.resourceType}:${opts.resourceId}`;
@@ -6021,6 +5821,30 @@ async function genericSearchOperation(params) {
6021
5821
  return { entries, total: entries.length };
6022
5822
  }
6023
5823
 
5824
+ // src/data/search/registry/allergyintolerance-search-parameters.ts
5825
+ var ALLERGYINTOLERANCE_SEARCH_PARAMETERS = [
5826
+ {
5827
+ code: "clinical-status",
5828
+ type: "token",
5829
+ jsonbPath: "$.clinicalStatus"
5830
+ },
5831
+ {
5832
+ code: "verification-status",
5833
+ type: "token",
5834
+ jsonbPath: "$.verificationStatus"
5835
+ },
5836
+ { code: "type", type: "token", jsonbPath: "$.type" },
5837
+ { code: "category", type: "token", jsonbPath: "$.category[*]" },
5838
+ { code: "criticality", type: "token", jsonbPath: "$.criticality" },
5839
+ { code: "code", type: "token", jsonbPath: "$.code" },
5840
+ { code: "patient", type: "reference", jsonbPath: "$.patient" },
5841
+ { code: "recorder", type: "reference", jsonbPath: "$.recorder" },
5842
+ { code: "asserter", type: "reference", jsonbPath: "$.asserter" },
5843
+ { code: "date", type: "date", jsonbPath: "$.recordedDate" },
5844
+ { code: "last-date", type: "date", jsonbPath: "$.lastOccurrence" },
5845
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
5846
+ ];
5847
+
6024
5848
  // src/data/search/registry/appointment-search-parameters.ts
6025
5849
  var APPOINTMENT_SEARCH_PARAMETERS = [
6026
5850
  { code: "status", type: "token", jsonbPath: "$.status" },
@@ -6055,6 +5879,32 @@ var APPOINTMENT_SEARCH_PARAMETERS = [
6055
5879
  { code: "slot", type: "reference", jsonbPath: "$.slot[*]" }
6056
5880
  ];
6057
5881
 
5882
+ // src/data/search/registry/condition-search-parameters.ts
5883
+ var CONDITION_SEARCH_PARAMETERS = [
5884
+ {
5885
+ code: "clinical-status",
5886
+ type: "token",
5887
+ jsonbPath: "$.clinicalStatus"
5888
+ },
5889
+ {
5890
+ code: "verification-status",
5891
+ type: "token",
5892
+ jsonbPath: "$.verificationStatus"
5893
+ },
5894
+ { code: "category", type: "token", jsonbPath: "$.category[*]" },
5895
+ { code: "severity", type: "token", jsonbPath: "$.severity" },
5896
+ { code: "code", type: "token", jsonbPath: "$.code" },
5897
+ { code: "subject", type: "reference", jsonbPath: "$.subject" },
5898
+ { code: "patient", type: "reference", jsonbPath: "$.subject" },
5899
+ { code: "encounter", type: "reference", jsonbPath: "$.encounter" },
5900
+ { code: "asserter", type: "reference", jsonbPath: "$.asserter" },
5901
+ { code: "recorder", type: "reference", jsonbPath: "$.recorder" },
5902
+ { code: "onset-date", type: "date", jsonbPath: "$.onsetDateTime" },
5903
+ { code: "recorded-date", type: "date", jsonbPath: "$.recordedDate" },
5904
+ { code: "body-site", type: "token", jsonbPath: "$.bodySite[*]" },
5905
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
5906
+ ];
5907
+
6058
5908
  // src/data/search/registry/encounter-search-parameters.ts
6059
5909
  var ENCOUNTER_SEARCH_PARAMETERS = [
6060
5910
  { code: "status", type: "token", jsonbPath: "$.status" },
@@ -6081,6 +5931,17 @@ var ENCOUNTER_SEARCH_PARAMETERS = [
6081
5931
  }
6082
5932
  ];
6083
5933
 
5934
+ // src/data/search/registry/familymemberhistory-search-parameters.ts
5935
+ var FAMILYMEMBERHISTORY_SEARCH_PARAMETERS = [
5936
+ { code: "status", type: "token", jsonbPath: "$.status" },
5937
+ { code: "relationship", type: "token", jsonbPath: "$.relationship" },
5938
+ { code: "sex", type: "token", jsonbPath: "$.sex" },
5939
+ { code: "patient", type: "reference", jsonbPath: "$.patient" },
5940
+ { code: "date", type: "date", jsonbPath: "$.date" },
5941
+ { code: "code", type: "token", jsonbPath: "$.condition[*]" },
5942
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
5943
+ ];
5944
+
6084
5945
  // src/data/search/registry/observation-search-parameters.ts
6085
5946
  var OBSERVATION_SEARCH_PARAMETERS = [
6086
5947
  { code: "status", type: "token", jsonbPath: "$.status" },
@@ -6102,108 +5963,415 @@ var OBSERVATION_SEARCH_PARAMETERS = [
6102
5963
  { code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" }
6103
5964
  ];
6104
5965
 
6105
- // src/data/search/registry/patient-search-parameters.ts
6106
- var PATIENT_SEARCH_PARAMETERS = [
6107
- { code: "gender", type: "token", jsonbPath: "$.gender" },
6108
- { code: "identifier", type: "token", jsonbPath: "$.identifier[*].value" },
6109
- { code: "birthdate", type: "date", jsonbPath: "$.birthDate" },
6110
- {
6111
- code: "name",
6112
- type: "string",
6113
- jsonbPath: "$.name[*].text",
6114
- modifiers: ["exact", "contains", "missing", "not"]
6115
- },
6116
- {
6117
- code: "family",
6118
- type: "string",
6119
- jsonbPath: "$.name[*].family",
6120
- modifiers: ["exact", "contains", "missing", "not"]
6121
- },
6122
- {
6123
- code: "given",
6124
- type: "string",
6125
- jsonbPath: "$.name[*].given",
6126
- modifiers: ["exact", "contains", "missing", "not"]
6127
- },
6128
- { code: "active", type: "token", jsonbPath: "$.active" },
6129
- { code: "deceased", type: "token", jsonbPath: "$.deceasedBoolean" },
6130
- {
6131
- code: "general-practitioner",
6132
- type: "reference",
6133
- jsonbPath: "$.generalPractitioner[*]"
6134
- },
6135
- {
6136
- code: "organization",
6137
- type: "reference",
6138
- jsonbPath: "$.managingOrganization"
5966
+ // src/data/search/registry/patient-search-parameters.ts
5967
+ var PATIENT_SEARCH_PARAMETERS = [
5968
+ { code: "gender", type: "token", jsonbPath: "$.gender" },
5969
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*].value" },
5970
+ { code: "birthdate", type: "date", jsonbPath: "$.birthDate" },
5971
+ {
5972
+ code: "name",
5973
+ type: "string",
5974
+ jsonbPath: "$.name[*].text",
5975
+ modifiers: ["exact", "contains", "missing", "not"]
5976
+ },
5977
+ {
5978
+ code: "family",
5979
+ type: "string",
5980
+ jsonbPath: "$.name[*].family",
5981
+ modifiers: ["exact", "contains", "missing", "not"]
5982
+ },
5983
+ {
5984
+ code: "given",
5985
+ type: "string",
5986
+ jsonbPath: "$.name[*].given",
5987
+ modifiers: ["exact", "contains", "missing", "not"]
5988
+ },
5989
+ { code: "active", type: "token", jsonbPath: "$.active" },
5990
+ { code: "deceased", type: "token", jsonbPath: "$.deceasedBoolean" },
5991
+ {
5992
+ code: "general-practitioner",
5993
+ type: "reference",
5994
+ jsonbPath: "$.generalPractitioner[*]"
5995
+ },
5996
+ {
5997
+ code: "organization",
5998
+ type: "reference",
5999
+ jsonbPath: "$.managingOrganization"
6000
+ }
6001
+ ];
6002
+
6003
+ // src/data/search/registry/procedure-search-parameters.ts
6004
+ var PROCEDURE_SEARCH_PARAMETERS = [
6005
+ { code: "status", type: "token", jsonbPath: "$.status" },
6006
+ { code: "category", type: "token", jsonbPath: "$.category" },
6007
+ { code: "code", type: "token", jsonbPath: "$.code" },
6008
+ { code: "subject", type: "reference", jsonbPath: "$.subject" },
6009
+ { code: "patient", type: "reference", jsonbPath: "$.subject" },
6010
+ { code: "encounter", type: "reference", jsonbPath: "$.encounter" },
6011
+ {
6012
+ code: "performer",
6013
+ type: "reference",
6014
+ jsonbPath: "$.performer[*].actor"
6015
+ },
6016
+ { code: "date", type: "date", jsonbPath: "$.performedDateTime" },
6017
+ { code: "location", type: "reference", jsonbPath: "$.location" },
6018
+ { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
6019
+ { code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
6020
+ { code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" },
6021
+ { code: "reason-code", type: "token", jsonbPath: "$.reasonCode[*]" },
6022
+ {
6023
+ code: "reason-reference",
6024
+ type: "reference",
6025
+ jsonbPath: "$.reasonReference[*]"
6026
+ }
6027
+ ];
6028
+
6029
+ // src/data/search/registry/resolver.ts
6030
+ var STATIC_SEARCH_PARAMETER_MAP = {
6031
+ AllergyIntolerance: ALLERGYINTOLERANCE_SEARCH_PARAMETERS,
6032
+ Appointment: APPOINTMENT_SEARCH_PARAMETERS,
6033
+ Condition: CONDITION_SEARCH_PARAMETERS,
6034
+ Encounter: ENCOUNTER_SEARCH_PARAMETERS,
6035
+ FamilyMemberHistory: FAMILYMEMBERHISTORY_SEARCH_PARAMETERS,
6036
+ Observation: OBSERVATION_SEARCH_PARAMETERS,
6037
+ Patient: PATIENT_SEARCH_PARAMETERS,
6038
+ Procedure: PROCEDURE_SEARCH_PARAMETERS
6039
+ };
6040
+ var defaultSearchParameterResolver = (resourceType, _tenantId) => STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
6041
+ function getRegisteredSearchParameters(resourceType) {
6042
+ return STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
6043
+ }
6044
+
6045
+ // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-list-route.ts
6046
+ var ALLERGYINTOLERANCE_RESOURCE_TYPE = "AllergyIntolerance";
6047
+ function stripModifier(key) {
6048
+ const idx = key.indexOf(":");
6049
+ return idx === -1 ? key : key.slice(0, idx);
6050
+ }
6051
+ function isResultParameter(key) {
6052
+ return key.startsWith("_");
6053
+ }
6054
+ function sendInvalidSearch400(res, diagnostics) {
6055
+ return res.status(400).json({
6056
+ resourceType: "OperationOutcome",
6057
+ issue: [{ severity: "error", code: "invalid", diagnostics }]
6058
+ });
6059
+ }
6060
+ function extractSearchParamKeys(query) {
6061
+ const out = [];
6062
+ for (const rawKey of Object.keys(query)) {
6063
+ if (isResultParameter(rawKey)) {
6064
+ continue;
6065
+ }
6066
+ out.push({ rawKey, code: stripModifier(rawKey) });
6067
+ }
6068
+ return out;
6069
+ }
6070
+ function buildUnknownParamDiagnostics(unknownCodes) {
6071
+ const validCodes = getRegisteredSearchParameters(
6072
+ ALLERGYINTOLERANCE_RESOURCE_TYPE
6073
+ ).map((p) => p.code).sort().join(", ");
6074
+ const codes = unknownCodes.join(", ");
6075
+ const isPlural = unknownCodes.length !== 1;
6076
+ return [
6077
+ `Unknown search ${isPlural ? "parameters" : "parameter"} for AllergyIntolerance: ${codes}.`,
6078
+ `Valid codes: ${validCodes}.`
6079
+ ].join(" ");
6080
+ }
6081
+ function findMalformedReference(query, searchParamKeys) {
6082
+ const referenceCodes = new Set(
6083
+ getRegisteredSearchParameters(ALLERGYINTOLERANCE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
6084
+ );
6085
+ for (const { rawKey, code } of searchParamKeys) {
6086
+ if (!referenceCodes.has(code)) {
6087
+ continue;
6088
+ }
6089
+ const raw = query[rawKey];
6090
+ const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
6091
+ for (const v of values) {
6092
+ const trimmed = v.trim();
6093
+ if (trimmed.length === 0) {
6094
+ continue;
6095
+ }
6096
+ if (parseTypedReference(trimmed) === void 0) {
6097
+ return { rawKey, value: trimmed };
6098
+ }
6099
+ }
6100
+ }
6101
+ return void 0;
6102
+ }
6103
+ async function listAllergyIntolerancesRoute(req, res) {
6104
+ const searchParamKeys = extractSearchParamKeys(
6105
+ req.query
6106
+ );
6107
+ if (searchParamKeys.length === 0) {
6108
+ return handleListRoute({
6109
+ req,
6110
+ res,
6111
+ basePath: BASE_PATH.ALLERGYINTOLERANCE,
6112
+ listOperation: listAllergyIntolerancesOperation,
6113
+ errorLogContext: "GET /AllergyIntolerance list error:"
6114
+ });
6115
+ }
6116
+ const registered = getRegisteredSearchParameters(
6117
+ ALLERGYINTOLERANCE_RESOURCE_TYPE
6118
+ );
6119
+ const validCodes = new Set(registered.map((p) => p.code));
6120
+ const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
6121
+ if (unknownCodes.length > 0) {
6122
+ return sendInvalidSearch400(
6123
+ res,
6124
+ buildUnknownParamDiagnostics([...new Set(unknownCodes)])
6125
+ );
6126
+ }
6127
+ const malformedRef = findMalformedReference(
6128
+ req.query,
6129
+ searchParamKeys
6130
+ );
6131
+ if (malformedRef !== void 0) {
6132
+ return sendInvalidSearch400(
6133
+ res,
6134
+ `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
6135
+ );
6136
+ }
6137
+ const ctx = req.openhiContext;
6138
+ try {
6139
+ const result = await genericSearchOperation({
6140
+ resourceType: ALLERGYINTOLERANCE_RESOURCE_TYPE,
6141
+ tenantId: ctx.tenantId,
6142
+ workspaceId: ctx.workspaceId,
6143
+ query: req.query,
6144
+ resolver: defaultSearchParameterResolver
6145
+ });
6146
+ const bundle = buildSearchsetBundle(
6147
+ BASE_PATH.ALLERGYINTOLERANCE,
6148
+ result.entries
6149
+ );
6150
+ return res.json(bundle);
6151
+ } catch (err) {
6152
+ return sendOperationOutcome500(
6153
+ res,
6154
+ err,
6155
+ "GET /AllergyIntolerance search error:"
6156
+ );
6157
+ }
6158
+ }
6159
+
6160
+ // src/data/operations/data/allergyintolerance/allergyintolerance-update-operation.ts
6161
+ async function updateAllergyIntoleranceOperation(params) {
6162
+ const { context, id, body, tableName } = params;
6163
+ const { tenantId, workspaceId, date, actorId, actorName } = context;
6164
+ const service = getDynamoDataService(tableName);
6165
+ return updateDataEntityById(
6166
+ service.entities.allergyintolerance,
6167
+ tenantId,
6168
+ workspaceId,
6169
+ id,
6170
+ "AllergyIntolerance",
6171
+ context,
6172
+ (existingResourceStr) => buildUpdatedResourceWithAudit(
6173
+ body,
6174
+ id,
6175
+ date,
6176
+ actorId,
6177
+ actorName,
6178
+ existingResourceStr,
6179
+ "AllergyIntolerance"
6180
+ )
6181
+ );
6182
+ }
6183
+
6184
+ // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-update-route.ts
6185
+ async function updateAllergyIntoleranceRoute(req, res) {
6186
+ const bodyResult = requireJsonBodyAs(req, res);
6187
+ if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
6188
+ const id = String(req.params.id);
6189
+ const ctx = req.openhiContext;
6190
+ const body = bodyResult.body;
6191
+ const resource = {
6192
+ ...body,
6193
+ resourceType: "AllergyIntolerance",
6194
+ id
6195
+ };
6196
+ try {
6197
+ const result = await updateAllergyIntoleranceOperation({
6198
+ context: ctx,
6199
+ id,
6200
+ body: resource
6201
+ });
6202
+ return res.json(result.resource);
6203
+ } catch (err) {
6204
+ const status = domainErrorToHttpStatus(err);
6205
+ if (status === 404) {
6206
+ const diagnostics = err instanceof NotFoundError ? err.message : `AllergyIntolerance ${id} not found`;
6207
+ return sendOperationOutcome404(res, diagnostics);
6208
+ }
6209
+ return sendOperationOutcome500(res, err, "PUT AllergyIntolerance error:");
6210
+ }
6211
+ }
6212
+
6213
+ // src/data/rest-api/routes/data/allergyintolerance/allergyintolerance.ts
6214
+ var router13 = express13.Router();
6215
+ router13.get("/", listAllergyIntolerancesRoute);
6216
+ router13.get("/:id", getAllergyIntoleranceByIdRoute);
6217
+ router13.post("/", createAllergyIntoleranceRoute);
6218
+ router13.put("/:id", updateAllergyIntoleranceRoute);
6219
+ router13.delete("/:id", deleteAllergyIntoleranceRoute);
6220
+
6221
+ // src/data/rest-api/routes/data/appointment/appointment.ts
6222
+ import express14 from "express";
6223
+
6224
+ // src/data/operations/data/appointment/appointment-create-operation.ts
6225
+ import { ulid as ulid5 } from "ulid";
6226
+ async function createAppointmentOperation(params) {
6227
+ const { context, body, tableName } = params;
6228
+ const { tenantId, workspaceId, date, actorId, actorName } = context;
6229
+ const id = body.id ?? ulid5();
6230
+ const meta = {
6231
+ ...body.meta ?? {},
6232
+ lastUpdated: date,
6233
+ versionId: "1"
6234
+ };
6235
+ const resourceWithAudit = {
6236
+ ...body,
6237
+ resourceType: "Appointment",
6238
+ id,
6239
+ meta: mergeAuditIntoMeta(meta, {
6240
+ createdDate: date,
6241
+ createdById: actorId,
6242
+ createdByName: actorName,
6243
+ modifiedDate: date,
6244
+ modifiedById: actorId,
6245
+ modifiedByName: actorName
6246
+ })
6247
+ };
6248
+ const service = getDynamoDataService(tableName);
6249
+ return createDataEntityRecord(
6250
+ service.entities.appointment,
6251
+ tenantId,
6252
+ workspaceId,
6253
+ id,
6254
+ resourceWithAudit,
6255
+ date
6256
+ );
6257
+ }
6258
+
6259
+ // src/data/rest-api/routes/data/appointment/appointment-create-route.ts
6260
+ async function createAppointmentRoute(req, res) {
6261
+ const bodyResult = requireJsonBodyAs(req, res);
6262
+ if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
6263
+ const ctx = req.openhiContext;
6264
+ const body = bodyResult.body;
6265
+ const resource = {
6266
+ ...body,
6267
+ resourceType: "Appointment"
6268
+ };
6269
+ try {
6270
+ const result = await createAppointmentOperation({
6271
+ context: ctx,
6272
+ body: resource
6273
+ });
6274
+ return res.status(201).location(`${BASE_PATH.APPOINTMENT}/${result.id}`).json(result.resource);
6275
+ } catch (err) {
6276
+ return sendOperationOutcome500(res, err, "POST Appointment error:");
6277
+ }
6278
+ }
6279
+
6280
+ // src/data/operations/data/appointment/appointment-delete-operation.ts
6281
+ async function deleteAppointmentOperation(params) {
6282
+ const { context, id, tableName } = params;
6283
+ const { tenantId, workspaceId } = context;
6284
+ const service = getDynamoDataService(tableName);
6285
+ await deleteDataEntityById(
6286
+ service.entities.appointment,
6287
+ tenantId,
6288
+ workspaceId,
6289
+ id
6290
+ );
6291
+ }
6292
+
6293
+ // src/data/rest-api/routes/data/appointment/appointment-delete-route.ts
6294
+ async function deleteAppointmentRoute(req, res) {
6295
+ const id = String(req.params.id);
6296
+ const ctx = req.openhiContext;
6297
+ try {
6298
+ await deleteAppointmentOperation({ context: ctx, id });
6299
+ return res.status(204).send();
6300
+ } catch (err) {
6301
+ return sendOperationOutcome500(res, err, "DELETE Appointment error:");
6139
6302
  }
6140
- ];
6303
+ }
6141
6304
 
6142
- // src/data/search/registry/procedure-search-parameters.ts
6143
- var PROCEDURE_SEARCH_PARAMETERS = [
6144
- { code: "status", type: "token", jsonbPath: "$.status" },
6145
- { code: "category", type: "token", jsonbPath: "$.category" },
6146
- { code: "code", type: "token", jsonbPath: "$.code" },
6147
- { code: "subject", type: "reference", jsonbPath: "$.subject" },
6148
- { code: "patient", type: "reference", jsonbPath: "$.subject" },
6149
- { code: "encounter", type: "reference", jsonbPath: "$.encounter" },
6150
- {
6151
- code: "performer",
6152
- type: "reference",
6153
- jsonbPath: "$.performer[*].actor"
6154
- },
6155
- { code: "date", type: "date", jsonbPath: "$.performedDateTime" },
6156
- { code: "location", type: "reference", jsonbPath: "$.location" },
6157
- { code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
6158
- { code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
6159
- { code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" },
6160
- { code: "reason-code", type: "token", jsonbPath: "$.reasonCode[*]" },
6161
- {
6162
- code: "reason-reference",
6163
- type: "reference",
6164
- jsonbPath: "$.reasonReference[*]"
6305
+ // src/data/operations/data/appointment/appointment-get-by-id-operation.ts
6306
+ async function getAppointmentByIdOperation(params) {
6307
+ const { context, id, tableName } = params;
6308
+ const { tenantId, workspaceId } = context;
6309
+ const service = getDynamoDataService(tableName);
6310
+ return getDataEntityById(
6311
+ service.entities.appointment,
6312
+ tenantId,
6313
+ workspaceId,
6314
+ id,
6315
+ "Appointment"
6316
+ );
6317
+ }
6318
+
6319
+ // src/data/rest-api/routes/data/appointment/appointment-get-by-id-route.ts
6320
+ async function getAppointmentByIdRoute(req, res) {
6321
+ const id = String(req.params.id);
6322
+ const ctx = req.openhiContext;
6323
+ try {
6324
+ const result = await getAppointmentByIdOperation({ context: ctx, id });
6325
+ return res.json(result.resource);
6326
+ } catch (err) {
6327
+ const status = domainErrorToHttpStatus(err);
6328
+ if (status === 404) {
6329
+ const diagnostics = err instanceof NotFoundError ? err.message : `Appointment ${id} not found`;
6330
+ return sendOperationOutcome404(res, diagnostics);
6331
+ }
6332
+ return sendOperationOutcome500(res, err, "GET Appointment error:");
6165
6333
  }
6166
- ];
6334
+ }
6167
6335
 
6168
- // src/data/search/registry/resolver.ts
6169
- var STATIC_SEARCH_PARAMETER_MAP = {
6170
- Appointment: APPOINTMENT_SEARCH_PARAMETERS,
6171
- Encounter: ENCOUNTER_SEARCH_PARAMETERS,
6172
- Observation: OBSERVATION_SEARCH_PARAMETERS,
6173
- Patient: PATIENT_SEARCH_PARAMETERS,
6174
- Procedure: PROCEDURE_SEARCH_PARAMETERS
6175
- };
6176
- var defaultSearchParameterResolver = (resourceType, _tenantId) => STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
6177
- function getRegisteredSearchParameters(resourceType) {
6178
- return STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
6336
+ // src/data/operations/data/appointment/appointment-list-operation.ts
6337
+ async function listAppointmentsOperation(params) {
6338
+ const { context, tableName, mode } = params;
6339
+ const { tenantId, workspaceId } = context;
6340
+ const service = getDynamoDataService(tableName);
6341
+ return listDataEntitiesByWorkspace(
6342
+ service.entities.appointment,
6343
+ tenantId,
6344
+ workspaceId,
6345
+ mode
6346
+ );
6179
6347
  }
6180
6348
 
6181
6349
  // src/data/rest-api/routes/data/appointment/appointment-list-route.ts
6182
6350
  var APPOINTMENT_RESOURCE_TYPE = "Appointment";
6183
- function stripModifier(key) {
6351
+ function stripModifier2(key) {
6184
6352
  const idx = key.indexOf(":");
6185
6353
  return idx === -1 ? key : key.slice(0, idx);
6186
6354
  }
6187
- function isResultParameter(key) {
6355
+ function isResultParameter2(key) {
6188
6356
  return key.startsWith("_");
6189
6357
  }
6190
- function sendInvalidSearch400(res, diagnostics) {
6358
+ function sendInvalidSearch4002(res, diagnostics) {
6191
6359
  return res.status(400).json({
6192
6360
  resourceType: "OperationOutcome",
6193
6361
  issue: [{ severity: "error", code: "invalid", diagnostics }]
6194
6362
  });
6195
6363
  }
6196
- function extractSearchParamKeys(query) {
6364
+ function extractSearchParamKeys2(query) {
6197
6365
  const out = [];
6198
6366
  for (const rawKey of Object.keys(query)) {
6199
- if (isResultParameter(rawKey)) {
6367
+ if (isResultParameter2(rawKey)) {
6200
6368
  continue;
6201
6369
  }
6202
- out.push({ rawKey, code: stripModifier(rawKey) });
6370
+ out.push({ rawKey, code: stripModifier2(rawKey) });
6203
6371
  }
6204
6372
  return out;
6205
6373
  }
6206
- function buildUnknownParamDiagnostics(unknownCodes) {
6374
+ function buildUnknownParamDiagnostics2(unknownCodes) {
6207
6375
  const validCodes = getRegisteredSearchParameters(APPOINTMENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
6208
6376
  const codes = unknownCodes.join(", ");
6209
6377
  const isPlural = unknownCodes.length !== 1;
@@ -6212,7 +6380,7 @@ function buildUnknownParamDiagnostics(unknownCodes) {
6212
6380
  `Valid codes: ${validCodes}.`
6213
6381
  ].join(" ");
6214
6382
  }
6215
- function findMalformedReference(query, searchParamKeys) {
6383
+ function findMalformedReference2(query, searchParamKeys) {
6216
6384
  const referenceCodes = new Set(
6217
6385
  getRegisteredSearchParameters(APPOINTMENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
6218
6386
  );
@@ -6235,7 +6403,7 @@ function findMalformedReference(query, searchParamKeys) {
6235
6403
  return void 0;
6236
6404
  }
6237
6405
  async function listAppointmentsRoute(req, res) {
6238
- const searchParamKeys = extractSearchParamKeys(
6406
+ const searchParamKeys = extractSearchParamKeys2(
6239
6407
  req.query
6240
6408
  );
6241
6409
  if (searchParamKeys.length === 0) {
@@ -6251,17 +6419,17 @@ async function listAppointmentsRoute(req, res) {
6251
6419
  const validCodes = new Set(registered.map((p) => p.code));
6252
6420
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
6253
6421
  if (unknownCodes.length > 0) {
6254
- return sendInvalidSearch400(
6422
+ return sendInvalidSearch4002(
6255
6423
  res,
6256
- buildUnknownParamDiagnostics([...new Set(unknownCodes)])
6424
+ buildUnknownParamDiagnostics2([...new Set(unknownCodes)])
6257
6425
  );
6258
6426
  }
6259
- const malformedRef = findMalformedReference(
6427
+ const malformedRef = findMalformedReference2(
6260
6428
  req.query,
6261
6429
  searchParamKeys
6262
6430
  );
6263
6431
  if (malformedRef !== void 0) {
6264
- return sendInvalidSearch400(
6432
+ return sendInvalidSearch4002(
6265
6433
  res,
6266
6434
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
6267
6435
  );
@@ -10507,62 +10675,155 @@ async function deleteConditionRoute(req, res) {
10507
10675
  return sendOperationOutcome500(res, err, "DELETE Condition error:");
10508
10676
  }
10509
10677
  }
10510
-
10511
- // src/data/operations/data/condition/condition-get-by-id-operation.ts
10512
- async function getConditionByIdOperation(params) {
10513
- const { context, id, tableName } = params;
10514
- const { tenantId, workspaceId } = context;
10515
- const service = getDynamoDataService(tableName);
10516
- return getDataEntityById(
10517
- service.entities.condition,
10518
- tenantId,
10519
- workspaceId,
10520
- id,
10521
- "Condition"
10678
+
10679
+ // src/data/operations/data/condition/condition-get-by-id-operation.ts
10680
+ async function getConditionByIdOperation(params) {
10681
+ const { context, id, tableName } = params;
10682
+ const { tenantId, workspaceId } = context;
10683
+ const service = getDynamoDataService(tableName);
10684
+ return getDataEntityById(
10685
+ service.entities.condition,
10686
+ tenantId,
10687
+ workspaceId,
10688
+ id,
10689
+ "Condition"
10690
+ );
10691
+ }
10692
+
10693
+ // src/data/rest-api/routes/data/condition/condition-get-by-id-route.ts
10694
+ async function getConditionByIdRoute(req, res) {
10695
+ const id = String(req.params.id);
10696
+ const ctx = req.openhiContext;
10697
+ try {
10698
+ const result = await getConditionByIdOperation({ context: ctx, id });
10699
+ return res.json(result.resource);
10700
+ } catch (err) {
10701
+ const status = domainErrorToHttpStatus(err);
10702
+ if (status === 404) {
10703
+ const diagnostics = err instanceof NotFoundError ? err.message : `Condition ${id} not found`;
10704
+ return sendOperationOutcome404(res, diagnostics);
10705
+ }
10706
+ return sendOperationOutcome500(res, err, "GET Condition error:");
10707
+ }
10708
+ }
10709
+
10710
+ // src/data/operations/data/condition/condition-list-operation.ts
10711
+ async function listConditionsOperation(params) {
10712
+ const { context, tableName, mode } = params;
10713
+ const { tenantId, workspaceId } = context;
10714
+ const service = getDynamoDataService(tableName);
10715
+ return listDataEntitiesByWorkspace(
10716
+ service.entities.condition,
10717
+ tenantId,
10718
+ workspaceId,
10719
+ mode
10720
+ );
10721
+ }
10722
+
10723
+ // src/data/rest-api/routes/data/condition/condition-list-route.ts
10724
+ var CONDITION_RESOURCE_TYPE = "Condition";
10725
+ function stripModifier3(key) {
10726
+ const idx = key.indexOf(":");
10727
+ return idx === -1 ? key : key.slice(0, idx);
10728
+ }
10729
+ function isResultParameter3(key) {
10730
+ return key.startsWith("_");
10731
+ }
10732
+ function sendInvalidSearch4003(res, diagnostics) {
10733
+ return res.status(400).json({
10734
+ resourceType: "OperationOutcome",
10735
+ issue: [{ severity: "error", code: "invalid", diagnostics }]
10736
+ });
10737
+ }
10738
+ function extractSearchParamKeys3(query) {
10739
+ const out = [];
10740
+ for (const rawKey of Object.keys(query)) {
10741
+ if (isResultParameter3(rawKey)) {
10742
+ continue;
10743
+ }
10744
+ out.push({ rawKey, code: stripModifier3(rawKey) });
10745
+ }
10746
+ return out;
10747
+ }
10748
+ function buildUnknownParamDiagnostics3(unknownCodes) {
10749
+ const validCodes = getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
10750
+ const codes = unknownCodes.join(", ");
10751
+ const isPlural = unknownCodes.length !== 1;
10752
+ return [
10753
+ `Unknown search ${isPlural ? "parameters" : "parameter"} for Condition: ${codes}.`,
10754
+ `Valid codes: ${validCodes}.`
10755
+ ].join(" ");
10756
+ }
10757
+ function findMalformedReference3(query, searchParamKeys) {
10758
+ const referenceCodes = new Set(
10759
+ getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
10760
+ );
10761
+ for (const { rawKey, code } of searchParamKeys) {
10762
+ if (!referenceCodes.has(code)) {
10763
+ continue;
10764
+ }
10765
+ const raw = query[rawKey];
10766
+ const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
10767
+ for (const v of values) {
10768
+ const trimmed = v.trim();
10769
+ if (trimmed.length === 0) {
10770
+ continue;
10771
+ }
10772
+ if (parseTypedReference(trimmed) === void 0) {
10773
+ return { rawKey, value: trimmed };
10774
+ }
10775
+ }
10776
+ }
10777
+ return void 0;
10778
+ }
10779
+ async function listConditionsRoute(req, res) {
10780
+ const searchParamKeys = extractSearchParamKeys3(
10781
+ req.query
10522
10782
  );
10523
- }
10524
-
10525
- // src/data/rest-api/routes/data/condition/condition-get-by-id-route.ts
10526
- async function getConditionByIdRoute(req, res) {
10527
- const id = String(req.params.id);
10783
+ if (searchParamKeys.length === 0) {
10784
+ return handleListRoute({
10785
+ req,
10786
+ res,
10787
+ basePath: BASE_PATH.CONDITION,
10788
+ listOperation: listConditionsOperation,
10789
+ errorLogContext: "GET /Condition list error:"
10790
+ });
10791
+ }
10792
+ const registered = getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE);
10793
+ const validCodes = new Set(registered.map((p) => p.code));
10794
+ const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
10795
+ if (unknownCodes.length > 0) {
10796
+ return sendInvalidSearch4003(
10797
+ res,
10798
+ buildUnknownParamDiagnostics3([...new Set(unknownCodes)])
10799
+ );
10800
+ }
10801
+ const malformedRef = findMalformedReference3(
10802
+ req.query,
10803
+ searchParamKeys
10804
+ );
10805
+ if (malformedRef !== void 0) {
10806
+ return sendInvalidSearch4003(
10807
+ res,
10808
+ `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
10809
+ );
10810
+ }
10528
10811
  const ctx = req.openhiContext;
10529
10812
  try {
10530
- const result = await getConditionByIdOperation({ context: ctx, id });
10531
- return res.json(result.resource);
10813
+ const result = await genericSearchOperation({
10814
+ resourceType: CONDITION_RESOURCE_TYPE,
10815
+ tenantId: ctx.tenantId,
10816
+ workspaceId: ctx.workspaceId,
10817
+ query: req.query,
10818
+ resolver: defaultSearchParameterResolver
10819
+ });
10820
+ const bundle = buildSearchsetBundle(BASE_PATH.CONDITION, result.entries);
10821
+ return res.json(bundle);
10532
10822
  } catch (err) {
10533
- const status = domainErrorToHttpStatus(err);
10534
- if (status === 404) {
10535
- const diagnostics = err instanceof NotFoundError ? err.message : `Condition ${id} not found`;
10536
- return sendOperationOutcome404(res, diagnostics);
10537
- }
10538
- return sendOperationOutcome500(res, err, "GET Condition error:");
10823
+ return sendOperationOutcome500(res, err, "GET /Condition search error:");
10539
10824
  }
10540
10825
  }
10541
10826
 
10542
- // src/data/operations/data/condition/condition-list-operation.ts
10543
- async function listConditionsOperation(params) {
10544
- const { context, tableName, mode } = params;
10545
- const { tenantId, workspaceId } = context;
10546
- const service = getDynamoDataService(tableName);
10547
- return listDataEntitiesByWorkspace(
10548
- service.entities.condition,
10549
- tenantId,
10550
- workspaceId,
10551
- mode
10552
- );
10553
- }
10554
-
10555
- // src/data/rest-api/routes/data/condition/condition-list-route.ts
10556
- async function listConditionsRoute(req, res) {
10557
- return handleListRoute({
10558
- req,
10559
- res,
10560
- basePath: BASE_PATH.CONDITION,
10561
- listOperation: listConditionsOperation,
10562
- errorLogContext: "GET /Condition list error:"
10563
- });
10564
- }
10565
-
10566
10827
  // src/data/operations/data/condition/condition-update-operation.ts
10567
10828
  async function updateConditionOperation(params) {
10568
10829
  const { context, id, body, tableName } = params;
@@ -13789,30 +14050,30 @@ async function listEncountersOperation(params) {
13789
14050
 
13790
14051
  // src/data/rest-api/routes/data/encounter/encounter-list-route.ts
13791
14052
  var ENCOUNTER_RESOURCE_TYPE = "Encounter";
13792
- function stripModifier2(key) {
14053
+ function stripModifier4(key) {
13793
14054
  const idx = key.indexOf(":");
13794
14055
  return idx === -1 ? key : key.slice(0, idx);
13795
14056
  }
13796
- function isResultParameter2(key) {
14057
+ function isResultParameter4(key) {
13797
14058
  return key.startsWith("_");
13798
14059
  }
13799
- function sendInvalidSearch4002(res, diagnostics) {
14060
+ function sendInvalidSearch4004(res, diagnostics) {
13800
14061
  return res.status(400).json({
13801
14062
  resourceType: "OperationOutcome",
13802
14063
  issue: [{ severity: "error", code: "invalid", diagnostics }]
13803
14064
  });
13804
14065
  }
13805
- function extractSearchParamKeys2(query) {
14066
+ function extractSearchParamKeys4(query) {
13806
14067
  const out = [];
13807
14068
  for (const rawKey of Object.keys(query)) {
13808
- if (isResultParameter2(rawKey)) {
14069
+ if (isResultParameter4(rawKey)) {
13809
14070
  continue;
13810
14071
  }
13811
- out.push({ rawKey, code: stripModifier2(rawKey) });
14072
+ out.push({ rawKey, code: stripModifier4(rawKey) });
13812
14073
  }
13813
14074
  return out;
13814
14075
  }
13815
- function buildUnknownParamDiagnostics2(unknownCodes) {
14076
+ function buildUnknownParamDiagnostics4(unknownCodes) {
13816
14077
  const validCodes = getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
13817
14078
  const codes = unknownCodes.join(", ");
13818
14079
  const isPlural = unknownCodes.length !== 1;
@@ -13821,7 +14082,7 @@ function buildUnknownParamDiagnostics2(unknownCodes) {
13821
14082
  `Valid codes: ${validCodes}.`
13822
14083
  ].join(" ");
13823
14084
  }
13824
- function findMalformedReference2(query, searchParamKeys) {
14085
+ function findMalformedReference4(query, searchParamKeys) {
13825
14086
  const referenceCodes = new Set(
13826
14087
  getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
13827
14088
  );
@@ -13844,7 +14105,7 @@ function findMalformedReference2(query, searchParamKeys) {
13844
14105
  return void 0;
13845
14106
  }
13846
14107
  async function listEncountersRoute(req, res) {
13847
- const searchParamKeys = extractSearchParamKeys2(
14108
+ const searchParamKeys = extractSearchParamKeys4(
13848
14109
  req.query
13849
14110
  );
13850
14111
  if (searchParamKeys.length === 0) {
@@ -13860,17 +14121,17 @@ async function listEncountersRoute(req, res) {
13860
14121
  const validCodes = new Set(registered.map((p) => p.code));
13861
14122
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
13862
14123
  if (unknownCodes.length > 0) {
13863
- return sendInvalidSearch4002(
14124
+ return sendInvalidSearch4004(
13864
14125
  res,
13865
- buildUnknownParamDiagnostics2([...new Set(unknownCodes)])
14126
+ buildUnknownParamDiagnostics4([...new Set(unknownCodes)])
13866
14127
  );
13867
14128
  }
13868
- const malformedRef = findMalformedReference2(
14129
+ const malformedRef = findMalformedReference4(
13869
14130
  req.query,
13870
14131
  searchParamKeys
13871
14132
  );
13872
14133
  if (malformedRef !== void 0) {
13873
- return sendInvalidSearch4002(
14134
+ return sendInvalidSearch4004(
13874
14135
  res,
13875
14136
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
13876
14137
  );
@@ -15914,15 +16175,119 @@ async function listFamilyMemberHistorysOperation(params) {
15914
16175
  }
15915
16176
 
15916
16177
  // src/data/rest-api/routes/data/familymemberhistory/familymemberhistory-list-route.ts
15917
- async function listFamilyMemberHistorysRoute(req, res) {
15918
- return handleListRoute({
15919
- req,
15920
- res,
15921
- basePath: BASE_PATH.FAMILYMEMBERHISTORY,
15922
- listOperation: listFamilyMemberHistorysOperation,
15923
- errorLogContext: "GET /FamilyMemberHistory list error:"
16178
+ var FAMILYMEMBERHISTORY_RESOURCE_TYPE = "FamilyMemberHistory";
16179
+ function stripModifier5(key) {
16180
+ const idx = key.indexOf(":");
16181
+ return idx === -1 ? key : key.slice(0, idx);
16182
+ }
16183
+ function isResultParameter5(key) {
16184
+ return key.startsWith("_");
16185
+ }
16186
+ function sendInvalidSearch4005(res, diagnostics) {
16187
+ return res.status(400).json({
16188
+ resourceType: "OperationOutcome",
16189
+ issue: [{ severity: "error", code: "invalid", diagnostics }]
15924
16190
  });
15925
16191
  }
16192
+ function extractSearchParamKeys5(query) {
16193
+ const out = [];
16194
+ for (const rawKey of Object.keys(query)) {
16195
+ if (isResultParameter5(rawKey)) {
16196
+ continue;
16197
+ }
16198
+ out.push({ rawKey, code: stripModifier5(rawKey) });
16199
+ }
16200
+ return out;
16201
+ }
16202
+ function buildUnknownParamDiagnostics5(unknownCodes) {
16203
+ const validCodes = getRegisteredSearchParameters(
16204
+ FAMILYMEMBERHISTORY_RESOURCE_TYPE
16205
+ ).map((p) => p.code).sort().join(", ");
16206
+ const codes = unknownCodes.join(", ");
16207
+ const isPlural = unknownCodes.length !== 1;
16208
+ return [
16209
+ `Unknown search ${isPlural ? "parameters" : "parameter"} for FamilyMemberHistory: ${codes}.`,
16210
+ `Valid codes: ${validCodes}.`
16211
+ ].join(" ");
16212
+ }
16213
+ function findMalformedReference5(query, searchParamKeys) {
16214
+ const referenceCodes = new Set(
16215
+ getRegisteredSearchParameters(FAMILYMEMBERHISTORY_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
16216
+ );
16217
+ for (const { rawKey, code } of searchParamKeys) {
16218
+ if (!referenceCodes.has(code)) {
16219
+ continue;
16220
+ }
16221
+ const raw = query[rawKey];
16222
+ const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
16223
+ for (const v of values) {
16224
+ const trimmed = v.trim();
16225
+ if (trimmed.length === 0) {
16226
+ continue;
16227
+ }
16228
+ if (parseTypedReference(trimmed) === void 0) {
16229
+ return { rawKey, value: trimmed };
16230
+ }
16231
+ }
16232
+ }
16233
+ return void 0;
16234
+ }
16235
+ async function listFamilyMemberHistorysRoute(req, res) {
16236
+ const searchParamKeys = extractSearchParamKeys5(
16237
+ req.query
16238
+ );
16239
+ if (searchParamKeys.length === 0) {
16240
+ return handleListRoute({
16241
+ req,
16242
+ res,
16243
+ basePath: BASE_PATH.FAMILYMEMBERHISTORY,
16244
+ listOperation: listFamilyMemberHistorysOperation,
16245
+ errorLogContext: "GET /FamilyMemberHistory list error:"
16246
+ });
16247
+ }
16248
+ const registered = getRegisteredSearchParameters(
16249
+ FAMILYMEMBERHISTORY_RESOURCE_TYPE
16250
+ );
16251
+ const validCodes = new Set(registered.map((p) => p.code));
16252
+ const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
16253
+ if (unknownCodes.length > 0) {
16254
+ return sendInvalidSearch4005(
16255
+ res,
16256
+ buildUnknownParamDiagnostics5([...new Set(unknownCodes)])
16257
+ );
16258
+ }
16259
+ const malformedRef = findMalformedReference5(
16260
+ req.query,
16261
+ searchParamKeys
16262
+ );
16263
+ if (malformedRef !== void 0) {
16264
+ return sendInvalidSearch4005(
16265
+ res,
16266
+ `?${malformedRef.rawKey} must be a typed reference like "Patient/<id>"; got "${malformedRef.value}".`
16267
+ );
16268
+ }
16269
+ const ctx = req.openhiContext;
16270
+ try {
16271
+ const result = await genericSearchOperation({
16272
+ resourceType: FAMILYMEMBERHISTORY_RESOURCE_TYPE,
16273
+ tenantId: ctx.tenantId,
16274
+ workspaceId: ctx.workspaceId,
16275
+ query: req.query,
16276
+ resolver: defaultSearchParameterResolver
16277
+ });
16278
+ const bundle = buildSearchsetBundle(
16279
+ BASE_PATH.FAMILYMEMBERHISTORY,
16280
+ result.entries
16281
+ );
16282
+ return res.json(bundle);
16283
+ } catch (err) {
16284
+ return sendOperationOutcome500(
16285
+ res,
16286
+ err,
16287
+ "GET /FamilyMemberHistory search error:"
16288
+ );
16289
+ }
16290
+ }
15926
16291
 
15927
16292
  // src/data/operations/data/familymemberhistory/familymemberhistory-update-operation.ts
15928
16293
  async function updateFamilyMemberHistoryOperation(params) {
@@ -24569,30 +24934,30 @@ async function listObservationsOperation(params) {
24569
24934
 
24570
24935
  // src/data/rest-api/routes/data/observation/observation-list-route.ts
24571
24936
  var OBSERVATION_RESOURCE_TYPE = "Observation";
24572
- function stripModifier3(key) {
24937
+ function stripModifier6(key) {
24573
24938
  const idx = key.indexOf(":");
24574
24939
  return idx === -1 ? key : key.slice(0, idx);
24575
24940
  }
24576
- function isResultParameter3(key) {
24941
+ function isResultParameter6(key) {
24577
24942
  return key.startsWith("_");
24578
24943
  }
24579
- function sendInvalidSearch4003(res, diagnostics) {
24944
+ function sendInvalidSearch4006(res, diagnostics) {
24580
24945
  return res.status(400).json({
24581
24946
  resourceType: "OperationOutcome",
24582
24947
  issue: [{ severity: "error", code: "invalid", diagnostics }]
24583
24948
  });
24584
24949
  }
24585
- function extractSearchParamKeys3(query) {
24950
+ function extractSearchParamKeys6(query) {
24586
24951
  const out = [];
24587
24952
  for (const rawKey of Object.keys(query)) {
24588
- if (isResultParameter3(rawKey)) {
24953
+ if (isResultParameter6(rawKey)) {
24589
24954
  continue;
24590
24955
  }
24591
- out.push({ rawKey, code: stripModifier3(rawKey) });
24956
+ out.push({ rawKey, code: stripModifier6(rawKey) });
24592
24957
  }
24593
24958
  return out;
24594
24959
  }
24595
- function buildUnknownParamDiagnostics3(unknownCodes) {
24960
+ function buildUnknownParamDiagnostics6(unknownCodes) {
24596
24961
  const validCodes = getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
24597
24962
  const codes = unknownCodes.join(", ");
24598
24963
  const isPlural = unknownCodes.length !== 1;
@@ -24601,7 +24966,7 @@ function buildUnknownParamDiagnostics3(unknownCodes) {
24601
24966
  `Valid codes: ${validCodes}.`
24602
24967
  ].join(" ");
24603
24968
  }
24604
- function findMalformedReference3(query, searchParamKeys) {
24969
+ function findMalformedReference6(query, searchParamKeys) {
24605
24970
  const referenceCodes = new Set(
24606
24971
  getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
24607
24972
  );
@@ -24624,7 +24989,7 @@ function findMalformedReference3(query, searchParamKeys) {
24624
24989
  return void 0;
24625
24990
  }
24626
24991
  async function listObservationsRoute(req, res) {
24627
- const searchParamKeys = extractSearchParamKeys3(
24992
+ const searchParamKeys = extractSearchParamKeys6(
24628
24993
  req.query
24629
24994
  );
24630
24995
  if (searchParamKeys.length === 0) {
@@ -24640,17 +25005,17 @@ async function listObservationsRoute(req, res) {
24640
25005
  const validCodes = new Set(registered.map((p) => p.code));
24641
25006
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
24642
25007
  if (unknownCodes.length > 0) {
24643
- return sendInvalidSearch4003(
25008
+ return sendInvalidSearch4006(
24644
25009
  res,
24645
- buildUnknownParamDiagnostics3([...new Set(unknownCodes)])
25010
+ buildUnknownParamDiagnostics6([...new Set(unknownCodes)])
24646
25011
  );
24647
25012
  }
24648
- const malformedRef = findMalformedReference3(
25013
+ const malformedRef = findMalformedReference6(
24649
25014
  req.query,
24650
25015
  searchParamKeys
24651
25016
  );
24652
25017
  if (malformedRef !== void 0) {
24653
- return sendInvalidSearch4003(
25018
+ return sendInvalidSearch4006(
24654
25019
  res,
24655
25020
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
24656
25021
  );
@@ -25645,30 +26010,30 @@ async function listPatientsOperation(params) {
25645
26010
 
25646
26011
  // src/data/rest-api/routes/data/patient/patient-list-route.ts
25647
26012
  var PATIENT_RESOURCE_TYPE = "Patient";
25648
- function stripModifier4(key) {
26013
+ function stripModifier7(key) {
25649
26014
  const idx = key.indexOf(":");
25650
26015
  return idx === -1 ? key : key.slice(0, idx);
25651
26016
  }
25652
- function isResultParameter4(key) {
26017
+ function isResultParameter7(key) {
25653
26018
  return key.startsWith("_");
25654
26019
  }
25655
- function sendInvalidSearch4004(res, diagnostics) {
26020
+ function sendInvalidSearch4007(res, diagnostics) {
25656
26021
  return res.status(400).json({
25657
26022
  resourceType: "OperationOutcome",
25658
26023
  issue: [{ severity: "error", code: "invalid", diagnostics }]
25659
26024
  });
25660
26025
  }
25661
- function extractSearchParamKeys4(query) {
26026
+ function extractSearchParamKeys7(query) {
25662
26027
  const out = [];
25663
26028
  for (const rawKey of Object.keys(query)) {
25664
- if (isResultParameter4(rawKey)) {
26029
+ if (isResultParameter7(rawKey)) {
25665
26030
  continue;
25666
26031
  }
25667
- out.push({ rawKey, code: stripModifier4(rawKey) });
26032
+ out.push({ rawKey, code: stripModifier7(rawKey) });
25668
26033
  }
25669
26034
  return out;
25670
26035
  }
25671
- function buildUnknownParamDiagnostics4(unknownCodes) {
26036
+ function buildUnknownParamDiagnostics7(unknownCodes) {
25672
26037
  const validCodes = getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
25673
26038
  const codes = unknownCodes.join(", ");
25674
26039
  const isPlural = unknownCodes.length !== 1;
@@ -25677,7 +26042,7 @@ function buildUnknownParamDiagnostics4(unknownCodes) {
25677
26042
  `Valid codes: ${validCodes}.`
25678
26043
  ].join(" ");
25679
26044
  }
25680
- function findMalformedReference4(query, searchParamKeys) {
26045
+ function findMalformedReference7(query, searchParamKeys) {
25681
26046
  const referenceCodes = new Set(
25682
26047
  getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
25683
26048
  );
@@ -25700,7 +26065,7 @@ function findMalformedReference4(query, searchParamKeys) {
25700
26065
  return void 0;
25701
26066
  }
25702
26067
  async function listPatientsRoute(req, res) {
25703
- const searchParamKeys = extractSearchParamKeys4(
26068
+ const searchParamKeys = extractSearchParamKeys7(
25704
26069
  req.query
25705
26070
  );
25706
26071
  if (searchParamKeys.length === 0) {
@@ -25716,17 +26081,17 @@ async function listPatientsRoute(req, res) {
25716
26081
  const validCodes = new Set(registered.map((p) => p.code));
25717
26082
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
25718
26083
  if (unknownCodes.length > 0) {
25719
- return sendInvalidSearch4004(
26084
+ return sendInvalidSearch4007(
25720
26085
  res,
25721
- buildUnknownParamDiagnostics4([...new Set(unknownCodes)])
26086
+ buildUnknownParamDiagnostics7([...new Set(unknownCodes)])
25722
26087
  );
25723
26088
  }
25724
- const malformedRef = findMalformedReference4(
26089
+ const malformedRef = findMalformedReference7(
25725
26090
  req.query,
25726
26091
  searchParamKeys
25727
26092
  );
25728
26093
  if (malformedRef !== void 0) {
25729
- return sendInvalidSearch4004(
26094
+ return sendInvalidSearch4007(
25730
26095
  res,
25731
26096
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
25732
26097
  );
@@ -27066,30 +27431,30 @@ async function listProceduresOperation(params) {
27066
27431
 
27067
27432
  // src/data/rest-api/routes/data/procedure/procedure-list-route.ts
27068
27433
  var PROCEDURE_RESOURCE_TYPE = "Procedure";
27069
- function stripModifier5(key) {
27434
+ function stripModifier8(key) {
27070
27435
  const idx = key.indexOf(":");
27071
27436
  return idx === -1 ? key : key.slice(0, idx);
27072
27437
  }
27073
- function isResultParameter5(key) {
27438
+ function isResultParameter8(key) {
27074
27439
  return key.startsWith("_");
27075
27440
  }
27076
- function sendInvalidSearch4005(res, diagnostics) {
27441
+ function sendInvalidSearch4008(res, diagnostics) {
27077
27442
  return res.status(400).json({
27078
27443
  resourceType: "OperationOutcome",
27079
27444
  issue: [{ severity: "error", code: "invalid", diagnostics }]
27080
27445
  });
27081
27446
  }
27082
- function extractSearchParamKeys5(query) {
27447
+ function extractSearchParamKeys8(query) {
27083
27448
  const out = [];
27084
27449
  for (const rawKey of Object.keys(query)) {
27085
- if (isResultParameter5(rawKey)) {
27450
+ if (isResultParameter8(rawKey)) {
27086
27451
  continue;
27087
27452
  }
27088
- out.push({ rawKey, code: stripModifier5(rawKey) });
27453
+ out.push({ rawKey, code: stripModifier8(rawKey) });
27089
27454
  }
27090
27455
  return out;
27091
27456
  }
27092
- function buildUnknownParamDiagnostics5(unknownCodes) {
27457
+ function buildUnknownParamDiagnostics8(unknownCodes) {
27093
27458
  const validCodes = getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
27094
27459
  const codes = unknownCodes.join(", ");
27095
27460
  const isPlural = unknownCodes.length !== 1;
@@ -27098,7 +27463,7 @@ function buildUnknownParamDiagnostics5(unknownCodes) {
27098
27463
  `Valid codes: ${validCodes}.`
27099
27464
  ].join(" ");
27100
27465
  }
27101
- function findMalformedReference5(query, searchParamKeys) {
27466
+ function findMalformedReference8(query, searchParamKeys) {
27102
27467
  const referenceCodes = new Set(
27103
27468
  getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
27104
27469
  );
@@ -27121,7 +27486,7 @@ function findMalformedReference5(query, searchParamKeys) {
27121
27486
  return void 0;
27122
27487
  }
27123
27488
  async function listProceduresRoute(req, res) {
27124
- const searchParamKeys = extractSearchParamKeys5(
27489
+ const searchParamKeys = extractSearchParamKeys8(
27125
27490
  req.query
27126
27491
  );
27127
27492
  if (searchParamKeys.length === 0) {
@@ -27137,17 +27502,17 @@ async function listProceduresRoute(req, res) {
27137
27502
  const validCodes = new Set(registered.map((p) => p.code));
27138
27503
  const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
27139
27504
  if (unknownCodes.length > 0) {
27140
- return sendInvalidSearch4005(
27505
+ return sendInvalidSearch4008(
27141
27506
  res,
27142
- buildUnknownParamDiagnostics5([...new Set(unknownCodes)])
27507
+ buildUnknownParamDiagnostics8([...new Set(unknownCodes)])
27143
27508
  );
27144
27509
  }
27145
- const malformedRef = findMalformedReference5(
27510
+ const malformedRef = findMalformedReference8(
27146
27511
  req.query,
27147
27512
  searchParamKeys
27148
27513
  );
27149
27514
  if (malformedRef !== void 0) {
27150
- return sendInvalidSearch4005(
27515
+ return sendInvalidSearch4008(
27151
27516
  res,
27152
27517
  `?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
27153
27518
  );
@@ -29674,7 +30039,7 @@ function singleStringQueryParam(req, name) {
29674
30039
  const trimmed = v.trim();
29675
30040
  return trimmed === "" ? void 0 : trimmed;
29676
30041
  }
29677
- function sendInvalidSearch4006(res, diagnostics) {
30042
+ function sendInvalidSearch4009(res, diagnostics) {
29678
30043
  return res.status(400).json({
29679
30044
  resourceType: "OperationOutcome",
29680
30045
  issue: [{ severity: "error", code: "invalid", diagnostics }]
@@ -29684,7 +30049,7 @@ async function listSchedulesRoute(req, res) {
29684
30049
  const actorRef = singleStringQueryParam(req, "actor");
29685
30050
  if (actorRef !== void 0) {
29686
30051
  if (parseTypedReference(actorRef) === void 0) {
29687
- return sendInvalidSearch4006(
30052
+ return sendInvalidSearch4009(
29688
30053
  res,
29689
30054
  `?actor must be a typed reference like "Practitioner/<id>"; got "${actorRef}".`
29690
30055
  );
@@ -33482,7 +33847,7 @@ function singleStringQueryParam2(req, name) {
33482
33847
  const trimmed = v.trim();
33483
33848
  return trimmed === "" ? void 0 : trimmed;
33484
33849
  }
33485
- function sendInvalidSearch4007(res, diagnostics) {
33850
+ function sendInvalidSearch40010(res, diagnostics) {
33486
33851
  return res.status(400).json({
33487
33852
  resourceType: "OperationOutcome",
33488
33853
  issue: [{ severity: "error", code: "invalid", diagnostics }]
@@ -33492,14 +33857,14 @@ async function listTasksRoute(req, res) {
33492
33857
  const ownerRef = singleStringQueryParam2(req, "owner");
33493
33858
  const requesterRef = singleStringQueryParam2(req, "requester");
33494
33859
  if (ownerRef !== void 0 && requesterRef !== void 0) {
33495
- return sendInvalidSearch4007(
33860
+ return sendInvalidSearch40010(
33496
33861
  res,
33497
33862
  "?owner= and ?requester= cannot be combined on the same request."
33498
33863
  );
33499
33864
  }
33500
33865
  if (ownerRef !== void 0) {
33501
33866
  if (parseTypedReference(ownerRef) === void 0) {
33502
- return sendInvalidSearch4007(
33867
+ return sendInvalidSearch40010(
33503
33868
  res,
33504
33869
  `?owner must be a typed reference like "Practitioner/<id>"; got "${ownerRef}".`
33505
33870
  );
@@ -33522,7 +33887,7 @@ async function listTasksRoute(req, res) {
33522
33887
  }
33523
33888
  if (requesterRef !== void 0) {
33524
33889
  if (parseTypedReference(requesterRef) === void 0) {
33525
- return sendInvalidSearch4007(
33890
+ return sendInvalidSearch40010(
33526
33891
  res,
33527
33892
  `?requester must be a typed reference like "Practitioner/<id>"; got "${requesterRef}".`
33528
33893
  );