@openhi/constructs 0.0.122 → 0.0.124
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.
|
@@ -9587,59 +9587,6 @@ async function getAppointmentByIdRoute(req, res) {
|
|
|
9587
9587
|
}
|
|
9588
9588
|
}
|
|
9589
9589
|
|
|
9590
|
-
// src/data/operations/data/appointment/appointment-date-search-predicate.ts
|
|
9591
|
-
var APPOINTMENT_DATE_SEARCH_PREFIXES = [
|
|
9592
|
-
"gt",
|
|
9593
|
-
"lt",
|
|
9594
|
-
"ge",
|
|
9595
|
-
"le",
|
|
9596
|
-
"sa",
|
|
9597
|
-
"eb"
|
|
9598
|
-
];
|
|
9599
|
-
function isAppointmentDateSearchPrefix(s) {
|
|
9600
|
-
return APPOINTMENT_DATE_SEARCH_PREFIXES.includes(
|
|
9601
|
-
s
|
|
9602
|
-
);
|
|
9603
|
-
}
|
|
9604
|
-
var APPT_START = "resource->>'start'";
|
|
9605
|
-
var APPT_END = "resource->>'end'";
|
|
9606
|
-
var HAS_ANY_BOUND_GUARD = `(${APPT_START} IS NOT NULL OR ${APPT_END} IS NOT NULL)`;
|
|
9607
|
-
function buildSinglePredicateSql(prefix, paramName) {
|
|
9608
|
-
switch (prefix) {
|
|
9609
|
-
case "gt":
|
|
9610
|
-
return `(${APPT_END} IS NULL OR ${APPT_END} > :${paramName})`;
|
|
9611
|
-
case "lt":
|
|
9612
|
-
return `(${APPT_START} IS NULL OR ${APPT_START} < :${paramName})`;
|
|
9613
|
-
case "ge":
|
|
9614
|
-
return `(${APPT_END} IS NULL OR ${APPT_END} >= :${paramName})`;
|
|
9615
|
-
case "le":
|
|
9616
|
-
return `(${APPT_START} IS NULL OR ${APPT_START} <= :${paramName})`;
|
|
9617
|
-
case "sa":
|
|
9618
|
-
return `(${APPT_START} IS NOT NULL AND ${APPT_START} > :${paramName})`;
|
|
9619
|
-
case "eb":
|
|
9620
|
-
return `(${APPT_END} IS NOT NULL AND ${APPT_END} < :${paramName})`;
|
|
9621
|
-
}
|
|
9622
|
-
}
|
|
9623
|
-
function appointmentDateConstraintParamName(index) {
|
|
9624
|
-
return `apptDateConstraint${index}`;
|
|
9625
|
-
}
|
|
9626
|
-
function buildAppointmentDateSearchPredicateSql(constraints) {
|
|
9627
|
-
if (constraints.length === 0) {
|
|
9628
|
-
return [];
|
|
9629
|
-
}
|
|
9630
|
-
const fragments = constraints.map(
|
|
9631
|
-
(c, i) => buildSinglePredicateSql(c.prefix, appointmentDateConstraintParamName(i))
|
|
9632
|
-
);
|
|
9633
|
-
fragments.push(HAS_ANY_BOUND_GUARD);
|
|
9634
|
-
return fragments;
|
|
9635
|
-
}
|
|
9636
|
-
function buildAppointmentDateSearchPredicateParams(constraints) {
|
|
9637
|
-
return constraints.map((c, i) => ({
|
|
9638
|
-
name: appointmentDateConstraintParamName(i),
|
|
9639
|
-
value: c.value
|
|
9640
|
-
}));
|
|
9641
|
-
}
|
|
9642
|
-
|
|
9643
9590
|
// src/data/operations/data/appointment/appointment-list-operation.ts
|
|
9644
9591
|
async function listAppointmentsOperation(params) {
|
|
9645
9592
|
const { context, tableName, mode } = params;
|
|
@@ -9814,123 +9761,93 @@ function getDefaultPostgresQueryRunner() {
|
|
|
9814
9761
|
return cached;
|
|
9815
9762
|
}
|
|
9816
9763
|
|
|
9817
|
-
// src/data/
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
]
|
|
9826
|
-
function isPeriodSearchPrefix(s) {
|
|
9827
|
-
return PERIOD_SEARCH_PREFIXES.includes(s);
|
|
9764
|
+
// src/data/search/engine/date-predicate.ts
|
|
9765
|
+
function flatJsonbExtract(jsonbPath) {
|
|
9766
|
+
const match = /^\$\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(jsonbPath);
|
|
9767
|
+
if (!match) {
|
|
9768
|
+
throw new Error(
|
|
9769
|
+
`Generic date predicate requires a flat top-level JSONPath like "$.fieldName"; received "${jsonbPath}".`
|
|
9770
|
+
);
|
|
9771
|
+
}
|
|
9772
|
+
return `resource->>'${match[1]}'`;
|
|
9828
9773
|
}
|
|
9829
|
-
var
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9774
|
+
var DEFAULT_INTERVAL_PARAM_PREFIX = "intervalDateConstraint";
|
|
9775
|
+
function intervalConstraintParamName(prefix, index) {
|
|
9776
|
+
return `${prefix}${index}`;
|
|
9777
|
+
}
|
|
9778
|
+
function buildIntervalSingleSql(prefix, startExtract, endExtract, paramName) {
|
|
9833
9779
|
switch (prefix) {
|
|
9780
|
+
case "eq":
|
|
9781
|
+
return `(${startExtract} IS NOT NULL AND ${startExtract} = :${paramName})`;
|
|
9834
9782
|
case "gt":
|
|
9835
|
-
return `(${
|
|
9783
|
+
return `(${endExtract} IS NULL OR ${endExtract} > :${paramName})`;
|
|
9836
9784
|
case "lt":
|
|
9837
|
-
return `(${
|
|
9785
|
+
return `(${startExtract} IS NULL OR ${startExtract} < :${paramName})`;
|
|
9838
9786
|
case "ge":
|
|
9839
|
-
return `(${
|
|
9787
|
+
return `(${endExtract} IS NULL OR ${endExtract} >= :${paramName})`;
|
|
9840
9788
|
case "le":
|
|
9841
|
-
return `(${
|
|
9789
|
+
return `(${startExtract} IS NULL OR ${startExtract} <= :${paramName})`;
|
|
9842
9790
|
case "sa":
|
|
9843
|
-
return `(${
|
|
9791
|
+
return `(${startExtract} IS NOT NULL AND ${startExtract} > :${paramName})`;
|
|
9844
9792
|
case "eb":
|
|
9845
|
-
return `(${
|
|
9793
|
+
return `(${endExtract} IS NOT NULL AND ${endExtract} < :${paramName})`;
|
|
9846
9794
|
}
|
|
9847
9795
|
}
|
|
9848
|
-
function
|
|
9849
|
-
return `periodConstraint${index}`;
|
|
9850
|
-
}
|
|
9851
|
-
function buildPeriodSearchPredicateSql(constraints) {
|
|
9796
|
+
function buildIntervalDateSearchPredicateSql(constraints, opts) {
|
|
9852
9797
|
if (constraints.length === 0) {
|
|
9853
9798
|
return [];
|
|
9854
9799
|
}
|
|
9800
|
+
const paramPrefix = opts.paramNamePrefix ?? DEFAULT_INTERVAL_PARAM_PREFIX;
|
|
9801
|
+
const startExtract = flatJsonbExtract(opts.startPath);
|
|
9802
|
+
const endExtract = flatJsonbExtract(opts.endPath);
|
|
9855
9803
|
const fragments = constraints.map(
|
|
9856
|
-
(c, i) =>
|
|
9804
|
+
(c, i) => buildIntervalSingleSql(
|
|
9805
|
+
c.prefix,
|
|
9806
|
+
startExtract,
|
|
9807
|
+
endExtract,
|
|
9808
|
+
intervalConstraintParamName(paramPrefix, i)
|
|
9809
|
+
)
|
|
9857
9810
|
);
|
|
9858
|
-
fragments.push(
|
|
9811
|
+
fragments.push(`(${startExtract} IS NOT NULL OR ${endExtract} IS NOT NULL)`);
|
|
9859
9812
|
return fragments;
|
|
9860
9813
|
}
|
|
9861
|
-
function
|
|
9814
|
+
function buildIntervalDateSearchPredicateParams(constraints, opts) {
|
|
9815
|
+
const paramPrefix = opts?.paramNamePrefix ?? DEFAULT_INTERVAL_PARAM_PREFIX;
|
|
9862
9816
|
return constraints.map((c, i) => ({
|
|
9863
|
-
name:
|
|
9817
|
+
name: intervalConstraintParamName(paramPrefix, i),
|
|
9864
9818
|
value: c.value
|
|
9865
9819
|
}));
|
|
9866
9820
|
}
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9821
|
+
var APPOINTMENT_DATE_SEARCH_PREFIXES = [
|
|
9822
|
+
"gt",
|
|
9823
|
+
"lt",
|
|
9824
|
+
"ge",
|
|
9825
|
+
"le",
|
|
9826
|
+
"sa",
|
|
9827
|
+
"eb"
|
|
9828
|
+
];
|
|
9829
|
+
function isAppointmentDateSearchPrefix(s) {
|
|
9830
|
+
return APPOINTMENT_DATE_SEARCH_PREFIXES.includes(
|
|
9831
|
+
s
|
|
9876
9832
|
);
|
|
9877
|
-
const lines = [
|
|
9878
|
-
"SELECT resource_id AS id, resource",
|
|
9879
|
-
"FROM resources",
|
|
9880
|
-
"WHERE tenant_id = :tenantId",
|
|
9881
|
-
" AND workspace_id = :workspaceId",
|
|
9882
|
-
" AND resource_type = 'Encounter'",
|
|
9883
|
-
" AND deleted_at IS NULL",
|
|
9884
|
-
" AND (resource @> :containmentRelative::jsonb",
|
|
9885
|
-
" OR resource @> :containmentUrn::jsonb)"
|
|
9886
|
-
];
|
|
9887
|
-
for (const fragment of periodPredicates) {
|
|
9888
|
-
lines.push(` AND ${fragment}`);
|
|
9889
|
-
}
|
|
9890
|
-
lines.push("ORDER BY last_updated DESC");
|
|
9891
|
-
lines.push("LIMIT :limit;");
|
|
9892
|
-
return lines.join("\n");
|
|
9893
9833
|
}
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
9898
|
-
|
|
9899
|
-
const limit = params.limit ?? DEFAULT_LIMIT;
|
|
9900
|
-
const containmentRelative = JSON.stringify({
|
|
9901
|
-
subject: { reference: `Patient/${patientId}` }
|
|
9834
|
+
function buildAppointmentDateSearchPredicateSql(constraints) {
|
|
9835
|
+
return buildIntervalDateSearchPredicateSql(constraints, {
|
|
9836
|
+
startPath: "$.start",
|
|
9837
|
+
endPath: "$.end",
|
|
9838
|
+
paramNamePrefix: "apptDateConstraint"
|
|
9902
9839
|
});
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
workspaceId,
|
|
9908
|
-
resourceType: "Patient",
|
|
9909
|
-
resourceId: patientId
|
|
9910
|
-
})
|
|
9911
|
-
}
|
|
9840
|
+
}
|
|
9841
|
+
function buildAppointmentDateSearchPredicateParams(constraints) {
|
|
9842
|
+
return buildIntervalDateSearchPredicateParams(constraints, {
|
|
9843
|
+
paramNamePrefix: "apptDateConstraint"
|
|
9912
9844
|
});
|
|
9913
|
-
const sql = buildSearchEncountersByPatientSql({ periodConstraints });
|
|
9914
|
-
const queryParams = [
|
|
9915
|
-
{ name: "tenantId", value: tenantId },
|
|
9916
|
-
{ name: "workspaceId", value: workspaceId },
|
|
9917
|
-
{ name: "containmentRelative", value: containmentRelative },
|
|
9918
|
-
{ name: "containmentUrn", value: containmentUrn },
|
|
9919
|
-
{ name: "limit", value: limit },
|
|
9920
|
-
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
9921
|
-
];
|
|
9922
|
-
const rows = await runner.query(sql, queryParams);
|
|
9923
|
-
const entries = rows.map((row) => ({
|
|
9924
|
-
id: row.id,
|
|
9925
|
-
resource: {
|
|
9926
|
-
...row.resource,
|
|
9927
|
-
id: row.id
|
|
9928
|
-
}
|
|
9929
|
-
}));
|
|
9930
|
-
return { entries, total: entries.length };
|
|
9931
9845
|
}
|
|
9932
9846
|
|
|
9933
|
-
// src/data/
|
|
9847
|
+
// src/data/search/engine/reference-predicate.ts
|
|
9848
|
+
function buildOpenHiResourceUrn(opts) {
|
|
9849
|
+
return `urn:ohi:${opts.tenantId}:${opts.workspaceId}:${opts.resourceType}:${opts.resourceId}`;
|
|
9850
|
+
}
|
|
9934
9851
|
var REFERENCE_CONTAINMENT_SQL_FRAGMENT = "(resource @> :containmentRelative::jsonb OR resource @> :containmentUrn::jsonb)";
|
|
9935
9852
|
function parseTypedReference(s) {
|
|
9936
9853
|
const match = /^([A-Za-z][A-Za-z0-9_]*)\/([^\s/]+)$/.exec(s);
|
|
@@ -9971,7 +9888,7 @@ function buildReferenceContainmentPayload(params) {
|
|
|
9971
9888
|
}
|
|
9972
9889
|
|
|
9973
9890
|
// src/data/operations/data/appointment/appointment-search-by-actor-operation.ts
|
|
9974
|
-
var
|
|
9891
|
+
var DEFAULT_LIMIT = 100;
|
|
9975
9892
|
function buildSearchAppointmentsByActorSql(opts) {
|
|
9976
9893
|
const datePredicates = buildAppointmentDateSearchPredicateSql(
|
|
9977
9894
|
opts?.dateConstraints ?? []
|
|
@@ -9997,7 +9914,7 @@ async function searchAppointmentsByActorOperation(params) {
|
|
|
9997
9914
|
const dateConstraints = params.dateConstraints ?? [];
|
|
9998
9915
|
const { tenantId, workspaceId } = context;
|
|
9999
9916
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
10000
|
-
const limit = params.limit ??
|
|
9917
|
+
const limit = params.limit ?? DEFAULT_LIMIT;
|
|
10001
9918
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
10002
9919
|
shape: {
|
|
10003
9920
|
kind: "array-of-objects",
|
|
@@ -10029,7 +9946,7 @@ async function searchAppointmentsByActorOperation(params) {
|
|
|
10029
9946
|
}
|
|
10030
9947
|
|
|
10031
9948
|
// src/data/operations/data/appointment/appointment-search-by-date-operation.ts
|
|
10032
|
-
var
|
|
9949
|
+
var DEFAULT_LIMIT2 = 100;
|
|
10033
9950
|
function buildSearchAppointmentsByDateSql(opts) {
|
|
10034
9951
|
const datePredicates = buildAppointmentDateSearchPredicateSql(
|
|
10035
9952
|
opts.dateConstraints
|
|
@@ -10058,7 +9975,7 @@ async function searchAppointmentsByDateOperation(params) {
|
|
|
10058
9975
|
}
|
|
10059
9976
|
const { tenantId, workspaceId } = context;
|
|
10060
9977
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
10061
|
-
const limit = params.limit ??
|
|
9978
|
+
const limit = params.limit ?? DEFAULT_LIMIT2;
|
|
10062
9979
|
const sql = buildSearchAppointmentsByDateSql({ dateConstraints });
|
|
10063
9980
|
const queryParams = [
|
|
10064
9981
|
{ name: "tenantId", value: tenantId },
|
|
@@ -10078,7 +9995,7 @@ async function searchAppointmentsByDateOperation(params) {
|
|
|
10078
9995
|
}
|
|
10079
9996
|
|
|
10080
9997
|
// src/data/operations/data/appointment/appointment-search-by-patient-operation.ts
|
|
10081
|
-
var
|
|
9998
|
+
var DEFAULT_LIMIT3 = 100;
|
|
10082
9999
|
function buildSearchAppointmentsByPatientSql(opts) {
|
|
10083
10000
|
const datePredicates = buildAppointmentDateSearchPredicateSql(
|
|
10084
10001
|
opts?.dateConstraints ?? []
|
|
@@ -10105,7 +10022,7 @@ async function searchAppointmentsByPatientOperation(params) {
|
|
|
10105
10022
|
const dateConstraints = params.dateConstraints ?? [];
|
|
10106
10023
|
const { tenantId, workspaceId } = context;
|
|
10107
10024
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
10108
|
-
const limit = params.limit ??
|
|
10025
|
+
const limit = params.limit ?? DEFAULT_LIMIT3;
|
|
10109
10026
|
const containmentRelative = JSON.stringify({
|
|
10110
10027
|
participant: [{ actor: { reference: `Patient/${patientId}` } }]
|
|
10111
10028
|
});
|
|
@@ -17821,8 +17738,59 @@ async function listEncountersOperation(params) {
|
|
|
17821
17738
|
);
|
|
17822
17739
|
}
|
|
17823
17740
|
|
|
17741
|
+
// src/data/operations/data/encounter/encounter-period-search-predicate.ts
|
|
17742
|
+
var PERIOD_SEARCH_PREFIXES = [
|
|
17743
|
+
"gt",
|
|
17744
|
+
"lt",
|
|
17745
|
+
"ge",
|
|
17746
|
+
"le",
|
|
17747
|
+
"sa",
|
|
17748
|
+
"eb"
|
|
17749
|
+
];
|
|
17750
|
+
function isPeriodSearchPrefix(s) {
|
|
17751
|
+
return PERIOD_SEARCH_PREFIXES.includes(s);
|
|
17752
|
+
}
|
|
17753
|
+
var PERIOD_START = "resource->'period'->>'start'";
|
|
17754
|
+
var PERIOD_END = "resource->'period'->>'end'";
|
|
17755
|
+
var HAS_ANY_BOUND_GUARD = `(${PERIOD_START} IS NOT NULL OR ${PERIOD_END} IS NOT NULL)`;
|
|
17756
|
+
function buildSinglePredicateSql(prefix, paramName) {
|
|
17757
|
+
switch (prefix) {
|
|
17758
|
+
case "gt":
|
|
17759
|
+
return `(${PERIOD_END} IS NULL OR ${PERIOD_END} > :${paramName})`;
|
|
17760
|
+
case "lt":
|
|
17761
|
+
return `(${PERIOD_START} IS NULL OR ${PERIOD_START} < :${paramName})`;
|
|
17762
|
+
case "ge":
|
|
17763
|
+
return `(${PERIOD_END} IS NULL OR ${PERIOD_END} >= :${paramName})`;
|
|
17764
|
+
case "le":
|
|
17765
|
+
return `(${PERIOD_START} IS NULL OR ${PERIOD_START} <= :${paramName})`;
|
|
17766
|
+
case "sa":
|
|
17767
|
+
return `(${PERIOD_START} IS NOT NULL AND ${PERIOD_START} > :${paramName})`;
|
|
17768
|
+
case "eb":
|
|
17769
|
+
return `(${PERIOD_END} IS NOT NULL AND ${PERIOD_END} < :${paramName})`;
|
|
17770
|
+
}
|
|
17771
|
+
}
|
|
17772
|
+
function periodConstraintParamName(index) {
|
|
17773
|
+
return `periodConstraint${index}`;
|
|
17774
|
+
}
|
|
17775
|
+
function buildPeriodSearchPredicateSql(constraints) {
|
|
17776
|
+
if (constraints.length === 0) {
|
|
17777
|
+
return [];
|
|
17778
|
+
}
|
|
17779
|
+
const fragments = constraints.map(
|
|
17780
|
+
(c, i) => buildSinglePredicateSql(c.prefix, periodConstraintParamName(i))
|
|
17781
|
+
);
|
|
17782
|
+
fragments.push(HAS_ANY_BOUND_GUARD);
|
|
17783
|
+
return fragments;
|
|
17784
|
+
}
|
|
17785
|
+
function buildPeriodSearchPredicateParams(constraints) {
|
|
17786
|
+
return constraints.map((c, i) => ({
|
|
17787
|
+
name: periodConstraintParamName(i),
|
|
17788
|
+
value: c.value
|
|
17789
|
+
}));
|
|
17790
|
+
}
|
|
17791
|
+
|
|
17824
17792
|
// src/data/operations/data/encounter/encounter-search-by-date-operation.ts
|
|
17825
|
-
var
|
|
17793
|
+
var DEFAULT_LIMIT4 = 100;
|
|
17826
17794
|
function buildSearchEncountersByDateSql(opts) {
|
|
17827
17795
|
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
17828
17796
|
opts.periodConstraints
|
|
@@ -17851,7 +17819,7 @@ async function searchEncountersByDateOperation(params) {
|
|
|
17851
17819
|
}
|
|
17852
17820
|
const { tenantId, workspaceId } = context;
|
|
17853
17821
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
17854
|
-
const limit = params.limit ??
|
|
17822
|
+
const limit = params.limit ?? DEFAULT_LIMIT4;
|
|
17855
17823
|
const sql = buildSearchEncountersByDateSql({ periodConstraints });
|
|
17856
17824
|
const queryParams = [
|
|
17857
17825
|
{ name: "tenantId", value: tenantId },
|
|
@@ -17871,7 +17839,7 @@ async function searchEncountersByDateOperation(params) {
|
|
|
17871
17839
|
}
|
|
17872
17840
|
|
|
17873
17841
|
// src/data/operations/data/encounter/encounter-search-by-participant-operation.ts
|
|
17874
|
-
var
|
|
17842
|
+
var DEFAULT_LIMIT5 = 100;
|
|
17875
17843
|
function buildSearchEncountersByParticipantSql(opts) {
|
|
17876
17844
|
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
17877
17845
|
opts?.periodConstraints ?? []
|
|
@@ -17897,7 +17865,7 @@ async function searchEncountersByParticipantOperation(params) {
|
|
|
17897
17865
|
const periodConstraints = params.periodConstraints ?? [];
|
|
17898
17866
|
const { tenantId, workspaceId } = context;
|
|
17899
17867
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
17900
|
-
const limit = params.limit ??
|
|
17868
|
+
const limit = params.limit ?? DEFAULT_LIMIT5;
|
|
17901
17869
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
17902
17870
|
shape: {
|
|
17903
17871
|
kind: "array-of-objects",
|
|
@@ -17928,6 +17896,68 @@ async function searchEncountersByParticipantOperation(params) {
|
|
|
17928
17896
|
return { entries, total: entries.length };
|
|
17929
17897
|
}
|
|
17930
17898
|
|
|
17899
|
+
// src/data/operations/data/encounter/encounter-search-by-patient-operation.ts
|
|
17900
|
+
var DEFAULT_LIMIT6 = 100;
|
|
17901
|
+
function buildSearchEncountersByPatientSql(opts) {
|
|
17902
|
+
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
17903
|
+
opts?.periodConstraints ?? []
|
|
17904
|
+
);
|
|
17905
|
+
const lines = [
|
|
17906
|
+
"SELECT resource_id AS id, resource",
|
|
17907
|
+
"FROM resources",
|
|
17908
|
+
"WHERE tenant_id = :tenantId",
|
|
17909
|
+
" AND workspace_id = :workspaceId",
|
|
17910
|
+
" AND resource_type = 'Encounter'",
|
|
17911
|
+
" AND deleted_at IS NULL",
|
|
17912
|
+
" AND (resource @> :containmentRelative::jsonb",
|
|
17913
|
+
" OR resource @> :containmentUrn::jsonb)"
|
|
17914
|
+
];
|
|
17915
|
+
for (const fragment of periodPredicates) {
|
|
17916
|
+
lines.push(` AND ${fragment}`);
|
|
17917
|
+
}
|
|
17918
|
+
lines.push("ORDER BY last_updated DESC");
|
|
17919
|
+
lines.push("LIMIT :limit;");
|
|
17920
|
+
return lines.join("\n");
|
|
17921
|
+
}
|
|
17922
|
+
async function searchEncountersByPatientOperation(params) {
|
|
17923
|
+
const { context, patientId } = params;
|
|
17924
|
+
const periodConstraints = params.periodConstraints ?? [];
|
|
17925
|
+
const { tenantId, workspaceId } = context;
|
|
17926
|
+
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
17927
|
+
const limit = params.limit ?? DEFAULT_LIMIT6;
|
|
17928
|
+
const containmentRelative = JSON.stringify({
|
|
17929
|
+
subject: { reference: `Patient/${patientId}` }
|
|
17930
|
+
});
|
|
17931
|
+
const containmentUrn = JSON.stringify({
|
|
17932
|
+
subject: {
|
|
17933
|
+
reference: buildOpenHiResourceUrn({
|
|
17934
|
+
tenantId,
|
|
17935
|
+
workspaceId,
|
|
17936
|
+
resourceType: "Patient",
|
|
17937
|
+
resourceId: patientId
|
|
17938
|
+
})
|
|
17939
|
+
}
|
|
17940
|
+
});
|
|
17941
|
+
const sql = buildSearchEncountersByPatientSql({ periodConstraints });
|
|
17942
|
+
const queryParams = [
|
|
17943
|
+
{ name: "tenantId", value: tenantId },
|
|
17944
|
+
{ name: "workspaceId", value: workspaceId },
|
|
17945
|
+
{ name: "containmentRelative", value: containmentRelative },
|
|
17946
|
+
{ name: "containmentUrn", value: containmentUrn },
|
|
17947
|
+
{ name: "limit", value: limit },
|
|
17948
|
+
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
17949
|
+
];
|
|
17950
|
+
const rows = await runner.query(sql, queryParams);
|
|
17951
|
+
const entries = rows.map((row) => ({
|
|
17952
|
+
id: row.id,
|
|
17953
|
+
resource: {
|
|
17954
|
+
...row.resource,
|
|
17955
|
+
id: row.id
|
|
17956
|
+
}
|
|
17957
|
+
}));
|
|
17958
|
+
return { entries, total: entries.length };
|
|
17959
|
+
}
|
|
17960
|
+
|
|
17931
17961
|
// src/data/rest-api/routes/data/encounter/encounter-list-route.ts
|
|
17932
17962
|
function singleStringQueryParam2(req, name) {
|
|
17933
17963
|
const v = req.query[name];
|