@openhi/constructs 0.0.140 → 0.0.141
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.
|
@@ -5637,13 +5637,17 @@ function parseDateSearchValue(raw) {
|
|
|
5637
5637
|
return { prefix: "eq", value: raw };
|
|
5638
5638
|
}
|
|
5639
5639
|
function flatJsonbExtract(jsonbPath) {
|
|
5640
|
-
const
|
|
5641
|
-
if (
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5640
|
+
const topLevel = /^\$\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(jsonbPath);
|
|
5641
|
+
if (topLevel) {
|
|
5642
|
+
return `resource->>'${topLevel[1]}'`;
|
|
5643
|
+
}
|
|
5644
|
+
const nested = /^\$\.([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(jsonbPath);
|
|
5645
|
+
if (nested) {
|
|
5646
|
+
return `resource->'${nested[1]}'->>'${nested[2]}'`;
|
|
5645
5647
|
}
|
|
5646
|
-
|
|
5648
|
+
throw new Error(
|
|
5649
|
+
`Generic date predicate requires a scalar JSONPath like "$.fieldName" or "$.field.subfield"; received "${jsonbPath}".`
|
|
5650
|
+
);
|
|
5647
5651
|
}
|
|
5648
5652
|
function emitDatePredicate(opts) {
|
|
5649
5653
|
const { jsonbPath, rawValue, paramName } = opts;
|
|
@@ -6051,6 +6055,53 @@ var APPOINTMENT_SEARCH_PARAMETERS = [
|
|
|
6051
6055
|
{ code: "slot", type: "reference", jsonbPath: "$.slot[*]" }
|
|
6052
6056
|
];
|
|
6053
6057
|
|
|
6058
|
+
// src/data/search/registry/encounter-search-parameters.ts
|
|
6059
|
+
var ENCOUNTER_SEARCH_PARAMETERS = [
|
|
6060
|
+
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
6061
|
+
{ code: "class", type: "token", jsonbPath: "$.class" },
|
|
6062
|
+
{ code: "type", type: "token", jsonbPath: "$.type[*]" },
|
|
6063
|
+
{ code: "subject", type: "reference", jsonbPath: "$.subject" },
|
|
6064
|
+
{ code: "patient", type: "reference", jsonbPath: "$.subject" },
|
|
6065
|
+
{
|
|
6066
|
+
code: "participant",
|
|
6067
|
+
type: "reference",
|
|
6068
|
+
jsonbPath: "$.participant[*].individual"
|
|
6069
|
+
},
|
|
6070
|
+
{ code: "date", type: "date", jsonbPath: "$.period.start" },
|
|
6071
|
+
{
|
|
6072
|
+
code: "service-provider",
|
|
6073
|
+
type: "reference",
|
|
6074
|
+
jsonbPath: "$.serviceProvider"
|
|
6075
|
+
},
|
|
6076
|
+
{ code: "appointment", type: "reference", jsonbPath: "$.appointment[*]" },
|
|
6077
|
+
{
|
|
6078
|
+
code: "episode-of-care",
|
|
6079
|
+
type: "reference",
|
|
6080
|
+
jsonbPath: "$.episodeOfCare[*]"
|
|
6081
|
+
}
|
|
6082
|
+
];
|
|
6083
|
+
|
|
6084
|
+
// src/data/search/registry/observation-search-parameters.ts
|
|
6085
|
+
var OBSERVATION_SEARCH_PARAMETERS = [
|
|
6086
|
+
{ code: "status", type: "token", jsonbPath: "$.status" },
|
|
6087
|
+
{ code: "category", type: "token", jsonbPath: "$.category[*]" },
|
|
6088
|
+
{ code: "code", type: "token", jsonbPath: "$.code" },
|
|
6089
|
+
{ code: "subject", type: "reference", jsonbPath: "$.subject" },
|
|
6090
|
+
{ code: "patient", type: "reference", jsonbPath: "$.subject" },
|
|
6091
|
+
{ code: "encounter", type: "reference", jsonbPath: "$.encounter" },
|
|
6092
|
+
{ code: "performer", type: "reference", jsonbPath: "$.performer[*]" },
|
|
6093
|
+
{ code: "date", type: "date", jsonbPath: "$.effectiveDateTime" },
|
|
6094
|
+
{
|
|
6095
|
+
code: "value-string",
|
|
6096
|
+
type: "string",
|
|
6097
|
+
jsonbPath: "$.valueString",
|
|
6098
|
+
modifiers: ["exact", "contains", "missing", "not"]
|
|
6099
|
+
},
|
|
6100
|
+
{ code: "identifier", type: "token", jsonbPath: "$.identifier[*]" },
|
|
6101
|
+
{ code: "based-on", type: "reference", jsonbPath: "$.basedOn[*]" },
|
|
6102
|
+
{ code: "part-of", type: "reference", jsonbPath: "$.partOf[*]" }
|
|
6103
|
+
];
|
|
6104
|
+
|
|
6054
6105
|
// src/data/search/registry/patient-search-parameters.ts
|
|
6055
6106
|
var PATIENT_SEARCH_PARAMETERS = [
|
|
6056
6107
|
{ code: "gender", type: "token", jsonbPath: "$.gender" },
|
|
@@ -6088,10 +6139,39 @@ var PATIENT_SEARCH_PARAMETERS = [
|
|
|
6088
6139
|
}
|
|
6089
6140
|
];
|
|
6090
6141
|
|
|
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[*]"
|
|
6165
|
+
}
|
|
6166
|
+
];
|
|
6167
|
+
|
|
6091
6168
|
// src/data/search/registry/resolver.ts
|
|
6092
6169
|
var STATIC_SEARCH_PARAMETER_MAP = {
|
|
6093
6170
|
Appointment: APPOINTMENT_SEARCH_PARAMETERS,
|
|
6094
|
-
|
|
6171
|
+
Encounter: ENCOUNTER_SEARCH_PARAMETERS,
|
|
6172
|
+
Observation: OBSERVATION_SEARCH_PARAMETERS,
|
|
6173
|
+
Patient: PATIENT_SEARCH_PARAMETERS,
|
|
6174
|
+
Procedure: PROCEDURE_SEARCH_PARAMETERS
|
|
6095
6175
|
};
|
|
6096
6176
|
var defaultSearchParameterResolver = (resourceType, _tenantId) => STATIC_SEARCH_PARAMETER_MAP[resourceType] ?? [];
|
|
6097
6177
|
function getRegisteredSearchParameters(resourceType) {
|
|
@@ -13707,353 +13787,108 @@ async function listEncountersOperation(params) {
|
|
|
13707
13787
|
);
|
|
13708
13788
|
}
|
|
13709
13789
|
|
|
13710
|
-
// src/data/
|
|
13711
|
-
var
|
|
13712
|
-
|
|
13713
|
-
"
|
|
13714
|
-
|
|
13715
|
-
"le",
|
|
13716
|
-
"sa",
|
|
13717
|
-
"eb"
|
|
13718
|
-
];
|
|
13719
|
-
function isPeriodSearchPrefix(s) {
|
|
13720
|
-
return PERIOD_SEARCH_PREFIXES.includes(s);
|
|
13721
|
-
}
|
|
13722
|
-
var PERIOD_START = "resource->'period'->>'start'";
|
|
13723
|
-
var PERIOD_END = "resource->'period'->>'end'";
|
|
13724
|
-
var HAS_ANY_BOUND_GUARD = `(${PERIOD_START} IS NOT NULL OR ${PERIOD_END} IS NOT NULL)`;
|
|
13725
|
-
function buildSinglePredicateSql(prefix, paramName) {
|
|
13726
|
-
switch (prefix) {
|
|
13727
|
-
case "gt":
|
|
13728
|
-
return `(${PERIOD_END} IS NULL OR ${PERIOD_END} > :${paramName})`;
|
|
13729
|
-
case "lt":
|
|
13730
|
-
return `(${PERIOD_START} IS NULL OR ${PERIOD_START} < :${paramName})`;
|
|
13731
|
-
case "ge":
|
|
13732
|
-
return `(${PERIOD_END} IS NULL OR ${PERIOD_END} >= :${paramName})`;
|
|
13733
|
-
case "le":
|
|
13734
|
-
return `(${PERIOD_START} IS NULL OR ${PERIOD_START} <= :${paramName})`;
|
|
13735
|
-
case "sa":
|
|
13736
|
-
return `(${PERIOD_START} IS NOT NULL AND ${PERIOD_START} > :${paramName})`;
|
|
13737
|
-
case "eb":
|
|
13738
|
-
return `(${PERIOD_END} IS NOT NULL AND ${PERIOD_END} < :${paramName})`;
|
|
13739
|
-
}
|
|
13740
|
-
}
|
|
13741
|
-
function periodConstraintParamName(index) {
|
|
13742
|
-
return `periodConstraint${index}`;
|
|
13743
|
-
}
|
|
13744
|
-
function buildPeriodSearchPredicateSql(constraints) {
|
|
13745
|
-
if (constraints.length === 0) {
|
|
13746
|
-
return [];
|
|
13747
|
-
}
|
|
13748
|
-
const fragments = constraints.map(
|
|
13749
|
-
(c, i) => buildSinglePredicateSql(c.prefix, periodConstraintParamName(i))
|
|
13750
|
-
);
|
|
13751
|
-
fragments.push(HAS_ANY_BOUND_GUARD);
|
|
13752
|
-
return fragments;
|
|
13753
|
-
}
|
|
13754
|
-
function buildPeriodSearchPredicateParams(constraints) {
|
|
13755
|
-
return constraints.map((c, i) => ({
|
|
13756
|
-
name: periodConstraintParamName(i),
|
|
13757
|
-
value: c.value
|
|
13758
|
-
}));
|
|
13759
|
-
}
|
|
13760
|
-
|
|
13761
|
-
// src/data/operations/data/encounter/encounter-search-by-date-operation.ts
|
|
13762
|
-
var DEFAULT_LIMIT2 = 100;
|
|
13763
|
-
function buildSearchEncountersByDateSql(opts) {
|
|
13764
|
-
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
13765
|
-
opts.periodConstraints
|
|
13766
|
-
);
|
|
13767
|
-
const lines = [
|
|
13768
|
-
"SELECT resource_id AS id, resource",
|
|
13769
|
-
"FROM resources",
|
|
13770
|
-
"WHERE tenant_id = :tenantId",
|
|
13771
|
-
" AND workspace_id = :workspaceId",
|
|
13772
|
-
" AND resource_type = 'Encounter'",
|
|
13773
|
-
" AND deleted_at IS NULL"
|
|
13774
|
-
];
|
|
13775
|
-
for (const fragment of periodPredicates) {
|
|
13776
|
-
lines.push(` AND ${fragment}`);
|
|
13777
|
-
}
|
|
13778
|
-
lines.push("ORDER BY last_updated DESC");
|
|
13779
|
-
lines.push("LIMIT :limit;");
|
|
13780
|
-
return lines.join("\n");
|
|
13781
|
-
}
|
|
13782
|
-
async function searchEncountersByDateOperation(params) {
|
|
13783
|
-
const { context, periodConstraints } = params;
|
|
13784
|
-
if (periodConstraints.length === 0) {
|
|
13785
|
-
throw new Error(
|
|
13786
|
-
"searchEncountersByDateOperation requires at least one periodConstraint"
|
|
13787
|
-
);
|
|
13788
|
-
}
|
|
13789
|
-
const { tenantId, workspaceId } = context;
|
|
13790
|
-
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
13791
|
-
const limit = params.limit ?? DEFAULT_LIMIT2;
|
|
13792
|
-
const sql = buildSearchEncountersByDateSql({ periodConstraints });
|
|
13793
|
-
const queryParams = [
|
|
13794
|
-
{ name: "tenantId", value: tenantId },
|
|
13795
|
-
{ name: "workspaceId", value: workspaceId },
|
|
13796
|
-
{ name: "limit", value: limit },
|
|
13797
|
-
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
13798
|
-
];
|
|
13799
|
-
const rows = await runner.query(sql, queryParams);
|
|
13800
|
-
const entries = rows.map((row) => ({
|
|
13801
|
-
id: row.id,
|
|
13802
|
-
resource: {
|
|
13803
|
-
...row.resource,
|
|
13804
|
-
id: row.id
|
|
13805
|
-
}
|
|
13806
|
-
}));
|
|
13807
|
-
return { entries, total: entries.length };
|
|
13790
|
+
// src/data/rest-api/routes/data/encounter/encounter-list-route.ts
|
|
13791
|
+
var ENCOUNTER_RESOURCE_TYPE = "Encounter";
|
|
13792
|
+
function stripModifier2(key) {
|
|
13793
|
+
const idx = key.indexOf(":");
|
|
13794
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
13808
13795
|
}
|
|
13809
|
-
|
|
13810
|
-
|
|
13811
|
-
var DEFAULT_LIMIT3 = 100;
|
|
13812
|
-
function buildSearchEncountersByParticipantSql(opts) {
|
|
13813
|
-
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
13814
|
-
opts?.periodConstraints ?? []
|
|
13815
|
-
);
|
|
13816
|
-
const lines = [
|
|
13817
|
-
"SELECT resource_id AS id, resource",
|
|
13818
|
-
"FROM resources",
|
|
13819
|
-
"WHERE tenant_id = :tenantId",
|
|
13820
|
-
" AND workspace_id = :workspaceId",
|
|
13821
|
-
" AND resource_type = 'Encounter'",
|
|
13822
|
-
" AND deleted_at IS NULL",
|
|
13823
|
-
` AND ${REFERENCE_CONTAINMENT_SQL_FRAGMENT}`
|
|
13824
|
-
];
|
|
13825
|
-
for (const fragment of periodPredicates) {
|
|
13826
|
-
lines.push(` AND ${fragment}`);
|
|
13827
|
-
}
|
|
13828
|
-
lines.push("ORDER BY last_updated DESC");
|
|
13829
|
-
lines.push("LIMIT :limit;");
|
|
13830
|
-
return lines.join("\n");
|
|
13796
|
+
function isResultParameter2(key) {
|
|
13797
|
+
return key.startsWith("_");
|
|
13831
13798
|
}
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
13837
|
-
const limit = params.limit ?? DEFAULT_LIMIT3;
|
|
13838
|
-
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
13839
|
-
shape: {
|
|
13840
|
-
kind: "array-of-objects",
|
|
13841
|
-
field: "participant",
|
|
13842
|
-
subfield: "individual"
|
|
13843
|
-
},
|
|
13844
|
-
reference: participantReference,
|
|
13845
|
-
tenantId,
|
|
13846
|
-
workspaceId
|
|
13799
|
+
function sendInvalidSearch4002(res, diagnostics) {
|
|
13800
|
+
return res.status(400).json({
|
|
13801
|
+
resourceType: "OperationOutcome",
|
|
13802
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
13847
13803
|
});
|
|
13848
|
-
const sql = buildSearchEncountersByParticipantSql({ periodConstraints });
|
|
13849
|
-
const queryParams = [
|
|
13850
|
-
{ name: "tenantId", value: tenantId },
|
|
13851
|
-
{ name: "workspaceId", value: workspaceId },
|
|
13852
|
-
{ name: "containmentRelative", value: containmentRelative },
|
|
13853
|
-
{ name: "containmentUrn", value: containmentUrn },
|
|
13854
|
-
{ name: "limit", value: limit },
|
|
13855
|
-
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
13856
|
-
];
|
|
13857
|
-
const rows = await runner.query(sql, queryParams);
|
|
13858
|
-
const entries = rows.map((row) => ({
|
|
13859
|
-
id: row.id,
|
|
13860
|
-
resource: {
|
|
13861
|
-
...row.resource,
|
|
13862
|
-
id: row.id
|
|
13863
|
-
}
|
|
13864
|
-
}));
|
|
13865
|
-
return { entries, total: entries.length };
|
|
13866
13804
|
}
|
|
13867
|
-
|
|
13868
|
-
|
|
13869
|
-
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
opts?.periodConstraints ?? []
|
|
13873
|
-
);
|
|
13874
|
-
const lines = [
|
|
13875
|
-
"SELECT resource_id AS id, resource",
|
|
13876
|
-
"FROM resources",
|
|
13877
|
-
"WHERE tenant_id = :tenantId",
|
|
13878
|
-
" AND workspace_id = :workspaceId",
|
|
13879
|
-
" AND resource_type = 'Encounter'",
|
|
13880
|
-
" AND deleted_at IS NULL",
|
|
13881
|
-
" AND (resource @> :containmentRelative::jsonb",
|
|
13882
|
-
" OR resource @> :containmentUrn::jsonb)"
|
|
13883
|
-
];
|
|
13884
|
-
for (const fragment of periodPredicates) {
|
|
13885
|
-
lines.push(` AND ${fragment}`);
|
|
13886
|
-
}
|
|
13887
|
-
lines.push("ORDER BY last_updated DESC");
|
|
13888
|
-
lines.push("LIMIT :limit;");
|
|
13889
|
-
return lines.join("\n");
|
|
13890
|
-
}
|
|
13891
|
-
async function searchEncountersByPatientOperation(params) {
|
|
13892
|
-
const { context, patientId } = params;
|
|
13893
|
-
const periodConstraints = params.periodConstraints ?? [];
|
|
13894
|
-
const { tenantId, workspaceId } = context;
|
|
13895
|
-
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
13896
|
-
const limit = params.limit ?? DEFAULT_LIMIT4;
|
|
13897
|
-
const containmentRelative = JSON.stringify({
|
|
13898
|
-
subject: { reference: `Patient/${patientId}` }
|
|
13899
|
-
});
|
|
13900
|
-
const containmentUrn = JSON.stringify({
|
|
13901
|
-
subject: {
|
|
13902
|
-
reference: buildOpenHiResourceUrn({
|
|
13903
|
-
tenantId,
|
|
13904
|
-
workspaceId,
|
|
13905
|
-
resourceType: "Patient",
|
|
13906
|
-
resourceId: patientId
|
|
13907
|
-
})
|
|
13908
|
-
}
|
|
13909
|
-
});
|
|
13910
|
-
const sql = buildSearchEncountersByPatientSql({ periodConstraints });
|
|
13911
|
-
const queryParams = [
|
|
13912
|
-
{ name: "tenantId", value: tenantId },
|
|
13913
|
-
{ name: "workspaceId", value: workspaceId },
|
|
13914
|
-
{ name: "containmentRelative", value: containmentRelative },
|
|
13915
|
-
{ name: "containmentUrn", value: containmentUrn },
|
|
13916
|
-
{ name: "limit", value: limit },
|
|
13917
|
-
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
13918
|
-
];
|
|
13919
|
-
const rows = await runner.query(sql, queryParams);
|
|
13920
|
-
const entries = rows.map((row) => ({
|
|
13921
|
-
id: row.id,
|
|
13922
|
-
resource: {
|
|
13923
|
-
...row.resource,
|
|
13924
|
-
id: row.id
|
|
13805
|
+
function extractSearchParamKeys2(query) {
|
|
13806
|
+
const out = [];
|
|
13807
|
+
for (const rawKey of Object.keys(query)) {
|
|
13808
|
+
if (isResultParameter2(rawKey)) {
|
|
13809
|
+
continue;
|
|
13925
13810
|
}
|
|
13926
|
-
|
|
13927
|
-
return { entries, total: entries.length };
|
|
13928
|
-
}
|
|
13929
|
-
|
|
13930
|
-
// src/data/rest-api/routes/data/encounter/encounter-list-route.ts
|
|
13931
|
-
function singleStringQueryParam(req, name) {
|
|
13932
|
-
const v = req.query[name];
|
|
13933
|
-
if (typeof v !== "string") {
|
|
13934
|
-
return void 0;
|
|
13811
|
+
out.push({ rawKey, code: stripModifier2(rawKey) });
|
|
13935
13812
|
}
|
|
13936
|
-
|
|
13937
|
-
return trimmed === "" ? void 0 : trimmed;
|
|
13813
|
+
return out;
|
|
13938
13814
|
}
|
|
13939
|
-
function
|
|
13940
|
-
|
|
13815
|
+
function buildUnknownParamDiagnostics2(unknownCodes) {
|
|
13816
|
+
const validCodes = getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
13817
|
+
const codes = unknownCodes.join(", ");
|
|
13818
|
+
const isPlural = unknownCodes.length !== 1;
|
|
13819
|
+
return [
|
|
13820
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for Encounter: ${codes}.`,
|
|
13821
|
+
`Valid codes: ${validCodes}.`
|
|
13822
|
+
].join(" ");
|
|
13941
13823
|
}
|
|
13942
|
-
function
|
|
13943
|
-
const
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
}
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
for (const v of values) {
|
|
13950
|
-
if (typeof v !== "string") {
|
|
13951
|
-
return { error: "Each ?date= value must be a string." };
|
|
13952
|
-
}
|
|
13953
|
-
const trimmed = v.trim();
|
|
13954
|
-
if (trimmed === "") {
|
|
13955
|
-
return { error: "?date= value must not be empty." };
|
|
13956
|
-
}
|
|
13957
|
-
const prefix = trimmed.slice(0, 2);
|
|
13958
|
-
const datetime = trimmed.slice(2);
|
|
13959
|
-
if (!isPeriodSearchPrefix(prefix)) {
|
|
13960
|
-
return {
|
|
13961
|
-
error: `Unsupported ?date= prefix in "${trimmed}". Supported prefixes: ${PERIOD_SEARCH_PREFIXES.join(", ")}.`
|
|
13962
|
-
};
|
|
13824
|
+
function findMalformedReference2(query, searchParamKeys) {
|
|
13825
|
+
const referenceCodes = new Set(
|
|
13826
|
+
getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
13827
|
+
);
|
|
13828
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
13829
|
+
if (!referenceCodes.has(code)) {
|
|
13830
|
+
continue;
|
|
13963
13831
|
}
|
|
13964
|
-
|
|
13965
|
-
|
|
13832
|
+
const raw = query[rawKey];
|
|
13833
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
13834
|
+
for (const v of values) {
|
|
13835
|
+
const trimmed = v.trim();
|
|
13836
|
+
if (trimmed.length === 0) {
|
|
13837
|
+
continue;
|
|
13838
|
+
}
|
|
13839
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
13840
|
+
return { rawKey, value: trimmed };
|
|
13841
|
+
}
|
|
13966
13842
|
}
|
|
13967
|
-
out.push({ prefix, value: datetime });
|
|
13968
13843
|
}
|
|
13969
|
-
return
|
|
13970
|
-
}
|
|
13971
|
-
function sendInvalidSearch4002(res, diagnostics) {
|
|
13972
|
-
return res.status(400).json({
|
|
13973
|
-
resourceType: "OperationOutcome",
|
|
13974
|
-
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
13975
|
-
});
|
|
13844
|
+
return void 0;
|
|
13976
13845
|
}
|
|
13977
13846
|
async function listEncountersRoute(req, res) {
|
|
13978
|
-
const
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
if (
|
|
13982
|
-
return
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13847
|
+
const searchParamKeys = extractSearchParamKeys2(
|
|
13848
|
+
req.query
|
|
13849
|
+
);
|
|
13850
|
+
if (searchParamKeys.length === 0) {
|
|
13851
|
+
return handleListRoute({
|
|
13852
|
+
req,
|
|
13853
|
+
res,
|
|
13854
|
+
basePath: BASE_PATH.ENCOUNTER,
|
|
13855
|
+
listOperation: listEncountersOperation,
|
|
13856
|
+
errorLogContext: "GET /Encounter list error:"
|
|
13857
|
+
});
|
|
13858
|
+
}
|
|
13859
|
+
const registered = getRegisteredSearchParameters(ENCOUNTER_RESOURCE_TYPE);
|
|
13860
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
13861
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
13862
|
+
if (unknownCodes.length > 0) {
|
|
13986
13863
|
return sendInvalidSearch4002(
|
|
13987
13864
|
res,
|
|
13988
|
-
|
|
13865
|
+
buildUnknownParamDiagnostics2([...new Set(unknownCodes)])
|
|
13989
13866
|
);
|
|
13990
13867
|
}
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
|
|
13997
|
-
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
const result = await searchEncountersByParticipantOperation({
|
|
14001
|
-
context: ctx,
|
|
14002
|
-
participantReference: participantRef,
|
|
14003
|
-
periodConstraints
|
|
14004
|
-
});
|
|
14005
|
-
const bundle = buildSearchsetBundle(BASE_PATH.ENCOUNTER, result.entries);
|
|
14006
|
-
return res.json(bundle);
|
|
14007
|
-
} catch (err) {
|
|
14008
|
-
return sendOperationOutcome500(
|
|
14009
|
-
res,
|
|
14010
|
-
err,
|
|
14011
|
-
"GET /Encounter?participant= search error:"
|
|
14012
|
-
);
|
|
14013
|
-
}
|
|
14014
|
-
}
|
|
14015
|
-
if (patientId !== void 0) {
|
|
14016
|
-
const ctx = req.openhiContext;
|
|
14017
|
-
try {
|
|
14018
|
-
const result = await searchEncountersByPatientOperation({
|
|
14019
|
-
context: ctx,
|
|
14020
|
-
patientId,
|
|
14021
|
-
periodConstraints
|
|
14022
|
-
});
|
|
14023
|
-
const bundle = buildSearchsetBundle(BASE_PATH.ENCOUNTER, result.entries);
|
|
14024
|
-
return res.json(bundle);
|
|
14025
|
-
} catch (err) {
|
|
14026
|
-
return sendOperationOutcome500(
|
|
14027
|
-
res,
|
|
14028
|
-
err,
|
|
14029
|
-
"GET /Encounter?patient= search error:"
|
|
14030
|
-
);
|
|
14031
|
-
}
|
|
13868
|
+
const malformedRef = findMalformedReference2(
|
|
13869
|
+
req.query,
|
|
13870
|
+
searchParamKeys
|
|
13871
|
+
);
|
|
13872
|
+
if (malformedRef !== void 0) {
|
|
13873
|
+
return sendInvalidSearch4002(
|
|
13874
|
+
res,
|
|
13875
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
13876
|
+
);
|
|
14032
13877
|
}
|
|
14033
|
-
|
|
14034
|
-
|
|
14035
|
-
|
|
14036
|
-
|
|
14037
|
-
|
|
14038
|
-
|
|
14039
|
-
|
|
14040
|
-
|
|
14041
|
-
|
|
14042
|
-
|
|
14043
|
-
|
|
14044
|
-
|
|
14045
|
-
|
|
14046
|
-
"GET /Encounter?date= search error:"
|
|
14047
|
-
);
|
|
14048
|
-
}
|
|
13878
|
+
const ctx = req.openhiContext;
|
|
13879
|
+
try {
|
|
13880
|
+
const result = await genericSearchOperation({
|
|
13881
|
+
resourceType: ENCOUNTER_RESOURCE_TYPE,
|
|
13882
|
+
tenantId: ctx.tenantId,
|
|
13883
|
+
workspaceId: ctx.workspaceId,
|
|
13884
|
+
query: req.query,
|
|
13885
|
+
resolver: defaultSearchParameterResolver
|
|
13886
|
+
});
|
|
13887
|
+
const bundle = buildSearchsetBundle(BASE_PATH.ENCOUNTER, result.entries);
|
|
13888
|
+
return res.json(bundle);
|
|
13889
|
+
} catch (err) {
|
|
13890
|
+
return sendOperationOutcome500(res, err, "GET /Encounter search error:");
|
|
14049
13891
|
}
|
|
14050
|
-
return handleListRoute({
|
|
14051
|
-
req,
|
|
14052
|
-
res,
|
|
14053
|
-
basePath: BASE_PATH.ENCOUNTER,
|
|
14054
|
-
listOperation: listEncountersOperation,
|
|
14055
|
-
errorLogContext: "GET /Encounter list error:"
|
|
14056
|
-
});
|
|
14057
13892
|
}
|
|
14058
13893
|
|
|
14059
13894
|
// src/data/operations/data/encounter/encounter-update-operation.ts
|
|
@@ -24733,15 +24568,108 @@ async function listObservationsOperation(params) {
|
|
|
24733
24568
|
}
|
|
24734
24569
|
|
|
24735
24570
|
// src/data/rest-api/routes/data/observation/observation-list-route.ts
|
|
24736
|
-
|
|
24737
|
-
|
|
24738
|
-
|
|
24739
|
-
|
|
24740
|
-
|
|
24741
|
-
|
|
24742
|
-
|
|
24571
|
+
var OBSERVATION_RESOURCE_TYPE = "Observation";
|
|
24572
|
+
function stripModifier3(key) {
|
|
24573
|
+
const idx = key.indexOf(":");
|
|
24574
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
24575
|
+
}
|
|
24576
|
+
function isResultParameter3(key) {
|
|
24577
|
+
return key.startsWith("_");
|
|
24578
|
+
}
|
|
24579
|
+
function sendInvalidSearch4003(res, diagnostics) {
|
|
24580
|
+
return res.status(400).json({
|
|
24581
|
+
resourceType: "OperationOutcome",
|
|
24582
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
24743
24583
|
});
|
|
24744
24584
|
}
|
|
24585
|
+
function extractSearchParamKeys3(query) {
|
|
24586
|
+
const out = [];
|
|
24587
|
+
for (const rawKey of Object.keys(query)) {
|
|
24588
|
+
if (isResultParameter3(rawKey)) {
|
|
24589
|
+
continue;
|
|
24590
|
+
}
|
|
24591
|
+
out.push({ rawKey, code: stripModifier3(rawKey) });
|
|
24592
|
+
}
|
|
24593
|
+
return out;
|
|
24594
|
+
}
|
|
24595
|
+
function buildUnknownParamDiagnostics3(unknownCodes) {
|
|
24596
|
+
const validCodes = getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
24597
|
+
const codes = unknownCodes.join(", ");
|
|
24598
|
+
const isPlural = unknownCodes.length !== 1;
|
|
24599
|
+
return [
|
|
24600
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for Observation: ${codes}.`,
|
|
24601
|
+
`Valid codes: ${validCodes}.`
|
|
24602
|
+
].join(" ");
|
|
24603
|
+
}
|
|
24604
|
+
function findMalformedReference3(query, searchParamKeys) {
|
|
24605
|
+
const referenceCodes = new Set(
|
|
24606
|
+
getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
24607
|
+
);
|
|
24608
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
24609
|
+
if (!referenceCodes.has(code)) {
|
|
24610
|
+
continue;
|
|
24611
|
+
}
|
|
24612
|
+
const raw = query[rawKey];
|
|
24613
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
24614
|
+
for (const v of values) {
|
|
24615
|
+
const trimmed = v.trim();
|
|
24616
|
+
if (trimmed.length === 0) {
|
|
24617
|
+
continue;
|
|
24618
|
+
}
|
|
24619
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
24620
|
+
return { rawKey, value: trimmed };
|
|
24621
|
+
}
|
|
24622
|
+
}
|
|
24623
|
+
}
|
|
24624
|
+
return void 0;
|
|
24625
|
+
}
|
|
24626
|
+
async function listObservationsRoute(req, res) {
|
|
24627
|
+
const searchParamKeys = extractSearchParamKeys3(
|
|
24628
|
+
req.query
|
|
24629
|
+
);
|
|
24630
|
+
if (searchParamKeys.length === 0) {
|
|
24631
|
+
return handleListRoute({
|
|
24632
|
+
req,
|
|
24633
|
+
res,
|
|
24634
|
+
basePath: BASE_PATH.OBSERVATION,
|
|
24635
|
+
listOperation: listObservationsOperation,
|
|
24636
|
+
errorLogContext: "GET /Observation list error:"
|
|
24637
|
+
});
|
|
24638
|
+
}
|
|
24639
|
+
const registered = getRegisteredSearchParameters(OBSERVATION_RESOURCE_TYPE);
|
|
24640
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
24641
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
24642
|
+
if (unknownCodes.length > 0) {
|
|
24643
|
+
return sendInvalidSearch4003(
|
|
24644
|
+
res,
|
|
24645
|
+
buildUnknownParamDiagnostics3([...new Set(unknownCodes)])
|
|
24646
|
+
);
|
|
24647
|
+
}
|
|
24648
|
+
const malformedRef = findMalformedReference3(
|
|
24649
|
+
req.query,
|
|
24650
|
+
searchParamKeys
|
|
24651
|
+
);
|
|
24652
|
+
if (malformedRef !== void 0) {
|
|
24653
|
+
return sendInvalidSearch4003(
|
|
24654
|
+
res,
|
|
24655
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
24656
|
+
);
|
|
24657
|
+
}
|
|
24658
|
+
const ctx = req.openhiContext;
|
|
24659
|
+
try {
|
|
24660
|
+
const result = await genericSearchOperation({
|
|
24661
|
+
resourceType: OBSERVATION_RESOURCE_TYPE,
|
|
24662
|
+
tenantId: ctx.tenantId,
|
|
24663
|
+
workspaceId: ctx.workspaceId,
|
|
24664
|
+
query: req.query,
|
|
24665
|
+
resolver: defaultSearchParameterResolver
|
|
24666
|
+
});
|
|
24667
|
+
const bundle = buildSearchsetBundle(BASE_PATH.OBSERVATION, result.entries);
|
|
24668
|
+
return res.json(bundle);
|
|
24669
|
+
} catch (err) {
|
|
24670
|
+
return sendOperationOutcome500(res, err, "GET /Observation search error:");
|
|
24671
|
+
}
|
|
24672
|
+
}
|
|
24745
24673
|
|
|
24746
24674
|
// src/data/operations/data/observation/observation-update-operation.ts
|
|
24747
24675
|
async function updateObservationOperation(params) {
|
|
@@ -25717,30 +25645,30 @@ async function listPatientsOperation(params) {
|
|
|
25717
25645
|
|
|
25718
25646
|
// src/data/rest-api/routes/data/patient/patient-list-route.ts
|
|
25719
25647
|
var PATIENT_RESOURCE_TYPE = "Patient";
|
|
25720
|
-
function
|
|
25648
|
+
function stripModifier4(key) {
|
|
25721
25649
|
const idx = key.indexOf(":");
|
|
25722
25650
|
return idx === -1 ? key : key.slice(0, idx);
|
|
25723
25651
|
}
|
|
25724
|
-
function
|
|
25652
|
+
function isResultParameter4(key) {
|
|
25725
25653
|
return key.startsWith("_");
|
|
25726
25654
|
}
|
|
25727
|
-
function
|
|
25655
|
+
function sendInvalidSearch4004(res, diagnostics) {
|
|
25728
25656
|
return res.status(400).json({
|
|
25729
25657
|
resourceType: "OperationOutcome",
|
|
25730
25658
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
25731
25659
|
});
|
|
25732
25660
|
}
|
|
25733
|
-
function
|
|
25661
|
+
function extractSearchParamKeys4(query) {
|
|
25734
25662
|
const out = [];
|
|
25735
25663
|
for (const rawKey of Object.keys(query)) {
|
|
25736
|
-
if (
|
|
25664
|
+
if (isResultParameter4(rawKey)) {
|
|
25737
25665
|
continue;
|
|
25738
25666
|
}
|
|
25739
|
-
out.push({ rawKey, code:
|
|
25667
|
+
out.push({ rawKey, code: stripModifier4(rawKey) });
|
|
25740
25668
|
}
|
|
25741
25669
|
return out;
|
|
25742
25670
|
}
|
|
25743
|
-
function
|
|
25671
|
+
function buildUnknownParamDiagnostics4(unknownCodes) {
|
|
25744
25672
|
const validCodes = getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
25745
25673
|
const codes = unknownCodes.join(", ");
|
|
25746
25674
|
const isPlural = unknownCodes.length !== 1;
|
|
@@ -25749,7 +25677,7 @@ function buildUnknownParamDiagnostics2(unknownCodes) {
|
|
|
25749
25677
|
`Valid codes: ${validCodes}.`
|
|
25750
25678
|
].join(" ");
|
|
25751
25679
|
}
|
|
25752
|
-
function
|
|
25680
|
+
function findMalformedReference4(query, searchParamKeys) {
|
|
25753
25681
|
const referenceCodes = new Set(
|
|
25754
25682
|
getRegisteredSearchParameters(PATIENT_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
25755
25683
|
);
|
|
@@ -25772,7 +25700,7 @@ function findMalformedReference2(query, searchParamKeys) {
|
|
|
25772
25700
|
return void 0;
|
|
25773
25701
|
}
|
|
25774
25702
|
async function listPatientsRoute(req, res) {
|
|
25775
|
-
const searchParamKeys =
|
|
25703
|
+
const searchParamKeys = extractSearchParamKeys4(
|
|
25776
25704
|
req.query
|
|
25777
25705
|
);
|
|
25778
25706
|
if (searchParamKeys.length === 0) {
|
|
@@ -25788,17 +25716,17 @@ async function listPatientsRoute(req, res) {
|
|
|
25788
25716
|
const validCodes = new Set(registered.map((p) => p.code));
|
|
25789
25717
|
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
25790
25718
|
if (unknownCodes.length > 0) {
|
|
25791
|
-
return
|
|
25719
|
+
return sendInvalidSearch4004(
|
|
25792
25720
|
res,
|
|
25793
|
-
|
|
25721
|
+
buildUnknownParamDiagnostics4([...new Set(unknownCodes)])
|
|
25794
25722
|
);
|
|
25795
25723
|
}
|
|
25796
|
-
const malformedRef =
|
|
25724
|
+
const malformedRef = findMalformedReference4(
|
|
25797
25725
|
req.query,
|
|
25798
25726
|
searchParamKeys
|
|
25799
25727
|
);
|
|
25800
25728
|
if (malformedRef !== void 0) {
|
|
25801
|
-
return
|
|
25729
|
+
return sendInvalidSearch4004(
|
|
25802
25730
|
res,
|
|
25803
25731
|
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
25804
25732
|
);
|
|
@@ -27137,15 +27065,108 @@ async function listProceduresOperation(params) {
|
|
|
27137
27065
|
}
|
|
27138
27066
|
|
|
27139
27067
|
// src/data/rest-api/routes/data/procedure/procedure-list-route.ts
|
|
27140
|
-
|
|
27141
|
-
|
|
27142
|
-
|
|
27143
|
-
|
|
27144
|
-
|
|
27145
|
-
|
|
27146
|
-
|
|
27068
|
+
var PROCEDURE_RESOURCE_TYPE = "Procedure";
|
|
27069
|
+
function stripModifier5(key) {
|
|
27070
|
+
const idx = key.indexOf(":");
|
|
27071
|
+
return idx === -1 ? key : key.slice(0, idx);
|
|
27072
|
+
}
|
|
27073
|
+
function isResultParameter5(key) {
|
|
27074
|
+
return key.startsWith("_");
|
|
27075
|
+
}
|
|
27076
|
+
function sendInvalidSearch4005(res, diagnostics) {
|
|
27077
|
+
return res.status(400).json({
|
|
27078
|
+
resourceType: "OperationOutcome",
|
|
27079
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
27147
27080
|
});
|
|
27148
27081
|
}
|
|
27082
|
+
function extractSearchParamKeys5(query) {
|
|
27083
|
+
const out = [];
|
|
27084
|
+
for (const rawKey of Object.keys(query)) {
|
|
27085
|
+
if (isResultParameter5(rawKey)) {
|
|
27086
|
+
continue;
|
|
27087
|
+
}
|
|
27088
|
+
out.push({ rawKey, code: stripModifier5(rawKey) });
|
|
27089
|
+
}
|
|
27090
|
+
return out;
|
|
27091
|
+
}
|
|
27092
|
+
function buildUnknownParamDiagnostics5(unknownCodes) {
|
|
27093
|
+
const validCodes = getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).map((p) => p.code).sort().join(", ");
|
|
27094
|
+
const codes = unknownCodes.join(", ");
|
|
27095
|
+
const isPlural = unknownCodes.length !== 1;
|
|
27096
|
+
return [
|
|
27097
|
+
`Unknown search ${isPlural ? "parameters" : "parameter"} for Procedure: ${codes}.`,
|
|
27098
|
+
`Valid codes: ${validCodes}.`
|
|
27099
|
+
].join(" ");
|
|
27100
|
+
}
|
|
27101
|
+
function findMalformedReference5(query, searchParamKeys) {
|
|
27102
|
+
const referenceCodes = new Set(
|
|
27103
|
+
getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE).filter((p) => p.type === "reference").map((p) => p.code)
|
|
27104
|
+
);
|
|
27105
|
+
for (const { rawKey, code } of searchParamKeys) {
|
|
27106
|
+
if (!referenceCodes.has(code)) {
|
|
27107
|
+
continue;
|
|
27108
|
+
}
|
|
27109
|
+
const raw = query[rawKey];
|
|
27110
|
+
const values = typeof raw === "string" ? raw.split(",") : Array.isArray(raw) ? raw.flatMap((v) => v.split(",")) : [];
|
|
27111
|
+
for (const v of values) {
|
|
27112
|
+
const trimmed = v.trim();
|
|
27113
|
+
if (trimmed.length === 0) {
|
|
27114
|
+
continue;
|
|
27115
|
+
}
|
|
27116
|
+
if (parseTypedReference(trimmed) === void 0) {
|
|
27117
|
+
return { rawKey, value: trimmed };
|
|
27118
|
+
}
|
|
27119
|
+
}
|
|
27120
|
+
}
|
|
27121
|
+
return void 0;
|
|
27122
|
+
}
|
|
27123
|
+
async function listProceduresRoute(req, res) {
|
|
27124
|
+
const searchParamKeys = extractSearchParamKeys5(
|
|
27125
|
+
req.query
|
|
27126
|
+
);
|
|
27127
|
+
if (searchParamKeys.length === 0) {
|
|
27128
|
+
return handleListRoute({
|
|
27129
|
+
req,
|
|
27130
|
+
res,
|
|
27131
|
+
basePath: BASE_PATH.PROCEDURE,
|
|
27132
|
+
listOperation: listProceduresOperation,
|
|
27133
|
+
errorLogContext: "GET /Procedure list error:"
|
|
27134
|
+
});
|
|
27135
|
+
}
|
|
27136
|
+
const registered = getRegisteredSearchParameters(PROCEDURE_RESOURCE_TYPE);
|
|
27137
|
+
const validCodes = new Set(registered.map((p) => p.code));
|
|
27138
|
+
const unknownCodes = searchParamKeys.map((k) => k.code).filter((code) => !validCodes.has(code));
|
|
27139
|
+
if (unknownCodes.length > 0) {
|
|
27140
|
+
return sendInvalidSearch4005(
|
|
27141
|
+
res,
|
|
27142
|
+
buildUnknownParamDiagnostics5([...new Set(unknownCodes)])
|
|
27143
|
+
);
|
|
27144
|
+
}
|
|
27145
|
+
const malformedRef = findMalformedReference5(
|
|
27146
|
+
req.query,
|
|
27147
|
+
searchParamKeys
|
|
27148
|
+
);
|
|
27149
|
+
if (malformedRef !== void 0) {
|
|
27150
|
+
return sendInvalidSearch4005(
|
|
27151
|
+
res,
|
|
27152
|
+
`?${malformedRef.rawKey} must be a typed reference like "Practitioner/<id>"; got "${malformedRef.value}".`
|
|
27153
|
+
);
|
|
27154
|
+
}
|
|
27155
|
+
const ctx = req.openhiContext;
|
|
27156
|
+
try {
|
|
27157
|
+
const result = await genericSearchOperation({
|
|
27158
|
+
resourceType: PROCEDURE_RESOURCE_TYPE,
|
|
27159
|
+
tenantId: ctx.tenantId,
|
|
27160
|
+
workspaceId: ctx.workspaceId,
|
|
27161
|
+
query: req.query,
|
|
27162
|
+
resolver: defaultSearchParameterResolver
|
|
27163
|
+
});
|
|
27164
|
+
const bundle = buildSearchsetBundle(BASE_PATH.PROCEDURE, result.entries);
|
|
27165
|
+
return res.json(bundle);
|
|
27166
|
+
} catch (err) {
|
|
27167
|
+
return sendOperationOutcome500(res, err, "GET /Procedure search error:");
|
|
27168
|
+
}
|
|
27169
|
+
}
|
|
27149
27170
|
|
|
27150
27171
|
// src/data/operations/data/procedure/procedure-update-operation.ts
|
|
27151
27172
|
async function updateProcedureOperation(params) {
|
|
@@ -29601,7 +29622,7 @@ async function listSchedulesOperation(params) {
|
|
|
29601
29622
|
}
|
|
29602
29623
|
|
|
29603
29624
|
// src/data/operations/data/schedule/schedule-search-by-actor-operation.ts
|
|
29604
|
-
var
|
|
29625
|
+
var DEFAULT_LIMIT2 = 100;
|
|
29605
29626
|
function buildSearchSchedulesByActorSql() {
|
|
29606
29627
|
return [
|
|
29607
29628
|
"SELECT resource_id AS id, resource",
|
|
@@ -29619,7 +29640,7 @@ async function searchSchedulesByActorOperation(params) {
|
|
|
29619
29640
|
const { context, actorReference } = params;
|
|
29620
29641
|
const { tenantId, workspaceId } = context;
|
|
29621
29642
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
29622
|
-
const limit = params.limit ??
|
|
29643
|
+
const limit = params.limit ?? DEFAULT_LIMIT2;
|
|
29623
29644
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
29624
29645
|
shape: { kind: "array-of-references", field: "actor" },
|
|
29625
29646
|
reference: actorReference,
|
|
@@ -29645,7 +29666,7 @@ async function searchSchedulesByActorOperation(params) {
|
|
|
29645
29666
|
}
|
|
29646
29667
|
|
|
29647
29668
|
// src/data/rest-api/routes/data/schedule/schedule-list-route.ts
|
|
29648
|
-
function
|
|
29669
|
+
function singleStringQueryParam(req, name) {
|
|
29649
29670
|
const v = req.query[name];
|
|
29650
29671
|
if (typeof v !== "string") {
|
|
29651
29672
|
return void 0;
|
|
@@ -29653,17 +29674,17 @@ function singleStringQueryParam2(req, name) {
|
|
|
29653
29674
|
const trimmed = v.trim();
|
|
29654
29675
|
return trimmed === "" ? void 0 : trimmed;
|
|
29655
29676
|
}
|
|
29656
|
-
function
|
|
29677
|
+
function sendInvalidSearch4006(res, diagnostics) {
|
|
29657
29678
|
return res.status(400).json({
|
|
29658
29679
|
resourceType: "OperationOutcome",
|
|
29659
29680
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
29660
29681
|
});
|
|
29661
29682
|
}
|
|
29662
29683
|
async function listSchedulesRoute(req, res) {
|
|
29663
|
-
const actorRef =
|
|
29684
|
+
const actorRef = singleStringQueryParam(req, "actor");
|
|
29664
29685
|
if (actorRef !== void 0) {
|
|
29665
29686
|
if (parseTypedReference(actorRef) === void 0) {
|
|
29666
|
-
return
|
|
29687
|
+
return sendInvalidSearch4006(
|
|
29667
29688
|
res,
|
|
29668
29689
|
`?actor must be a typed reference like "Practitioner/<id>"; got "${actorRef}".`
|
|
29669
29690
|
);
|
|
@@ -33365,7 +33386,7 @@ async function listTasksOperation(params) {
|
|
|
33365
33386
|
}
|
|
33366
33387
|
|
|
33367
33388
|
// src/data/operations/data/task/task-search-by-owner-operation.ts
|
|
33368
|
-
var
|
|
33389
|
+
var DEFAULT_LIMIT3 = 100;
|
|
33369
33390
|
function buildSearchTasksByOwnerSql() {
|
|
33370
33391
|
return [
|
|
33371
33392
|
"SELECT resource_id AS id, resource",
|
|
@@ -33383,7 +33404,7 @@ async function searchTasksByOwnerOperation(params) {
|
|
|
33383
33404
|
const { context, ownerReference } = params;
|
|
33384
33405
|
const { tenantId, workspaceId } = context;
|
|
33385
33406
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
33386
|
-
const limit = params.limit ??
|
|
33407
|
+
const limit = params.limit ?? DEFAULT_LIMIT3;
|
|
33387
33408
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
33388
33409
|
shape: { kind: "scalar", field: "owner" },
|
|
33389
33410
|
reference: ownerReference,
|
|
@@ -33409,7 +33430,7 @@ async function searchTasksByOwnerOperation(params) {
|
|
|
33409
33430
|
}
|
|
33410
33431
|
|
|
33411
33432
|
// src/data/operations/data/task/task-search-by-requester-operation.ts
|
|
33412
|
-
var
|
|
33433
|
+
var DEFAULT_LIMIT4 = 100;
|
|
33413
33434
|
function buildSearchTasksByRequesterSql() {
|
|
33414
33435
|
return [
|
|
33415
33436
|
"SELECT resource_id AS id, resource",
|
|
@@ -33427,7 +33448,7 @@ async function searchTasksByRequesterOperation(params) {
|
|
|
33427
33448
|
const { context, requesterReference } = params;
|
|
33428
33449
|
const { tenantId, workspaceId } = context;
|
|
33429
33450
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
33430
|
-
const limit = params.limit ??
|
|
33451
|
+
const limit = params.limit ?? DEFAULT_LIMIT4;
|
|
33431
33452
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
33432
33453
|
shape: { kind: "scalar", field: "requester" },
|
|
33433
33454
|
reference: requesterReference,
|
|
@@ -33453,7 +33474,7 @@ async function searchTasksByRequesterOperation(params) {
|
|
|
33453
33474
|
}
|
|
33454
33475
|
|
|
33455
33476
|
// src/data/rest-api/routes/data/task/task-list-route.ts
|
|
33456
|
-
function
|
|
33477
|
+
function singleStringQueryParam2(req, name) {
|
|
33457
33478
|
const v = req.query[name];
|
|
33458
33479
|
if (typeof v !== "string") {
|
|
33459
33480
|
return void 0;
|
|
@@ -33461,24 +33482,24 @@ function singleStringQueryParam3(req, name) {
|
|
|
33461
33482
|
const trimmed = v.trim();
|
|
33462
33483
|
return trimmed === "" ? void 0 : trimmed;
|
|
33463
33484
|
}
|
|
33464
|
-
function
|
|
33485
|
+
function sendInvalidSearch4007(res, diagnostics) {
|
|
33465
33486
|
return res.status(400).json({
|
|
33466
33487
|
resourceType: "OperationOutcome",
|
|
33467
33488
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
33468
33489
|
});
|
|
33469
33490
|
}
|
|
33470
33491
|
async function listTasksRoute(req, res) {
|
|
33471
|
-
const ownerRef =
|
|
33472
|
-
const requesterRef =
|
|
33492
|
+
const ownerRef = singleStringQueryParam2(req, "owner");
|
|
33493
|
+
const requesterRef = singleStringQueryParam2(req, "requester");
|
|
33473
33494
|
if (ownerRef !== void 0 && requesterRef !== void 0) {
|
|
33474
|
-
return
|
|
33495
|
+
return sendInvalidSearch4007(
|
|
33475
33496
|
res,
|
|
33476
33497
|
"?owner= and ?requester= cannot be combined on the same request."
|
|
33477
33498
|
);
|
|
33478
33499
|
}
|
|
33479
33500
|
if (ownerRef !== void 0) {
|
|
33480
33501
|
if (parseTypedReference(ownerRef) === void 0) {
|
|
33481
|
-
return
|
|
33502
|
+
return sendInvalidSearch4007(
|
|
33482
33503
|
res,
|
|
33483
33504
|
`?owner must be a typed reference like "Practitioner/<id>"; got "${ownerRef}".`
|
|
33484
33505
|
);
|
|
@@ -33501,7 +33522,7 @@ async function listTasksRoute(req, res) {
|
|
|
33501
33522
|
}
|
|
33502
33523
|
if (requesterRef !== void 0) {
|
|
33503
33524
|
if (parseTypedReference(requesterRef) === void 0) {
|
|
33504
|
-
return
|
|
33525
|
+
return sendInvalidSearch4007(
|
|
33505
33526
|
res,
|
|
33506
33527
|
`?requester must be a typed reference like "Practitioner/<id>"; got "${requesterRef}".`
|
|
33507
33528
|
);
|