@openhi/constructs 0.0.122 → 0.0.123
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.
|
@@ -5394,59 +5394,6 @@ async function getAppointmentByIdRoute(req, res) {
|
|
|
5394
5394
|
}
|
|
5395
5395
|
}
|
|
5396
5396
|
|
|
5397
|
-
// src/data/operations/data/appointment/appointment-date-search-predicate.ts
|
|
5398
|
-
var APPOINTMENT_DATE_SEARCH_PREFIXES = [
|
|
5399
|
-
"gt",
|
|
5400
|
-
"lt",
|
|
5401
|
-
"ge",
|
|
5402
|
-
"le",
|
|
5403
|
-
"sa",
|
|
5404
|
-
"eb"
|
|
5405
|
-
];
|
|
5406
|
-
function isAppointmentDateSearchPrefix(s) {
|
|
5407
|
-
return APPOINTMENT_DATE_SEARCH_PREFIXES.includes(
|
|
5408
|
-
s
|
|
5409
|
-
);
|
|
5410
|
-
}
|
|
5411
|
-
var APPT_START = "resource->>'start'";
|
|
5412
|
-
var APPT_END = "resource->>'end'";
|
|
5413
|
-
var HAS_ANY_BOUND_GUARD = `(${APPT_START} IS NOT NULL OR ${APPT_END} IS NOT NULL)`;
|
|
5414
|
-
function buildSinglePredicateSql(prefix, paramName) {
|
|
5415
|
-
switch (prefix) {
|
|
5416
|
-
case "gt":
|
|
5417
|
-
return `(${APPT_END} IS NULL OR ${APPT_END} > :${paramName})`;
|
|
5418
|
-
case "lt":
|
|
5419
|
-
return `(${APPT_START} IS NULL OR ${APPT_START} < :${paramName})`;
|
|
5420
|
-
case "ge":
|
|
5421
|
-
return `(${APPT_END} IS NULL OR ${APPT_END} >= :${paramName})`;
|
|
5422
|
-
case "le":
|
|
5423
|
-
return `(${APPT_START} IS NULL OR ${APPT_START} <= :${paramName})`;
|
|
5424
|
-
case "sa":
|
|
5425
|
-
return `(${APPT_START} IS NOT NULL AND ${APPT_START} > :${paramName})`;
|
|
5426
|
-
case "eb":
|
|
5427
|
-
return `(${APPT_END} IS NOT NULL AND ${APPT_END} < :${paramName})`;
|
|
5428
|
-
}
|
|
5429
|
-
}
|
|
5430
|
-
function appointmentDateConstraintParamName(index) {
|
|
5431
|
-
return `apptDateConstraint${index}`;
|
|
5432
|
-
}
|
|
5433
|
-
function buildAppointmentDateSearchPredicateSql(constraints) {
|
|
5434
|
-
if (constraints.length === 0) {
|
|
5435
|
-
return [];
|
|
5436
|
-
}
|
|
5437
|
-
const fragments = constraints.map(
|
|
5438
|
-
(c, i) => buildSinglePredicateSql(c.prefix, appointmentDateConstraintParamName(i))
|
|
5439
|
-
);
|
|
5440
|
-
fragments.push(HAS_ANY_BOUND_GUARD);
|
|
5441
|
-
return fragments;
|
|
5442
|
-
}
|
|
5443
|
-
function buildAppointmentDateSearchPredicateParams(constraints) {
|
|
5444
|
-
return constraints.map((c, i) => ({
|
|
5445
|
-
name: appointmentDateConstraintParamName(i),
|
|
5446
|
-
value: c.value
|
|
5447
|
-
}));
|
|
5448
|
-
}
|
|
5449
|
-
|
|
5450
5397
|
// src/data/operations/data/appointment/appointment-list-operation.ts
|
|
5451
5398
|
async function listAppointmentsOperation(params) {
|
|
5452
5399
|
const { context, tableName, mode } = params;
|
|
@@ -5584,123 +5531,93 @@ function getDefaultPostgresQueryRunner() {
|
|
|
5584
5531
|
return cached;
|
|
5585
5532
|
}
|
|
5586
5533
|
|
|
5587
|
-
// src/data/
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
]
|
|
5596
|
-
function isPeriodSearchPrefix(s) {
|
|
5597
|
-
return PERIOD_SEARCH_PREFIXES.includes(s);
|
|
5534
|
+
// src/data/search/engine/date-predicate.ts
|
|
5535
|
+
function flatJsonbExtract(jsonbPath) {
|
|
5536
|
+
const match = /^\$\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(jsonbPath);
|
|
5537
|
+
if (!match) {
|
|
5538
|
+
throw new Error(
|
|
5539
|
+
`Generic date predicate requires a flat top-level JSONPath like "$.fieldName"; received "${jsonbPath}".`
|
|
5540
|
+
);
|
|
5541
|
+
}
|
|
5542
|
+
return `resource->>'${match[1]}'`;
|
|
5598
5543
|
}
|
|
5599
|
-
var
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5544
|
+
var DEFAULT_INTERVAL_PARAM_PREFIX = "intervalDateConstraint";
|
|
5545
|
+
function intervalConstraintParamName(prefix, index) {
|
|
5546
|
+
return `${prefix}${index}`;
|
|
5547
|
+
}
|
|
5548
|
+
function buildIntervalSingleSql(prefix, startExtract, endExtract, paramName) {
|
|
5603
5549
|
switch (prefix) {
|
|
5550
|
+
case "eq":
|
|
5551
|
+
return `(${startExtract} IS NOT NULL AND ${startExtract} = :${paramName})`;
|
|
5604
5552
|
case "gt":
|
|
5605
|
-
return `(${
|
|
5553
|
+
return `(${endExtract} IS NULL OR ${endExtract} > :${paramName})`;
|
|
5606
5554
|
case "lt":
|
|
5607
|
-
return `(${
|
|
5555
|
+
return `(${startExtract} IS NULL OR ${startExtract} < :${paramName})`;
|
|
5608
5556
|
case "ge":
|
|
5609
|
-
return `(${
|
|
5557
|
+
return `(${endExtract} IS NULL OR ${endExtract} >= :${paramName})`;
|
|
5610
5558
|
case "le":
|
|
5611
|
-
return `(${
|
|
5559
|
+
return `(${startExtract} IS NULL OR ${startExtract} <= :${paramName})`;
|
|
5612
5560
|
case "sa":
|
|
5613
|
-
return `(${
|
|
5561
|
+
return `(${startExtract} IS NOT NULL AND ${startExtract} > :${paramName})`;
|
|
5614
5562
|
case "eb":
|
|
5615
|
-
return `(${
|
|
5563
|
+
return `(${endExtract} IS NOT NULL AND ${endExtract} < :${paramName})`;
|
|
5616
5564
|
}
|
|
5617
5565
|
}
|
|
5618
|
-
function
|
|
5619
|
-
return `periodConstraint${index}`;
|
|
5620
|
-
}
|
|
5621
|
-
function buildPeriodSearchPredicateSql(constraints) {
|
|
5566
|
+
function buildIntervalDateSearchPredicateSql(constraints, opts) {
|
|
5622
5567
|
if (constraints.length === 0) {
|
|
5623
5568
|
return [];
|
|
5624
5569
|
}
|
|
5570
|
+
const paramPrefix = opts.paramNamePrefix ?? DEFAULT_INTERVAL_PARAM_PREFIX;
|
|
5571
|
+
const startExtract = flatJsonbExtract(opts.startPath);
|
|
5572
|
+
const endExtract = flatJsonbExtract(opts.endPath);
|
|
5625
5573
|
const fragments = constraints.map(
|
|
5626
|
-
(c, i) =>
|
|
5574
|
+
(c, i) => buildIntervalSingleSql(
|
|
5575
|
+
c.prefix,
|
|
5576
|
+
startExtract,
|
|
5577
|
+
endExtract,
|
|
5578
|
+
intervalConstraintParamName(paramPrefix, i)
|
|
5579
|
+
)
|
|
5627
5580
|
);
|
|
5628
|
-
fragments.push(
|
|
5581
|
+
fragments.push(`(${startExtract} IS NOT NULL OR ${endExtract} IS NOT NULL)`);
|
|
5629
5582
|
return fragments;
|
|
5630
5583
|
}
|
|
5631
|
-
function
|
|
5584
|
+
function buildIntervalDateSearchPredicateParams(constraints, opts) {
|
|
5585
|
+
const paramPrefix = opts?.paramNamePrefix ?? DEFAULT_INTERVAL_PARAM_PREFIX;
|
|
5632
5586
|
return constraints.map((c, i) => ({
|
|
5633
|
-
name:
|
|
5587
|
+
name: intervalConstraintParamName(paramPrefix, i),
|
|
5634
5588
|
value: c.value
|
|
5635
5589
|
}));
|
|
5636
5590
|
}
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5591
|
+
var APPOINTMENT_DATE_SEARCH_PREFIXES = [
|
|
5592
|
+
"gt",
|
|
5593
|
+
"lt",
|
|
5594
|
+
"ge",
|
|
5595
|
+
"le",
|
|
5596
|
+
"sa",
|
|
5597
|
+
"eb"
|
|
5598
|
+
];
|
|
5599
|
+
function isAppointmentDateSearchPrefix(s) {
|
|
5600
|
+
return APPOINTMENT_DATE_SEARCH_PREFIXES.includes(
|
|
5601
|
+
s
|
|
5646
5602
|
);
|
|
5647
|
-
const lines = [
|
|
5648
|
-
"SELECT resource_id AS id, resource",
|
|
5649
|
-
"FROM resources",
|
|
5650
|
-
"WHERE tenant_id = :tenantId",
|
|
5651
|
-
" AND workspace_id = :workspaceId",
|
|
5652
|
-
" AND resource_type = 'Encounter'",
|
|
5653
|
-
" AND deleted_at IS NULL",
|
|
5654
|
-
" AND (resource @> :containmentRelative::jsonb",
|
|
5655
|
-
" OR resource @> :containmentUrn::jsonb)"
|
|
5656
|
-
];
|
|
5657
|
-
for (const fragment of periodPredicates) {
|
|
5658
|
-
lines.push(` AND ${fragment}`);
|
|
5659
|
-
}
|
|
5660
|
-
lines.push("ORDER BY last_updated DESC");
|
|
5661
|
-
lines.push("LIMIT :limit;");
|
|
5662
|
-
return lines.join("\n");
|
|
5663
5603
|
}
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
const limit = params.limit ?? DEFAULT_LIMIT;
|
|
5670
|
-
const containmentRelative = JSON.stringify({
|
|
5671
|
-
subject: { reference: `Patient/${patientId}` }
|
|
5604
|
+
function buildAppointmentDateSearchPredicateSql(constraints) {
|
|
5605
|
+
return buildIntervalDateSearchPredicateSql(constraints, {
|
|
5606
|
+
startPath: "$.start",
|
|
5607
|
+
endPath: "$.end",
|
|
5608
|
+
paramNamePrefix: "apptDateConstraint"
|
|
5672
5609
|
});
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
workspaceId,
|
|
5678
|
-
resourceType: "Patient",
|
|
5679
|
-
resourceId: patientId
|
|
5680
|
-
})
|
|
5681
|
-
}
|
|
5610
|
+
}
|
|
5611
|
+
function buildAppointmentDateSearchPredicateParams(constraints) {
|
|
5612
|
+
return buildIntervalDateSearchPredicateParams(constraints, {
|
|
5613
|
+
paramNamePrefix: "apptDateConstraint"
|
|
5682
5614
|
});
|
|
5683
|
-
const sql = buildSearchEncountersByPatientSql({ periodConstraints });
|
|
5684
|
-
const queryParams = [
|
|
5685
|
-
{ name: "tenantId", value: tenantId },
|
|
5686
|
-
{ name: "workspaceId", value: workspaceId },
|
|
5687
|
-
{ name: "containmentRelative", value: containmentRelative },
|
|
5688
|
-
{ name: "containmentUrn", value: containmentUrn },
|
|
5689
|
-
{ name: "limit", value: limit },
|
|
5690
|
-
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
5691
|
-
];
|
|
5692
|
-
const rows = await runner.query(sql, queryParams);
|
|
5693
|
-
const entries = rows.map((row) => ({
|
|
5694
|
-
id: row.id,
|
|
5695
|
-
resource: {
|
|
5696
|
-
...row.resource,
|
|
5697
|
-
id: row.id
|
|
5698
|
-
}
|
|
5699
|
-
}));
|
|
5700
|
-
return { entries, total: entries.length };
|
|
5701
5615
|
}
|
|
5702
5616
|
|
|
5703
|
-
// src/data/
|
|
5617
|
+
// src/data/search/engine/reference-predicate.ts
|
|
5618
|
+
function buildOpenHiResourceUrn(opts) {
|
|
5619
|
+
return `urn:ohi:${opts.tenantId}:${opts.workspaceId}:${opts.resourceType}:${opts.resourceId}`;
|
|
5620
|
+
}
|
|
5704
5621
|
var REFERENCE_CONTAINMENT_SQL_FRAGMENT = "(resource @> :containmentRelative::jsonb OR resource @> :containmentUrn::jsonb)";
|
|
5705
5622
|
function parseTypedReference(s) {
|
|
5706
5623
|
const match = /^([A-Za-z][A-Za-z0-9_]*)\/([^\s/]+)$/.exec(s);
|
|
@@ -5741,7 +5658,7 @@ function buildReferenceContainmentPayload(params) {
|
|
|
5741
5658
|
}
|
|
5742
5659
|
|
|
5743
5660
|
// src/data/operations/data/appointment/appointment-search-by-actor-operation.ts
|
|
5744
|
-
var
|
|
5661
|
+
var DEFAULT_LIMIT = 100;
|
|
5745
5662
|
function buildSearchAppointmentsByActorSql(opts) {
|
|
5746
5663
|
const datePredicates = buildAppointmentDateSearchPredicateSql(
|
|
5747
5664
|
opts?.dateConstraints ?? []
|
|
@@ -5767,7 +5684,7 @@ async function searchAppointmentsByActorOperation(params) {
|
|
|
5767
5684
|
const dateConstraints = params.dateConstraints ?? [];
|
|
5768
5685
|
const { tenantId, workspaceId } = context;
|
|
5769
5686
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
5770
|
-
const limit = params.limit ??
|
|
5687
|
+
const limit = params.limit ?? DEFAULT_LIMIT;
|
|
5771
5688
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
5772
5689
|
shape: {
|
|
5773
5690
|
kind: "array-of-objects",
|
|
@@ -5799,7 +5716,7 @@ async function searchAppointmentsByActorOperation(params) {
|
|
|
5799
5716
|
}
|
|
5800
5717
|
|
|
5801
5718
|
// src/data/operations/data/appointment/appointment-search-by-date-operation.ts
|
|
5802
|
-
var
|
|
5719
|
+
var DEFAULT_LIMIT2 = 100;
|
|
5803
5720
|
function buildSearchAppointmentsByDateSql(opts) {
|
|
5804
5721
|
const datePredicates = buildAppointmentDateSearchPredicateSql(
|
|
5805
5722
|
opts.dateConstraints
|
|
@@ -5828,7 +5745,7 @@ async function searchAppointmentsByDateOperation(params) {
|
|
|
5828
5745
|
}
|
|
5829
5746
|
const { tenantId, workspaceId } = context;
|
|
5830
5747
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
5831
|
-
const limit = params.limit ??
|
|
5748
|
+
const limit = params.limit ?? DEFAULT_LIMIT2;
|
|
5832
5749
|
const sql = buildSearchAppointmentsByDateSql({ dateConstraints });
|
|
5833
5750
|
const queryParams = [
|
|
5834
5751
|
{ name: "tenantId", value: tenantId },
|
|
@@ -5848,7 +5765,7 @@ async function searchAppointmentsByDateOperation(params) {
|
|
|
5848
5765
|
}
|
|
5849
5766
|
|
|
5850
5767
|
// src/data/operations/data/appointment/appointment-search-by-patient-operation.ts
|
|
5851
|
-
var
|
|
5768
|
+
var DEFAULT_LIMIT3 = 100;
|
|
5852
5769
|
function buildSearchAppointmentsByPatientSql(opts) {
|
|
5853
5770
|
const datePredicates = buildAppointmentDateSearchPredicateSql(
|
|
5854
5771
|
opts?.dateConstraints ?? []
|
|
@@ -5875,7 +5792,7 @@ async function searchAppointmentsByPatientOperation(params) {
|
|
|
5875
5792
|
const dateConstraints = params.dateConstraints ?? [];
|
|
5876
5793
|
const { tenantId, workspaceId } = context;
|
|
5877
5794
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
5878
|
-
const limit = params.limit ??
|
|
5795
|
+
const limit = params.limit ?? DEFAULT_LIMIT3;
|
|
5879
5796
|
const containmentRelative = JSON.stringify({
|
|
5880
5797
|
participant: [{ actor: { reference: `Patient/${patientId}` } }]
|
|
5881
5798
|
});
|
|
@@ -13556,8 +13473,59 @@ async function listEncountersOperation(params) {
|
|
|
13556
13473
|
);
|
|
13557
13474
|
}
|
|
13558
13475
|
|
|
13476
|
+
// src/data/operations/data/encounter/encounter-period-search-predicate.ts
|
|
13477
|
+
var PERIOD_SEARCH_PREFIXES = [
|
|
13478
|
+
"gt",
|
|
13479
|
+
"lt",
|
|
13480
|
+
"ge",
|
|
13481
|
+
"le",
|
|
13482
|
+
"sa",
|
|
13483
|
+
"eb"
|
|
13484
|
+
];
|
|
13485
|
+
function isPeriodSearchPrefix(s) {
|
|
13486
|
+
return PERIOD_SEARCH_PREFIXES.includes(s);
|
|
13487
|
+
}
|
|
13488
|
+
var PERIOD_START = "resource->'period'->>'start'";
|
|
13489
|
+
var PERIOD_END = "resource->'period'->>'end'";
|
|
13490
|
+
var HAS_ANY_BOUND_GUARD = `(${PERIOD_START} IS NOT NULL OR ${PERIOD_END} IS NOT NULL)`;
|
|
13491
|
+
function buildSinglePredicateSql(prefix, paramName) {
|
|
13492
|
+
switch (prefix) {
|
|
13493
|
+
case "gt":
|
|
13494
|
+
return `(${PERIOD_END} IS NULL OR ${PERIOD_END} > :${paramName})`;
|
|
13495
|
+
case "lt":
|
|
13496
|
+
return `(${PERIOD_START} IS NULL OR ${PERIOD_START} < :${paramName})`;
|
|
13497
|
+
case "ge":
|
|
13498
|
+
return `(${PERIOD_END} IS NULL OR ${PERIOD_END} >= :${paramName})`;
|
|
13499
|
+
case "le":
|
|
13500
|
+
return `(${PERIOD_START} IS NULL OR ${PERIOD_START} <= :${paramName})`;
|
|
13501
|
+
case "sa":
|
|
13502
|
+
return `(${PERIOD_START} IS NOT NULL AND ${PERIOD_START} > :${paramName})`;
|
|
13503
|
+
case "eb":
|
|
13504
|
+
return `(${PERIOD_END} IS NOT NULL AND ${PERIOD_END} < :${paramName})`;
|
|
13505
|
+
}
|
|
13506
|
+
}
|
|
13507
|
+
function periodConstraintParamName(index) {
|
|
13508
|
+
return `periodConstraint${index}`;
|
|
13509
|
+
}
|
|
13510
|
+
function buildPeriodSearchPredicateSql(constraints) {
|
|
13511
|
+
if (constraints.length === 0) {
|
|
13512
|
+
return [];
|
|
13513
|
+
}
|
|
13514
|
+
const fragments = constraints.map(
|
|
13515
|
+
(c, i) => buildSinglePredicateSql(c.prefix, periodConstraintParamName(i))
|
|
13516
|
+
);
|
|
13517
|
+
fragments.push(HAS_ANY_BOUND_GUARD);
|
|
13518
|
+
return fragments;
|
|
13519
|
+
}
|
|
13520
|
+
function buildPeriodSearchPredicateParams(constraints) {
|
|
13521
|
+
return constraints.map((c, i) => ({
|
|
13522
|
+
name: periodConstraintParamName(i),
|
|
13523
|
+
value: c.value
|
|
13524
|
+
}));
|
|
13525
|
+
}
|
|
13526
|
+
|
|
13559
13527
|
// src/data/operations/data/encounter/encounter-search-by-date-operation.ts
|
|
13560
|
-
var
|
|
13528
|
+
var DEFAULT_LIMIT4 = 100;
|
|
13561
13529
|
function buildSearchEncountersByDateSql(opts) {
|
|
13562
13530
|
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
13563
13531
|
opts.periodConstraints
|
|
@@ -13586,7 +13554,7 @@ async function searchEncountersByDateOperation(params) {
|
|
|
13586
13554
|
}
|
|
13587
13555
|
const { tenantId, workspaceId } = context;
|
|
13588
13556
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
13589
|
-
const limit = params.limit ??
|
|
13557
|
+
const limit = params.limit ?? DEFAULT_LIMIT4;
|
|
13590
13558
|
const sql = buildSearchEncountersByDateSql({ periodConstraints });
|
|
13591
13559
|
const queryParams = [
|
|
13592
13560
|
{ name: "tenantId", value: tenantId },
|
|
@@ -13606,7 +13574,7 @@ async function searchEncountersByDateOperation(params) {
|
|
|
13606
13574
|
}
|
|
13607
13575
|
|
|
13608
13576
|
// src/data/operations/data/encounter/encounter-search-by-participant-operation.ts
|
|
13609
|
-
var
|
|
13577
|
+
var DEFAULT_LIMIT5 = 100;
|
|
13610
13578
|
function buildSearchEncountersByParticipantSql(opts) {
|
|
13611
13579
|
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
13612
13580
|
opts?.periodConstraints ?? []
|
|
@@ -13632,7 +13600,7 @@ async function searchEncountersByParticipantOperation(params) {
|
|
|
13632
13600
|
const periodConstraints = params.periodConstraints ?? [];
|
|
13633
13601
|
const { tenantId, workspaceId } = context;
|
|
13634
13602
|
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
13635
|
-
const limit = params.limit ??
|
|
13603
|
+
const limit = params.limit ?? DEFAULT_LIMIT5;
|
|
13636
13604
|
const { containmentRelative, containmentUrn } = buildReferenceContainmentPayload({
|
|
13637
13605
|
shape: {
|
|
13638
13606
|
kind: "array-of-objects",
|
|
@@ -13663,6 +13631,68 @@ async function searchEncountersByParticipantOperation(params) {
|
|
|
13663
13631
|
return { entries, total: entries.length };
|
|
13664
13632
|
}
|
|
13665
13633
|
|
|
13634
|
+
// src/data/operations/data/encounter/encounter-search-by-patient-operation.ts
|
|
13635
|
+
var DEFAULT_LIMIT6 = 100;
|
|
13636
|
+
function buildSearchEncountersByPatientSql(opts) {
|
|
13637
|
+
const periodPredicates = buildPeriodSearchPredicateSql(
|
|
13638
|
+
opts?.periodConstraints ?? []
|
|
13639
|
+
);
|
|
13640
|
+
const lines = [
|
|
13641
|
+
"SELECT resource_id AS id, resource",
|
|
13642
|
+
"FROM resources",
|
|
13643
|
+
"WHERE tenant_id = :tenantId",
|
|
13644
|
+
" AND workspace_id = :workspaceId",
|
|
13645
|
+
" AND resource_type = 'Encounter'",
|
|
13646
|
+
" AND deleted_at IS NULL",
|
|
13647
|
+
" AND (resource @> :containmentRelative::jsonb",
|
|
13648
|
+
" OR resource @> :containmentUrn::jsonb)"
|
|
13649
|
+
];
|
|
13650
|
+
for (const fragment of periodPredicates) {
|
|
13651
|
+
lines.push(` AND ${fragment}`);
|
|
13652
|
+
}
|
|
13653
|
+
lines.push("ORDER BY last_updated DESC");
|
|
13654
|
+
lines.push("LIMIT :limit;");
|
|
13655
|
+
return lines.join("\n");
|
|
13656
|
+
}
|
|
13657
|
+
async function searchEncountersByPatientOperation(params) {
|
|
13658
|
+
const { context, patientId } = params;
|
|
13659
|
+
const periodConstraints = params.periodConstraints ?? [];
|
|
13660
|
+
const { tenantId, workspaceId } = context;
|
|
13661
|
+
const runner = params.runner ?? getDefaultPostgresQueryRunner();
|
|
13662
|
+
const limit = params.limit ?? DEFAULT_LIMIT6;
|
|
13663
|
+
const containmentRelative = JSON.stringify({
|
|
13664
|
+
subject: { reference: `Patient/${patientId}` }
|
|
13665
|
+
});
|
|
13666
|
+
const containmentUrn = JSON.stringify({
|
|
13667
|
+
subject: {
|
|
13668
|
+
reference: buildOpenHiResourceUrn({
|
|
13669
|
+
tenantId,
|
|
13670
|
+
workspaceId,
|
|
13671
|
+
resourceType: "Patient",
|
|
13672
|
+
resourceId: patientId
|
|
13673
|
+
})
|
|
13674
|
+
}
|
|
13675
|
+
});
|
|
13676
|
+
const sql = buildSearchEncountersByPatientSql({ periodConstraints });
|
|
13677
|
+
const queryParams = [
|
|
13678
|
+
{ name: "tenantId", value: tenantId },
|
|
13679
|
+
{ name: "workspaceId", value: workspaceId },
|
|
13680
|
+
{ name: "containmentRelative", value: containmentRelative },
|
|
13681
|
+
{ name: "containmentUrn", value: containmentUrn },
|
|
13682
|
+
{ name: "limit", value: limit },
|
|
13683
|
+
...buildPeriodSearchPredicateParams(periodConstraints)
|
|
13684
|
+
];
|
|
13685
|
+
const rows = await runner.query(sql, queryParams);
|
|
13686
|
+
const entries = rows.map((row) => ({
|
|
13687
|
+
id: row.id,
|
|
13688
|
+
resource: {
|
|
13689
|
+
...row.resource,
|
|
13690
|
+
id: row.id
|
|
13691
|
+
}
|
|
13692
|
+
}));
|
|
13693
|
+
return { entries, total: entries.length };
|
|
13694
|
+
}
|
|
13695
|
+
|
|
13666
13696
|
// src/data/rest-api/routes/data/encounter/encounter-list-route.ts
|
|
13667
13697
|
function singleStringQueryParam2(req, name) {
|
|
13668
13698
|
const v = req.query[name];
|