@openhi/constructs 0.0.104 → 0.0.106

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.
Files changed (83) hide show
  1. package/README.md +14 -0
  2. package/lib/chunk-2PM2NGXI.mjs +31 -0
  3. package/lib/chunk-2PM2NGXI.mjs.map +1 -0
  4. package/lib/chunk-AGF3RAAZ.mjs +20 -0
  5. package/lib/chunk-AGF3RAAZ.mjs.map +1 -0
  6. package/lib/chunk-AO3E22CS.mjs +108 -0
  7. package/lib/chunk-AO3E22CS.mjs.map +1 -0
  8. package/lib/chunk-CHPEQRXU.mjs +45 -0
  9. package/lib/chunk-CHPEQRXU.mjs.map +1 -0
  10. package/lib/chunk-JUNL76HF.mjs +428 -0
  11. package/lib/chunk-JUNL76HF.mjs.map +1 -0
  12. package/lib/chunk-L6UAP4KP.mjs +27 -0
  13. package/lib/chunk-L6UAP4KP.mjs.map +1 -0
  14. package/lib/{chunk-3QS3WKRC.mjs → chunk-LZOMFHX3.mjs} +9 -2
  15. package/lib/chunk-QMIOLLAS.mjs +531 -0
  16. package/lib/chunk-QMIOLLAS.mjs.map +1 -0
  17. package/lib/chunk-SYBADQXI.mjs +607 -0
  18. package/lib/chunk-SYBADQXI.mjs.map +1 -0
  19. package/lib/chunk-VXX4I3EF.mjs +19 -0
  20. package/lib/chunk-VXX4I3EF.mjs.map +1 -0
  21. package/lib/{chunk-MLTYFMSE.mjs → chunk-VYDIGFIX.mjs} +74 -29
  22. package/lib/chunk-VYDIGFIX.mjs.map +1 -0
  23. package/lib/chunk-YU2HRNUP.mjs +33 -0
  24. package/lib/chunk-YU2HRNUP.mjs.map +1 -0
  25. package/lib/chunk-YZZDUJHI.mjs +37 -0
  26. package/lib/chunk-YZZDUJHI.mjs.map +1 -0
  27. package/lib/cors-options-lambda.handler.mjs +1 -1
  28. package/lib/data-store-postgres-replication.handler.mjs +1 -1
  29. package/lib/events-BfrkMoBD.d.mts +44 -0
  30. package/lib/events-BfrkMoBD.d.ts +44 -0
  31. package/lib/events-CVA3_eEB.d.mts +23 -0
  32. package/lib/events-CVA3_eEB.d.ts +23 -0
  33. package/lib/events-DGep6C7w.d.mts +207 -0
  34. package/lib/events-DGep6C7w.d.ts +207 -0
  35. package/lib/firehose-archive-transform.handler.mjs +1 -1
  36. package/lib/index.d.mts +508 -29
  37. package/lib/index.d.ts +773 -30
  38. package/lib/index.js +2536 -105
  39. package/lib/index.js.map +1 -1
  40. package/lib/index.mjs +899 -106
  41. package/lib/index.mjs.map +1 -1
  42. package/lib/openhi-context-CaBH8SFo.d.mts +39 -0
  43. package/lib/openhi-context-CaBH8SFo.d.ts +39 -0
  44. package/lib/platform-deploy-bridge.handler.d.mts +14 -0
  45. package/lib/platform-deploy-bridge.handler.d.ts +14 -0
  46. package/lib/platform-deploy-bridge.handler.js +762 -0
  47. package/lib/platform-deploy-bridge.handler.js.map +1 -0
  48. package/lib/platform-deploy-bridge.handler.mjs +134 -0
  49. package/lib/platform-deploy-bridge.handler.mjs.map +1 -0
  50. package/lib/post-authentication.handler.mjs +1 -1
  51. package/lib/post-confirmation.handler.js +50 -904
  52. package/lib/post-confirmation.handler.js.map +1 -1
  53. package/lib/post-confirmation.handler.mjs +37 -112
  54. package/lib/post-confirmation.handler.mjs.map +1 -1
  55. package/lib/pre-token-generation.handler.js +135 -55
  56. package/lib/pre-token-generation.handler.js.map +1 -1
  57. package/lib/pre-token-generation.handler.mjs +25 -32
  58. package/lib/pre-token-generation.handler.mjs.map +1 -1
  59. package/lib/provision-default-workspace.handler.d.mts +13 -0
  60. package/lib/provision-default-workspace.handler.d.ts +13 -0
  61. package/lib/provision-default-workspace.handler.js +1172 -0
  62. package/lib/provision-default-workspace.handler.js.map +1 -0
  63. package/lib/provision-default-workspace.handler.mjs +175 -0
  64. package/lib/provision-default-workspace.handler.mjs.map +1 -0
  65. package/lib/rest-api-lambda.handler.js +114 -59
  66. package/lib/rest-api-lambda.handler.js.map +1 -1
  67. package/lib/rest-api-lambda.handler.mjs +60 -587
  68. package/lib/rest-api-lambda.handler.mjs.map +1 -1
  69. package/lib/seed-demo-data.handler.d.mts +107 -0
  70. package/lib/seed-demo-data.handler.d.ts +107 -0
  71. package/lib/seed-demo-data.handler.js +2037 -0
  72. package/lib/seed-demo-data.handler.js.map +1 -0
  73. package/lib/seed-demo-data.handler.mjs +23 -0
  74. package/lib/seed-demo-data.handler.mjs.map +1 -0
  75. package/lib/seed-system-data.handler.d.mts +64 -0
  76. package/lib/seed-system-data.handler.d.ts +64 -0
  77. package/lib/seed-system-data.handler.js +1631 -0
  78. package/lib/seed-system-data.handler.js.map +1 -0
  79. package/lib/seed-system-data.handler.mjs +135 -0
  80. package/lib/seed-system-data.handler.mjs.map +1 -0
  81. package/package.json +4 -2
  82. package/lib/chunk-MLTYFMSE.mjs.map +0 -1
  83. /package/lib/{chunk-3QS3WKRC.mjs.map → chunk-LZOMFHX3.mjs.map} +0 -0
