@openhi/constructs 0.0.142 → 0.0.144
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,129 +5931,516 @@ var ENCOUNTER_SEARCH_PARAMETERS = [
|
|
|
6081
5931
|
}
|
|
6082
5932
|
];
|
|
6083
5933
|
|
|
6084
|
-
// src/data/search/registry/
|
|
6085
|
-
var
|
|
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
|
+
|
|
5945
|
+
// src/data/search/registry/immunization-search-parameters.ts
|
|
5946
|
+
var IMMUNIZATION_SEARCH_PARAMETERS = [
|
|
5947
|
+
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
5948
|
+
{ code: "status-reason", type: "token", jsonbPath: "$.statusReason" },
|
|
5949
|
+
{ code: "vaccine-code", type: "token", jsonbPath: "$.vaccineCode" },
|
|
5950
|
+
{ code: "patient", type: "reference", jsonbPath: "$.patient" },
|
|
5951
|
+
{ code: "date", type: "date", jsonbPath: "$.occurrenceDateTime" },
|
|
5952
|
+
{ code: "performer", type: "reference", jsonbPath: "$.performer[*].actor" },
|
|
5953
|
+
{ code: "location", type: "reference", jsonbPath: "$.location" },
|
|
5954
|
+
{
|
|
5955
|
+
code: "lot-number",
|
|
5956
|
+
type: "string",
|
|
5957
|
+
jsonbPath: "$.lotNumber",
|
|
5958
|
+
modifiers: ["exact", "contains", "missing", "not"]
|
|
5959
|
+
},
|
|
5960
|
+
{ code: "manufacturer", type: "reference", jsonbPath: "$.manufacturer" },
|
|
5961
|
+
{ code: "reaction", type: "reference", jsonbPath: "$.reaction[*].detail" },
|
|
5962
|
+
{ code: "reason-code", type: "token", jsonbPath: "$.reasonCode[*]" },
|
|
5963
|
+
{
|
|
5964
|
+
code: "reason-reference",
|
|
5965
|
+
type: "reference",
|
|
5966
|
+
jsonbPath: "$.reasonReference[*]"
|
|
5967
|
+
},
|
|
5968
|
+
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
|
|
5969
|
+
];
|
|
5970
|
+
|
|
5971
|
+
// src/data/search/registry/medicationrequest-search-parameters.ts
|
|
5972
|
+
var MEDICATIONREQUEST_SEARCH_PARAMETERS = [
|
|
6086
5973
|
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
5974
|
+
{ code: "intent", type: "token", jsonbPath: "$.intent" },
|
|
6087
5975
|
{ code: "category", type: "token", jsonbPath: "$.category[*]" },
|
|
6088
|
-
{ code: "
|
|
5976
|
+
{ code: "priority", type: "token", jsonbPath: "$.priority" },
|
|
5977
|
+
{ code: "code", type: "token", jsonbPath: "$.medicationCodeableConcept" },
|
|
6089
5978
|
{ code: "subject", type: "reference", jsonbPath: "$.subject" },
|
|
6090
5979
|
{ code: "patient", type: "reference", jsonbPath: "$.subject" },
|
|
6091
5980
|
{ code: "encounter", type: "reference", jsonbPath: "$.encounter" },
|
|
6092
|
-
{ code: "
|
|
6093
|
-
{ code: "
|
|
5981
|
+
{ code: "authored-on", type: "date", jsonbPath: "$.authoredOn" },
|
|
5982
|
+
{ code: "requester", type: "reference", jsonbPath: "$.requester" },
|
|
5983
|
+
{ code: "performer", type: "reference", jsonbPath: "$.performer" },
|
|
5984
|
+
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*]" }
|
|
5985
|
+
];
|
|
5986
|
+
|
|
5987
|
+
// src/data/search/registry/medicationstatement-search-parameters.ts
|
|
5988
|
+
var MEDICATIONSTATEMENT_SEARCH_PARAMETERS = [
|
|
5989
|
+
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
5990
|
+
{ code: "category", type: "token", jsonbPath: "$.category" },
|
|
5991
|
+
{ code: "code", type: "token", jsonbPath: "$.medicationCodeableConcept" },
|
|
5992
|
+
{ code: "subject", type: "reference", jsonbPath: "$.subject" },
|
|
5993
|
+
{ code: "patient", type: "reference", jsonbPath: "$.subject" },
|
|
5994
|
+
{ code: "context", type: "reference", jsonbPath: "$.context" },
|
|
5995
|
+
{ code: "effective", type: "date", jsonbPath: "$.effectiveDateTime" },
|
|
6094
5996
|
{
|
|
6095
|
-
code: "
|
|
6096
|
-
type: "
|
|
6097
|
-
jsonbPath: "$.
|
|
6098
|
-
|
|
5997
|
+
code: "information-source",
|
|
5998
|
+
type: "reference",
|
|
5999
|
+
jsonbPath: "$.informationSource"
|
|
6000
|
+
},
|
|
6001
|
+
{
|
|
6002
|
+
code: "medication",
|
|
6003
|
+
type: "reference",
|
|
6004
|
+
jsonbPath: "$.medicationReference"
|
|
6005
|
+
},
|
|
6006
|
+
{ code: "source", type: "reference", jsonbPath: "$.informationSource" },
|
|
6007
|
+
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
|
|
6008
|
+
{ code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" }
|
|
6009
|
+
];
|
|
6010
|
+
|
|
6011
|
+
// src/data/search/registry/observation-search-parameters.ts
|
|
6012
|
+
var OBSERVATION_SEARCH_PARAMETERS = [
|
|
6013
|
+
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
6014
|
+
{ code: "category", type: "token", jsonbPath: "$.category[*]" },
|
|
6015
|
+
{ code: "code", type: "token", jsonbPath: "$.code" },
|
|
6016
|
+
{ code: "subject", type: "reference", jsonbPath: "$.subject" },
|
|
6017
|
+
{ code: "patient", type: "reference", jsonbPath: "$.subject" },
|
|
6018
|
+
{ code: "encounter", type: "reference", jsonbPath: "$.encounter" },
|
|
6019
|
+
{ code: "performer", type: "reference", jsonbPath: "$.performer[*]" },
|
|
6020
|
+
{ code: "date", type: "date", jsonbPath: "$.effectiveDateTime" },
|
|
6021
|
+
{
|
|
6022
|
+
code: "value-string",
|
|
6023
|
+
type: "string",
|
|
6024
|
+
jsonbPath: "$.valueString",
|
|
6025
|
+
modifiers: ["exact", "contains", "missing", "not"]
|
|
6099
6026
|
},
|
|
6100
6027
|
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
|
|
6101
6028
|
{ code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
|
|
6102
6029
|
{ code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" }
|
|
6103
6030
|
];
|
|
6104
6031
|
|
|
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"
|
|
6032
|
+
// src/data/search/registry/patient-search-parameters.ts
|
|
6033
|
+
var PATIENT_SEARCH_PARAMETERS = [
|
|
6034
|
+
{ code: "gender", type: "token", jsonbPath: "$.gender" },
|
|
6035
|
+
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*].value" },
|
|
6036
|
+
{ code: "birthdate", type: "date", jsonbPath: "$.birthDate" },
|
|
6037
|
+
{
|
|
6038
|
+
code: "name",
|
|
6039
|
+
type: "string",
|
|
6040
|
+
jsonbPath: "$.name[*].text",
|
|
6041
|
+
modifiers: ["exact", "contains", "missing", "not"]
|
|
6042
|
+
},
|
|
6043
|
+
{
|
|
6044
|
+
code: "family",
|
|
6045
|
+
type: "string",
|
|
6046
|
+
jsonbPath: "$.name[*].family",
|
|
6047
|
+
modifiers: ["exact", "contains", "missing", "not"]
|
|
6048
|
+
},
|
|
6049
|
+
{
|
|
6050
|
+
code: "given",
|
|
6051
|
+
type: "string",
|
|
6052
|
+
jsonbPath: "$.name[*].given",
|
|
6053
|
+
modifiers: ["exact", "contains", "missing", "not"]
|
|
6054
|
+
},
|
|
6055
|
+
{ code: "active", type: "token", jsonbPath: "$.active" },
|
|
6056
|
+
{ code: "deceased", type: "token", jsonbPath: "$.deceasedBoolean" },
|
|
6057
|
+
{
|
|
6058
|
+
code: "general-practitioner",
|
|
6059
|
+
type: "reference",
|
|
6060
|
+
jsonbPath: "$.generalPractitioner[*]"
|
|
6061
|
+
},
|
|
6062
|
+
{
|
|
6063
|
+
code: "organization",
|
|
6064
|
+
type: "reference",
|
|
6065
|
+
jsonbPath: "$.managingOrganization"
|
|
6066
|
+
}
|
|
6067
|
+
];
|
|
6068
|
+
|
|
6069
|
+
// src/data/search/registry/procedure-search-parameters.ts
|
|
6070
|
+
var PROCEDURE_SEARCH_PARAMETERS = [
|
|
6071
|
+
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
6072
|
+
{ code: "category", type: "token", jsonbPath: "$.category" },
|
|
6073
|
+
{ code: "code", type: "token", jsonbPath: "$.code" },
|
|
6074
|
+
{ code: "subject", type: "reference", jsonbPath: "$.subject" },
|
|
6075
|
+
{ code: "patient", type: "reference", jsonbPath: "$.subject" },
|
|
6076
|
+
{ code: "encounter", type: "reference", jsonbPath: "$.encounter" },
|
|
6077
|
+
{
|
|
6078
|
+
code: "performer",
|
|
6079
|
+
type: "reference",
|
|
6080
|
+
jsonbPath: "$.performer[*].actor"
|
|
6081
|
+
},
|
|
6082
|
+
{ code: "date", type: "date", jsonbPath: "$.performedDateTime" },
|
|
6083
|
+
{ code: "location", type: "reference", jsonbPath: "$.location" },
|
|
6084
|
+
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
|
|
6085
|
+
{ code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
|
|
6086
|
+
{ code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" },
|
|
6087
|
+
{ code: "reason-code", type: "token", jsonbPath: "$.reasonCode[*]" },
|
|
6088
|
+
{
|
|
6089
|
+
code: "reason-reference",
|
|
6090
|
+
type: "reference",
|
|
6091
|
+
jsonbPath: "$.reasonReference[*]"
|
|
6092
|
+
}
|
|
6093
|
+
];
|
|
6094
|
+
|
|
6095
|
+
// src/data/search/registry/resolver.ts
|
|
6096
|
+
var STATIC_SEARCH_PARAMETER_MAP = {
|
|
6097
|
+
AllergyIntolerance: ALLERGYINTOLERANCE_SEARCH_PARAMETERS,
|
|
6098
|
+
Appointment: APPOINTMENT_SEARCH_PARAMETERS,
|
|
6099
|
+
Condition: CONDITION_SEARCH_PARAMETERS,
|
|
6100
|
+
Encounter: ENCOUNTER_SEARCH_PARAMETERS,
|
|
6101
|
+
FamilyMemberHistory: FAMILYMEMBERHISTORY_SEARCH_PARAMETERS,
|
|
6102
|
+
Immunization: IMMUNIZATION_SEARCH_PARAMETERS,
|
|
6103
|
+
MedicationRequest: MEDICATIONREQUEST_SEARCH_PARAMETERS,
|
|
6104
|
+
MedicationStatement: MEDICATIONSTATEMENT_SEARCH_PARAMETERS,
|
|
6105
|
+
Observation: OBSERVATION_SEARCH_PARAMETERS,
|
|
6106
|
+
Patient: PATIENT_SEARCH_PARAMETERS,
|
|
6107
|
+
Procedure: PROCEDURE_SEARCH_PARAMETERS
|
|
6108
|
+
};
|
|
6109
|
+
var defaultSearchParameterResolver = (resourceType, _tenantId) => STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
|
|
6110
|
+
function getRegisteredSearchParameters(resourceType) {
|
|
6111
|
+
return STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
|
|
6112
|
+
}
|
|
6113
|
+
|
|
6114
|
+
// src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-list-route.ts
|
|
6115
|
+
var ALLERGYINTOLERANCE_RESOURCE_TYPE = "AllergyIntolerance";
|
|
6116
|
+
function stripModifier(key) {
|
|
6117
|
+
const idx = key.indexOf(":");
|
|
6118
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
6119
|
+
}
|
|
6120
|
+
function isResultParameter(key) {
|
|
6121
|
+
return key.startsWith("_");
|
|
6122
|
+
}
|
|
6123
|
+
function sendInvalidSearch400(res, diagnostics) {
|
|
6124
|
+
return res.status(400).json({
|
|
6125
|
+
resourceType: "OperationOutcome",
|
|
6126
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
6127
|
+
});
|
|
6128
|
+
}
|
|
6129
|
+
function extractSearchParamKeys(query) {
|
|
6130
|
+
const out = [];
|
|
6131
|
+
for (const rawKey of Object.keys(query)) {
|
|
6132
|
+
if (isResultParameter(rawKey)) {
|
|
6133
|
+
continue;
|
|
6134
|
+
}
|
|
6135
|
+
out.push({ rawKey, code: stripModifier(rawKey) });
|
|
6136
|
+
}
|
|
6137
|
+
return out;
|
|
6138
|
+
}
|
|
6139
|
+
function buildUnknownParamDiagnostics(unknownCodes) {
|
|
6140
|
+
const validCodes = getRegisteredSearchParameters(
|
|
6141
|
+
ALLERGYINTOLERANCE_RESOURCE_TYPE
|
|
6142
|
+
).map((p) => p.code).sort().join(", ");
|
|
6143
|
+
const codes = unknownCodes.join(", ");
|
|
6144
|
+
const isPlural = unknownCodes.length !== 1;
|
|
6145
|
+
return [
|
|
6146
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for AllergyIntolerance: ${codes}.`,
|
|
6147
|
+
`Valid codes: ${validCodes}.`
|
|
6148
|
+
].join(" ");
|
|
6149
|
+
}
|
|
6150
|
+
function findMalformedReference(query, searchParamKeys) {
|
|
6151
|
+
const referenceCodes = new Set(
|
|
6152
|
+
getRegisteredSearchParameters(ALLERGYINTOLERANCE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
6153
|
+
);
|
|
6154
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
6155
|
+
if (!referenceCodes.has(code)) {
|
|
6156
|
+
continue;
|
|
6157
|
+
}
|
|
6158
|
+
const raw = query[rawKey];
|
|
6159
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
6160
|
+
for (const v of values) {
|
|
6161
|
+
const trimmed = v.trim();
|
|
6162
|
+
if (trimmed.length === 0) {
|
|
6163
|
+
continue;
|
|
6164
|
+
}
|
|
6165
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
6166
|
+
return { rawKey, value: trimmed };
|
|
6167
|
+
}
|
|
6168
|
+
}
|
|
6169
|
+
}
|
|
6170
|
+
return void 0;
|
|
6171
|
+
}
|
|
6172
|
+
async function listAllergyIntolerancesRoute(req, res) {
|
|
6173
|
+
const searchParamKeys = extractSearchParamKeys(
|
|
6174
|
+
req.query
|
|
6175
|
+
);
|
|
6176
|
+
if (searchParamKeys.length === 0) {
|
|
6177
|
+
return handleListRoute({
|
|
6178
|
+
req,
|
|
6179
|
+
res,
|
|
6180
|
+
basePath: BASE_PATH.ALLERGYINTOLERANCE,
|
|
6181
|
+
listOperation: listAllergyIntolerancesOperation,
|
|
6182
|
+
errorLogContext: "GET /AllergyIntolerance list error:"
|
|
6183
|
+
});
|
|
6184
|
+
}
|
|
6185
|
+
const registered = getRegisteredSearchParameters(
|
|
6186
|
+
ALLERGYINTOLERANCE_RESOURCE_TYPE
|
|
6187
|
+
);
|
|
6188
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
6189
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
6190
|
+
if (unknownCodes.length > 0) {
|
|
6191
|
+
return sendInvalidSearch400(
|
|
6192
|
+
res,
|
|
6193
|
+
buildUnknownParamDiagnostics([...new Set(unknownCodes)])
|
|
6194
|
+
);
|
|
6195
|
+
}
|
|
6196
|
+
const malformedRef = findMalformedReference(
|
|
6197
|
+
req.query,
|
|
6198
|
+
searchParamKeys
|
|
6199
|
+
);
|
|
6200
|
+
if (malformedRef !== void 0) {
|
|
6201
|
+
return sendInvalidSearch400(
|
|
6202
|
+
res,
|
|
6203
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
6204
|
+
);
|
|
6205
|
+
}
|
|
6206
|
+
const ctx = req.openhiContext;
|
|
6207
|
+
try {
|
|
6208
|
+
const result = await genericSearchOperation({
|
|
6209
|
+
resourceType: ALLERGYINTOLERANCE_RESOURCE_TYPE,
|
|
6210
|
+
tenantId: ctx.tenantId,
|
|
6211
|
+
workspaceId: ctx.workspaceId,
|
|
6212
|
+
query: req.query,
|
|
6213
|
+
resolver: defaultSearchParameterResolver
|
|
6214
|
+
});
|
|
6215
|
+
const bundle = buildSearchsetBundle(
|
|
6216
|
+
BASE_PATH.ALLERGYINTOLERANCE,
|
|
6217
|
+
result.entries
|
|
6218
|
+
);
|
|
6219
|
+
return res.json(bundle);
|
|
6220
|
+
} catch (err) {
|
|
6221
|
+
return sendOperationOutcome500(
|
|
6222
|
+
res,
|
|
6223
|
+
err,
|
|
6224
|
+
"GET /AllergyIntolerance search error:"
|
|
6225
|
+
);
|
|
6226
|
+
}
|
|
6227
|
+
}
|
|
6228
|
+
|
|
6229
|
+
// src/data/operations/data/allergyintolerance/allergyintolerance-update-operation.ts
|
|
6230
|
+
async function updateAllergyIntoleranceOperation(params) {
|
|
6231
|
+
const { context, id, body, tableName } = params;
|
|
6232
|
+
const { tenantId, workspaceId, date, actorId, actorName } = context;
|
|
6233
|
+
const service = getDynamoDataService(tableName);
|
|
6234
|
+
return updateDataEntityById(
|
|
6235
|
+
service.entities.allergyintolerance,
|
|
6236
|
+
tenantId,
|
|
6237
|
+
workspaceId,
|
|
6238
|
+
id,
|
|
6239
|
+
"AllergyIntolerance",
|
|
6240
|
+
context,
|
|
6241
|
+
(existingResourceStr) => buildUpdatedResourceWithAudit(
|
|
6242
|
+
body,
|
|
6243
|
+
id,
|
|
6244
|
+
date,
|
|
6245
|
+
actorId,
|
|
6246
|
+
actorName,
|
|
6247
|
+
existingResourceStr,
|
|
6248
|
+
"AllergyIntolerance"
|
|
6249
|
+
)
|
|
6250
|
+
);
|
|
6251
|
+
}
|
|
6252
|
+
|
|
6253
|
+
// src/data/rest-api/routes/data/allergyintolerance/allergyintolerance-update-route.ts
|
|
6254
|
+
async function updateAllergyIntoleranceRoute(req, res) {
|
|
6255
|
+
const bodyResult = requireJsonBodyAs(req, res);
|
|
6256
|
+
if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
|
|
6257
|
+
const id = String(req.params.id);
|
|
6258
|
+
const ctx = req.openhiContext;
|
|
6259
|
+
const body = bodyResult.body;
|
|
6260
|
+
const resource = {
|
|
6261
|
+
...body,
|
|
6262
|
+
resourceType: "AllergyIntolerance",
|
|
6263
|
+
id
|
|
6264
|
+
};
|
|
6265
|
+
try {
|
|
6266
|
+
const result = await updateAllergyIntoleranceOperation({
|
|
6267
|
+
context: ctx,
|
|
6268
|
+
id,
|
|
6269
|
+
body: resource
|
|
6270
|
+
});
|
|
6271
|
+
return res.json(result.resource);
|
|
6272
|
+
} catch (err) {
|
|
6273
|
+
const status = domainErrorToHttpStatus(err);
|
|
6274
|
+
if (status === 404) {
|
|
6275
|
+
const diagnostics = err instanceof NotFoundError ? err.message : `AllergyIntolerance ${id} not found`;
|
|
6276
|
+
return sendOperationOutcome404(res, diagnostics);
|
|
6277
|
+
}
|
|
6278
|
+
return sendOperationOutcome500(res, err, "PUT AllergyIntolerance error:");
|
|
6279
|
+
}
|
|
6280
|
+
}
|
|
6281
|
+
|
|
6282
|
+
// src/data/rest-api/routes/data/allergyintolerance/allergyintolerance.ts
|
|
6283
|
+
var router13 = express13.Router();
|
|
6284
|
+
router13.get("/", listAllergyIntolerancesRoute);
|
|
6285
|
+
router13.get("/:id", getAllergyIntoleranceByIdRoute);
|
|
6286
|
+
router13.post("/", createAllergyIntoleranceRoute);
|
|
6287
|
+
router13.put("/:id", updateAllergyIntoleranceRoute);
|
|
6288
|
+
router13.delete("/:id", deleteAllergyIntoleranceRoute);
|
|
6289
|
+
|
|
6290
|
+
// src/data/rest-api/routes/data/appointment/appointment.ts
|
|
6291
|
+
import express14 from "express";
|
|
6292
|
+
|
|
6293
|
+
// src/data/operations/data/appointment/appointment-create-operation.ts
|
|
6294
|
+
import { ulid as ulid5 } from "ulid";
|
|
6295
|
+
async function createAppointmentOperation(params) {
|
|
6296
|
+
const { context, body, tableName } = params;
|
|
6297
|
+
const { tenantId, workspaceId, date, actorId, actorName } = context;
|
|
6298
|
+
const id = body.id ?? ulid5();
|
|
6299
|
+
const meta = {
|
|
6300
|
+
...body.meta ?? {},
|
|
6301
|
+
lastUpdated: date,
|
|
6302
|
+
versionId: "1"
|
|
6303
|
+
};
|
|
6304
|
+
const resourceWithAudit = {
|
|
6305
|
+
...body,
|
|
6306
|
+
resourceType: "Appointment",
|
|
6307
|
+
id,
|
|
6308
|
+
meta: mergeAuditIntoMeta(meta, {
|
|
6309
|
+
createdDate: date,
|
|
6310
|
+
createdById: actorId,
|
|
6311
|
+
createdByName: actorName,
|
|
6312
|
+
modifiedDate: date,
|
|
6313
|
+
modifiedById: actorId,
|
|
6314
|
+
modifiedByName: actorName
|
|
6315
|
+
})
|
|
6316
|
+
};
|
|
6317
|
+
const service = getDynamoDataService(tableName);
|
|
6318
|
+
return createDataEntityRecord(
|
|
6319
|
+
service.entities.appointment,
|
|
6320
|
+
tenantId,
|
|
6321
|
+
workspaceId,
|
|
6322
|
+
id,
|
|
6323
|
+
resourceWithAudit,
|
|
6324
|
+
date
|
|
6325
|
+
);
|
|
6326
|
+
}
|
|
6327
|
+
|
|
6328
|
+
// src/data/rest-api/routes/data/appointment/appointment-create-route.ts
|
|
6329
|
+
async function createAppointmentRoute(req, res) {
|
|
6330
|
+
const bodyResult = requireJsonBodyAs(req, res);
|
|
6331
|
+
if ("errorResponse" in bodyResult) return bodyResult.errorResponse;
|
|
6332
|
+
const ctx = req.openhiContext;
|
|
6333
|
+
const body = bodyResult.body;
|
|
6334
|
+
const resource = {
|
|
6335
|
+
...body,
|
|
6336
|
+
resourceType: "Appointment"
|
|
6337
|
+
};
|
|
6338
|
+
try {
|
|
6339
|
+
const result = await createAppointmentOperation({
|
|
6340
|
+
context: ctx,
|
|
6341
|
+
body: resource
|
|
6342
|
+
});
|
|
6343
|
+
return res.status(201).location(`${BASE_PATH.APPOINTMENT}/${result.id}`).json(result.resource);
|
|
6344
|
+
} catch (err) {
|
|
6345
|
+
return sendOperationOutcome500(res, err, "POST Appointment error:");
|
|
6346
|
+
}
|
|
6347
|
+
}
|
|
6348
|
+
|
|
6349
|
+
// src/data/operations/data/appointment/appointment-delete-operation.ts
|
|
6350
|
+
async function deleteAppointmentOperation(params) {
|
|
6351
|
+
const { context, id, tableName } = params;
|
|
6352
|
+
const { tenantId, workspaceId } = context;
|
|
6353
|
+
const service = getDynamoDataService(tableName);
|
|
6354
|
+
await deleteDataEntityById(
|
|
6355
|
+
service.entities.appointment,
|
|
6356
|
+
tenantId,
|
|
6357
|
+
workspaceId,
|
|
6358
|
+
id
|
|
6359
|
+
);
|
|
6360
|
+
}
|
|
6361
|
+
|
|
6362
|
+
// src/data/rest-api/routes/data/appointment/appointment-delete-route.ts
|
|
6363
|
+
async function deleteAppointmentRoute(req, res) {
|
|
6364
|
+
const id = String(req.params.id);
|
|
6365
|
+
const ctx = req.openhiContext;
|
|
6366
|
+
try {
|
|
6367
|
+
await deleteAppointmentOperation({ context: ctx, id });
|
|
6368
|
+
return res.status(204).send();
|
|
6369
|
+
} catch (err) {
|
|
6370
|
+
return sendOperationOutcome500(res, err, "DELETE Appointment error:");
|
|
6139
6371
|
}
|
|
6140
|
-
|
|
6372
|
+
}
|
|
6141
6373
|
|
|
6142
|
-
// src/data/
|
|
6143
|
-
|
|
6144
|
-
{
|
|
6145
|
-
{
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
{
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6374
|
+
// src/data/operations/data/appointment/appointment-get-by-id-operation.ts
|
|
6375
|
+
async function getAppointmentByIdOperation(params) {
|
|
6376
|
+
const { context, id, tableName } = params;
|
|
6377
|
+
const { tenantId, workspaceId } = context;
|
|
6378
|
+
const service = getDynamoDataService(tableName);
|
|
6379
|
+
return getDataEntityById(
|
|
6380
|
+
service.entities.appointment,
|
|
6381
|
+
tenantId,
|
|
6382
|
+
workspaceId,
|
|
6383
|
+
id,
|
|
6384
|
+
"Appointment"
|
|
6385
|
+
);
|
|
6386
|
+
}
|
|
6387
|
+
|
|
6388
|
+
// src/data/rest-api/routes/data/appointment/appointment-get-by-id-route.ts
|
|
6389
|
+
async function getAppointmentByIdRoute(req, res) {
|
|
6390
|
+
const id = String(req.params.id);
|
|
6391
|
+
const ctx = req.openhiContext;
|
|
6392
|
+
try {
|
|
6393
|
+
const result = await getAppointmentByIdOperation({ context: ctx, id });
|
|
6394
|
+
return res.json(result.resource);
|
|
6395
|
+
} catch (err) {
|
|
6396
|
+
const status = domainErrorToHttpStatus(err);
|
|
6397
|
+
if (status === 404) {
|
|
6398
|
+
const diagnostics = err instanceof NotFoundError ? err.message : `Appointment ${id} not found`;
|
|
6399
|
+
return sendOperationOutcome404(res, diagnostics);
|
|
6400
|
+
}
|
|
6401
|
+
return sendOperationOutcome500(res, err, "GET Appointment error:");
|
|
6165
6402
|
}
|
|
6166
|
-
|
|
6403
|
+
}
|
|
6167
6404
|
|
|
6168
|
-
// src/data/
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6405
|
+
// src/data/operations/data/appointment/appointment-list-operation.ts
|
|
6406
|
+
async function listAppointmentsOperation(params) {
|
|
6407
|
+
const { context, tableName, mode } = params;
|
|
6408
|
+
const { tenantId, workspaceId } = context;
|
|
6409
|
+
const service = getDynamoDataService(tableName);
|
|
6410
|
+
return listDataEntitiesByWorkspace(
|
|
6411
|
+
service.entities.appointment,
|
|
6412
|
+
tenantId,
|
|
6413
|
+
workspaceId,
|
|
6414
|
+
mode
|
|
6415
|
+
);
|
|
6179
6416
|
}
|
|
6180
6417
|
|
|
6181
6418
|
// src/data/rest-api/routes/data/appointment/appointment-list-route.ts
|
|
6182
6419
|
var APPOINTMENT_RESOURCE_TYPE = "Appointment";
|
|
6183
|
-
function
|
|
6420
|
+
function stripModifier2(key) {
|
|
6184
6421
|
const idx = key.indexOf(":");
|
|
6185
6422
|
return idx === -1 ? key : key.slice(0, idx);
|
|
6186
6423
|
}
|
|
6187
|
-
function
|
|
6424
|
+
function isResultParameter2(key) {
|
|
6188
6425
|
return key.startsWith("_");
|
|
6189
6426
|
}
|
|
6190
|
-
function
|
|
6427
|
+
function sendInvalidSearch4002(res, diagnostics) {
|
|
6191
6428
|
return res.status(400).json({
|
|
6192
6429
|
resourceType: "OperationOutcome",
|
|
6193
6430
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
6194
6431
|
});
|
|
6195
6432
|
}
|
|
6196
|
-
function
|
|
6433
|
+
function extractSearchParamKeys2(query) {
|
|
6197
6434
|
const out = [];
|
|
6198
6435
|
for (const rawKey of Object.keys(query)) {
|
|
6199
|
-
if (
|
|
6436
|
+
if (isResultParameter2(rawKey)) {
|
|
6200
6437
|
continue;
|
|
6201
6438
|
}
|
|
6202
|
-
out.push({ rawKey, code:
|
|
6439
|
+
out.push({ rawKey, code: stripModifier2(rawKey) });
|
|
6203
6440
|
}
|
|
6204
6441
|
return out;
|
|
6205
6442
|
}
|
|
6206
|
-
function
|
|
6443
|
+
function buildUnknownParamDiagnostics2(unknownCodes) {
|
|
6207
6444
|
const validCodes = getRegisteredSearchParameters(APPOINTMENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
6208
6445
|
const codes = unknownCodes.join(", ");
|
|
6209
6446
|
const isPlural = unknownCodes.length !== 1;
|
|
@@ -6212,7 +6449,7 @@ function buildUnknownParamDiagnostics(unknownCodes) {
|
|
|
6212
6449
|
`Valid codes: ${validCodes}.`
|
|
6213
6450
|
].join(" ");
|
|
6214
6451
|
}
|
|
6215
|
-
function
|
|
6452
|
+
function findMalformedReference2(query, searchParamKeys) {
|
|
6216
6453
|
const referenceCodes = new Set(
|
|
6217
6454
|
getRegisteredSearchParameters(APPOINTMENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
6218
6455
|
);
|
|
@@ -6235,7 +6472,7 @@ function findMalformedReference(query, searchParamKeys) {
|
|
|
6235
6472
|
return void 0;
|
|
6236
6473
|
}
|
|
6237
6474
|
async function listAppointmentsRoute(req, res) {
|
|
6238
|
-
const searchParamKeys =
|
|
6475
|
+
const searchParamKeys = extractSearchParamKeys2(
|
|
6239
6476
|
req.query
|
|
6240
6477
|
);
|
|
6241
6478
|
if (searchParamKeys.length === 0) {
|
|
@@ -6251,17 +6488,17 @@ async function listAppointmentsRoute(req, res) {
|
|
|
6251
6488
|
const validCodes = new Set(registered.map((p) => p.code));
|
|
6252
6489
|
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
6253
6490
|
if (unknownCodes.length > 0) {
|
|
6254
|
-
return
|
|
6491
|
+
return sendInvalidSearch4002(
|
|
6255
6492
|
res,
|
|
6256
|
-
|
|
6493
|
+
buildUnknownParamDiagnostics2([...new Set(unknownCodes)])
|
|
6257
6494
|
);
|
|
6258
6495
|
}
|
|
6259
|
-
const malformedRef =
|
|
6496
|
+
const malformedRef = findMalformedReference2(
|
|
6260
6497
|
req.query,
|
|
6261
6498
|
searchParamKeys
|
|
6262
6499
|
);
|
|
6263
6500
|
if (malformedRef !== void 0) {
|
|
6264
|
-
return
|
|
6501
|
+
return sendInvalidSearch4002(
|
|
6265
6502
|
res,
|
|
6266
6503
|
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
6267
6504
|
);
|
|
@@ -10527,42 +10764,135 @@ async function getConditionByIdRoute(req, res) {
|
|
|
10527
10764
|
const id = String(req.params.id);
|
|
10528
10765
|
const ctx = req.openhiContext;
|
|
10529
10766
|
try {
|
|
10530
|
-
const result = await getConditionByIdOperation({ context: ctx, id });
|
|
10531
|
-
return res.json(result.resource);
|
|
10767
|
+
const result = await getConditionByIdOperation({ context: ctx, id });
|
|
10768
|
+
return res.json(result.resource);
|
|
10769
|
+
} catch (err) {
|
|
10770
|
+
const status = domainErrorToHttpStatus(err);
|
|
10771
|
+
if (status === 404) {
|
|
10772
|
+
const diagnostics = err instanceof NotFoundError ? err.message : `Condition ${id} not found`;
|
|
10773
|
+
return sendOperationOutcome404(res, diagnostics);
|
|
10774
|
+
}
|
|
10775
|
+
return sendOperationOutcome500(res, err, "GET Condition error:");
|
|
10776
|
+
}
|
|
10777
|
+
}
|
|
10778
|
+
|
|
10779
|
+
// src/data/operations/data/condition/condition-list-operation.ts
|
|
10780
|
+
async function listConditionsOperation(params) {
|
|
10781
|
+
const { context, tableName, mode } = params;
|
|
10782
|
+
const { tenantId, workspaceId } = context;
|
|
10783
|
+
const service = getDynamoDataService(tableName);
|
|
10784
|
+
return listDataEntitiesByWorkspace(
|
|
10785
|
+
service.entities.condition,
|
|
10786
|
+
tenantId,
|
|
10787
|
+
workspaceId,
|
|
10788
|
+
mode
|
|
10789
|
+
);
|
|
10790
|
+
}
|
|
10791
|
+
|
|
10792
|
+
// src/data/rest-api/routes/data/condition/condition-list-route.ts
|
|
10793
|
+
var CONDITION_RESOURCE_TYPE = "Condition";
|
|
10794
|
+
function stripModifier3(key) {
|
|
10795
|
+
const idx = key.indexOf(":");
|
|
10796
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
10797
|
+
}
|
|
10798
|
+
function isResultParameter3(key) {
|
|
10799
|
+
return key.startsWith("_");
|
|
10800
|
+
}
|
|
10801
|
+
function sendInvalidSearch4003(res, diagnostics) {
|
|
10802
|
+
return res.status(400).json({
|
|
10803
|
+
resourceType: "OperationOutcome",
|
|
10804
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
10805
|
+
});
|
|
10806
|
+
}
|
|
10807
|
+
function extractSearchParamKeys3(query) {
|
|
10808
|
+
const out = [];
|
|
10809
|
+
for (const rawKey of Object.keys(query)) {
|
|
10810
|
+
if (isResultParameter3(rawKey)) {
|
|
10811
|
+
continue;
|
|
10812
|
+
}
|
|
10813
|
+
out.push({ rawKey, code: stripModifier3(rawKey) });
|
|
10814
|
+
}
|
|
10815
|
+
return out;
|
|
10816
|
+
}
|
|
10817
|
+
function buildUnknownParamDiagnostics3(unknownCodes) {
|
|
10818
|
+
const validCodes = getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
10819
|
+
const codes = unknownCodes.join(", ");
|
|
10820
|
+
const isPlural = unknownCodes.length !== 1;
|
|
10821
|
+
return [
|
|
10822
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for Condition: ${codes}.`,
|
|
10823
|
+
`Valid codes: ${validCodes}.`
|
|
10824
|
+
].join(" ");
|
|
10825
|
+
}
|
|
10826
|
+
function findMalformedReference3(query, searchParamKeys) {
|
|
10827
|
+
const referenceCodes = new Set(
|
|
10828
|
+
getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
10829
|
+
);
|
|
10830
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
10831
|
+
if (!referenceCodes.has(code)) {
|
|
10832
|
+
continue;
|
|
10833
|
+
}
|
|
10834
|
+
const raw = query[rawKey];
|
|
10835
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
10836
|
+
for (const v of values) {
|
|
10837
|
+
const trimmed = v.trim();
|
|
10838
|
+
if (trimmed.length === 0) {
|
|
10839
|
+
continue;
|
|
10840
|
+
}
|
|
10841
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
10842
|
+
return { rawKey, value: trimmed };
|
|
10843
|
+
}
|
|
10844
|
+
}
|
|
10845
|
+
}
|
|
10846
|
+
return void 0;
|
|
10847
|
+
}
|
|
10848
|
+
async function listConditionsRoute(req, res) {
|
|
10849
|
+
const searchParamKeys = extractSearchParamKeys3(
|
|
10850
|
+
req.query
|
|
10851
|
+
);
|
|
10852
|
+
if (searchParamKeys.length === 0) {
|
|
10853
|
+
return handleListRoute({
|
|
10854
|
+
req,
|
|
10855
|
+
res,
|
|
10856
|
+
basePath: BASE_PATH.CONDITION,
|
|
10857
|
+
listOperation: listConditionsOperation,
|
|
10858
|
+
errorLogContext: "GET /Condition list error:"
|
|
10859
|
+
});
|
|
10860
|
+
}
|
|
10861
|
+
const registered = getRegisteredSearchParameters(CONDITION_RESOURCE_TYPE);
|
|
10862
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
10863
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
10864
|
+
if (unknownCodes.length > 0) {
|
|
10865
|
+
return sendInvalidSearch4003(
|
|
10866
|
+
res,
|
|
10867
|
+
buildUnknownParamDiagnostics3([...new Set(unknownCodes)])
|
|
10868
|
+
);
|
|
10869
|
+
}
|
|
10870
|
+
const malformedRef = findMalformedReference3(
|
|
10871
|
+
req.query,
|
|
10872
|
+
searchParamKeys
|
|
10873
|
+
);
|
|
10874
|
+
if (malformedRef !== void 0) {
|
|
10875
|
+
return sendInvalidSearch4003(
|
|
10876
|
+
res,
|
|
10877
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
10878
|
+
);
|
|
10879
|
+
}
|
|
10880
|
+
const ctx = req.openhiContext;
|
|
10881
|
+
try {
|
|
10882
|
+
const result = await genericSearchOperation({
|
|
10883
|
+
resourceType: CONDITION_RESOURCE_TYPE,
|
|
10884
|
+
tenantId: ctx.tenantId,
|
|
10885
|
+
workspaceId: ctx.workspaceId,
|
|
10886
|
+
query: req.query,
|
|
10887
|
+
resolver: defaultSearchParameterResolver
|
|
10888
|
+
});
|
|
10889
|
+
const bundle = buildSearchsetBundle(BASE_PATH.CONDITION, result.entries);
|
|
10890
|
+
return res.json(bundle);
|
|
10532
10891
|
} catch (err) {
|
|
10533
|
-
|
|
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:");
|
|
10892
|
+
return sendOperationOutcome500(res, err, "GET /Condition search error:");
|
|
10539
10893
|
}
|
|
10540
10894
|
}
|
|
10541
10895
|
|
|
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
10896
|
// src/data/operations/data/condition/condition-update-operation.ts
|
|
10567
10897
|
async function updateConditionOperation(params) {
|
|
10568
10898
|
const { context, id, body, tableName } = params;
|
|
@@ -13789,30 +14119,30 @@ async function listEncountersOperation(params) {
|
|
|
13789
14119
|
|
|
13790
14120
|
// src/data/rest-api/routes/data/encounter/encounter-list-route.ts
|
|
13791
14121
|
var ENCOUNTER_RESOURCE_TYPE = "Encounter";
|
|
13792
|
-
function
|
|
14122
|
+
function stripModifier4(key) {
|
|
13793
14123
|
const idx = key.indexOf(":");
|
|
13794
14124
|
return idx === -1 ? key : key.slice(0, idx);
|
|
13795
14125
|
}
|
|
13796
|
-
function
|
|
14126
|
+
function isResultParameter4(key) {
|
|
13797
14127
|
return key.startsWith("_");
|
|
13798
14128
|
}
|
|
13799
|
-
function
|
|
14129
|
+
function sendInvalidSearch4004(res, diagnostics) {
|
|
13800
14130
|
return res.status(400).json({
|
|
13801
14131
|
resourceType: "OperationOutcome",
|
|
13802
14132
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
13803
14133
|
});
|
|
13804
14134
|
}
|
|
13805
|
-
function
|
|
14135
|
+
function extractSearchParamKeys4(query) {
|
|
13806
14136
|
const out = [];
|
|
13807
14137
|
for (const rawKey of Object.keys(query)) {
|
|
13808
|
-
if (
|
|
14138
|
+
if (isResultParameter4(rawKey)) {
|
|
13809
14139
|
continue;
|
|
13810
14140
|
}
|
|
13811
|
-
out.push({ rawKey, code:
|
|
14141
|
+
out.push({ rawKey, code: stripModifier4(rawKey) });
|
|
13812
14142
|
}
|
|
13813
14143
|
return out;
|
|
13814
14144
|
}
|
|
13815
|
-
function
|
|
14145
|
+
function buildUnknownParamDiagnostics4(unknownCodes) {
|
|
13816
14146
|
const validCodes = getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
13817
14147
|
const codes = unknownCodes.join(", ");
|
|
13818
14148
|
const isPlural = unknownCodes.length !== 1;
|
|
@@ -13821,7 +14151,7 @@ function buildUnknownParamDiagnostics2(unknownCodes) {
|
|
|
13821
14151
|
`Valid codes: ${validCodes}.`
|
|
13822
14152
|
].join(" ");
|
|
13823
14153
|
}
|
|
13824
|
-
function
|
|
14154
|
+
function findMalformedReference4(query, searchParamKeys) {
|
|
13825
14155
|
const referenceCodes = new Set(
|
|
13826
14156
|
getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
13827
14157
|
);
|
|
@@ -13844,7 +14174,7 @@ function findMalformedReference2(query, searchParamKeys) {
|
|
|
13844
14174
|
return void 0;
|
|
13845
14175
|
}
|
|
13846
14176
|
async function listEncountersRoute(req, res) {
|
|
13847
|
-
const searchParamKeys =
|
|
14177
|
+
const searchParamKeys = extractSearchParamKeys4(
|
|
13848
14178
|
req.query
|
|
13849
14179
|
);
|
|
13850
14180
|
if (searchParamKeys.length === 0) {
|
|
@@ -13860,17 +14190,17 @@ async function listEncountersRoute(req, res) {
|
|
|
13860
14190
|
const validCodes = new Set(registered.map((p) => p.code));
|
|
13861
14191
|
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
13862
14192
|
if (unknownCodes.length > 0) {
|
|
13863
|
-
return
|
|
14193
|
+
return sendInvalidSearch4004(
|
|
13864
14194
|
res,
|
|
13865
|
-
|
|
14195
|
+
buildUnknownParamDiagnostics4([...new Set(unknownCodes)])
|
|
13866
14196
|
);
|
|
13867
14197
|
}
|
|
13868
|
-
const malformedRef =
|
|
14198
|
+
const malformedRef = findMalformedReference4(
|
|
13869
14199
|
req.query,
|
|
13870
14200
|
searchParamKeys
|
|
13871
14201
|
);
|
|
13872
14202
|
if (malformedRef !== void 0) {
|
|
13873
|
-
return
|
|
14203
|
+
return sendInvalidSearch4004(
|
|
13874
14204
|
res,
|
|
13875
14205
|
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
13876
14206
|
);
|
|
@@ -15914,15 +16244,119 @@ async function listFamilyMemberHistorysOperation(params) {
|
|
|
15914
16244
|
}
|
|
15915
16245
|
|
|
15916
16246
|
// src/data/rest-api/routes/data/familymemberhistory/familymemberhistory-list-route.ts
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
|
|
15923
|
-
|
|
16247
|
+
var FAMILYMEMBERHISTORY_RESOURCE_TYPE = "FamilyMemberHistory";
|
|
16248
|
+
function stripModifier5(key) {
|
|
16249
|
+
const idx = key.indexOf(":");
|
|
16250
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
16251
|
+
}
|
|
16252
|
+
function isResultParameter5(key) {
|
|
16253
|
+
return key.startsWith("_");
|
|
16254
|
+
}
|
|
16255
|
+
function sendInvalidSearch4005(res, diagnostics) {
|
|
16256
|
+
return res.status(400).json({
|
|
16257
|
+
resourceType: "OperationOutcome",
|
|
16258
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
15924
16259
|
});
|
|
15925
16260
|
}
|
|
16261
|
+
function extractSearchParamKeys5(query) {
|
|
16262
|
+
const out = [];
|
|
16263
|
+
for (const rawKey of Object.keys(query)) {
|
|
16264
|
+
if (isResultParameter5(rawKey)) {
|
|
16265
|
+
continue;
|
|
16266
|
+
}
|
|
16267
|
+
out.push({ rawKey, code: stripModifier5(rawKey) });
|
|
16268
|
+
}
|
|
16269
|
+
return out;
|
|
16270
|
+
}
|
|
16271
|
+
function buildUnknownParamDiagnostics5(unknownCodes) {
|
|
16272
|
+
const validCodes = getRegisteredSearchParameters(
|
|
16273
|
+
FAMILYMEMBERHISTORY_RESOURCE_TYPE
|
|
16274
|
+
).map((p) => p.code).sort().join(", ");
|
|
16275
|
+
const codes = unknownCodes.join(", ");
|
|
16276
|
+
const isPlural = unknownCodes.length !== 1;
|
|
16277
|
+
return [
|
|
16278
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for FamilyMemberHistory: ${codes}.`,
|
|
16279
|
+
`Valid codes: ${validCodes}.`
|
|
16280
|
+
].join(" ");
|
|
16281
|
+
}
|
|
16282
|
+
function findMalformedReference5(query, searchParamKeys) {
|
|
16283
|
+
const referenceCodes = new Set(
|
|
16284
|
+
getRegisteredSearchParameters(FAMILYMEMBERHISTORY_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
16285
|
+
);
|
|
16286
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
16287
|
+
if (!referenceCodes.has(code)) {
|
|
16288
|
+
continue;
|
|
16289
|
+
}
|
|
16290
|
+
const raw = query[rawKey];
|
|
16291
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
16292
|
+
for (const v of values) {
|
|
16293
|
+
const trimmed = v.trim();
|
|
16294
|
+
if (trimmed.length === 0) {
|
|
16295
|
+
continue;
|
|
16296
|
+
}
|
|
16297
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
16298
|
+
return { rawKey, value: trimmed };
|
|
16299
|
+
}
|
|
16300
|
+
}
|
|
16301
|
+
}
|
|
16302
|
+
return void 0;
|
|
16303
|
+
}
|
|
16304
|
+
async function listFamilyMemberHistorysRoute(req, res) {
|
|
16305
|
+
const searchParamKeys = extractSearchParamKeys5(
|
|
16306
|
+
req.query
|
|
16307
|
+
);
|
|
16308
|
+
if (searchParamKeys.length === 0) {
|
|
16309
|
+
return handleListRoute({
|
|
16310
|
+
req,
|
|
16311
|
+
res,
|
|
16312
|
+
basePath: BASE_PATH.FAMILYMEMBERHISTORY,
|
|
16313
|
+
listOperation: listFamilyMemberHistorysOperation,
|
|
16314
|
+
errorLogContext: "GET /FamilyMemberHistory list error:"
|
|
16315
|
+
});
|
|
16316
|
+
}
|
|
16317
|
+
const registered = getRegisteredSearchParameters(
|
|
16318
|
+
FAMILYMEMBERHISTORY_RESOURCE_TYPE
|
|
16319
|
+
);
|
|
16320
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
16321
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
16322
|
+
if (unknownCodes.length > 0) {
|
|
16323
|
+
return sendInvalidSearch4005(
|
|
16324
|
+
res,
|
|
16325
|
+
buildUnknownParamDiagnostics5([...new Set(unknownCodes)])
|
|
16326
|
+
);
|
|
16327
|
+
}
|
|
16328
|
+
const malformedRef = findMalformedReference5(
|
|
16329
|
+
req.query,
|
|
16330
|
+
searchParamKeys
|
|
16331
|
+
);
|
|
16332
|
+
if (malformedRef !== void 0) {
|
|
16333
|
+
return sendInvalidSearch4005(
|
|
16334
|
+
res,
|
|
16335
|
+
`?${malformedRef.rawKey} must be a typed reference like "Patient/<id>"; got "${malformedRef.value}".`
|
|
16336
|
+
);
|
|
16337
|
+
}
|
|
16338
|
+
const ctx = req.openhiContext;
|
|
16339
|
+
try {
|
|
16340
|
+
const result = await genericSearchOperation({
|
|
16341
|
+
resourceType: FAMILYMEMBERHISTORY_RESOURCE_TYPE,
|
|
16342
|
+
tenantId: ctx.tenantId,
|
|
16343
|
+
workspaceId: ctx.workspaceId,
|
|
16344
|
+
query: req.query,
|
|
16345
|
+
resolver: defaultSearchParameterResolver
|
|
16346
|
+
});
|
|
16347
|
+
const bundle = buildSearchsetBundle(
|
|
16348
|
+
BASE_PATH.FAMILYMEMBERHISTORY,
|
|
16349
|
+
result.entries
|
|
16350
|
+
);
|
|
16351
|
+
return res.json(bundle);
|
|
16352
|
+
} catch (err) {
|
|
16353
|
+
return sendOperationOutcome500(
|
|
16354
|
+
res,
|
|
16355
|
+
err,
|
|
16356
|
+
"GET /FamilyMemberHistory search error:"
|
|
16357
|
+
);
|
|
16358
|
+
}
|
|
16359
|
+
}
|
|
15926
16360
|
|
|
15927
16361
|
// src/data/operations/data/familymemberhistory/familymemberhistory-update-operation.ts
|
|
15928
16362
|
async function updateFamilyMemberHistoryOperation(params) {
|
|
@@ -17491,42 +17925,135 @@ async function getImmunizationByIdRoute(req, res) {
|
|
|
17491
17925
|
const id = String(req.params.id);
|
|
17492
17926
|
const ctx = req.openhiContext;
|
|
17493
17927
|
try {
|
|
17494
|
-
const result = await getImmunizationByIdOperation({ context: ctx, id });
|
|
17495
|
-
return res.json(result.resource);
|
|
17928
|
+
const result = await getImmunizationByIdOperation({ context: ctx, id });
|
|
17929
|
+
return res.json(result.resource);
|
|
17930
|
+
} catch (err) {
|
|
17931
|
+
const status = domainErrorToHttpStatus(err);
|
|
17932
|
+
if (status === 404) {
|
|
17933
|
+
const diagnostics = err instanceof NotFoundError ? err.message : `Immunization ${id} not found`;
|
|
17934
|
+
return sendOperationOutcome404(res, diagnostics);
|
|
17935
|
+
}
|
|
17936
|
+
return sendOperationOutcome500(res, err, "GET Immunization error:");
|
|
17937
|
+
}
|
|
17938
|
+
}
|
|
17939
|
+
|
|
17940
|
+
// src/data/operations/data/immunization/immunization-list-operation.ts
|
|
17941
|
+
async function listImmunizationsOperation(params) {
|
|
17942
|
+
const { context, tableName, mode } = params;
|
|
17943
|
+
const { tenantId, workspaceId } = context;
|
|
17944
|
+
const service = getDynamoDataService(tableName);
|
|
17945
|
+
return listDataEntitiesByWorkspace(
|
|
17946
|
+
service.entities.immunization,
|
|
17947
|
+
tenantId,
|
|
17948
|
+
workspaceId,
|
|
17949
|
+
mode
|
|
17950
|
+
);
|
|
17951
|
+
}
|
|
17952
|
+
|
|
17953
|
+
// src/data/rest-api/routes/data/immunization/immunization-list-route.ts
|
|
17954
|
+
var IMMUNIZATION_RESOURCE_TYPE = "Immunization";
|
|
17955
|
+
function stripModifier6(key) {
|
|
17956
|
+
const idx = key.indexOf(":");
|
|
17957
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
17958
|
+
}
|
|
17959
|
+
function isResultParameter6(key) {
|
|
17960
|
+
return key.startsWith("_");
|
|
17961
|
+
}
|
|
17962
|
+
function sendInvalidSearch4006(res, diagnostics) {
|
|
17963
|
+
return res.status(400).json({
|
|
17964
|
+
resourceType: "OperationOutcome",
|
|
17965
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
17966
|
+
});
|
|
17967
|
+
}
|
|
17968
|
+
function extractSearchParamKeys6(query) {
|
|
17969
|
+
const out = [];
|
|
17970
|
+
for (const rawKey of Object.keys(query)) {
|
|
17971
|
+
if (isResultParameter6(rawKey)) {
|
|
17972
|
+
continue;
|
|
17973
|
+
}
|
|
17974
|
+
out.push({ rawKey, code: stripModifier6(rawKey) });
|
|
17975
|
+
}
|
|
17976
|
+
return out;
|
|
17977
|
+
}
|
|
17978
|
+
function buildUnknownParamDiagnostics6(unknownCodes) {
|
|
17979
|
+
const validCodes = getRegisteredSearchParameters(IMMUNIZATION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
17980
|
+
const codes = unknownCodes.join(", ");
|
|
17981
|
+
const isPlural = unknownCodes.length !== 1;
|
|
17982
|
+
return [
|
|
17983
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for Immunization: ${codes}.`,
|
|
17984
|
+
`Valid codes: ${validCodes}.`
|
|
17985
|
+
].join(" ");
|
|
17986
|
+
}
|
|
17987
|
+
function findMalformedReference6(query, searchParamKeys) {
|
|
17988
|
+
const referenceCodes = new Set(
|
|
17989
|
+
getRegisteredSearchParameters(IMMUNIZATION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
17990
|
+
);
|
|
17991
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
17992
|
+
if (!referenceCodes.has(code)) {
|
|
17993
|
+
continue;
|
|
17994
|
+
}
|
|
17995
|
+
const raw = query[rawKey];
|
|
17996
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
17997
|
+
for (const v of values) {
|
|
17998
|
+
const trimmed = v.trim();
|
|
17999
|
+
if (trimmed.length === 0) {
|
|
18000
|
+
continue;
|
|
18001
|
+
}
|
|
18002
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
18003
|
+
return { rawKey, value: trimmed };
|
|
18004
|
+
}
|
|
18005
|
+
}
|
|
18006
|
+
}
|
|
18007
|
+
return void 0;
|
|
18008
|
+
}
|
|
18009
|
+
async function listImmunizationsRoute(req, res) {
|
|
18010
|
+
const searchParamKeys = extractSearchParamKeys6(
|
|
18011
|
+
req.query
|
|
18012
|
+
);
|
|
18013
|
+
if (searchParamKeys.length === 0) {
|
|
18014
|
+
return handleListRoute({
|
|
18015
|
+
req,
|
|
18016
|
+
res,
|
|
18017
|
+
basePath: BASE_PATH.IMMUNIZATION,
|
|
18018
|
+
listOperation: listImmunizationsOperation,
|
|
18019
|
+
errorLogContext: "GET /Immunization list error:"
|
|
18020
|
+
});
|
|
18021
|
+
}
|
|
18022
|
+
const registered = getRegisteredSearchParameters(IMMUNIZATION_RESOURCE_TYPE);
|
|
18023
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
18024
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
18025
|
+
if (unknownCodes.length > 0) {
|
|
18026
|
+
return sendInvalidSearch4006(
|
|
18027
|
+
res,
|
|
18028
|
+
buildUnknownParamDiagnostics6([...new Set(unknownCodes)])
|
|
18029
|
+
);
|
|
18030
|
+
}
|
|
18031
|
+
const malformedRef = findMalformedReference6(
|
|
18032
|
+
req.query,
|
|
18033
|
+
searchParamKeys
|
|
18034
|
+
);
|
|
18035
|
+
if (malformedRef !== void 0) {
|
|
18036
|
+
return sendInvalidSearch4006(
|
|
18037
|
+
res,
|
|
18038
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
18039
|
+
);
|
|
18040
|
+
}
|
|
18041
|
+
const ctx = req.openhiContext;
|
|
18042
|
+
try {
|
|
18043
|
+
const result = await genericSearchOperation({
|
|
18044
|
+
resourceType: IMMUNIZATION_RESOURCE_TYPE,
|
|
18045
|
+
tenantId: ctx.tenantId,
|
|
18046
|
+
workspaceId: ctx.workspaceId,
|
|
18047
|
+
query: req.query,
|
|
18048
|
+
resolver: defaultSearchParameterResolver
|
|
18049
|
+
});
|
|
18050
|
+
const bundle = buildSearchsetBundle(BASE_PATH.IMMUNIZATION, result.entries);
|
|
18051
|
+
return res.json(bundle);
|
|
17496
18052
|
} catch (err) {
|
|
17497
|
-
|
|
17498
|
-
if (status === 404) {
|
|
17499
|
-
const diagnostics = err instanceof NotFoundError ? err.message : `Immunization ${id} not found`;
|
|
17500
|
-
return sendOperationOutcome404(res, diagnostics);
|
|
17501
|
-
}
|
|
17502
|
-
return sendOperationOutcome500(res, err, "GET Immunization error:");
|
|
18053
|
+
return sendOperationOutcome500(res, err, "GET /Immunization search error:");
|
|
17503
18054
|
}
|
|
17504
18055
|
}
|
|
17505
18056
|
|
|
17506
|
-
// src/data/operations/data/immunization/immunization-list-operation.ts
|
|
17507
|
-
async function listImmunizationsOperation(params) {
|
|
17508
|
-
const { context, tableName, mode } = params;
|
|
17509
|
-
const { tenantId, workspaceId } = context;
|
|
17510
|
-
const service = getDynamoDataService(tableName);
|
|
17511
|
-
return listDataEntitiesByWorkspace(
|
|
17512
|
-
service.entities.immunization,
|
|
17513
|
-
tenantId,
|
|
17514
|
-
workspaceId,
|
|
17515
|
-
mode
|
|
17516
|
-
);
|
|
17517
|
-
}
|
|
17518
|
-
|
|
17519
|
-
// src/data/rest-api/routes/data/immunization/immunization-list-route.ts
|
|
17520
|
-
async function listImmunizationsRoute(req, res) {
|
|
17521
|
-
return handleListRoute({
|
|
17522
|
-
req,
|
|
17523
|
-
res,
|
|
17524
|
-
basePath: BASE_PATH.IMMUNIZATION,
|
|
17525
|
-
listOperation: listImmunizationsOperation,
|
|
17526
|
-
errorLogContext: "GET /Immunization list error:"
|
|
17527
|
-
});
|
|
17528
|
-
}
|
|
17529
|
-
|
|
17530
18057
|
// src/data/operations/data/immunization/immunization-update-operation.ts
|
|
17531
18058
|
async function updateImmunizationOperation(params) {
|
|
17532
18059
|
const { context, id, body, tableName } = params;
|
|
@@ -20998,15 +21525,119 @@ async function listMedicationRequestsOperation(params) {
|
|
|
20998
21525
|
}
|
|
20999
21526
|
|
|
21000
21527
|
// src/data/rest-api/routes/data/medicationrequest/medicationrequest-list-route.ts
|
|
21001
|
-
|
|
21002
|
-
|
|
21003
|
-
|
|
21004
|
-
|
|
21005
|
-
|
|
21006
|
-
|
|
21007
|
-
|
|
21528
|
+
var MEDICATIONREQUEST_RESOURCE_TYPE = "MedicationRequest";
|
|
21529
|
+
function stripModifier7(key) {
|
|
21530
|
+
const idx = key.indexOf(":");
|
|
21531
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
21532
|
+
}
|
|
21533
|
+
function isResultParameter7(key) {
|
|
21534
|
+
return key.startsWith("_");
|
|
21535
|
+
}
|
|
21536
|
+
function sendInvalidSearch4007(res, diagnostics) {
|
|
21537
|
+
return res.status(400).json({
|
|
21538
|
+
resourceType: "OperationOutcome",
|
|
21539
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
21008
21540
|
});
|
|
21009
21541
|
}
|
|
21542
|
+
function extractSearchParamKeys7(query) {
|
|
21543
|
+
const out = [];
|
|
21544
|
+
for (const rawKey of Object.keys(query)) {
|
|
21545
|
+
if (isResultParameter7(rawKey)) {
|
|
21546
|
+
continue;
|
|
21547
|
+
}
|
|
21548
|
+
out.push({ rawKey, code: stripModifier7(rawKey) });
|
|
21549
|
+
}
|
|
21550
|
+
return out;
|
|
21551
|
+
}
|
|
21552
|
+
function buildUnknownParamDiagnostics7(unknownCodes) {
|
|
21553
|
+
const validCodes = getRegisteredSearchParameters(
|
|
21554
|
+
MEDICATIONREQUEST_RESOURCE_TYPE
|
|
21555
|
+
).map((p) => p.code).sort().join(", ");
|
|
21556
|
+
const codes = unknownCodes.join(", ");
|
|
21557
|
+
const isPlural = unknownCodes.length !== 1;
|
|
21558
|
+
return [
|
|
21559
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for MedicationRequest: ${codes}.`,
|
|
21560
|
+
`Valid codes: ${validCodes}.`
|
|
21561
|
+
].join(" ");
|
|
21562
|
+
}
|
|
21563
|
+
function findMalformedReference7(query, searchParamKeys) {
|
|
21564
|
+
const referenceCodes = new Set(
|
|
21565
|
+
getRegisteredSearchParameters(MEDICATIONREQUEST_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
21566
|
+
);
|
|
21567
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
21568
|
+
if (!referenceCodes.has(code)) {
|
|
21569
|
+
continue;
|
|
21570
|
+
}
|
|
21571
|
+
const raw = query[rawKey];
|
|
21572
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
21573
|
+
for (const v of values) {
|
|
21574
|
+
const trimmed = v.trim();
|
|
21575
|
+
if (trimmed.length === 0) {
|
|
21576
|
+
continue;
|
|
21577
|
+
}
|
|
21578
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
21579
|
+
return { rawKey, value: trimmed };
|
|
21580
|
+
}
|
|
21581
|
+
}
|
|
21582
|
+
}
|
|
21583
|
+
return void 0;
|
|
21584
|
+
}
|
|
21585
|
+
async function listMedicationRequestsRoute(req, res) {
|
|
21586
|
+
const searchParamKeys = extractSearchParamKeys7(
|
|
21587
|
+
req.query
|
|
21588
|
+
);
|
|
21589
|
+
if (searchParamKeys.length === 0) {
|
|
21590
|
+
return handleListRoute({
|
|
21591
|
+
req,
|
|
21592
|
+
res,
|
|
21593
|
+
basePath: BASE_PATH.MEDICATIONREQUEST,
|
|
21594
|
+
listOperation: listMedicationRequestsOperation,
|
|
21595
|
+
errorLogContext: "GET /MedicationRequest list error:"
|
|
21596
|
+
});
|
|
21597
|
+
}
|
|
21598
|
+
const registered = getRegisteredSearchParameters(
|
|
21599
|
+
MEDICATIONREQUEST_RESOURCE_TYPE
|
|
21600
|
+
);
|
|
21601
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
21602
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
21603
|
+
if (unknownCodes.length > 0) {
|
|
21604
|
+
return sendInvalidSearch4007(
|
|
21605
|
+
res,
|
|
21606
|
+
buildUnknownParamDiagnostics7([...new Set(unknownCodes)])
|
|
21607
|
+
);
|
|
21608
|
+
}
|
|
21609
|
+
const malformedRef = findMalformedReference7(
|
|
21610
|
+
req.query,
|
|
21611
|
+
searchParamKeys
|
|
21612
|
+
);
|
|
21613
|
+
if (malformedRef !== void 0) {
|
|
21614
|
+
return sendInvalidSearch4007(
|
|
21615
|
+
res,
|
|
21616
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
21617
|
+
);
|
|
21618
|
+
}
|
|
21619
|
+
const ctx = req.openhiContext;
|
|
21620
|
+
try {
|
|
21621
|
+
const result = await genericSearchOperation({
|
|
21622
|
+
resourceType: MEDICATIONREQUEST_RESOURCE_TYPE,
|
|
21623
|
+
tenantId: ctx.tenantId,
|
|
21624
|
+
workspaceId: ctx.workspaceId,
|
|
21625
|
+
query: req.query,
|
|
21626
|
+
resolver: defaultSearchParameterResolver
|
|
21627
|
+
});
|
|
21628
|
+
const bundle = buildSearchsetBundle(
|
|
21629
|
+
BASE_PATH.MEDICATIONREQUEST,
|
|
21630
|
+
result.entries
|
|
21631
|
+
);
|
|
21632
|
+
return res.json(bundle);
|
|
21633
|
+
} catch (err) {
|
|
21634
|
+
return sendOperationOutcome500(
|
|
21635
|
+
res,
|
|
21636
|
+
err,
|
|
21637
|
+
"GET /MedicationRequest search error:"
|
|
21638
|
+
);
|
|
21639
|
+
}
|
|
21640
|
+
}
|
|
21010
21641
|
|
|
21011
21642
|
// src/data/operations/data/medicationrequest/medicationrequest-update-operation.ts
|
|
21012
21643
|
async function updateMedicationRequestOperation(params) {
|
|
@@ -21205,15 +21836,119 @@ async function listMedicationStatementsOperation(params) {
|
|
|
21205
21836
|
}
|
|
21206
21837
|
|
|
21207
21838
|
// src/data/rest-api/routes/data/medicationstatement/medicationstatement-list-route.ts
|
|
21208
|
-
|
|
21209
|
-
|
|
21210
|
-
|
|
21211
|
-
|
|
21212
|
-
|
|
21213
|
-
|
|
21214
|
-
|
|
21839
|
+
var MEDICATIONSTATEMENT_RESOURCE_TYPE = "MedicationStatement";
|
|
21840
|
+
function stripModifier8(key) {
|
|
21841
|
+
const idx = key.indexOf(":");
|
|
21842
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
21843
|
+
}
|
|
21844
|
+
function isResultParameter8(key) {
|
|
21845
|
+
return key.startsWith("_");
|
|
21846
|
+
}
|
|
21847
|
+
function sendInvalidSearch4008(res, diagnostics) {
|
|
21848
|
+
return res.status(400).json({
|
|
21849
|
+
resourceType: "OperationOutcome",
|
|
21850
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
21215
21851
|
});
|
|
21216
21852
|
}
|
|
21853
|
+
function extractSearchParamKeys8(query) {
|
|
21854
|
+
const out = [];
|
|
21855
|
+
for (const rawKey of Object.keys(query)) {
|
|
21856
|
+
if (isResultParameter8(rawKey)) {
|
|
21857
|
+
continue;
|
|
21858
|
+
}
|
|
21859
|
+
out.push({ rawKey, code: stripModifier8(rawKey) });
|
|
21860
|
+
}
|
|
21861
|
+
return out;
|
|
21862
|
+
}
|
|
21863
|
+
function buildUnknownParamDiagnostics8(unknownCodes) {
|
|
21864
|
+
const validCodes = getRegisteredSearchParameters(
|
|
21865
|
+
MEDICATIONSTATEMENT_RESOURCE_TYPE
|
|
21866
|
+
).map((p) => p.code).sort().join(", ");
|
|
21867
|
+
const codes = unknownCodes.join(", ");
|
|
21868
|
+
const isPlural = unknownCodes.length !== 1;
|
|
21869
|
+
return [
|
|
21870
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for MedicationStatement: ${codes}.`,
|
|
21871
|
+
`Valid codes: ${validCodes}.`
|
|
21872
|
+
].join(" ");
|
|
21873
|
+
}
|
|
21874
|
+
function findMalformedReference8(query, searchParamKeys) {
|
|
21875
|
+
const referenceCodes = new Set(
|
|
21876
|
+
getRegisteredSearchParameters(MEDICATIONSTATEMENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
21877
|
+
);
|
|
21878
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
21879
|
+
if (!referenceCodes.has(code)) {
|
|
21880
|
+
continue;
|
|
21881
|
+
}
|
|
21882
|
+
const raw = query[rawKey];
|
|
21883
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
21884
|
+
for (const v of values) {
|
|
21885
|
+
const trimmed = v.trim();
|
|
21886
|
+
if (trimmed.length === 0) {
|
|
21887
|
+
continue;
|
|
21888
|
+
}
|
|
21889
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
21890
|
+
return { rawKey, value: trimmed };
|
|
21891
|
+
}
|
|
21892
|
+
}
|
|
21893
|
+
}
|
|
21894
|
+
return void 0;
|
|
21895
|
+
}
|
|
21896
|
+
async function listMedicationStatementsRoute(req, res) {
|
|
21897
|
+
const searchParamKeys = extractSearchParamKeys8(
|
|
21898
|
+
req.query
|
|
21899
|
+
);
|
|
21900
|
+
if (searchParamKeys.length === 0) {
|
|
21901
|
+
return handleListRoute({
|
|
21902
|
+
req,
|
|
21903
|
+
res,
|
|
21904
|
+
basePath: BASE_PATH.MEDICATIONSTATEMENT,
|
|
21905
|
+
listOperation: listMedicationStatementsOperation,
|
|
21906
|
+
errorLogContext: "GET /MedicationStatement list error:"
|
|
21907
|
+
});
|
|
21908
|
+
}
|
|
21909
|
+
const registered = getRegisteredSearchParameters(
|
|
21910
|
+
MEDICATIONSTATEMENT_RESOURCE_TYPE
|
|
21911
|
+
);
|
|
21912
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
21913
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
21914
|
+
if (unknownCodes.length > 0) {
|
|
21915
|
+
return sendInvalidSearch4008(
|
|
21916
|
+
res,
|
|
21917
|
+
buildUnknownParamDiagnostics8([...new Set(unknownCodes)])
|
|
21918
|
+
);
|
|
21919
|
+
}
|
|
21920
|
+
const malformedRef = findMalformedReference8(
|
|
21921
|
+
req.query,
|
|
21922
|
+
searchParamKeys
|
|
21923
|
+
);
|
|
21924
|
+
if (malformedRef !== void 0) {
|
|
21925
|
+
return sendInvalidSearch4008(
|
|
21926
|
+
res,
|
|
21927
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
21928
|
+
);
|
|
21929
|
+
}
|
|
21930
|
+
const ctx = req.openhiContext;
|
|
21931
|
+
try {
|
|
21932
|
+
const result = await genericSearchOperation({
|
|
21933
|
+
resourceType: MEDICATIONSTATEMENT_RESOURCE_TYPE,
|
|
21934
|
+
tenantId: ctx.tenantId,
|
|
21935
|
+
workspaceId: ctx.workspaceId,
|
|
21936
|
+
query: req.query,
|
|
21937
|
+
resolver: defaultSearchParameterResolver
|
|
21938
|
+
});
|
|
21939
|
+
const bundle = buildSearchsetBundle(
|
|
21940
|
+
BASE_PATH.MEDICATIONSTATEMENT,
|
|
21941
|
+
result.entries
|
|
21942
|
+
);
|
|
21943
|
+
return res.json(bundle);
|
|
21944
|
+
} catch (err) {
|
|
21945
|
+
return sendOperationOutcome500(
|
|
21946
|
+
res,
|
|
21947
|
+
err,
|
|
21948
|
+
"GET /MedicationStatement search error:"
|
|
21949
|
+
);
|
|
21950
|
+
}
|
|
21951
|
+
}
|
|
21217
21952
|
|
|
21218
21953
|
// src/data/operations/data/medicationstatement/medicationstatement-update-operation.ts
|
|
21219
21954
|
async function updateMedicationStatementOperation(params) {
|
|
@@ -24569,30 +25304,30 @@ async function listObservationsOperation(params) {
|
|
|
24569
25304
|
|
|
24570
25305
|
// src/data/rest-api/routes/data/observation/observation-list-route.ts
|
|
24571
25306
|
var OBSERVATION_RESOURCE_TYPE = "Observation";
|
|
24572
|
-
function
|
|
25307
|
+
function stripModifier9(key) {
|
|
24573
25308
|
const idx = key.indexOf(":");
|
|
24574
25309
|
return idx === -1 ? key : key.slice(0, idx);
|
|
24575
25310
|
}
|
|
24576
|
-
function
|
|
25311
|
+
function isResultParameter9(key) {
|
|
24577
25312
|
return key.startsWith("_");
|
|
24578
25313
|
}
|
|
24579
|
-
function
|
|
25314
|
+
function sendInvalidSearch4009(res, diagnostics) {
|
|
24580
25315
|
return res.status(400).json({
|
|
24581
25316
|
resourceType: "OperationOutcome",
|
|
24582
25317
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
24583
25318
|
});
|
|
24584
25319
|
}
|
|
24585
|
-
function
|
|
25320
|
+
function extractSearchParamKeys9(query) {
|
|
24586
25321
|
const out = [];
|
|
24587
25322
|
for (const rawKey of Object.keys(query)) {
|
|
24588
|
-
if (
|
|
25323
|
+
if (isResultParameter9(rawKey)) {
|
|
24589
25324
|
continue;
|
|
24590
25325
|
}
|
|
24591
|
-
out.push({ rawKey, code:
|
|
25326
|
+
out.push({ rawKey, code: stripModifier9(rawKey) });
|
|
24592
25327
|
}
|
|
24593
25328
|
return out;
|
|
24594
25329
|
}
|
|
24595
|
-
function
|
|
25330
|
+
function buildUnknownParamDiagnostics9(unknownCodes) {
|
|
24596
25331
|
const validCodes = getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
24597
25332
|
const codes = unknownCodes.join(", ");
|
|
24598
25333
|
const isPlural = unknownCodes.length !== 1;
|
|
@@ -24601,7 +25336,7 @@ function buildUnknownParamDiagnostics3(unknownCodes) {
|
|
|
24601
25336
|
`Valid codes: ${validCodes}.`
|
|
24602
25337
|
].join(" ");
|
|
24603
25338
|
}
|
|
24604
|
-
function
|
|
25339
|
+
function findMalformedReference9(query, searchParamKeys) {
|
|
24605
25340
|
const referenceCodes = new Set(
|
|
24606
25341
|
getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
24607
25342
|
);
|
|
@@ -24624,7 +25359,7 @@ function findMalformedReference3(query, searchParamKeys) {
|
|
|
24624
25359
|
return void 0;
|
|
24625
25360
|
}
|
|
24626
25361
|
async function listObservationsRoute(req, res) {
|
|
24627
|
-
const searchParamKeys =
|
|
25362
|
+
const searchParamKeys = extractSearchParamKeys9(
|
|
24628
25363
|
req.query
|
|
24629
25364
|
);
|
|
24630
25365
|
if (searchParamKeys.length === 0) {
|
|
@@ -24640,17 +25375,17 @@ async function listObservationsRoute(req, res) {
|
|
|
24640
25375
|
const validCodes = new Set(registered.map((p) => p.code));
|
|
24641
25376
|
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
24642
25377
|
if (unknownCodes.length > 0) {
|
|
24643
|
-
return
|
|
25378
|
+
return sendInvalidSearch4009(
|
|
24644
25379
|
res,
|
|
24645
|
-
|
|
25380
|
+
buildUnknownParamDiagnostics9([...new Set(unknownCodes)])
|
|
24646
25381
|
);
|
|
24647
25382
|
}
|
|
24648
|
-
const malformedRef =
|
|
25383
|
+
const malformedRef = findMalformedReference9(
|
|
24649
25384
|
req.query,
|
|
24650
25385
|
searchParamKeys
|
|
24651
25386
|
);
|
|
24652
25387
|
if (malformedRef !== void 0) {
|
|
24653
|
-
return
|
|
25388
|
+
return sendInvalidSearch4009(
|
|
24654
25389
|
res,
|
|
24655
25390
|
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
24656
25391
|
);
|
|
@@ -25645,30 +26380,30 @@ async function listPatientsOperation(params) {
|
|
|
25645
26380
|
|
|
25646
26381
|
// src/data/rest-api/routes/data/patient/patient-list-route.ts
|
|
25647
26382
|
var PATIENT_RESOURCE_TYPE = "Patient";
|
|
25648
|
-
function
|
|
26383
|
+
function stripModifier10(key) {
|
|
25649
26384
|
const idx = key.indexOf(":");
|
|
25650
26385
|
return idx === -1 ? key : key.slice(0, idx);
|
|
25651
26386
|
}
|
|
25652
|
-
function
|
|
26387
|
+
function isResultParameter10(key) {
|
|
25653
26388
|
return key.startsWith("_");
|
|
25654
26389
|
}
|
|
25655
|
-
function
|
|
26390
|
+
function sendInvalidSearch40010(res, diagnostics) {
|
|
25656
26391
|
return res.status(400).json({
|
|
25657
26392
|
resourceType: "OperationOutcome",
|
|
25658
26393
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
25659
26394
|
});
|
|
25660
26395
|
}
|
|
25661
|
-
function
|
|
26396
|
+
function extractSearchParamKeys10(query) {
|
|
25662
26397
|
const out = [];
|
|
25663
26398
|
for (const rawKey of Object.keys(query)) {
|
|
25664
|
-
if (
|
|
26399
|
+
if (isResultParameter10(rawKey)) {
|
|
25665
26400
|
continue;
|
|
25666
26401
|
}
|
|
25667
|
-
out.push({ rawKey, code:
|
|
26402
|
+
out.push({ rawKey, code: stripModifier10(rawKey) });
|
|
25668
26403
|
}
|
|
25669
26404
|
return out;
|
|
25670
26405
|
}
|
|
25671
|
-
function
|
|
26406
|
+
function buildUnknownParamDiagnostics10(unknownCodes) {
|
|
25672
26407
|
const validCodes = getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
25673
26408
|
const codes = unknownCodes.join(", ");
|
|
25674
26409
|
const isPlural = unknownCodes.length !== 1;
|
|
@@ -25677,7 +26412,7 @@ function buildUnknownParamDiagnostics4(unknownCodes) {
|
|
|
25677
26412
|
`Valid codes: ${validCodes}.`
|
|
25678
26413
|
].join(" ");
|
|
25679
26414
|
}
|
|
25680
|
-
function
|
|
26415
|
+
function findMalformedReference10(query, searchParamKeys) {
|
|
25681
26416
|
const referenceCodes = new Set(
|
|
25682
26417
|
getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
25683
26418
|
);
|
|
@@ -25700,7 +26435,7 @@ function findMalformedReference4(query, searchParamKeys) {
|
|
|
25700
26435
|
return void 0;
|
|
25701
26436
|
}
|
|
25702
26437
|
async function listPatientsRoute(req, res) {
|
|
25703
|
-
const searchParamKeys =
|
|
26438
|
+
const searchParamKeys = extractSearchParamKeys10(
|
|
25704
26439
|
req.query
|
|
25705
26440
|
);
|
|
25706
26441
|
if (searchParamKeys.length === 0) {
|
|
@@ -25716,17 +26451,17 @@ async function listPatientsRoute(req, res) {
|
|
|
25716
26451
|
const validCodes = new Set(registered.map((p) => p.code));
|
|
25717
26452
|
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
25718
26453
|
if (unknownCodes.length > 0) {
|
|
25719
|
-
return
|
|
26454
|
+
return sendInvalidSearch40010(
|
|
25720
26455
|
res,
|
|
25721
|
-
|
|
26456
|
+
buildUnknownParamDiagnostics10([...new Set(unknownCodes)])
|
|
25722
26457
|
);
|
|
25723
26458
|
}
|
|
25724
|
-
const malformedRef =
|
|
26459
|
+
const malformedRef = findMalformedReference10(
|
|
25725
26460
|
req.query,
|
|
25726
26461
|
searchParamKeys
|
|
25727
26462
|
);
|
|
25728
26463
|
if (malformedRef !== void 0) {
|
|
25729
|
-
return
|
|
26464
|
+
return sendInvalidSearch40010(
|
|
25730
26465
|
res,
|
|
25731
26466
|
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
25732
26467
|
);
|
|
@@ -27066,30 +27801,30 @@ async function listProceduresOperation(params) {
|
|
|
27066
27801
|
|
|
27067
27802
|
// src/data/rest-api/routes/data/procedure/procedure-list-route.ts
|
|
27068
27803
|
var PROCEDURE_RESOURCE_TYPE = "Procedure";
|
|
27069
|
-
function
|
|
27804
|
+
function stripModifier11(key) {
|
|
27070
27805
|
const idx = key.indexOf(":");
|
|
27071
27806
|
return idx === -1 ? key : key.slice(0, idx);
|
|
27072
27807
|
}
|
|
27073
|
-
function
|
|
27808
|
+
function isResultParameter11(key) {
|
|
27074
27809
|
return key.startsWith("_");
|
|
27075
27810
|
}
|
|
27076
|
-
function
|
|
27811
|
+
function sendInvalidSearch40011(res, diagnostics) {
|
|
27077
27812
|
return res.status(400).json({
|
|
27078
27813
|
resourceType: "OperationOutcome",
|
|
27079
27814
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
27080
27815
|
});
|
|
27081
27816
|
}
|
|
27082
|
-
function
|
|
27817
|
+
function extractSearchParamKeys11(query) {
|
|
27083
27818
|
const out = [];
|
|
27084
27819
|
for (const rawKey of Object.keys(query)) {
|
|
27085
|
-
if (
|
|
27820
|
+
if (isResultParameter11(rawKey)) {
|
|
27086
27821
|
continue;
|
|
27087
27822
|
}
|
|
27088
|
-
out.push({ rawKey, code:
|
|
27823
|
+
out.push({ rawKey, code: stripModifier11(rawKey) });
|
|
27089
27824
|
}
|
|
27090
27825
|
return out;
|
|
27091
27826
|
}
|
|
27092
|
-
function
|
|
27827
|
+
function buildUnknownParamDiagnostics11(unknownCodes) {
|
|
27093
27828
|
const validCodes = getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
27094
27829
|
const codes = unknownCodes.join(", ");
|
|
27095
27830
|
const isPlural = unknownCodes.length !== 1;
|
|
@@ -27098,7 +27833,7 @@ function buildUnknownParamDiagnostics5(unknownCodes) {
|
|
|
27098
27833
|
`Valid codes: ${validCodes}.`
|
|
27099
27834
|
].join(" ");
|
|
27100
27835
|
}
|
|
27101
|
-
function
|
|
27836
|
+
function findMalformedReference11(query, searchParamKeys) {
|
|
27102
27837
|
const referenceCodes = new Set(
|
|
27103
27838
|
getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
27104
27839
|
);
|
|
@@ -27121,7 +27856,7 @@ function findMalformedReference5(query, searchParamKeys) {
|
|
|
27121
27856
|
return void 0;
|
|
27122
27857
|
}
|
|
27123
27858
|
async function listProceduresRoute(req, res) {
|
|
27124
|
-
const searchParamKeys =
|
|
27859
|
+
const searchParamKeys = extractSearchParamKeys11(
|
|
27125
27860
|
req.query
|
|
27126
27861
|
);
|
|
27127
27862
|
if (searchParamKeys.length === 0) {
|
|
@@ -27137,17 +27872,17 @@ async function listProceduresRoute(req, res) {
|
|
|
27137
27872
|
const validCodes = new Set(registered.map((p) => p.code));
|
|
27138
27873
|
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
27139
27874
|
if (unknownCodes.length > 0) {
|
|
27140
|
-
return
|
|
27875
|
+
return sendInvalidSearch40011(
|
|
27141
27876
|
res,
|
|
27142
|
-
|
|
27877
|
+
buildUnknownParamDiagnostics11([...new Set(unknownCodes)])
|
|
27143
27878
|
);
|
|
27144
27879
|
}
|
|
27145
|
-
const malformedRef =
|
|
27880
|
+
const malformedRef = findMalformedReference11(
|
|
27146
27881
|
req.query,
|
|
27147
27882
|
searchParamKeys
|
|
27148
27883
|
);
|
|
27149
27884
|
if (malformedRef !== void 0) {
|
|
27150
|
-
return
|
|
27885
|
+
return sendInvalidSearch40011(
|
|
27151
27886
|
res,
|
|
27152
27887
|
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
27153
27888
|
);
|
|
@@ -29674,7 +30409,7 @@ function singleStringQueryParam(req, name) {
|
|
|
29674
30409
|
const trimmed = v.trim();
|
|
29675
30410
|
return trimmed === "" ? void 0 : trimmed;
|
|
29676
30411
|
}
|
|
29677
|
-
function
|
|
30412
|
+
function sendInvalidSearch40012(res, diagnostics) {
|
|
29678
30413
|
return res.status(400).json({
|
|
29679
30414
|
resourceType: "OperationOutcome",
|
|
29680
30415
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
@@ -29684,7 +30419,7 @@ async function listSchedulesRoute(req, res) {
|
|
|
29684
30419
|
const actorRef = singleStringQueryParam(req, "actor");
|
|
29685
30420
|
if (actorRef !== void 0) {
|
|
29686
30421
|
if (parseTypedReference(actorRef) === void 0) {
|
|
29687
|
-
return
|
|
30422
|
+
return sendInvalidSearch40012(
|
|
29688
30423
|
res,
|
|
29689
30424
|
`?actor must be a typed reference like "Practitioner/<id>"; got "${actorRef}".`
|
|
29690
30425
|
);
|
|
@@ -33482,7 +34217,7 @@ function singleStringQueryParam2(req, name) {
|
|
|
33482
34217
|
const trimmed = v.trim();
|
|
33483
34218
|
return trimmed === "" ? void 0 : trimmed;
|
|
33484
34219
|
}
|
|
33485
|
-
function
|
|
34220
|
+
function sendInvalidSearch40013(res, diagnostics) {
|
|
33486
34221
|
return res.status(400).json({
|
|
33487
34222
|
resourceType: "OperationOutcome",
|
|
33488
34223
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
@@ -33492,14 +34227,14 @@ async function listTasksRoute(req, res) {
|
|
|
33492
34227
|
const ownerRef = singleStringQueryParam2(req, "owner");
|
|
33493
34228
|
const requesterRef = singleStringQueryParam2(req, "requester");
|
|
33494
34229
|
if (ownerRef !== void 0 && requesterRef !== void 0) {
|
|
33495
|
-
return
|
|
34230
|
+
return sendInvalidSearch40013(
|
|
33496
34231
|
res,
|
|
33497
34232
|
"?owner= and ?requester= cannot be combined on the same request."
|
|
33498
34233
|
);
|
|
33499
34234
|
}
|
|
33500
34235
|
if (ownerRef !== void 0) {
|
|
33501
34236
|
if (parseTypedReference(ownerRef) === void 0) {
|
|
33502
|
-
return
|
|
34237
|
+
return sendInvalidSearch40013(
|
|
33503
34238
|
res,
|
|
33504
34239
|
`?owner must be a typed reference like "Practitioner/<id>"; got "${ownerRef}".`
|
|
33505
34240
|
);
|
|
@@ -33522,7 +34257,7 @@ async function listTasksRoute(req, res) {
|
|
|
33522
34257
|
}
|
|
33523
34258
|
if (requesterRef !== void 0) {
|
|
33524
34259
|
if (parseTypedReference(requesterRef) === void 0) {
|
|
33525
|
-
return
|
|
34260
|
+
return sendInvalidSearch40013(
|
|
33526
34261
|
res,
|
|
33527
34262
|
`?requester must be a typed reference like "Practitioner/<id>"; got "${requesterRef}".`
|
|
33528
34263
|
);
|