@openhi/constructs 0.0.178 → 0.0.180
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.
- package/lib/{chunk-Z4PZSLYY.mjs → chunk-3M4QTQH6.mjs} +2 -2
- package/lib/{chunk-JUSVETWK.mjs → chunk-4LQR32D2.mjs} +38 -40
- package/lib/{chunk-JUSVETWK.mjs.map → chunk-4LQR32D2.mjs.map} +1 -1
- package/lib/{chunk-XNUCKVSE.mjs → chunk-7GMTHOYF.mjs} +2 -2
- package/lib/{chunk-E2OWEBBH.mjs → chunk-DIVYB6GD.mjs} +18 -4
- package/lib/chunk-DIVYB6GD.mjs.map +1 -0
- package/lib/chunk-F2LY4TEI.mjs +272 -0
- package/lib/chunk-F2LY4TEI.mjs.map +1 -0
- package/lib/{chunk-GG2WD6TA.mjs → chunk-JJ3AQ6G5.mjs} +9 -3
- package/lib/{chunk-GG2WD6TA.mjs.map → chunk-JJ3AQ6G5.mjs.map} +1 -1
- package/lib/{chunk-EBB4RNUG.mjs → chunk-PIQISEGW.mjs} +2 -2
- package/lib/{chunk-FDBBTNCI.mjs → chunk-Q4KQD2NB.mjs} +117 -5
- package/lib/chunk-Q4KQD2NB.mjs.map +1 -0
- package/lib/{chunk-Y4RGUAM2.mjs → chunk-V6KLFEHC.mjs} +105 -34
- package/lib/chunk-V6KLFEHC.mjs.map +1 -0
- package/lib/chunk-VQY57NOV.mjs +60 -0
- package/lib/chunk-VQY57NOV.mjs.map +1 -0
- package/lib/counter-maintenance.handler.mjs +4 -4
- package/lib/counter-reconciliation.handler.js +2 -2
- package/lib/counter-reconciliation.handler.js.map +1 -1
- package/lib/counter-reconciliation.handler.mjs +9 -267
- package/lib/counter-reconciliation.handler.mjs.map +1 -1
- package/lib/index.d.mts +117 -2
- package/lib/index.d.ts +117 -2
- package/lib/index.js +6454 -6243
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +106 -4
- package/lib/index.mjs.map +1 -1
- package/lib/pre-token-generation.handler.js +28 -19
- package/lib/pre-token-generation.handler.js.map +1 -1
- package/lib/pre-token-generation.handler.mjs +4 -5
- package/lib/pre-token-generation.handler.mjs.map +1 -1
- package/lib/provision-default-workspace.handler.js +22 -19
- package/lib/provision-default-workspace.handler.js.map +1 -1
- package/lib/provision-default-workspace.handler.mjs +3 -4
- package/lib/provision-default-workspace.handler.mjs.map +1 -1
- package/lib/rest-api-lambda.handler.js +367 -208
- package/lib/rest-api-lambda.handler.js.map +1 -1
- package/lib/rest-api-lambda.handler.mjs +210 -165
- package/lib/rest-api-lambda.handler.mjs.map +1 -1
- package/lib/seed-demo-data.handler.d.mts +19 -0
- package/lib/seed-demo-data.handler.d.ts +19 -0
- package/lib/seed-demo-data.handler.js +805 -159
- package/lib/seed-demo-data.handler.js.map +1 -1
- package/lib/seed-demo-data.handler.mjs +8 -4
- package/package.json +1 -1
- package/lib/chunk-6HGSR3TG.mjs +0 -123
- package/lib/chunk-6HGSR3TG.mjs.map +0 -1
- package/lib/chunk-E2OWEBBH.mjs.map +0 -1
- package/lib/chunk-FDBBTNCI.mjs.map +0 -1
- package/lib/chunk-Y4RGUAM2.mjs.map +0 -1
- /package/lib/{chunk-Z4PZSLYY.mjs.map → chunk-3M4QTQH6.mjs.map} +0 -0
- /package/lib/{chunk-XNUCKVSE.mjs.map → chunk-7GMTHOYF.mjs.map} +0 -0
- /package/lib/{chunk-EBB4RNUG.mjs.map → chunk-PIQISEGW.mjs.map} +0 -0
|
@@ -3578,7 +3578,7 @@ async function deleteDataEntityById(entity, tenantId, workspaceId, id) {
|
|
|
3578
3578
|
}
|
|
3579
3579
|
var BATCH_GET_MAX_ATTEMPTS = 3;
|
|
3580
3580
|
var BATCH_GET_BASE_BACKOFF_MS = 50;
|
|
3581
|
-
async function batchGetWithRetry(entity, keys) {
|
|
3581
|
+
async function batchGetWithRetry(entity, keys, options) {
|
|
3582
3582
|
if (keys.length === 0) return [];
|
|
3583
3583
|
const collected = [];
|
|
3584
3584
|
let pending = keys;
|
|
@@ -3590,7 +3590,7 @@ async function batchGetWithRetry(entity, keys) {
|
|
|
3590
3590
|
);
|
|
3591
3591
|
}
|
|
3592
3592
|
attempt++;
|
|
3593
|
-
const result = await entity.get(pending).go();
|
|
3593
|
+
const result = await entity.get(pending).go(options?.consistent ? { consistent: true } : void 0);
|
|
3594
3594
|
collected.push(...result.data);
|
|
3595
3595
|
const unprocessed = result.unprocessed ?? [];
|
|
3596
3596
|
if (unprocessed.length === 0) break;
|
|
@@ -7153,9 +7153,15 @@ async function listRoleAssignmentsOperation(params) {
|
|
|
7153
7153
|
)
|
|
7154
7154
|
);
|
|
7155
7155
|
return dispatchListMode(mode, shardResults, {
|
|
7156
|
+
// Strongly-consistent BatchGet on the base table so a role change is
|
|
7157
|
+
// reflected immediately by the read-back the admin-console dropdowns
|
|
7158
|
+
// issue right after their PUT/POST. Without it the eventually-consistent
|
|
7159
|
+
// hydration can return the *previous* role, making the dropdown appear
|
|
7160
|
+
// to revert (#1347).
|
|
7156
7161
|
hydrate: (orderedIds) => batchGetWithRetry(
|
|
7157
7162
|
service.entities.roleAssignment,
|
|
7158
|
-
orderedIds.map((id) => ({ tenantId, id, sk: SK8 }))
|
|
7163
|
+
orderedIds.map((id) => ({ tenantId, id, sk: SK8 })),
|
|
7164
|
+
{ consistent: true }
|
|
7159
7165
|
),
|
|
7160
7166
|
getId: (item) => item.id,
|
|
7161
7167
|
buildEntry: (id, item) => ({
|
|
@@ -7543,6 +7549,76 @@ async function listTenantsRoute(req, res) {
|
|
|
7543
7549
|
});
|
|
7544
7550
|
}
|
|
7545
7551
|
|
|
7552
|
+
// src/data/operations/control/roleassignment/roleassignment-list-by-user-operation.ts
|
|
7553
|
+
function buildSkPrefix(mode) {
|
|
7554
|
+
switch (mode) {
|
|
7555
|
+
case "tenant":
|
|
7556
|
+
return "ROLEASSIGNMENT#TENANT#";
|
|
7557
|
+
case "workspace":
|
|
7558
|
+
case "workspaceInTenant":
|
|
7559
|
+
return "ROLEASSIGNMENT#WORKSPACE#";
|
|
7560
|
+
case "all":
|
|
7561
|
+
default:
|
|
7562
|
+
return "ROLEASSIGNMENT#";
|
|
7563
|
+
}
|
|
7564
|
+
}
|
|
7565
|
+
async function roleAssignmentListByUserOperation(params) {
|
|
7566
|
+
const {
|
|
7567
|
+
userId,
|
|
7568
|
+
mode = "all",
|
|
7569
|
+
tenantId,
|
|
7570
|
+
workspaceId,
|
|
7571
|
+
cursor = null,
|
|
7572
|
+
limit,
|
|
7573
|
+
order,
|
|
7574
|
+
consistent,
|
|
7575
|
+
tableName
|
|
7576
|
+
} = params;
|
|
7577
|
+
if (mode === "workspaceInTenant" && !tenantId) {
|
|
7578
|
+
throw new Error(
|
|
7579
|
+
'roleAssignmentListByUserOperation: tenantId is required when mode === "workspaceInTenant"'
|
|
7580
|
+
);
|
|
7581
|
+
}
|
|
7582
|
+
const service = getDynamoControlService(tableName);
|
|
7583
|
+
const skPrefix = buildSkPrefix(mode);
|
|
7584
|
+
const goOptions = {
|
|
7585
|
+
cursor
|
|
7586
|
+
};
|
|
7587
|
+
if (limit !== void 0) {
|
|
7588
|
+
goOptions.limit = limit;
|
|
7589
|
+
}
|
|
7590
|
+
if (order !== void 0) {
|
|
7591
|
+
goOptions.order = order;
|
|
7592
|
+
}
|
|
7593
|
+
if (consistent) {
|
|
7594
|
+
goOptions.consistent = true;
|
|
7595
|
+
}
|
|
7596
|
+
const baseQuery = service.entities.roleAssignmentUserProjection.query.record({ userId }).begins({ sk: skPrefix });
|
|
7597
|
+
const filteredQuery = mode === "workspaceInTenant" ? baseQuery.where((attr, op) => {
|
|
7598
|
+
const tenantClause = op.eq(attr.tenantId, tenantId);
|
|
7599
|
+
if (workspaceId === void 0 || workspaceId.length === 0) {
|
|
7600
|
+
return tenantClause;
|
|
7601
|
+
}
|
|
7602
|
+
return `${tenantClause} AND ${op.eq(attr.workspaceId, workspaceId)}`;
|
|
7603
|
+
}) : baseQuery;
|
|
7604
|
+
const result = await filteredQuery.go(goOptions);
|
|
7605
|
+
const items = (result.data ?? []).map((row) => ({
|
|
7606
|
+
userId: row.userId,
|
|
7607
|
+
sk: row.sk,
|
|
7608
|
+
tenantId: row.tenantId,
|
|
7609
|
+
workspaceId: row.workspaceId,
|
|
7610
|
+
roleId: row.roleId,
|
|
7611
|
+
roleAssignmentId: row.roleAssignmentId,
|
|
7612
|
+
summary: row.summary,
|
|
7613
|
+
vid: row.vid,
|
|
7614
|
+
lastUpdated: row.lastUpdated,
|
|
7615
|
+
denormalizedTenantName: row.denormalizedTenantName,
|
|
7616
|
+
denormalizedUserName: row.denormalizedUserName,
|
|
7617
|
+
denormalizedRoleName: row.denormalizedRoleName
|
|
7618
|
+
}));
|
|
7619
|
+
return { items, cursor: result.cursor ?? null };
|
|
7620
|
+
}
|
|
7621
|
+
|
|
7546
7622
|
// src/data/operations/control/workspace/workspace-list-operation.ts
|
|
7547
7623
|
var SK10 = "CURRENT";
|
|
7548
7624
|
function counterValue2(value) {
|
|
@@ -7626,18 +7702,6 @@ function extractDisplayName(user) {
|
|
|
7626
7702
|
const composed = `${given} ${family}`.trim();
|
|
7627
7703
|
return composed.length > 0 ? composed : null;
|
|
7628
7704
|
}
|
|
7629
|
-
function extractReferenceDisplay(resource, fieldName) {
|
|
7630
|
-
const field = resource[fieldName];
|
|
7631
|
-
if (!field || typeof field !== "object") {
|
|
7632
|
-
return null;
|
|
7633
|
-
}
|
|
7634
|
-
const display = field.display;
|
|
7635
|
-
if (typeof display !== "string") {
|
|
7636
|
-
return null;
|
|
7637
|
-
}
|
|
7638
|
-
const trimmed = display.trim();
|
|
7639
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
7640
|
-
}
|
|
7641
7705
|
function ensureAccumulator(byUser, userId) {
|
|
7642
7706
|
let acc = byUser.get(userId);
|
|
7643
7707
|
if (!acc) {
|
|
@@ -7649,9 +7713,8 @@ function ensureAccumulator(byUser, userId) {
|
|
|
7649
7713
|
async function tenantUsersOperation(params) {
|
|
7650
7714
|
const { context, tableName } = params;
|
|
7651
7715
|
const service = getDynamoControlService(tableName);
|
|
7652
|
-
const [memberships,
|
|
7716
|
+
const [memberships, workspaces] = await Promise.all([
|
|
7653
7717
|
listMembershipsOperation({ context, tableName }),
|
|
7654
|
-
listRoleAssignmentsOperation({ context, tableName }),
|
|
7655
7718
|
listWorkspacesOperation({ context, tableName })
|
|
7656
7719
|
]);
|
|
7657
7720
|
const workspaceNames = /* @__PURE__ */ new Map();
|
|
@@ -7673,34 +7736,46 @@ async function tenantUsersOperation(params) {
|
|
|
7673
7736
|
acc.workspaces.set(workspaceId, { workspaceId, role: null });
|
|
7674
7737
|
}
|
|
7675
7738
|
}
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7739
|
+
const membershipUserIds = Array.from(byUser.keys());
|
|
7740
|
+
const projectionPages = await Promise.all(
|
|
7741
|
+
membershipUserIds.map(
|
|
7742
|
+
(userId) => roleAssignmentListByUserOperation({
|
|
7743
|
+
userId,
|
|
7744
|
+
mode: "all",
|
|
7745
|
+
consistent: true,
|
|
7746
|
+
tableName
|
|
7747
|
+
})
|
|
7748
|
+
)
|
|
7749
|
+
);
|
|
7750
|
+
projectionPages.forEach((page, index) => {
|
|
7751
|
+
const userId = membershipUserIds[index];
|
|
7683
7752
|
const acc = ensureAccumulator(byUser, userId);
|
|
7684
|
-
const
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
const
|
|
7693
|
-
if (
|
|
7694
|
-
|
|
7753
|
+
for (const row of page.items) {
|
|
7754
|
+
if (row.tenantId !== context.tenantId) {
|
|
7755
|
+
continue;
|
|
7756
|
+
}
|
|
7757
|
+
const role = {
|
|
7758
|
+
roleId: row.roleId,
|
|
7759
|
+
roleName: row.denormalizedRoleName ?? null
|
|
7760
|
+
};
|
|
7761
|
+
const workspaceId = row.workspaceId;
|
|
7762
|
+
if (workspaceId === void 0 || workspaceId.length === 0) {
|
|
7763
|
+
acc.tenantRole = role;
|
|
7695
7764
|
} else {
|
|
7696
|
-
acc.workspaces.
|
|
7765
|
+
const existing = acc.workspaces.get(workspaceId);
|
|
7766
|
+
if (existing) {
|
|
7767
|
+
existing.role = role;
|
|
7768
|
+
} else {
|
|
7769
|
+
acc.workspaces.set(workspaceId, { workspaceId, role });
|
|
7770
|
+
}
|
|
7697
7771
|
}
|
|
7698
7772
|
}
|
|
7699
|
-
}
|
|
7773
|
+
});
|
|
7700
7774
|
const userIds = Array.from(byUser.keys());
|
|
7701
7775
|
const userRows = userIds.length === 0 ? [] : await batchGetWithRetry(
|
|
7702
7776
|
service.entities.user,
|
|
7703
|
-
userIds.map((id) => ({ id, sk: USER_SK }))
|
|
7777
|
+
userIds.map((id) => ({ id, sk: USER_SK })),
|
|
7778
|
+
{ consistent: true }
|
|
7704
7779
|
);
|
|
7705
7780
|
const usersById = /* @__PURE__ */ new Map();
|
|
7706
7781
|
for (const row of userRows) {
|
|
@@ -7847,8 +7922,240 @@ router6.delete("/:id", deleteTenantRoute);
|
|
|
7847
7922
|
// src/data/rest-api/routes/control/user/user.ts
|
|
7848
7923
|
var import_express7 = __toESM(require("express"));
|
|
7849
7924
|
|
|
7850
|
-
// src/data/operations/control/user/user-
|
|
7925
|
+
// src/data/operations/control/user/user-admin-set-context-operation.ts
|
|
7851
7926
|
var import_types18 = require("@openhi/types");
|
|
7927
|
+
|
|
7928
|
+
// src/data/operations/control/user/user-get-by-id-operation.ts
|
|
7929
|
+
async function getUserByIdOperation(params) {
|
|
7930
|
+
const { id, tableName } = params;
|
|
7931
|
+
const service = getDynamoControlService(tableName);
|
|
7932
|
+
const response = await service.entities.user.get({ id, sk: "CURRENT" }).go();
|
|
7933
|
+
const item = response.data;
|
|
7934
|
+
if (!item) {
|
|
7935
|
+
throw new NotFoundError(`User not found: ${id}`);
|
|
7936
|
+
}
|
|
7937
|
+
const parsedResource = JSON.parse(item.resource);
|
|
7938
|
+
return {
|
|
7939
|
+
id,
|
|
7940
|
+
resource: { resourceType: "User", id, ...parsedResource }
|
|
7941
|
+
};
|
|
7942
|
+
}
|
|
7943
|
+
|
|
7944
|
+
// src/data/operations/fhir-reference.ts
|
|
7945
|
+
function idFromReference(reference, prefix) {
|
|
7946
|
+
if (!reference || !reference.startsWith(prefix)) {
|
|
7947
|
+
return void 0;
|
|
7948
|
+
}
|
|
7949
|
+
const id = reference.slice(prefix.length);
|
|
7950
|
+
return id.length > 0 ? id : void 0;
|
|
7951
|
+
}
|
|
7952
|
+
|
|
7953
|
+
// src/data/operations/control/membership/membership-list-by-user-operation.ts
|
|
7954
|
+
function buildSkPrefix2(mode, tenantId) {
|
|
7955
|
+
switch (mode) {
|
|
7956
|
+
case "tenant":
|
|
7957
|
+
return "MEMBERSHIP#TENANT#";
|
|
7958
|
+
case "workspace":
|
|
7959
|
+
return "MEMBERSHIP#WORKSPACE#";
|
|
7960
|
+
case "workspaceInTenant":
|
|
7961
|
+
return `MEMBERSHIP#WORKSPACE#TID#${tenantId}#`;
|
|
7962
|
+
case "all":
|
|
7963
|
+
default:
|
|
7964
|
+
return "MEMBERSHIP#";
|
|
7965
|
+
}
|
|
7966
|
+
}
|
|
7967
|
+
async function membershipListByUserOperation(params) {
|
|
7968
|
+
const {
|
|
7969
|
+
userId,
|
|
7970
|
+
mode = "all",
|
|
7971
|
+
tenantId,
|
|
7972
|
+
cursor = null,
|
|
7973
|
+
limit,
|
|
7974
|
+
order,
|
|
7975
|
+
tableName
|
|
7976
|
+
} = params;
|
|
7977
|
+
if (mode === "workspaceInTenant" && !tenantId) {
|
|
7978
|
+
throw new Error(
|
|
7979
|
+
'membershipListByUserOperation: tenantId is required when mode === "workspaceInTenant"'
|
|
7980
|
+
);
|
|
7981
|
+
}
|
|
7982
|
+
const service = getDynamoControlService(tableName);
|
|
7983
|
+
const skPrefix = buildSkPrefix2(mode, tenantId);
|
|
7984
|
+
const goOptions = {
|
|
7985
|
+
cursor
|
|
7986
|
+
};
|
|
7987
|
+
if (limit !== void 0) {
|
|
7988
|
+
goOptions.limit = limit;
|
|
7989
|
+
}
|
|
7990
|
+
if (order !== void 0) {
|
|
7991
|
+
goOptions.order = order;
|
|
7992
|
+
}
|
|
7993
|
+
const result = await service.entities.membershipUserProjection.query.record({ userId }).begins({ sk: skPrefix }).go(goOptions);
|
|
7994
|
+
const items = (result.data ?? []).map(
|
|
7995
|
+
(row) => ({
|
|
7996
|
+
userId: row.userId,
|
|
7997
|
+
sk: row.sk,
|
|
7998
|
+
tenantId: row.tenantId,
|
|
7999
|
+
workspaceId: row.workspaceId,
|
|
8000
|
+
membershipId: row.membershipId,
|
|
8001
|
+
summary: row.summary,
|
|
8002
|
+
vid: row.vid,
|
|
8003
|
+
lastUpdated: row.lastUpdated,
|
|
8004
|
+
denormalizedTenantName: row.denormalizedTenantName,
|
|
8005
|
+
denormalizedUserName: row.denormalizedUserName,
|
|
8006
|
+
denormalizedWorkspaceName: row.denormalizedWorkspaceName
|
|
8007
|
+
})
|
|
8008
|
+
);
|
|
8009
|
+
return { items, cursor: result.cursor ?? null };
|
|
8010
|
+
}
|
|
8011
|
+
|
|
8012
|
+
// src/data/operations/control/user/user-admin-set-context-operation.ts
|
|
8013
|
+
var SK11 = "CURRENT";
|
|
8014
|
+
async function adminSetUserContextOperation(params) {
|
|
8015
|
+
const {
|
|
8016
|
+
context,
|
|
8017
|
+
targetUserId,
|
|
8018
|
+
tenantReference,
|
|
8019
|
+
workspaceReference,
|
|
8020
|
+
tableName
|
|
8021
|
+
} = params;
|
|
8022
|
+
const tenantId = idFromReference(tenantReference, "Tenant/");
|
|
8023
|
+
if (!tenantId) {
|
|
8024
|
+
throw new ValidationError(
|
|
8025
|
+
"tenant.reference must be a 'Tenant/<id>' reference."
|
|
8026
|
+
);
|
|
8027
|
+
}
|
|
8028
|
+
const workspaceId = idFromReference(workspaceReference, "Workspace/");
|
|
8029
|
+
if (!workspaceId) {
|
|
8030
|
+
throw new ValidationError(
|
|
8031
|
+
"workspace.reference must be a 'Workspace/<id>' reference."
|
|
8032
|
+
);
|
|
8033
|
+
}
|
|
8034
|
+
const target = await getUserByIdOperation({
|
|
8035
|
+
context,
|
|
8036
|
+
id: targetUserId,
|
|
8037
|
+
tableName
|
|
8038
|
+
});
|
|
8039
|
+
const projection = await membershipListByUserOperation({
|
|
8040
|
+
userId: targetUserId,
|
|
8041
|
+
mode: "workspaceInTenant",
|
|
8042
|
+
tenantId,
|
|
8043
|
+
tableName
|
|
8044
|
+
});
|
|
8045
|
+
const hasMembership = projection.items.some(
|
|
8046
|
+
(row) => row.workspaceId === workspaceId
|
|
8047
|
+
);
|
|
8048
|
+
if (!hasMembership) {
|
|
8049
|
+
throw new ForbiddenError(
|
|
8050
|
+
`User is not a member of Workspace/${workspaceId} in Tenant/${tenantId}.`
|
|
8051
|
+
);
|
|
8052
|
+
}
|
|
8053
|
+
const updatedResource = {
|
|
8054
|
+
...target.resource,
|
|
8055
|
+
resourceType: "User",
|
|
8056
|
+
id: targetUserId,
|
|
8057
|
+
currentTenant: { reference: `Tenant/${tenantId}` },
|
|
8058
|
+
currentWorkspace: { reference: `Workspace/${workspaceId}` }
|
|
8059
|
+
};
|
|
8060
|
+
const lastUpdated = (params.now ? params.now() : /* @__PURE__ */ new Date()).toISOString();
|
|
8061
|
+
const vid = `${Date.now()}`;
|
|
8062
|
+
const summary = JSON.stringify(
|
|
8063
|
+
(0, import_types18.extractSummary)(updatedResource)
|
|
8064
|
+
);
|
|
8065
|
+
const service = getDynamoControlService(tableName);
|
|
8066
|
+
await service.entities.user.patch({ id: targetUserId, sk: SK11 }).set({
|
|
8067
|
+
resource: JSON.stringify(updatedResource),
|
|
8068
|
+
summary,
|
|
8069
|
+
vid,
|
|
8070
|
+
lastUpdated
|
|
8071
|
+
}).go();
|
|
8072
|
+
return {
|
|
8073
|
+
id: targetUserId,
|
|
8074
|
+
resource: updatedResource,
|
|
8075
|
+
meta: { lastUpdated, versionId: vid }
|
|
8076
|
+
};
|
|
8077
|
+
}
|
|
8078
|
+
|
|
8079
|
+
// src/data/rest-api/routes/control/user/user-admin-set-context-route.ts
|
|
8080
|
+
async function userAdminSetContextRoute(req, res) {
|
|
8081
|
+
const ctx = req.openhiContext;
|
|
8082
|
+
if (!ctx) {
|
|
8083
|
+
return res.status(403).json({
|
|
8084
|
+
resourceType: "OperationOutcome",
|
|
8085
|
+
issue: [
|
|
8086
|
+
{
|
|
8087
|
+
severity: "error",
|
|
8088
|
+
code: "forbidden",
|
|
8089
|
+
diagnostics: "Missing or invalid OpenHI JWT claims (tenant, workspace, or audit context)."
|
|
8090
|
+
}
|
|
8091
|
+
]
|
|
8092
|
+
});
|
|
8093
|
+
}
|
|
8094
|
+
const targetUserId = String(req.params.id);
|
|
8095
|
+
const bodyResult = requireJsonBody(req, res);
|
|
8096
|
+
if ("errorResponse" in bodyResult) {
|
|
8097
|
+
return bodyResult.errorResponse;
|
|
8098
|
+
}
|
|
8099
|
+
const body = bodyResult.body;
|
|
8100
|
+
const tenantReference = body.tenant?.reference;
|
|
8101
|
+
const workspaceReference = body.workspace?.reference;
|
|
8102
|
+
if (typeof tenantReference !== "string" || tenantReference === "") {
|
|
8103
|
+
return sendInvalid(
|
|
8104
|
+
res,
|
|
8105
|
+
"Body must include `tenant.reference` (e.g. 'Tenant/<id>')."
|
|
8106
|
+
);
|
|
8107
|
+
}
|
|
8108
|
+
if (typeof workspaceReference !== "string" || workspaceReference === "") {
|
|
8109
|
+
return sendInvalid(
|
|
8110
|
+
res,
|
|
8111
|
+
"Body must include `workspace.reference` (e.g. 'Workspace/<id>')."
|
|
8112
|
+
);
|
|
8113
|
+
}
|
|
8114
|
+
try {
|
|
8115
|
+
const result = await adminSetUserContextOperation({
|
|
8116
|
+
context: ctx,
|
|
8117
|
+
targetUserId,
|
|
8118
|
+
tenantReference,
|
|
8119
|
+
workspaceReference
|
|
8120
|
+
});
|
|
8121
|
+
res.setHeader("Cache-Control", "no-store");
|
|
8122
|
+
return res.status(200).json(result.resource);
|
|
8123
|
+
} catch (err) {
|
|
8124
|
+
if (err instanceof ValidationError) {
|
|
8125
|
+
return sendInvalid(res, err.message);
|
|
8126
|
+
}
|
|
8127
|
+
if (err instanceof ForbiddenError) {
|
|
8128
|
+
return res.status(403).json({
|
|
8129
|
+
resourceType: "OperationOutcome",
|
|
8130
|
+
issue: [
|
|
8131
|
+
{ severity: "error", code: "forbidden", diagnostics: err.message }
|
|
8132
|
+
]
|
|
8133
|
+
});
|
|
8134
|
+
}
|
|
8135
|
+
if (err instanceof NotFoundError) {
|
|
8136
|
+
return res.status(404).json({
|
|
8137
|
+
resourceType: "OperationOutcome",
|
|
8138
|
+
issue: [
|
|
8139
|
+
{ severity: "error", code: "not-found", diagnostics: err.message }
|
|
8140
|
+
]
|
|
8141
|
+
});
|
|
8142
|
+
}
|
|
8143
|
+
return sendOperationOutcome500(
|
|
8144
|
+
res,
|
|
8145
|
+
err,
|
|
8146
|
+
"POST /User/:id/$set-context error:"
|
|
8147
|
+
);
|
|
8148
|
+
}
|
|
8149
|
+
}
|
|
8150
|
+
function sendInvalid(res, diagnostics) {
|
|
8151
|
+
return res.status(400).json({
|
|
8152
|
+
resourceType: "OperationOutcome",
|
|
8153
|
+
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
8154
|
+
});
|
|
8155
|
+
}
|
|
8156
|
+
|
|
8157
|
+
// src/data/operations/control/user/user-create-operation.ts
|
|
8158
|
+
var import_types19 = require("@openhi/types");
|
|
7852
8159
|
var import_ulid5 = require("ulid");
|
|
7853
8160
|
async function createUserOperation(params) {
|
|
7854
8161
|
const { context, body, tableName } = params;
|
|
@@ -7858,7 +8165,7 @@ async function createUserOperation(params) {
|
|
|
7858
8165
|
const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
7859
8166
|
const vid = `1`;
|
|
7860
8167
|
const resource = { resourceType: "User", id, ...parsedResource };
|
|
7861
|
-
const summary = JSON.stringify((0,
|
|
8168
|
+
const summary = JSON.stringify((0, import_types19.extractSummary)(resource));
|
|
7862
8169
|
await service.entities.user.put({
|
|
7863
8170
|
id,
|
|
7864
8171
|
resource: JSON.stringify(resource),
|
|
@@ -7925,22 +8232,6 @@ async function deleteUserRoute(req, res) {
|
|
|
7925
8232
|
}
|
|
7926
8233
|
}
|
|
7927
8234
|
|
|
7928
|
-
// src/data/operations/control/user/user-get-by-id-operation.ts
|
|
7929
|
-
async function getUserByIdOperation(params) {
|
|
7930
|
-
const { id, tableName } = params;
|
|
7931
|
-
const service = getDynamoControlService(tableName);
|
|
7932
|
-
const response = await service.entities.user.get({ id, sk: "CURRENT" }).go();
|
|
7933
|
-
const item = response.data;
|
|
7934
|
-
if (!item) {
|
|
7935
|
-
throw new NotFoundError(`User not found: ${id}`);
|
|
7936
|
-
}
|
|
7937
|
-
const parsedResource = JSON.parse(item.resource);
|
|
7938
|
-
return {
|
|
7939
|
-
id,
|
|
7940
|
-
resource: { resourceType: "User", id, ...parsedResource }
|
|
7941
|
-
};
|
|
7942
|
-
}
|
|
7943
|
-
|
|
7944
8235
|
// src/data/rest-api/routes/control/user/user-get-by-id-route.ts
|
|
7945
8236
|
async function getUserByIdRoute(req, res) {
|
|
7946
8237
|
const id = String(req.params.id);
|
|
@@ -8291,65 +8582,6 @@ async function listUserConfigurationsRoute(req, res) {
|
|
|
8291
8582
|
}
|
|
8292
8583
|
}
|
|
8293
8584
|
|
|
8294
|
-
// src/data/operations/control/membership/membership-list-by-user-operation.ts
|
|
8295
|
-
function buildSkPrefix(mode, tenantId) {
|
|
8296
|
-
switch (mode) {
|
|
8297
|
-
case "tenant":
|
|
8298
|
-
return "MEMBERSHIP#TENANT#";
|
|
8299
|
-
case "workspace":
|
|
8300
|
-
return "MEMBERSHIP#WORKSPACE#";
|
|
8301
|
-
case "workspaceInTenant":
|
|
8302
|
-
return `MEMBERSHIP#WORKSPACE#TID#${tenantId}#`;
|
|
8303
|
-
case "all":
|
|
8304
|
-
default:
|
|
8305
|
-
return "MEMBERSHIP#";
|
|
8306
|
-
}
|
|
8307
|
-
}
|
|
8308
|
-
async function membershipListByUserOperation(params) {
|
|
8309
|
-
const {
|
|
8310
|
-
userId,
|
|
8311
|
-
mode = "all",
|
|
8312
|
-
tenantId,
|
|
8313
|
-
cursor = null,
|
|
8314
|
-
limit,
|
|
8315
|
-
order,
|
|
8316
|
-
tableName
|
|
8317
|
-
} = params;
|
|
8318
|
-
if (mode === "workspaceInTenant" && !tenantId) {
|
|
8319
|
-
throw new Error(
|
|
8320
|
-
'membershipListByUserOperation: tenantId is required when mode === "workspaceInTenant"'
|
|
8321
|
-
);
|
|
8322
|
-
}
|
|
8323
|
-
const service = getDynamoControlService(tableName);
|
|
8324
|
-
const skPrefix = buildSkPrefix(mode, tenantId);
|
|
8325
|
-
const goOptions = {
|
|
8326
|
-
cursor
|
|
8327
|
-
};
|
|
8328
|
-
if (limit !== void 0) {
|
|
8329
|
-
goOptions.limit = limit;
|
|
8330
|
-
}
|
|
8331
|
-
if (order !== void 0) {
|
|
8332
|
-
goOptions.order = order;
|
|
8333
|
-
}
|
|
8334
|
-
const result = await service.entities.membershipUserProjection.query.record({ userId }).begins({ sk: skPrefix }).go(goOptions);
|
|
8335
|
-
const items = (result.data ?? []).map(
|
|
8336
|
-
(row) => ({
|
|
8337
|
-
userId: row.userId,
|
|
8338
|
-
sk: row.sk,
|
|
8339
|
-
tenantId: row.tenantId,
|
|
8340
|
-
workspaceId: row.workspaceId,
|
|
8341
|
-
membershipId: row.membershipId,
|
|
8342
|
-
summary: row.summary,
|
|
8343
|
-
vid: row.vid,
|
|
8344
|
-
lastUpdated: row.lastUpdated,
|
|
8345
|
-
denormalizedTenantName: row.denormalizedTenantName,
|
|
8346
|
-
denormalizedUserName: row.denormalizedUserName,
|
|
8347
|
-
denormalizedWorkspaceName: row.denormalizedWorkspaceName
|
|
8348
|
-
})
|
|
8349
|
-
);
|
|
8350
|
-
return { items, cursor: result.cursor ?? null };
|
|
8351
|
-
}
|
|
8352
|
-
|
|
8353
8585
|
// src/data/operations/control/membership/membership-count-by-user-operation.ts
|
|
8354
8586
|
async function countMembershipsByUserOperation(params) {
|
|
8355
8587
|
const { userId, mode = "all", tenantId, tableName } = params;
|
|
@@ -8359,7 +8591,7 @@ async function countMembershipsByUserOperation(params) {
|
|
|
8359
8591
|
);
|
|
8360
8592
|
}
|
|
8361
8593
|
const service = getDynamoControlService(tableName);
|
|
8362
|
-
const skPrefix =
|
|
8594
|
+
const skPrefix = buildSkPrefix2(mode, tenantId);
|
|
8363
8595
|
const result = await service.entities.membershipUserProjection.query.record({ userId }).begins({ sk: skPrefix }).go({ pages: "all", attributes: ["membershipId"] });
|
|
8364
8596
|
return (result.data ?? []).length;
|
|
8365
8597
|
}
|
|
@@ -8512,72 +8744,6 @@ async function listUserMembershipsRoute(req, res) {
|
|
|
8512
8744
|
}
|
|
8513
8745
|
}
|
|
8514
8746
|
|
|
8515
|
-
// src/data/operations/control/roleassignment/roleassignment-list-by-user-operation.ts
|
|
8516
|
-
function buildSkPrefix2(mode) {
|
|
8517
|
-
switch (mode) {
|
|
8518
|
-
case "tenant":
|
|
8519
|
-
return "ROLEASSIGNMENT#TENANT#";
|
|
8520
|
-
case "workspace":
|
|
8521
|
-
case "workspaceInTenant":
|
|
8522
|
-
return "ROLEASSIGNMENT#WORKSPACE#";
|
|
8523
|
-
case "all":
|
|
8524
|
-
default:
|
|
8525
|
-
return "ROLEASSIGNMENT#";
|
|
8526
|
-
}
|
|
8527
|
-
}
|
|
8528
|
-
async function roleAssignmentListByUserOperation(params) {
|
|
8529
|
-
const {
|
|
8530
|
-
userId,
|
|
8531
|
-
mode = "all",
|
|
8532
|
-
tenantId,
|
|
8533
|
-
workspaceId,
|
|
8534
|
-
cursor = null,
|
|
8535
|
-
limit,
|
|
8536
|
-
order,
|
|
8537
|
-
tableName
|
|
8538
|
-
} = params;
|
|
8539
|
-
if (mode === "workspaceInTenant" && !tenantId) {
|
|
8540
|
-
throw new Error(
|
|
8541
|
-
'roleAssignmentListByUserOperation: tenantId is required when mode === "workspaceInTenant"'
|
|
8542
|
-
);
|
|
8543
|
-
}
|
|
8544
|
-
const service = getDynamoControlService(tableName);
|
|
8545
|
-
const skPrefix = buildSkPrefix2(mode);
|
|
8546
|
-
const goOptions = {
|
|
8547
|
-
cursor
|
|
8548
|
-
};
|
|
8549
|
-
if (limit !== void 0) {
|
|
8550
|
-
goOptions.limit = limit;
|
|
8551
|
-
}
|
|
8552
|
-
if (order !== void 0) {
|
|
8553
|
-
goOptions.order = order;
|
|
8554
|
-
}
|
|
8555
|
-
const baseQuery = service.entities.roleAssignmentUserProjection.query.record({ userId }).begins({ sk: skPrefix });
|
|
8556
|
-
const filteredQuery = mode === "workspaceInTenant" ? baseQuery.where((attr, op) => {
|
|
8557
|
-
const tenantClause = op.eq(attr.tenantId, tenantId);
|
|
8558
|
-
if (workspaceId === void 0 || workspaceId.length === 0) {
|
|
8559
|
-
return tenantClause;
|
|
8560
|
-
}
|
|
8561
|
-
return `${tenantClause} AND ${op.eq(attr.workspaceId, workspaceId)}`;
|
|
8562
|
-
}) : baseQuery;
|
|
8563
|
-
const result = await filteredQuery.go(goOptions);
|
|
8564
|
-
const items = (result.data ?? []).map((row) => ({
|
|
8565
|
-
userId: row.userId,
|
|
8566
|
-
sk: row.sk,
|
|
8567
|
-
tenantId: row.tenantId,
|
|
8568
|
-
workspaceId: row.workspaceId,
|
|
8569
|
-
roleId: row.roleId,
|
|
8570
|
-
roleAssignmentId: row.roleAssignmentId,
|
|
8571
|
-
summary: row.summary,
|
|
8572
|
-
vid: row.vid,
|
|
8573
|
-
lastUpdated: row.lastUpdated,
|
|
8574
|
-
denormalizedTenantName: row.denormalizedTenantName,
|
|
8575
|
-
denormalizedUserName: row.denormalizedUserName,
|
|
8576
|
-
denormalizedRoleName: row.denormalizedRoleName
|
|
8577
|
-
}));
|
|
8578
|
-
return { items, cursor: result.cursor ?? null };
|
|
8579
|
-
}
|
|
8580
|
-
|
|
8581
8747
|
// src/data/operations/control/roleassignment/roleassignment-list-by-workspace-operation.ts
|
|
8582
8748
|
function buildSkPrefix3(roleId) {
|
|
8583
8749
|
if (roleId === void 0 || roleId.length === 0) {
|
|
@@ -8714,7 +8880,7 @@ async function listUserRoleAssignmentsRoute(req, res) {
|
|
|
8714
8880
|
}
|
|
8715
8881
|
|
|
8716
8882
|
// src/data/operations/control/user/user-list-operation.ts
|
|
8717
|
-
var
|
|
8883
|
+
var SK12 = "CURRENT";
|
|
8718
8884
|
function counterValue3(value) {
|
|
8719
8885
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
8720
8886
|
}
|
|
@@ -8730,7 +8896,7 @@ async function listUsersOperation(params) {
|
|
|
8730
8896
|
return dispatchListMode(mode, shardResults, {
|
|
8731
8897
|
hydrate: (orderedIds) => batchGetWithRetry(
|
|
8732
8898
|
service.entities.user,
|
|
8733
|
-
orderedIds.map((id) => ({ id, sk:
|
|
8899
|
+
orderedIds.map((id) => ({ id, sk: SK12 }))
|
|
8734
8900
|
),
|
|
8735
8901
|
getId: (item) => item.id,
|
|
8736
8902
|
// FULL mode (admin list default): read the ADR-028 counters off the
|
|
@@ -8774,7 +8940,7 @@ async function listUsersRoute(req, res) {
|
|
|
8774
8940
|
}
|
|
8775
8941
|
|
|
8776
8942
|
// src/data/operations/control/user/user-update-operation.ts
|
|
8777
|
-
var
|
|
8943
|
+
var import_types20 = require("@openhi/types");
|
|
8778
8944
|
async function updateUserOperation(params) {
|
|
8779
8945
|
const { context, id, body, tableName } = params;
|
|
8780
8946
|
const service = getDynamoControlService(tableName);
|
|
@@ -8786,7 +8952,7 @@ async function updateUserOperation(params) {
|
|
|
8786
8952
|
const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
8787
8953
|
const vid = `${Date.now()}`;
|
|
8788
8954
|
const resource = { resourceType: "User", id, ...parsedResource };
|
|
8789
|
-
const summary = JSON.stringify((0,
|
|
8955
|
+
const summary = JSON.stringify((0, import_types20.extractSummary)(resource));
|
|
8790
8956
|
await service.entities.user.put({
|
|
8791
8957
|
id,
|
|
8792
8958
|
resource: JSON.stringify(resource),
|
|
@@ -8848,6 +9014,7 @@ router7.get("/:id", getUserByIdRoute);
|
|
|
8848
9014
|
router7.post("/", createUserRoute);
|
|
8849
9015
|
router7.put("/:id", updateUserRoute);
|
|
8850
9016
|
router7.delete("/:id", deleteUserRoute);
|
|
9017
|
+
router7.post("/:id/$set-context", userAdminSetContextRoute);
|
|
8851
9018
|
router7.get("/:id/Membership", listUserMembershipsRoute);
|
|
8852
9019
|
router7.get("/:id/RoleAssignment", listUserRoleAssignmentsRoute);
|
|
8853
9020
|
router7.get("/:id/Configuration", listUserConfigurationsRoute);
|
|
@@ -8893,7 +9060,7 @@ async function findUserBySubOperation(params) {
|
|
|
8893
9060
|
}
|
|
8894
9061
|
|
|
8895
9062
|
// src/data/operations/control/user/user-switch-tenant-workspace-operation.ts
|
|
8896
|
-
var
|
|
9063
|
+
var import_types21 = require("@openhi/types");
|
|
8897
9064
|
|
|
8898
9065
|
// src/data/operations/control/user/user-resource-helpers.ts
|
|
8899
9066
|
function parseUserResource(resource) {
|
|
@@ -8904,17 +9071,8 @@ function parseUserResource(resource) {
|
|
|
8904
9071
|
}
|
|
8905
9072
|
}
|
|
8906
9073
|
|
|
8907
|
-
// src/data/operations/fhir-reference.ts
|
|
8908
|
-
function idFromReference(reference, prefix) {
|
|
8909
|
-
if (!reference || !reference.startsWith(prefix)) {
|
|
8910
|
-
return void 0;
|
|
8911
|
-
}
|
|
8912
|
-
const id = reference.slice(prefix.length);
|
|
8913
|
-
return id.length > 0 ? id : void 0;
|
|
8914
|
-
}
|
|
8915
|
-
|
|
8916
9074
|
// src/data/operations/control/user/user-switch-tenant-workspace-operation.ts
|
|
8917
|
-
var
|
|
9075
|
+
var SK13 = "CURRENT";
|
|
8918
9076
|
async function switchUserTenantWorkspaceOperation(params) {
|
|
8919
9077
|
const { cognitoSub, tenantReference, workspaceReference, tableName } = params;
|
|
8920
9078
|
const tenantId = idFromReference(tenantReference, "Tenant/");
|
|
@@ -8972,10 +9130,10 @@ async function switchUserTenantWorkspaceOperation(params) {
|
|
|
8972
9130
|
const lastUpdated = (params.now ? params.now() : /* @__PURE__ */ new Date()).toISOString();
|
|
8973
9131
|
const vid = `${Date.now()}`;
|
|
8974
9132
|
const summary = JSON.stringify(
|
|
8975
|
-
(0,
|
|
9133
|
+
(0, import_types21.extractSummary)(updatedResource)
|
|
8976
9134
|
);
|
|
8977
9135
|
const service = getDynamoControlService(tableName);
|
|
8978
|
-
await service.entities.user.patch({ id: user.id, sk:
|
|
9136
|
+
await service.entities.user.patch({ id: user.id, sk: SK13 }).set({
|
|
8979
9137
|
resource: JSON.stringify(updatedResource),
|
|
8980
9138
|
summary,
|
|
8981
9139
|
vid,
|
|
@@ -9330,13 +9488,13 @@ async function userSwitchRoute(req, res) {
|
|
|
9330
9488
|
const tenantReference = body.tenant?.reference;
|
|
9331
9489
|
const workspaceReference = body.workspace?.reference;
|
|
9332
9490
|
if (typeof tenantReference !== "string" || tenantReference === "") {
|
|
9333
|
-
return
|
|
9491
|
+
return sendInvalid2(
|
|
9334
9492
|
res,
|
|
9335
9493
|
"Body must include `tenant.reference` (e.g. 'Tenant/<id>')."
|
|
9336
9494
|
);
|
|
9337
9495
|
}
|
|
9338
9496
|
if (typeof workspaceReference !== "string" || workspaceReference === "") {
|
|
9339
|
-
return
|
|
9497
|
+
return sendInvalid2(
|
|
9340
9498
|
res,
|
|
9341
9499
|
"Body must include `workspace.reference` (e.g. 'Workspace/<id>')."
|
|
9342
9500
|
);
|
|
@@ -9351,7 +9509,7 @@ async function userSwitchRoute(req, res) {
|
|
|
9351
9509
|
return res.status(200).json(result.resource);
|
|
9352
9510
|
} catch (err) {
|
|
9353
9511
|
if (err instanceof ValidationError) {
|
|
9354
|
-
return
|
|
9512
|
+
return sendInvalid2(res, err.message);
|
|
9355
9513
|
}
|
|
9356
9514
|
if (err instanceof ForbiddenError) {
|
|
9357
9515
|
return res.status(403).json({
|
|
@@ -9372,7 +9530,7 @@ async function userSwitchRoute(req, res) {
|
|
|
9372
9530
|
return sendOperationOutcome500(res, err, "POST /User/$switch error:");
|
|
9373
9531
|
}
|
|
9374
9532
|
}
|
|
9375
|
-
function
|
|
9533
|
+
function sendInvalid2(res, diagnostics) {
|
|
9376
9534
|
return res.status(400).json({
|
|
9377
9535
|
resourceType: "OperationOutcome",
|
|
9378
9536
|
issue: [{ severity: "error", code: "invalid", diagnostics }]
|
|
@@ -9388,7 +9546,7 @@ router8.post("/$switch", userSwitchRoute);
|
|
|
9388
9546
|
var import_express9 = __toESM(require("express"));
|
|
9389
9547
|
|
|
9390
9548
|
// src/data/operations/control/workspace/workspace-create-operation.ts
|
|
9391
|
-
var
|
|
9549
|
+
var import_types22 = require("@openhi/types");
|
|
9392
9550
|
var import_ulid6 = require("ulid");
|
|
9393
9551
|
|
|
9394
9552
|
// src/data/operations/data/organization/organization-provision-for-workspace-operation.ts
|
|
@@ -9439,7 +9597,7 @@ async function createWorkspaceOperation(params) {
|
|
|
9439
9597
|
const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
|
|
9440
9598
|
const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
|
|
9441
9599
|
const resource = { resourceType: "Workspace", id, ...parsedResource };
|
|
9442
|
-
const summary = JSON.stringify((0,
|
|
9600
|
+
const summary = JSON.stringify((0, import_types22.extractSummary)(resource));
|
|
9443
9601
|
await service.entities.workspace.put({
|
|
9444
9602
|
tenantId,
|
|
9445
9603
|
id,
|
|
@@ -9803,7 +9961,7 @@ async function listWorkspacesRoute(req, res) {
|
|
|
9803
9961
|
}
|
|
9804
9962
|
|
|
9805
9963
|
// src/data/operations/control/workspace/workspace-update-operation.ts
|
|
9806
|
-
var
|
|
9964
|
+
var import_types23 = require("@openhi/types");
|
|
9807
9965
|
async function updateWorkspaceOperation(params) {
|
|
9808
9966
|
const { context, id, body, tableName } = params;
|
|
9809
9967
|
const { tenantId } = context;
|
|
@@ -9822,7 +9980,7 @@ async function updateWorkspaceOperation(params) {
|
|
|
9822
9980
|
resourceType: "Workspace",
|
|
9823
9981
|
id
|
|
9824
9982
|
};
|
|
9825
|
-
const summary = JSON.stringify((0,
|
|
9983
|
+
const summary = JSON.stringify((0, import_types23.extractSummary)(updated));
|
|
9826
9984
|
await service.entities.workspace.patch({ tenantId, id, sk: "CURRENT" }).set({ resource: JSON.stringify(updated), summary, vid, lastUpdated }).go();
|
|
9827
9985
|
return { id, resource: updated, meta: { lastUpdated, versionId: vid } };
|
|
9828
9986
|
}
|
|
@@ -11250,7 +11408,8 @@ function combineSearchPredicates(opts) {
|
|
|
11250
11408
|
if (fragmentSqls.length === 1) {
|
|
11251
11409
|
groupSqls.push(fragmentSqls[0]);
|
|
11252
11410
|
} else {
|
|
11253
|
-
|
|
11411
|
+
const joiner = registered.type === "date" ? " AND " : " OR ";
|
|
11412
|
+
groupSqls.push(`(${fragmentSqls.join(joiner)})`);
|
|
11254
11413
|
}
|
|
11255
11414
|
}
|
|
11256
11415
|
if (groupSqls.length === 0) {
|