@@ -173,6 +173,9 @@ var dynamoClient = new import_client_dynamodb.DynamoDBClient({
173
173
  // src/data/dynamo/entities/control/configuration-entity.ts
174
174
  var import_electrodb = require("electrodb");
175
175
 
176
+ // src/data/dynamo/entities/control/control-entity-common.ts
177
+ var import_types = require("@openhi/types");
178
+
176
179
  // src/data/dynamo/shard.ts
177
180
  var SHARD_COUNT = 4;
178
181
  function computeShard(id) {
@@ -195,6 +198,29 @@ var gsi1ShardAttribute = {
195
198
  return String(computeShard(item.id));
196
199
  }
197
200
  };
201
+ var gsi1skAttribute = {
202
+ type: "string",
203
+ watch: ["resource", "lastUpdated", "id"],
204
+ set: (_val, item) => {
205
+ const id = typeof item?.id === "string" ? item.id : "";
206
+ const lastUpdated = typeof item?.lastUpdated === "string" ? item.lastUpdated : "";
207
+ const fallback = `${lastUpdated}#${id}`;
208
+ if (typeof item?.resource !== "string" || item.resource.length === 0) {
209
+ return fallback;
210
+ }
211
+ let parsed;
212
+ try {
213
+ parsed = JSON.parse(item.resource);
214
+ } catch {
215
+ return fallback;
216
+ }
217
+ if (!parsed || typeof parsed !== "object") return fallback;
218
+ const resourceType = parsed.resourceType;
219
+ if (typeof resourceType !== "string") return fallback;
220
+ const label = (0, import_types.extractLabel)(parsed);
221
+ return label !== void 0 ? `${label}#${id}` : fallback;
222
+ }
223
+ };
198
224
 
199
225
  // src/data/dynamo/entities/control/configuration-entity.ts
200
226
  var ConfigurationEntity = new import_electrodb.Entity({
@@ -300,8 +326,9 @@ var ConfigurationEntity = new import_electrodb.Entity({
300
326
  * (workspaceId = "-") or "list configs scoped to this workspace". Does not support
301
327
  * hierarchical resolution in one query; use base table GetItem in fallback order
302
328
  * (user → workspace → tenant → baseline) for that.
303
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
304
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
329
+ * SK is `<key>#<id>` Configuration's `key` is a required entity attribute (the
330
+ * config category: endpoints, branding, display, …) and the natural sort/lookup
331
+ * dimension. `casing: "none"` preserves the literal key value.
305
332
  */
306
333
  gsi1: {
307
334
  index: "GSI1",
@@ -313,8 +340,8 @@ var ConfigurationEntity = new import_electrodb.Entity({
313
340
  sk: {
314
341
  field: "GSI1SK",
315
342
  casing: "none",
316
- composite: ["lastUpdated", "id"],
317
- template: "${lastUpdated}#${id}"
343
+ composite: ["key", "id"],
344
+ template: "${key}#${id}"
318
345
  }
319
346
  }
320
347
  }
@@ -368,6 +395,8 @@ var MembershipEntity = new import_electrodb2.Entity({
368
395
  required: true
369
396
  },
370
397
  gsi1Shard: gsi1ShardAttribute,
398
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
399
+ gsi1sk: gsi1skAttribute,
371
400
  deleted: {
372
401
  type: "boolean",
373
402
  required: false
@@ -398,8 +427,9 @@ var MembershipEntity = new import_electrodb2.Entity({
398
427
  /**
399
428
  * GSI1 — Unified Sharded List per ADR-011: list all Memberships for a tenant across the
400
429
  * four shards. Membership is tenant-scoped only, so `WID#-` is a sentinel.
401
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
402
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
430
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
431
+ * extractable, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves the
432
+ * normalized label and ISO-8601 `T`/`Z`.
403
433
  */
404
434
  gsi1: {
405
435
  index: "GSI1",
@@ -411,8 +441,8 @@ var MembershipEntity = new import_electrodb2.Entity({
411
441
  sk: {
412
442
  field: "GSI1SK",
413
443
  casing: "none",
414
- composite: ["lastUpdated", "id"],
415
- template: "${lastUpdated}#${id}"
444
+ composite: ["gsi1sk"],
445
+ template: "${gsi1sk}"
416
446
  }
417
447
  }
418
448
  }
@@ -461,6 +491,8 @@ var RoleEntity = new import_electrodb3.Entity({
461
491
  required: true
462
492
  },
463
493
  gsi1Shard: gsi1ShardAttribute,
494
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
495
+ gsi1sk: gsi1skAttribute,
464
496
  deleted: {
465
497
  type: "boolean",
466
498
  required: false
@@ -491,8 +523,9 @@ var RoleEntity = new import_electrodb3.Entity({
491
523
  /**
492
524
  * GSI1 — Unified Sharded List per ADR-011: list all Roles across the four shards.
493
525
  * Non-tenant-isolated, so `TID#-#WID#-` sentinels precede `RT#Role#SHARD#<n>`.
494
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
495
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
526
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
527
+ * extractable, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves the
528
+ * normalized label and ISO-8601 `T`/`Z`.
496
529
  */
497
530
  gsi1: {
498
531
  index: "GSI1",
@@ -504,8 +537,8 @@ var RoleEntity = new import_electrodb3.Entity({
504
537
  sk: {
505
538
  field: "GSI1SK",
506
539
  casing: "none",
507
- composite: ["lastUpdated", "id"],
508
- template: "${lastUpdated}#${id}"
540
+ composite: ["gsi1sk"],
541
+ template: "${gsi1sk}"
509
542
  }
510
543
  }
511
544
  }
@@ -559,6 +592,8 @@ var RoleAssignmentEntity = new import_electrodb4.Entity({
559
592
  required: true
560
593
  },
561
594
  gsi1Shard: gsi1ShardAttribute,
595
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
596
+ gsi1sk: gsi1skAttribute,
562
597
  deleted: {
563
598
  type: "boolean",
564
599
  required: false
@@ -589,8 +624,9 @@ var RoleAssignmentEntity = new import_electrodb4.Entity({
589
624
  /**
590
625
  * GSI1 — Unified Sharded List per ADR-011: list all RoleAssignments for a tenant across the
591
626
  * four shards. Tenant-scoped only, so `WID#-` is a sentinel.
592
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
593
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
627
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
628
+ * extractable, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves the
629
+ * normalized label and ISO-8601 `T`/`Z`.
594
630
  */
595
631
  gsi1: {
596
632
  index: "GSI1",
@@ -602,8 +638,8 @@ var RoleAssignmentEntity = new import_electrodb4.Entity({
602
638
  sk: {
603
639
  field: "GSI1SK",
604
640
  casing: "none",
605
- composite: ["lastUpdated", "id"],
606
- template: "${lastUpdated}#${id}"
641
+ composite: ["gsi1sk"],
642
+ template: "${gsi1sk}"
607
643
  }
608
644
  }
609
645
  }
@@ -657,6 +693,8 @@ var TenantEntity = new import_electrodb5.Entity({
657
693
  required: true
658
694
  },
659
695
  gsi1Shard: gsi1ShardAttribute,
696
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
697
+ gsi1sk: gsi1skAttribute,
660
698
  deleted: {
661
699
  type: "boolean",
662
700
  required: false
@@ -687,8 +725,9 @@ var TenantEntity = new import_electrodb5.Entity({
687
725
  /**
688
726
  * GSI1 — Unified Sharded List per ADR-011: list all Tenants across the four shards.
689
727
  * Tenant lives at the platform tier (no parent tenant or workspace), so `TID#-#WID#-`
690
- * sentinels precede `RT#Tenant#SHARD#<n>`. SK is `<ISO-8601 lastUpdated>#<id>` (control-plane
691
- * unlabeled per DR-004). `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
728
+ * sentinels precede `RT#Tenant#SHARD#<n>`. SK is derived via `gsi1skAttribute` —
729
+ * `<normalizedName>#<id>` when the resource carries a `name`, else `<lastUpdated>#<id>`
730
+ * (DR-004). `casing: "none"` preserves the normalized label and ISO-8601 `T`/`Z`.
692
731
  */
693
732
  gsi1: {
694
733
  index: "GSI1",
@@ -700,8 +739,8 @@ var TenantEntity = new import_electrodb5.Entity({
700
739
  sk: {
701
740
  field: "GSI1SK",
702
741
  casing: "none",
703
- composite: ["lastUpdated", "id"],
704
- template: "${lastUpdated}#${id}"
742
+ composite: ["gsi1sk"],
743
+ template: "${gsi1sk}"
705
744
  }
706
745
  }
707
746
  }
@@ -758,6 +797,8 @@ var UserEntity = new import_electrodb6.Entity({
758
797
  required: true
759
798
  },
760
799
  gsi1Shard: gsi1ShardAttribute,
800
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
801
+ gsi1sk: gsi1skAttribute,
761
802
  deleted: {
762
803
  type: "boolean",
763
804
  required: false
@@ -788,8 +829,9 @@ var UserEntity = new import_electrodb6.Entity({
788
829
  /**
789
830
  * GSI1 — Unified Sharded List per ADR-011: list all Users across the four shards.
790
831
  * Non-tenant-isolated, so `TID#-#WID#-` sentinels precede `RT#User#SHARD#<n>`.
791
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
792
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z` characters.
832
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
833
+ * extractable (string `name`/`title` via introspection), else `<lastUpdated>#<id>`
834
+ * (DR-004). `casing: "none"` preserves the normalized label and ISO-8601 `T`/`Z`.
793
835
  */
794
836
  gsi1: {
795
837
  index: "GSI1",
@@ -801,8 +843,8 @@ var UserEntity = new import_electrodb6.Entity({
801
843
  sk: {
802
844
  field: "GSI1SK",
803
845
  casing: "none",
804
- composite: ["lastUpdated", "id"],
805
- template: "${lastUpdated}#${id}"
846
+ composite: ["gsi1sk"],
847
+ template: "${gsi1sk}"
806
848
  }
807
849
  },
808
850
  /**
@@ -877,6 +919,8 @@ var WorkspaceEntity = new import_electrodb7.Entity({
877
919
  required: true
878
920
  },
879
921
  gsi1Shard: gsi1ShardAttribute,
922
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
923
+ gsi1sk: gsi1skAttribute,
880
924
  deleted: {
881
925
  type: "boolean",
882
926
  required: false
@@ -907,8 +951,9 @@ var WorkspaceEntity = new import_electrodb7.Entity({
907
951
  /**
908
952
  * GSI1 — Unified Sharded List per ADR-011: list all Workspaces for a tenant across the
909
953
  * four shards. Workspace is itself the workspace identity, so `WID#-` is a sentinel.
910
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
911
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
954
+ * SK is derived via `gsi1skAttribute` — `<normalizedName>#<id>` when the resource
955
+ * carries a `name`, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves
956
+ * the normalized label and ISO-8601 `T`/`Z`.
912
957
  */
913
958
  gsi1: {
914
959
  index: "GSI1",
@@ -920,8 +965,8 @@ var WorkspaceEntity = new import_electrodb7.Entity({
920
965
  sk: {
921
966
  field: "GSI1SK",
922
967
  casing: "none",
923
- composite: ["lastUpdated", "id"],
924
- template: "${lastUpdated}#${id}"
968
+ composite: ["gsi1sk"],
969
+ template: "${gsi1sk}"
925
970
  }
926
971
  }
927
972
  }
@@ -1424,7 +1469,7 @@ async function getConfigurationByIdRoute(req, res) {
1424
1469
  }
1425
1470
 
1426
1471
  // src/data/operations/data-operations-common.ts
1427
- var import_types = require("@openhi/types");
1472
+ var import_types2 = require("@openhi/types");
1428
1473
 
1429
1474
  // src/data/audit-meta.ts
1430
1475
  var OPENHI_EXT = "http://openhi.org/fhir/StructureDefinition";
@@ -1582,8 +1627,8 @@ async function createDataEntityRecord(entity, tenantId, workspaceId, id, resourc
1582
1627
  const lastUpdated = resourceWithAudit.meta?.lastUpdated ?? fallbackDate ?? (/* @__PURE__ */ new Date()).toISOString();
1583
1628
  const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
1584
1629
  const resourceLike = resourceWithAudit;
1585
- const summary = JSON.stringify((0, import_types.extractSummary)(resourceLike));
1586
- const gsi1sk = (0, import_types.extractSortKey)(resourceLike);
1630
+ const summary = JSON.stringify((0, import_types2.extractSummary)(resourceLike));
1631
+ const gsi1sk = (0, import_types2.extractSortKey)(resourceLike);
1587
1632
  await entity.put({
1588
1633
  sk: DATA_ENTITY_SK,
1589
1634
  tenantId,
@@ -1641,8 +1686,8 @@ async function updateDataEntityById(entity, tenantId, workspaceId, id, resourceL
1641
1686
  const existingStr = decompressResource(existing.data.resource);
1642
1687
  const { resource, lastUpdated } = buildPatched(existingStr);
1643
1688
  const resourceLike = resource;
1644
- const summary = JSON.stringify((0, import_types.extractSummary)(resourceLike));
1645
- const gsi1sk = (0, import_types.extractSortKey)(resourceLike);
1689
+ const summary = JSON.stringify((0, import_types2.extractSummary)(resourceLike));
1690
+ const gsi1sk = (0, import_types2.extractSortKey)(resourceLike);
1646
1691
  await entity.patch({
1647
1692
  tenantId,
1648
1693
  workspaceId,
@@ -2125,7 +2170,7 @@ router.delete("/:id", deleteConfigurationRoute);
2125
2170
  var import_express2 = __toESM(require("express"));
2126
2171
 
2127
2172
  // src/data/operations/control/membership/membership-create-operation.ts
2128
- var import_types2 = require("@openhi/types");
2173
+ var import_types3 = require("@openhi/types");
2129
2174
  async function createMembershipOperation(params) {
2130
2175
  const { context, body, tableName } = params;
2131
2176
  const service = getDynamoControlService(tableName);
@@ -2134,7 +2179,7 @@ async function createMembershipOperation(params) {
2134
2179
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2135
2180
  const vid = `1`;
2136
2181
  const resource = { resourceType: "Membership", id, ...parsedResource };
2137
- const summary = JSON.stringify((0, import_types2.extractSummary)(resource));
2182
+ const summary = JSON.stringify((0, import_types3.extractSummary)(resource));
2138
2183
  await service.entities.membership.put({
2139
2184
  tenantId: context.tenantId,
2140
2185
  id,
@@ -2294,7 +2339,7 @@ async function listMembershipsRoute(req, res) {
2294
2339
  }
2295
2340
 
2296
2341
  // src/data/operations/control/membership/membership-update-operation.ts
2297
- var import_types3 = require("@openhi/types");
2342
+ var import_types4 = require("@openhi/types");
2298
2343
  async function updateMembershipOperation(params) {
2299
2344
  const { context, id, body, tableName } = params;
2300
2345
  const service = getDynamoControlService(tableName);
@@ -2306,7 +2351,7 @@ async function updateMembershipOperation(params) {
2306
2351
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2307
2352
  const vid = `${Date.now()}`;
2308
2353
  const resource = { resourceType: "Membership", id, ...parsedResource };
2309
- const summary = JSON.stringify((0, import_types3.extractSummary)(resource));
2354
+ const summary = JSON.stringify((0, import_types4.extractSummary)(resource));
2310
2355
  await service.entities.membership.put({
2311
2356
  tenantId: context.tenantId,
2312
2357
  id,
@@ -2374,7 +2419,7 @@ router2.delete("/:id", deleteMembershipRoute);
2374
2419
  var import_express3 = __toESM(require("express"));
2375
2420
 
2376
2421
  // src/data/operations/control/role/role-create-operation.ts
2377
- var import_types4 = require("@openhi/types");
2422
+ var import_types5 = require("@openhi/types");
2378
2423
  async function createRoleOperation(params) {
2379
2424
  const { context, body, tableName } = params;
2380
2425
  const service = getDynamoControlService(tableName);
@@ -2383,7 +2428,7 @@ async function createRoleOperation(params) {
2383
2428
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2384
2429
  const vid = `1`;
2385
2430
  const resource = { resourceType: "Role", id, ...parsedResource };
2386
- const summary = JSON.stringify((0, import_types4.extractSummary)(resource));
2431
+ const summary = JSON.stringify((0, import_types5.extractSummary)(resource));
2387
2432
  await service.entities.role.put({
2388
2433
  id,
2389
2434
  resource: JSON.stringify(resource),
@@ -2541,7 +2586,7 @@ async function listRolesRoute(req, res) {
2541
2586
  }
2542
2587
 
2543
2588
  // src/data/operations/control/role/role-update-operation.ts
2544
- var import_types5 = require("@openhi/types");
2589
+ var import_types6 = require("@openhi/types");
2545
2590
  async function updateRoleOperation(params) {
2546
2591
  const { context, id, body, tableName } = params;
2547
2592
  const service = getDynamoControlService(tableName);
@@ -2553,7 +2598,7 @@ async function updateRoleOperation(params) {
2553
2598
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2554
2599
  const vid = `${Date.now()}`;
2555
2600
  const resource = { resourceType: "Role", id, ...parsedResource };
2556
- const summary = JSON.stringify((0, import_types5.extractSummary)(resource));
2601
+ const summary = JSON.stringify((0, import_types6.extractSummary)(resource));
2557
2602
  await service.entities.role.put({
2558
2603
  id,
2559
2604
  resource: JSON.stringify(resource),
@@ -2620,7 +2665,7 @@ router3.delete("/:id", deleteRoleRoute);
2620
2665
  var import_express4 = __toESM(require("express"));
2621
2666
 
2622
2667
  // src/data/operations/control/roleassignment/roleassignment-create-operation.ts
2623
- var import_types6 = require("@openhi/types");
2668
+ var import_types7 = require("@openhi/types");
2624
2669
  async function createRoleAssignmentOperation(params) {
2625
2670
  const { context, body, tableName } = params;
2626
2671
  const service = getDynamoControlService(tableName);
@@ -2629,7 +2674,7 @@ async function createRoleAssignmentOperation(params) {
2629
2674
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2630
2675
  const vid = `1`;
2631
2676
  const resource = { resourceType: "RoleAssignment", id, ...parsedResource };
2632
- const summary = JSON.stringify((0, import_types6.extractSummary)(resource));
2677
+ const summary = JSON.stringify((0, import_types7.extractSummary)(resource));
2633
2678
  await service.entities.roleAssignment.put({
2634
2679
  tenantId: context.tenantId,
2635
2680
  id,
@@ -2789,7 +2834,7 @@ async function listRoleAssignmentsRoute(req, res) {
2789
2834
  }
2790
2835
 
2791
2836
  // src/data/operations/control/roleassignment/roleassignment-update-operation.ts
2792
- var import_types7 = require("@openhi/types");
2837
+ var import_types8 = require("@openhi/types");
2793
2838
  async function updateRoleAssignmentOperation(params) {
2794
2839
  const { context, id, body, tableName } = params;
2795
2840
  const service = getDynamoControlService(tableName);
@@ -2801,7 +2846,7 @@ async function updateRoleAssignmentOperation(params) {
2801
2846
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2802
2847
  const vid = `${Date.now()}`;
2803
2848
  const resource = { resourceType: "RoleAssignment", id, ...parsedResource };
2804
- const summary = JSON.stringify((0, import_types7.extractSummary)(resource));
2849
+ const summary = JSON.stringify((0, import_types8.extractSummary)(resource));
2805
2850
  await service.entities.roleAssignment.put({
2806
2851
  tenantId: context.tenantId,
2807
2852
  id,
@@ -2869,7 +2914,7 @@ router4.delete("/:id", deleteRoleAssignmentRoute);
2869
2914
  var import_express5 = __toESM(require("express"));
2870
2915
 
2871
2916
  // src/data/operations/control/tenant/tenant-create-operation.ts
2872
- var import_types8 = require("@openhi/types");
2917
+ var import_types9 = require("@openhi/types");
2873
2918
  async function createTenantOperation(params) {
2874
2919
  const { context, body, tableName } = params;
2875
2920
  const service = getDynamoControlService(tableName);
@@ -2878,7 +2923,7 @@ async function createTenantOperation(params) {
2878
2923
  const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
2879
2924
  const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
2880
2925
  const resource = { resourceType: "Tenant", id, ...parsedResource };
2881
- const summary = JSON.stringify((0, import_types8.extractSummary)(resource));
2926
+ const summary = JSON.stringify((0, import_types9.extractSummary)(resource));
2882
2927
  await service.entities.tenant.put({
2883
2928
  tenantId: id,
2884
2929
  id,
@@ -3036,7 +3081,7 @@ async function listTenantsRoute(req, res) {
3036
3081
  }
3037
3082
 
3038
3083
  // src/data/operations/control/tenant/tenant-update-operation.ts
3039
- var import_types9 = require("@openhi/types");
3084
+ var import_types10 = require("@openhi/types");
3040
3085
  async function updateTenantOperation(params) {
3041
3086
  const { context, id, body, tableName } = params;
3042
3087
  const service = getDynamoControlService(tableName);
@@ -3054,7 +3099,7 @@ async function updateTenantOperation(params) {
3054
3099
  resourceType: "Tenant",
3055
3100
  id
3056
3101
  };
3057
- const summary = JSON.stringify((0, import_types9.extractSummary)(updated));
3102
+ const summary = JSON.stringify((0, import_types10.extractSummary)(updated));
3058
3103
  await service.entities.tenant.patch({ tenantId: id, sk: "CURRENT" }).set({ resource: JSON.stringify(updated), summary, vid, lastUpdated }).go();
3059
3104
  return { id, resource: updated, meta: { lastUpdated, versionId: vid } };
3060
3105
  }
@@ -3111,7 +3156,7 @@ router5.delete("/:id", deleteTenantRoute);
3111
3156
  var import_express6 = __toESM(require("express"));
3112
3157
 
3113
3158
  // src/data/operations/control/user/user-create-operation.ts
3114
- var import_types10 = require("@openhi/types");
3159
+ var import_types11 = require("@openhi/types");
3115
3160
  async function createUserOperation(params) {
3116
3161
  const { context, body, tableName } = params;
3117
3162
  const service = getDynamoControlService(tableName);
@@ -3120,7 +3165,7 @@ async function createUserOperation(params) {
3120
3165
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
3121
3166
  const vid = `1`;
3122
3167
  const resource = { resourceType: "User", id, ...parsedResource };
3123
- const summary = JSON.stringify((0, import_types10.extractSummary)(resource));
3168
+ const summary = JSON.stringify((0, import_types11.extractSummary)(resource));
3124
3169
  await service.entities.user.put({
3125
3170
  id,
3126
3171
  resource: JSON.stringify(resource),
@@ -3278,7 +3323,7 @@ async function listUsersRoute(req, res) {
3278
3323
  }
3279
3324
 
3280
3325
  // src/data/operations/control/user/user-update-operation.ts
3281
- var import_types11 = require("@openhi/types");
3326
+ var import_types12 = require("@openhi/types");
3282
3327
  async function updateUserOperation(params) {
3283
3328
  const { context, id, body, tableName } = params;
3284
3329
  const service = getDynamoControlService(tableName);
@@ -3290,7 +3335,7 @@ async function updateUserOperation(params) {
3290
3335
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
3291
3336
  const vid = `${Date.now()}`;
3292
3337
  const resource = { resourceType: "User", id, ...parsedResource };
3293
- const summary = JSON.stringify((0, import_types11.extractSummary)(resource));
3338
+ const summary = JSON.stringify((0, import_types12.extractSummary)(resource));
3294
3339
  await service.entities.user.put({
3295
3340
  id,
3296
3341
  resource: JSON.stringify(resource),
@@ -3357,7 +3402,7 @@ router6.delete("/:id", deleteUserRoute);
3357
3402
  var import_express7 = __toESM(require("express"));
3358
3403
 
3359
3404
  // src/data/operations/control/workspace/workspace-create-operation.ts
3360
- var import_types12 = require("@openhi/types");
3405
+ var import_types13 = require("@openhi/types");
3361
3406
  async function createWorkspaceOperation(params) {
3362
3407
  const { context, body, tableName } = params;
3363
3408
  const { tenantId } = context;
@@ -3367,7 +3412,7 @@ async function createWorkspaceOperation(params) {
3367
3412
  const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
3368
3413
  const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
3369
3414
  const resource = { resourceType: "Workspace", id, ...parsedResource };
3370
- const summary = JSON.stringify((0, import_types12.extractSummary)(resource));
3415
+ const summary = JSON.stringify((0, import_types13.extractSummary)(resource));
3371
3416
  await service.entities.workspace.put({
3372
3417
  tenantId,
3373
3418
  id,
@@ -3528,7 +3573,7 @@ async function listWorkspacesRoute(req, res) {
3528
3573
  }
3529
3574
 
3530
3575
  // src/data/operations/control/workspace/workspace-update-operation.ts
3531
- var import_types13 = require("@openhi/types");
3576
+ var import_types14 = require("@openhi/types");
3532
3577
  async function updateWorkspaceOperation(params) {
3533
3578
  const { context, id, body, tableName } = params;
3534
3579
  const { tenantId } = context;
@@ -3547,7 +3592,7 @@ async function updateWorkspaceOperation(params) {
3547
3592
  resourceType: "Workspace",
3548
3593
  id
3549
3594
  };
3550
- const summary = JSON.stringify((0, import_types13.extractSummary)(updated));
3595
+ const summary = JSON.stringify((0, import_types14.extractSummary)(updated));
3551
3596
  await service.entities.workspace.patch({ tenantId, id, sk: "CURRENT" }).set({ resource: JSON.stringify(updated), summary, vid, lastUpdated }).go();
3552
3597
  return { id, resource: updated, meta: { lastUpdated, versionId: vid } };
3553
3598
  }
@@ -5645,8 +5690,12 @@ var DataApiPostgresQueryRunner = class {
5645
5690
  resourceArn: this.clusterArn,
5646
5691
  secretArn: this.secretArn,
5647
5692
  database: this.database,
5648
- schema: this.schema,
5649
- sql,
5693
+ // NOTE: the Data API `schema` field is intentionally NOT set —
5694
+ // Aurora Serverless v2's Data API rejects it with
5695
+ // `ValidationException: The schema parameter isn't supported.`
5696
+ // Instead, the SQL is rewritten to schema-qualify the `resources`
5697
+ // table inline before being sent. See {@link qualifyResourcesTable}.
5698
+ sql: qualifyResourcesTable(sql, this.schema),
5650
5699
  parameters: params.map(toSqlParameter),
5651
5700
  // Results as named columns so we can map them back to JS objects.
5652
5701
  includeResultMetadata: true,
@@ -5662,6 +5711,12 @@ var DataApiPostgresQueryRunner = class {
5662
5711
  return JSON.parse(out.formattedRecords);
5663
5712
  }
5664
5713
  };
5714
+ function qualifyResourcesTable(sql, schema) {
5715
+ return sql.replace(
5716
+ /(\b(?:FROM|JOIN)\s+)resources\b/gi,
5717
+ `$1"${schema}".resources`
5718
+ );
5719
+ }
5665
5720
  function toSqlParameter(param) {
5666
5721
  if (param.value === null) {
5667
5722
  return { name: param.name, value: { isNull: true } };