@openhi/constructs 0.0.106 → 0.0.108

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 (54) hide show
  1. package/lib/{chunk-CHPEQRXU.mjs → chunk-6J7NQ6A4.mjs} +2 -2
  2. package/lib/{chunk-YU2HRNUP.mjs → chunk-AJ3G3THO.mjs} +2 -2
  3. package/lib/{chunk-L6UAP4KP.mjs → chunk-EST32BJ2.mjs} +3 -3
  4. package/lib/chunk-GT7SFZLP.mjs +126 -0
  5. package/lib/chunk-GT7SFZLP.mjs.map +1 -0
  6. package/lib/{chunk-QMIOLLAS.mjs → chunk-L3QHWDHB.mjs} +16 -18
  7. package/lib/chunk-L3QHWDHB.mjs.map +1 -0
  8. package/lib/chunk-LKG3I536.mjs +1383 -0
  9. package/lib/chunk-LKG3I536.mjs.map +1 -0
  10. package/lib/{chunk-VYDIGFIX.mjs → chunk-QR5JVSCF.mjs} +11 -1
  11. package/lib/chunk-QR5JVSCF.mjs.map +1 -0
  12. package/lib/{chunk-AO3E22CS.mjs → chunk-WWGJZNXJ.mjs} +74 -4
  13. package/lib/chunk-WWGJZNXJ.mjs.map +1 -0
  14. package/lib/chunk-ZGOHB4RA.mjs +96 -0
  15. package/lib/chunk-ZGOHB4RA.mjs.map +1 -0
  16. package/lib/{events-DGep6C7w.d.mts → events-DPodvl07.d.mts} +3 -3
  17. package/lib/{events-DGep6C7w.d.ts → events-DPodvl07.d.ts} +3 -3
  18. package/lib/index.d.mts +2 -2
  19. package/lib/index.d.ts +4 -4
  20. package/lib/index.js +1045 -9
  21. package/lib/index.js.map +1 -1
  22. package/lib/index.mjs +9 -11
  23. package/lib/index.mjs.map +1 -1
  24. package/lib/pre-token-generation.handler.js +1356 -10
  25. package/lib/pre-token-generation.handler.js.map +1 -1
  26. package/lib/pre-token-generation.handler.mjs +103 -5
  27. package/lib/pre-token-generation.handler.mjs.map +1 -1
  28. package/lib/provision-default-workspace.handler.js +1172 -1
  29. package/lib/provision-default-workspace.handler.js.map +1 -1
  30. package/lib/provision-default-workspace.handler.mjs +5 -5
  31. package/lib/rest-api-lambda.handler.js +2769 -2434
  32. package/lib/rest-api-lambda.handler.js.map +1 -1
  33. package/lib/rest-api-lambda.handler.mjs +630 -1464
  34. package/lib/rest-api-lambda.handler.mjs.map +1 -1
  35. package/lib/seed-demo-data.handler.d.mts +2 -2
  36. package/lib/seed-demo-data.handler.d.ts +2 -2
  37. package/lib/seed-demo-data.handler.js +1174 -10
  38. package/lib/seed-demo-data.handler.js.map +1 -1
  39. package/lib/seed-demo-data.handler.mjs +5 -5
  40. package/lib/seed-system-data.handler.js +15 -5
  41. package/lib/seed-system-data.handler.js.map +1 -1
  42. package/lib/seed-system-data.handler.mjs +9 -9
  43. package/lib/seed-system-data.handler.mjs.map +1 -1
  44. package/package.json +1 -1
  45. package/lib/chunk-AO3E22CS.mjs.map +0 -1
  46. package/lib/chunk-JUNL76HF.mjs +0 -428
  47. package/lib/chunk-JUNL76HF.mjs.map +0 -1
  48. package/lib/chunk-QMIOLLAS.mjs.map +0 -1
  49. package/lib/chunk-VYDIGFIX.mjs.map +0 -1
  50. package/lib/chunk-YZZDUJHI.mjs +0 -37
  51. package/lib/chunk-YZZDUJHI.mjs.map +0 -1
  52. /package/lib/{chunk-CHPEQRXU.mjs.map → chunk-6J7NQ6A4.mjs.map} +0 -0
  53. /package/lib/{chunk-YU2HRNUP.mjs.map → chunk-AJ3G3THO.mjs.map} +0 -0
  54. /package/lib/{chunk-L6UAP4KP.mjs.map → chunk-EST32BJ2.mjs.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDynamoControlService
3
- } from "./chunk-VYDIGFIX.mjs";
3
+ } from "./chunk-QR5JVSCF.mjs";
4
4
 
5
5
  // src/data/operations/control/user/user-find-by-sub-operation.ts
6
6
  async function findUserBySubOperation(params) {
@@ -42,4 +42,4 @@ export {
42
42
  parseUserResource,
43
43
  idFromReference
44
44
  };
45
- //# sourceMappingURL=chunk-CHPEQRXU.mjs.map
45
+ //# sourceMappingURL=chunk-6J7NQ6A4.mjs.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDynamoControlService
3
- } from "./chunk-VYDIGFIX.mjs";
3
+ } from "./chunk-QR5JVSCF.mjs";
4
4
 
5
5
  // src/data/operations/control/role/role-create-operation.ts
6
6
  import { extractSummary } from "@openhi/types";
@@ -30,4 +30,4 @@ async function createRoleOperation(params) {
30
30
  export {
31
31
  createRoleOperation
32
32
  };
33
- //# sourceMappingURL=chunk-YU2HRNUP.mjs.map
33
+ //# sourceMappingURL=chunk-AJ3G3THO.mjs.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  NotFoundError
3
- } from "./chunk-YZZDUJHI.mjs";
3
+ } from "./chunk-LKG3I536.mjs";
4
4
  import {
5
5
  getDynamoControlService
6
- } from "./chunk-VYDIGFIX.mjs";
6
+ } from "./chunk-QR5JVSCF.mjs";
7
7
 
8
8
  // src/data/operations/control/role/role-get-by-id-operation.ts
9
9
  async function getRoleByIdOperation(params) {
@@ -24,4 +24,4 @@ async function getRoleByIdOperation(params) {
24
24
  export {
25
25
  getRoleByIdOperation
26
26
  };
27
- //# sourceMappingURL=chunk-L6UAP4KP.mjs.map
27
+ //# sourceMappingURL=chunk-EST32BJ2.mjs.map
@@ -0,0 +1,126 @@
1
+ import {
2
+ NotFoundError,
3
+ batchGetWithRetry,
4
+ dispatchListMode
5
+ } from "./chunk-LKG3I536.mjs";
6
+ import {
7
+ SHARD_COUNT,
8
+ getDynamoControlService
9
+ } from "./chunk-QR5JVSCF.mjs";
10
+
11
+ // src/data/operations/control/user/user-create-operation.ts
12
+ import { extractSummary } from "@openhi/types";
13
+ async function createUserOperation(params) {
14
+ const { context, body, tableName } = params;
15
+ const service = getDynamoControlService(tableName);
16
+ const id = body.id ?? `user-${Date.now()}`;
17
+ const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
18
+ const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
19
+ const vid = `1`;
20
+ const resource = { resourceType: "User", id, ...parsedResource };
21
+ const summary = JSON.stringify(extractSummary(resource));
22
+ await service.entities.user.put({
23
+ id,
24
+ resource: JSON.stringify(resource),
25
+ summary,
26
+ vid,
27
+ lastUpdated
28
+ }).go();
29
+ return {
30
+ id,
31
+ resource,
32
+ meta: { lastUpdated, versionId: vid }
33
+ };
34
+ }
35
+
36
+ // src/data/operations/control/user/user-delete-operation.ts
37
+ async function deleteUserOperation(params) {
38
+ const { id, tableName } = params;
39
+ const service = getDynamoControlService(tableName);
40
+ await service.entities.user.delete({ id, sk: "CURRENT" }).go();
41
+ }
42
+
43
+ // src/data/operations/control/user/user-get-by-id-operation.ts
44
+ async function getUserByIdOperation(params) {
45
+ const { id, tableName } = params;
46
+ const service = getDynamoControlService(tableName);
47
+ const response = await service.entities.user.get({ id, sk: "CURRENT" }).go();
48
+ const item = response.data;
49
+ if (!item) {
50
+ throw new NotFoundError(`User not found: ${id}`);
51
+ }
52
+ const parsedResource = JSON.parse(item.resource);
53
+ return {
54
+ id,
55
+ resource: { resourceType: "User", id, ...parsedResource }
56
+ };
57
+ }
58
+
59
+ // src/data/operations/control/user/user-list-operation.ts
60
+ var SK = "CURRENT";
61
+ async function listUsersOperation(params) {
62
+ const { tableName, mode = "full" } = params;
63
+ const service = getDynamoControlService(tableName);
64
+ const shardResults = await Promise.all(
65
+ Array.from(
66
+ { length: SHARD_COUNT },
67
+ (_, shard) => service.entities.user.query.gsi1({ gsi1Shard: String(shard) }).go()
68
+ )
69
+ );
70
+ return dispatchListMode(mode, shardResults, {
71
+ hydrate: (orderedIds) => batchGetWithRetry(
72
+ service.entities.user,
73
+ orderedIds.map((id) => ({ id, sk: SK }))
74
+ ),
75
+ getId: (item) => item.id,
76
+ buildEntry: (id, item) => ({
77
+ id,
78
+ resource: {
79
+ resourceType: "User",
80
+ id,
81
+ ...JSON.parse(item.resource)
82
+ }
83
+ }),
84
+ buildSummaryEntry: (id, parsed) => ({
85
+ id,
86
+ resource: { resourceType: "User", id, ...parsed }
87
+ })
88
+ });
89
+ }
90
+
91
+ // src/data/operations/control/user/user-update-operation.ts
92
+ import { extractSummary as extractSummary2 } from "@openhi/types";
93
+ async function updateUserOperation(params) {
94
+ const { context, id, body, tableName } = params;
95
+ const service = getDynamoControlService(tableName);
96
+ const existing = await service.entities.user.get({ id, sk: "CURRENT" }).go();
97
+ if (!existing.data) {
98
+ throw new NotFoundError(`User not found: ${id}`);
99
+ }
100
+ const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
101
+ const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
102
+ const vid = `${Date.now()}`;
103
+ const resource = { resourceType: "User", id, ...parsedResource };
104
+ const summary = JSON.stringify(extractSummary2(resource));
105
+ await service.entities.user.put({
106
+ id,
107
+ resource: JSON.stringify(resource),
108
+ summary,
109
+ vid,
110
+ lastUpdated
111
+ }).go();
112
+ return {
113
+ id,
114
+ resource,
115
+ meta: { lastUpdated, versionId: vid }
116
+ };
117
+ }
118
+
119
+ export {
120
+ createUserOperation,
121
+ deleteUserOperation,
122
+ getUserByIdOperation,
123
+ listUsersOperation,
124
+ updateUserOperation
125
+ };
126
+ //# sourceMappingURL=chunk-GT7SFZLP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/data/operations/control/user/user-create-operation.ts","../src/data/operations/control/user/user-delete-operation.ts","../src/data/operations/control/user/user-get-by-id-operation.ts","../src/data/operations/control/user/user-list-operation.ts","../src/data/operations/control/user/user-update-operation.ts"],"sourcesContent":["import { extractSummary, type FhirResourceLike } from \"@openhi/types\";\nimport { getDynamoControlService } from \"../../../dynamo/dynamo-control-service\";\nimport { OpenHiContext } from \"../../../openhi-context\";\n\nexport interface UserCreateParams {\n context: OpenHiContext;\n body: { id?: string; resource?: Record<string, unknown> | string };\n tableName?: string;\n}\n\nexport interface UserCreateResult {\n id: string;\n resource: { resourceType: string; id: string; [key: string]: unknown };\n meta: { lastUpdated: string; versionId: string };\n}\n\nexport async function createUserOperation(\n params: UserCreateParams,\n): Promise<UserCreateResult> {\n const { context, body, tableName } = params;\n const service = getDynamoControlService(tableName);\n\n const id = body.id ?? `user-${Date.now()}`;\n const parsedResource =\n typeof body.resource === \"string\"\n ? (JSON.parse(body.resource) as Record<string, unknown>)\n : (body.resource ?? {});\n\n const lastUpdated = context.date ?? new Date().toISOString();\n const vid = `1`;\n\n const resource = { resourceType: \"User\", id, ...parsedResource };\n const summary = JSON.stringify(extractSummary(resource as FhirResourceLike));\n\n await service.entities.user\n .put({\n id,\n resource: JSON.stringify(resource),\n summary,\n vid,\n lastUpdated,\n })\n .go();\n\n return {\n id,\n resource,\n meta: { lastUpdated, versionId: vid },\n };\n}\n","import { getDynamoControlService } from \"../../../dynamo/dynamo-control-service\";\nimport { OpenHiContext } from \"../../../openhi-context\";\n\nexport interface UserDeleteParams {\n context: OpenHiContext;\n id: string;\n tableName?: string;\n}\n\nexport async function deleteUserOperation(\n params: UserDeleteParams,\n): Promise<void> {\n const { id, tableName } = params;\n const service = getDynamoControlService(tableName);\n\n await service.entities.user.delete({ id, sk: \"CURRENT\" }).go();\n}\n","import { getDynamoControlService } from \"../../../dynamo/dynamo-control-service\";\nimport { NotFoundError } from \"../../../errors\";\nimport { OpenHiContext } from \"../../../openhi-context\";\n\nexport interface UserGetByIdParams {\n context: OpenHiContext;\n id: string;\n tableName?: string;\n}\n\nexport interface UserGetByIdResult {\n id: string;\n resource: { resourceType: string; id: string; [key: string]: unknown };\n}\n\nexport async function getUserByIdOperation(\n params: UserGetByIdParams,\n): Promise<UserGetByIdResult> {\n const { id, tableName } = params;\n const service = getDynamoControlService(tableName);\n\n const response = await service.entities.user.get({ id, sk: \"CURRENT\" }).go();\n\n const item = response.data;\n if (!item) {\n throw new NotFoundError(`User not found: ${id}`);\n }\n\n const parsedResource = JSON.parse(item.resource) as Record<string, unknown>;\n\n return {\n id,\n resource: { resourceType: \"User\", id, ...parsedResource },\n };\n}\n","import { getDynamoControlService } from \"../../../dynamo/dynamo-control-service\";\nimport { SHARD_COUNT } from \"../../../dynamo/shard\";\nimport { OpenHiContext } from \"../../../openhi-context\";\nimport {\n batchGetWithRetry,\n dispatchListMode,\n type ListOperationMode,\n} from \"../../data-operations-common\";\n\nconst SK = \"CURRENT\";\n\nexport interface UserListParams {\n context: OpenHiContext;\n tableName?: string;\n /** #853: defaults to `\"full\"`. `\"summary\"` skips BatchGet, `\"count\"` returns total only. */\n mode?: ListOperationMode;\n}\n\nexport interface UserListResult {\n entries: Array<{\n id: string;\n resource: { resourceType: string; id: string; [key: string]: unknown };\n }>;\n total: number;\n}\n\n/**\n * Lists Users via GSI1 (sharded). `mode` (default `\"full\"`) selects between BatchGet hydration,\n * summary-only (parse `summary` JSON projected on GSI1), or count-only (skip both). See\n * `dispatchListMode` in data-operations-common for the canonical mode contract.\n */\nexport async function listUsersOperation(\n params: UserListParams,\n): Promise<UserListResult> {\n const { tableName, mode = \"full\" } = params;\n const service = getDynamoControlService(tableName);\n\n const shardResults = await Promise.all(\n Array.from({ length: SHARD_COUNT }, (_, shard) =>\n service.entities.user.query.gsi1({ gsi1Shard: String(shard) }).go(),\n ),\n );\n\n return dispatchListMode<\n { id: string; resource: string },\n UserListResult[\"entries\"][number]\n >(mode, shardResults, {\n hydrate: (orderedIds) =>\n batchGetWithRetry(\n service.entities.user,\n orderedIds.map((id) => ({ id, sk: SK })),\n ) as Promise<Array<{ id: string; resource: string }>>,\n getId: (item) => item.id,\n buildEntry: (id, item) => ({\n id,\n resource: {\n resourceType: \"User\",\n id,\n ...(JSON.parse(item.resource) as Record<string, unknown>),\n },\n }),\n buildSummaryEntry: (id, parsed) => ({\n id,\n resource: { resourceType: \"User\", id, ...parsed },\n }),\n });\n}\n","import { extractSummary, type FhirResourceLike } from \"@openhi/types\";\nimport { getDynamoControlService } from \"../../../dynamo/dynamo-control-service\";\nimport { NotFoundError } from \"../../../errors\";\nimport { OpenHiContext } from \"../../../openhi-context\";\n\nexport interface UserUpdateParams {\n context: OpenHiContext;\n id: string;\n body: { resource?: Record<string, unknown> | string };\n tableName?: string;\n}\n\nexport interface UserUpdateResult {\n id: string;\n resource: { resourceType: string; id: string; [key: string]: unknown };\n meta: { lastUpdated: string; versionId: string };\n}\n\nexport async function updateUserOperation(\n params: UserUpdateParams,\n): Promise<UserUpdateResult> {\n const { context, id, body, tableName } = params;\n const service = getDynamoControlService(tableName);\n\n const existing = await service.entities.user.get({ id, sk: \"CURRENT\" }).go();\n if (!existing.data) {\n throw new NotFoundError(`User not found: ${id}`);\n }\n\n const parsedResource =\n typeof body.resource === \"string\"\n ? (JSON.parse(body.resource) as Record<string, unknown>)\n : (body.resource ?? {});\n\n const lastUpdated = context.date ?? new Date().toISOString();\n const vid = `${Date.now()}`;\n\n const resource = { resourceType: \"User\", id, ...parsedResource };\n const summary = JSON.stringify(extractSummary(resource as FhirResourceLike));\n\n await service.entities.user\n .put({\n id,\n resource: JSON.stringify(resource),\n summary,\n vid,\n lastUpdated,\n })\n .go();\n\n return {\n id,\n resource,\n meta: { lastUpdated, versionId: vid },\n };\n}\n"],"mappings":"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","names":["extractSummary","extractSummary"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getRoleByIdOperation
3
- } from "./chunk-L6UAP4KP.mjs";
3
+ } from "./chunk-EST32BJ2.mjs";
4
4
  import {
5
5
  require_lib
6
6
  } from "./chunk-SYBADQXI.mjs";
@@ -9,13 +9,13 @@ import {
9
9
  createRoleAssignmentOperation,
10
10
  createTenantOperation,
11
11
  createWorkspaceOperation
12
- } from "./chunk-AO3E22CS.mjs";
12
+ } from "./chunk-WWGJZNXJ.mjs";
13
13
  import {
14
14
  NotFoundError
15
- } from "./chunk-YZZDUJHI.mjs";
15
+ } from "./chunk-LKG3I536.mjs";
16
16
  import {
17
17
  getDynamoControlService
18
- } from "./chunk-VYDIGFIX.mjs";
18
+ } from "./chunk-QR5JVSCF.mjs";
19
19
  import {
20
20
  __toESM
21
21
  } from "./chunk-LZOMFHX3.mjs";
@@ -32,17 +32,15 @@ import {
32
32
  } from "@aws-sdk/client-cognito-identity-provider";
33
33
  import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
34
34
  import {
35
- CONTROL_PLANE_ROLE_CODE as CONTROL_PLANE_ROLE_CODE2,
36
- CONTROL_PLANE_ROLE_CONCEPTS,
37
- CONTROL_PLANE_ROLE_IDS,
35
+ PLATFORM_ROLE_CODE as PLATFORM_ROLE_CODE2,
36
+ PLATFORM_ROLE_CONCEPTS,
37
+ PLATFORM_ROLE_IDS,
38
38
  extractSummary
39
39
  } from "@openhi/types";
40
40
 
41
41
  // src/workflows/control-plane/seed-demo-data/events.ts
42
42
  var import_workflows = __toESM(require_lib());
43
- import {
44
- CONTROL_PLANE_ROLE_CODE
45
- } from "@openhi/types";
43
+ import { PLATFORM_ROLE_CODE } from "@openhi/types";
46
44
  var SEED_DEMO_DATA_CONSUMER_NAME = "seed-demo-data";
47
45
  var DEMO_URN_SYSTEM = "urn:openhi:demo";
48
46
  var OPENHI_RESOURCE_URN_SYSTEM = "http://openhi.org/";
@@ -130,7 +128,7 @@ var openhiResourceIdentifier = (params) => ({
130
128
  var demoRolesForUserInTenant = (_user, _tenantId) => {
131
129
  void _user;
132
130
  void _tenantId;
133
- return [CONTROL_PLANE_ROLE_CODE.TENANT_ADMIN];
131
+ return [PLATFORM_ROLE_CODE.TENANT_ADMIN];
134
132
  };
135
133
  var rolePartitionKey = (roleId) => `role#id#${roleId}`;
136
134
  var demoTenantPartitionKey = (tenantId) => `tenant#id#${tenantId}`;
@@ -174,7 +172,7 @@ var demoDevUserPartitionKeys = (devUsers) => {
174
172
  demoRoleAssignmentId(
175
173
  user.id,
176
174
  PLATFORM_SCOPE_TENANT_ID,
177
- CONTROL_PLANE_ROLE_CODE.SYSTEM_ADMIN
175
+ PLATFORM_ROLE_CODE.SYSTEM_ADMIN
178
176
  )
179
177
  )
180
178
  );
@@ -191,9 +189,9 @@ var errorMessage = (err) => {
191
189
  return String(err);
192
190
  };
193
191
  var idForRoleCode = (code) => {
194
- for (const key of Object.keys(CONTROL_PLANE_ROLE_IDS)) {
195
- if (CONTROL_PLANE_ROLE_CONCEPTS[key].code === code) {
196
- return CONTROL_PLANE_ROLE_IDS[key];
192
+ for (const key of Object.keys(PLATFORM_ROLE_IDS)) {
193
+ if (PLATFORM_ROLE_CONCEPTS[key].code === code) {
194
+ return PLATFORM_ROLE_IDS[key];
197
195
  }
198
196
  }
199
197
  throw new Error(`No id mapping for role code "${code}".`);
@@ -208,7 +206,7 @@ var verifySystemRolesExist = async () => {
208
206
  actorType: "internal-system",
209
207
  source: "step-function"
210
208
  };
211
- for (const id of Object.values(CONTROL_PLANE_ROLE_IDS)) {
209
+ for (const id of Object.values(PLATFORM_ROLE_IDS)) {
212
210
  try {
213
211
  await getRoleByIdOperation({ context: probeContext, id });
214
212
  } catch (err) {
@@ -357,7 +355,7 @@ var seedDemoGraph = async (params) => {
357
355
  ...baseContext,
358
356
  tenantId: PLATFORM_SCOPE_TENANT_ID
359
357
  };
360
- const platformRoleCode = CONTROL_PLANE_ROLE_CODE2.SYSTEM_ADMIN;
358
+ const platformRoleCode = PLATFORM_ROLE_CODE2.SYSTEM_ADMIN;
361
359
  const platformRaId = demoRoleAssignmentId(
362
360
  user.id,
363
361
  PLATFORM_SCOPE_TENANT_ID,
@@ -528,4 +526,4 @@ export {
528
526
  productionCognitoProvisioner,
529
527
  handler
530
528
  };
531
- //# sourceMappingURL=chunk-QMIOLLAS.mjs.map
529
+ //# sourceMappingURL=chunk-L3QHWDHB.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/workflows/control-plane/seed-demo-data/seed-demo-data.handler.ts","../src/workflows/control-plane/seed-demo-data/events.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n AdminCreateUserCommand,\n AdminGetUserCommand,\n AdminSetUserPasswordCommand,\n CognitoIdentityProviderClient,\n UsernameExistsException,\n type AttributeType,\n} from \"@aws-sdk/client-cognito-identity-provider\";\nimport { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";\nimport {\n PLATFORM_ROLE_CODE,\n PLATFORM_ROLE_CONCEPTS,\n PLATFORM_ROLE_IDS,\n extractSummary,\n type PlatformRoleCode,\n type FhirResourceLike,\n} from \"@openhi/types\";\nimport {\n parseWorkflowEvent,\n workflowDedupClient,\n type WorkflowDedupClient,\n} from \"@openhi/workflows\";\nimport type { EventBridgeEvent } from \"aws-lambda\";\nimport {\n DEMO_PERIOD,\n DEMO_TENANT_SPECS,\n DEV_USERS,\n PLACEHOLDER_TENANT_ID,\n PLACEHOLDER_WORKSPACE_ID,\n PLATFORM_SCOPE_TENANT_ID,\n PlatformSystemDataSeededV1,\n SEED_DEMO_DATA_CONSUMER_NAME,\n demoMembershipId,\n demoRoleAssignmentId,\n demoRolesForUserInTenant,\n demoScenarioIdentifier,\n openhiResourceIdentifier,\n type DemoDevUser,\n} from \"./events\";\nimport { getDynamoControlService } from \"../../../data/dynamo/dynamo-control-service\";\nimport { NotFoundError } from \"../../../data/errors\";\nimport type { OpenHiContext } from \"../../../data/openhi-context\";\nimport { createMembershipOperation } from \"../../../data/operations/control/membership/membership-create-operation\";\nimport { getRoleByIdOperation } from \"../../../data/operations/control/role/role-get-by-id-operation\";\nimport { createRoleAssignmentOperation } from \"../../../data/operations/control/roleassignment/roleassignment-create-operation\";\nimport { createTenantOperation } from \"../../../data/operations/control/tenant/tenant-create-operation\";\nimport { createWorkspaceOperation } from \"../../../data/operations/control/workspace/workspace-create-operation\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/seed-demo-data/seed-demo-data-handler.md\n *\n * EventBridge workflow handler invoked once per platform-deploy event\n * on the control event bus. Pre-flight verifies that\n * `seed-system-data` has already seeded the canonical Role records,\n * then idempotently re-asserts the demo-data graph: the placeholder\n * Tenant + Workspace, the three demo tenants + their workspaces, and\n * for each entry in {@link DEV_USERS} a Cognito user, a DynamoDB User,\n * 4 Memberships, 4 `tenant-admin` RoleAssignments, plus 1\n * platform-scoped `system-admin` RoleAssignment.\n */\n\ntype SeedDemoDataEvent = EventBridgeEvent<\n \"platform.system-data-seeded.v1\",\n unknown\n>;\n\n/** Env var the lambda construct injects with the Cognito User Pool ID. */\nexport const SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR =\n \"SEED_DEMO_DATA_USER_POOL_ID\";\n\n/** Inputs the handler needs to provision Cognito users for every dev. */\nexport interface CognitoProvisioner {\n /**\n * Ensure a Cognito user exists for `email`. Returns the user's\n * `sub`. Implementations MUST be idempotent: a second invocation\n * for the same email returns the existing user's sub without\n * resetting its password or touching any attribute.\n */\n readonly ensureUser: (email: string) => Promise<string>;\n}\n\n/**\n * Dependency seam for tests. The factory mirrors the production\n * arrangement: a real DynamoDB client + the real `workflowDedupClient`\n * factory bound to the `OPENHI_WORKFLOW_DEDUP_TABLE_NAME` env var the\n * construct injects via `grantConsumer`.\n */\nexport interface SeedDemoDataDependencies {\n readonly dedupClient: WorkflowDedupClient;\n /**\n * Reads every id in `PLATFORM_ROLE_IDS`. Throws when any Role\n * record is missing — that means `seed-system-data` has not yet\n * run on this environment, and emitting demo RoleAssignments that\n * reference non-existent Roles would produce orphaned records.\n */\n readonly verifyRoles: () => Promise<void>;\n /**\n * Upserts every Tenant + Workspace in {@link DEMO_TENANT_SPECS},\n * plus per-dev-user Cognito users, DynamoDB User records,\n * Memberships, and RoleAssignments.\n */\n readonly seedDemoGraph: (params: {\n readonly baseContext: OpenHiContext;\n readonly devUsers: ReadonlyArray<DemoDevUser>;\n readonly cognito: CognitoProvisioner;\n }) => Promise<void>;\n /** Cognito provisioner threaded into `seedDemoGraph`. */\n readonly cognito: CognitoProvisioner;\n}\n\nconst errorMessage = (err: unknown): string => {\n if (err instanceof Error) {\n return err.message;\n }\n return String(err);\n};\n\n/**\n * Map a role code back to its canonical stable id from\n * `PLATFORM_ROLE_IDS`. Mirrors the lookup in\n * `seed-system-data.handler.ts` — the generator emits `_IDS` and\n * `_CONCEPTS` in lockstep, so a single SCREAMING_SNAKE key resolves\n * both projections.\n */\nconst idForRoleCode = (code: PlatformRoleCode): string => {\n for (const key of Object.keys(PLATFORM_ROLE_IDS) as Array<\n keyof typeof PLATFORM_ROLE_IDS\n >) {\n if (PLATFORM_ROLE_CONCEPTS[key].code === code) {\n return PLATFORM_ROLE_IDS[key];\n }\n }\n throw new Error(`No id mapping for role code \"${code}\".`);\n};\n\n/**\n * Pre-flight Role check. Iterates every id in\n * `PLATFORM_ROLE_IDS` and reads the record. If any read returns\n * not-found, this throws and `markFailed`'s the dedup row — the\n * replay tooling can retry once `seed-system-data` has populated the\n * Roles.\n */\nconst verifySystemRolesExist = async (): Promise<void> => {\n const probeContext: OpenHiContext = {\n tenantId: \"\",\n workspaceId: \"\",\n date: new Date(0).toISOString(),\n actorId: \"platform-deploy-bridge\",\n actorName: \"Platform Deploy Bridge\",\n actorType: \"internal-system\",\n source: \"step-function\",\n };\n for (const id of Object.values(PLATFORM_ROLE_IDS)) {\n try {\n await getRoleByIdOperation({ context: probeContext, id });\n } catch (err) {\n if (err instanceof NotFoundError) {\n throw new Error(\n `seed-demo-data pre-flight: control-plane Role \"${id}\" is missing. ` +\n \"Ensure seed-system-data has run on this environment before retrying.\",\n );\n }\n throw err;\n }\n }\n};\n\n/**\n * Build the resource body for one demo Tenant. Carries the two\n * identifiers per scope decision #6: the demo-scenario URN and the\n * canonical OpenHI resource URN (ADR 2026-03-12-01).\n */\nconst tenantResourceBody = (\n spec: (typeof DEMO_TENANT_SPECS)[number],\n): Record<string, unknown> => ({\n name: spec.tenantName,\n active: true,\n identifier: [\n demoScenarioIdentifier(spec.scenario, \"tenant\"),\n openhiResourceIdentifier({\n tenantId: spec.tenantId,\n workspaceId: \"\",\n resourceType: \"Tenant\",\n id: spec.tenantId,\n }),\n ],\n});\n\nconst workspaceResourceBody = (\n spec: (typeof DEMO_TENANT_SPECS)[number],\n workspace: (typeof DEMO_TENANT_SPECS)[number][\"workspaces\"][number],\n): Record<string, unknown> => ({\n name: workspace.name,\n active: true,\n identifier: [\n demoScenarioIdentifier(spec.scenario, workspace.roleSuffix),\n openhiResourceIdentifier({\n tenantId: spec.tenantId,\n workspaceId: \"\",\n resourceType: \"Workspace\",\n id: workspace.id,\n }),\n ],\n tenant: { reference: `Tenant/${spec.tenantId}`, type: \"Tenant\" },\n});\n\nconst membershipResourceBody = (\n spec: (typeof DEMO_TENANT_SPECS)[number],\n user: DemoDevUser,\n membershipId: string,\n): Record<string, unknown> => ({\n identifier: [\n demoScenarioIdentifier(spec.scenario, `membership-${user.id}`),\n openhiResourceIdentifier({\n tenantId: spec.tenantId,\n workspaceId: \"\",\n resourceType: \"Membership\",\n id: membershipId,\n }),\n ],\n user: { reference: `User/${user.id}`, type: \"User\" },\n tenant: { reference: `Tenant/${spec.tenantId}`, type: \"Tenant\" },\n period: DEMO_PERIOD,\n});\n\nconst roleAssignmentResourceBody = (\n scenario: string,\n tenantId: string,\n user: DemoDevUser,\n roleCode: PlatformRoleCode,\n roleAssignmentId: string,\n): Record<string, unknown> => ({\n identifier: [\n demoScenarioIdentifier(scenario, `roleassignment-${user.id}-${roleCode}`),\n openhiResourceIdentifier({\n tenantId,\n workspaceId: \"\",\n resourceType: \"RoleAssignment\",\n id: roleAssignmentId,\n }),\n ],\n user: { reference: `User/${user.id}`, type: \"User\" },\n role: { reference: `Role/${idForRoleCode(roleCode)}`, type: \"Role\" },\n tenant: { reference: `Tenant/${tenantId}`, type: \"Tenant\" },\n period: DEMO_PERIOD,\n});\n\n/** Build the FHIR User resource body for a seeded dev user. */\nconst userResourceBody = (\n user: DemoDevUser,\n cognitoSub: string,\n): Record<string, unknown> => ({\n resourceType: \"User\",\n id: user.id,\n name: [{ text: user.email }],\n status: \"active\",\n cognitoSub,\n currentTenant: { reference: `Tenant/${PLACEHOLDER_TENANT_ID}` },\n currentWorkspace: { reference: `Workspace/${PLACEHOLDER_WORKSPACE_ID}` },\n});\n\n/**\n * Idempotent User upsert. The User entity is non-tenant-isolated, so\n * the put is unconditional — the entity's PK is `USER#ID#<id>` and\n * supplying the same id re-asserts the same row.\n */\nconst upsertUser = async (\n context: OpenHiContext,\n user: DemoDevUser,\n cognitoSub: string,\n): Promise<void> => {\n const service = getDynamoControlService();\n const resource = userResourceBody(user, cognitoSub);\n const summary = JSON.stringify(extractSummary(resource as FhirResourceLike));\n await service.entities.user\n .put({\n id: user.id,\n cognitoSub,\n resource: JSON.stringify(resource),\n summary,\n vid: \"1\",\n lastUpdated: context.date ?? new Date().toISOString(),\n })\n .go();\n};\n\n/**\n * Upsert the full demo-data graph. Walks each spec in\n * {@link DEMO_TENANT_SPECS}: Tenant → Workspaces. Then per dev user:\n * Cognito user → DynamoDB User → per-tenant Membership +\n * `tenant-admin` RoleAssignment → platform-scoped `system-admin`\n * RoleAssignment. Every put is keyed by a deterministic stable id so\n * re-runs after dedup-TTL expiry upsert the same records.\n *\n * Exported so the seeder test file can exercise it directly against\n * a mocked DynamoControlService; the production handler reaches it\n * through {@link SeedDemoDataDependencies.seedDemoGraph}.\n */\nexport const seedDemoGraph = async (params: {\n baseContext: OpenHiContext;\n devUsers: ReadonlyArray<DemoDevUser>;\n cognito: CognitoProvisioner;\n}): Promise<void> => {\n const { baseContext, devUsers, cognito } = params;\n\n // Phase 1: Tenants + Workspaces (no Memberships / RoleAssignments\n // yet — those need the per-user Cognito sub).\n for (const spec of DEMO_TENANT_SPECS) {\n const tenantContext: OpenHiContext = {\n ...baseContext,\n tenantId: spec.tenantId,\n };\n\n await createTenantOperation({\n context: tenantContext,\n body: { id: spec.tenantId, resource: tenantResourceBody(spec) },\n });\n\n for (const workspace of spec.workspaces) {\n await createWorkspaceOperation({\n context: tenantContext,\n body: {\n id: workspace.id,\n resource: workspaceResourceBody(spec, workspace),\n },\n });\n }\n }\n\n // Phase 2: per-dev-user records. The Cognito provisioner is the\n // only step that can fail in a way EventBridge can usefully retry —\n // it runs first so a failed Cognito call short-circuits before any\n // DynamoDB writes for that user.\n for (const user of devUsers) {\n const cognitoSub = await cognito.ensureUser(user.email);\n\n await upsertUser(baseContext, user, cognitoSub);\n\n for (const spec of DEMO_TENANT_SPECS) {\n const tenantContext: OpenHiContext = {\n ...baseContext,\n tenantId: spec.tenantId,\n };\n\n const membershipId = demoMembershipId(user.id, spec.tenantId);\n await createMembershipOperation({\n context: tenantContext,\n body: {\n id: membershipId,\n resource: membershipResourceBody(spec, user, membershipId),\n },\n });\n\n for (const roleCode of demoRolesForUserInTenant(user, spec.tenantId)) {\n const raId = demoRoleAssignmentId(user.id, spec.tenantId, roleCode);\n await createRoleAssignmentOperation({\n context: tenantContext,\n body: {\n id: raId,\n resource: roleAssignmentResourceBody(\n spec.scenario,\n spec.tenantId,\n user,\n roleCode,\n raId,\n ),\n },\n });\n }\n }\n\n // Platform-scoped system-admin RoleAssignment. The sentinel\n // tenantId is PLATFORM_SCOPE_TENANT_ID — there is no real Tenant\n // to point at, so the operation runs with an OpenHiContext whose\n // tenantId is the sentinel.\n const platformContext: OpenHiContext = {\n ...baseContext,\n tenantId: PLATFORM_SCOPE_TENANT_ID,\n };\n const platformRoleCode = PLATFORM_ROLE_CODE.SYSTEM_ADMIN;\n const platformRaId = demoRoleAssignmentId(\n user.id,\n PLATFORM_SCOPE_TENANT_ID,\n platformRoleCode,\n );\n await createRoleAssignmentOperation({\n context: platformContext,\n body: {\n id: platformRaId,\n resource: roleAssignmentResourceBody(\n \"platform\",\n PLATFORM_SCOPE_TENANT_ID,\n user,\n platformRoleCode,\n platformRaId,\n ),\n },\n });\n }\n};\n\n/**\n * Test-visible orchestrator. The production `handler` calls this with\n * real dependencies and the hardcoded {@link DEV_USERS} list; unit\n * tests inject fakes and pass the dev-user list directly.\n */\nexport const runSeedDemoData = async (\n event: SeedDemoDataEvent,\n deps: SeedDemoDataDependencies,\n devUsers: ReadonlyArray<DemoDevUser>,\n): Promise<void> => {\n const parsed = parseWorkflowEvent(event, PlatformSystemDataSeededV1);\n\n const recordResult = await deps.dedupClient.recordIfAbsent({\n consumerName: SEED_DEMO_DATA_CONSUMER_NAME,\n eventId: parsed.dedupKey.eventId,\n attempt: parsed.dedupKey.attempt,\n });\n if (!recordResult.recorded) {\n return;\n }\n\n const baseContext: OpenHiContext = {\n tenantId: \"\",\n workspaceId: \"\",\n date: parsed.envelope.occurredAt,\n actorId: \"platform-deploy-bridge\",\n actorName: \"Platform Deploy Bridge\",\n actorType: \"internal-system\",\n source: \"step-function\",\n };\n\n try {\n await deps.verifyRoles();\n await deps.seedDemoGraph({\n baseContext,\n devUsers,\n cognito: deps.cognito,\n });\n } catch (err) {\n // Mark the dedup row failed so the replay tooling (TR-016 follow-up)\n // can re-publish the originating event with a fresh attempt. The\n // re-throw keeps EventBridge's failure-detection path intact — the\n // event ends up in the DLQ + the workflow Lambda's failure\n // CloudWatch alarm fires.\n await deps.dedupClient.markFailed({\n consumerName: SEED_DEMO_DATA_CONSUMER_NAME,\n eventId: parsed.dedupKey.eventId,\n attempt: parsed.dedupKey.attempt,\n reason: errorMessage(err),\n });\n throw err;\n }\n};\n\n/**\n * Deterministic password derived from the user's email. Re-running\n * the algorithm with the same email reproduces the password, so devs\n * can recover their own credentials from the docs page without the\n * workflow ever surfacing them. The shape satisfies the default\n * Cognito password policy (≥8 chars, upper + lower + number + symbol).\n */\nexport const devPasswordForEmail = (email: string): string => {\n const digest = createHash(\"sha256\").update(email).digest();\n const base64url = digest\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\");\n return `Dev-${base64url.slice(0, 20)}!1`;\n};\n\n/**\n * Production Cognito provisioner backed by the AWS SDK. Reads the\n * user-pool id from the env var the lambda construct injects.\n *\n * Idempotency contract:\n * - On first invocation, calls `AdminCreateUser` (with\n * `MessageAction: SUPPRESS` so no invitation email fires) then\n * `AdminSetUserPassword` (permanent). Returns the new user's sub.\n * - On subsequent invocations, `AdminCreateUser` throws\n * `UsernameExistsException`; the provisioner catches it, calls\n * `AdminGetUser` to read the existing user's sub, and returns\n * **without** touching the password or any attribute.\n */\nexport const productionCognitoProvisioner = (): CognitoProvisioner => {\n const client = new CognitoIdentityProviderClient({});\n const userPoolId = process.env[SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR];\n if (!userPoolId || userPoolId.trim() === \"\") {\n throw new Error(\n `${SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR} is not set; the seed-demo-data Lambda ` +\n \"cannot provision Cognito users without a user-pool id.\",\n );\n }\n const subFromAttributes = (\n attrs: ReadonlyArray<AttributeType> | undefined,\n ): string | undefined => {\n for (const attr of attrs ?? []) {\n if (attr.Name === \"sub\" && typeof attr.Value === \"string\") {\n return attr.Value;\n }\n }\n return undefined;\n };\n return {\n ensureUser: async (email: string): Promise<string> => {\n try {\n const created = await client.send(\n new AdminCreateUserCommand({\n UserPoolId: userPoolId,\n Username: email,\n MessageAction: \"SUPPRESS\",\n UserAttributes: [\n { Name: \"email\", Value: email },\n { Name: \"email_verified\", Value: \"true\" },\n ],\n }),\n );\n await client.send(\n new AdminSetUserPasswordCommand({\n UserPoolId: userPoolId,\n Username: email,\n Password: devPasswordForEmail(email),\n Permanent: true,\n }),\n );\n const sub = subFromAttributes(created.User?.Attributes);\n if (!sub) {\n throw new Error(\n `AdminCreateUser response for \"${email}\" did not carry a sub attribute.`,\n );\n }\n return sub;\n } catch (err) {\n if (err instanceof UsernameExistsException) {\n // User already exists — skip password reset entirely and\n // just read the existing sub.\n const got = await client.send(\n new AdminGetUserCommand({\n UserPoolId: userPoolId,\n Username: email,\n }),\n );\n const sub = subFromAttributes(got.UserAttributes);\n if (!sub) {\n throw new Error(\n `AdminGetUser response for \"${email}\" did not carry a sub attribute.`,\n );\n }\n return sub;\n }\n throw err;\n }\n },\n };\n};\n\nconst productionDependencies = (): SeedDemoDataDependencies => {\n const dynamodb = new DynamoDBClient({});\n const cognito = productionCognitoProvisioner();\n return {\n dedupClient: workflowDedupClient(dynamodb),\n verifyRoles: verifySystemRolesExist,\n seedDemoGraph,\n cognito,\n };\n};\n\nexport const handler = async (event: SeedDemoDataEvent): Promise<void> =>\n runSeedDemoData(event, productionDependencies(), DEV_USERS);\n","import { PLATFORM_ROLE_CODE, type PlatformRoleCode } from \"@openhi/types\";\nimport { PlatformSystemDataSeededV1 } from \"@openhi/workflows\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/seed-demo-data/events.md\n */\n\n/**\n * Stable logical name this workflow registers with the shared\n * `WorkflowDedupTable` (TR-015). Used in both the construct grant\n * (`workflowDedupTable.grantConsumer(lambda, SEED_DEMO_DATA_CONSUMER_NAME)`)\n * and the handler's runtime `recordIfAbsent` call — keep them aligned by\n * importing this constant in both places.\n */\nexport const SEED_DEMO_DATA_CONSUMER_NAME = \"seed-demo-data\";\n\n/** FHIR `Identifier.system` for the demo-scenario URN scheme. */\nexport const DEMO_URN_SYSTEM = \"urn:openhi:demo\";\n\n/**\n * FHIR `Identifier.system` for the canonical OpenHI resource URN\n * (ADR 2026-03-12-01). The value form is\n * `urn:ohi:<tenantId>:<workspaceId>:<resourceType>:<id>`; empty\n * workspaceId means the resource has tenant-wide scope (or is itself\n * the workspace identity, in the Workspace case).\n */\nexport const OPENHI_RESOURCE_URN_SYSTEM = \"http://openhi.org/\";\n\n/**\n * Period stamped on every demo Membership and RoleAssignment. Fixed\n * start so re-runs produce byte-identical bodies (decision #4); no\n * end so demo memberships are open-ended.\n */\nexport const DEMO_PERIOD = { start: \"2026-01-01T00:00:00Z\" } as const;\n\n/**\n * Sentinel `tenantId` used on every dev user's `system-admin`\n * RoleAssignment. A `system-admin` RA is platform-scoped (it spans\n * every tenant), but the RoleAssignment entity requires a tenantId on\n * its key for sharding — there is no real tenant to point at. The\n * `\"platform\"` literal is a reserved value that never matches a real\n * Tenant id and signals \"this RA scopes across all tenants\".\n *\n * Renaming this constant is a wire-format break — the IAM grant in\n * `seed-demo-data-lambda.ts` enumerates exact-match `LeadingKeys`\n * computed from this value, and the in-band records written under it\n * become unreachable if the sentinel changes.\n */\nexport const PLATFORM_SCOPE_TENANT_ID = \"platform\";\n\n/** Placeholder Tenant id seeded by the workflow as the dev-user `currentTenant`. */\nexport const PLACEHOLDER_TENANT_ID = \"placeholder-tenant-id\";\n\n/** Placeholder Workspace id seeded by the workflow as the dev-user `currentWorkspace`. */\nexport const PLACEHOLDER_WORKSPACE_ID = \"placeholder-workspace-id\";\n\n/**\n * Dev-user descriptor. Every entry produces:\n * - one Cognito user (idempotent create-then-skip),\n * - one DynamoDB User record (id = `dev-<email-local-part>`),\n * - four Memberships (placeholder + the three demo tenants),\n * - four `tenant-admin` RoleAssignments (one per tenant the user\n * belongs to),\n * - one `system-admin` RoleAssignment scoped to {@link PLATFORM_SCOPE_TENANT_ID}.\n */\nexport interface DemoDevUser {\n /** Stable DynamoDB User id. */\n readonly id: string;\n /** Email used as the Cognito `Username` and as the seed for the password algorithm. */\n readonly email: string;\n}\n\n/**\n * Hardcoded dev-user roster. Adding a new developer is a one-line\n * change here plus a re-deploy. The list intentionally lives in-source\n * (not behind an env-var seam) so the IAM grant in\n * `seed-demo-data-lambda.ts` can enumerate per-user PKs at synth time.\n */\nexport const DEV_USERS: ReadonlyArray<DemoDevUser> = [\n { id: \"dev-russell\", email: \"russell@codedrifters.com\" },\n { id: \"dev-cameron\", email: \"cameron@codedrifters.com\" },\n { id: \"dev-neelima\", email: \"neelima@codedrifters.com\" },\n { id: \"dev-garon\", email: \"garon@codedrifters.com\" },\n { id: \"dev-dave\", email: \"dave@codedrifters.com\" },\n { id: \"dev-drew\", email: \"drew@codedrifters.com\" },\n { id: \"dev-jessica\", email: \"jessica@codedrifters.com\" },\n { id: \"dev-jared\", email: \"jared@codedrifters.com\" },\n { id: \"dev-goddess\", email: \"goddess@codedrifters.com\" },\n];\n\n/**\n * A single workspace inside a demo tenant. The mixed tenant has two\n * workspaces (wound-care and primary-care sub-workspaces); the other\n * two tenants have one each.\n */\nexport interface DemoWorkspaceSpec {\n /** Stable id (DynamoDB record id; also drives the canonical OHI URN). */\n readonly id: string;\n /** FHIR `Workspace.name`. */\n readonly name: string;\n /**\n * Role suffix used in the demo URN value (`<scenario>:<roleSuffix>`).\n * Mirrors seed-fixtures' role suffix convention: `workspace` for\n * single-workspace tenants, `workspace-<sub>` for the mixed tenant.\n */\n readonly roleSuffix: string;\n}\n\n/**\n * One demo tenant + the workspaces it owns. Re-exported via {@link\n * DEMO_TENANT_SPECS} as the canonical list; iterate that constant in\n * the handler and the IAM-grant builder so the value sets agree.\n */\nexport interface DemoTenantSpec {\n /**\n * Scenario slug — `placeholder`, `demo-wound-care`, `demo-primary-care`,\n * `demo-mixed`. The placeholder tenant's slug is `placeholder`; the\n * three demo tenants mirror seed-fixtures' `fixture-*` slugs renamed\n * to `demo-*`.\n */\n readonly scenario: string;\n /** Stable id (DynamoDB record id; also drives the canonical OHI URN). */\n readonly tenantId: string;\n /** FHIR `Tenant.name`. */\n readonly tenantName: string;\n /** Workspaces owned by this tenant. */\n readonly workspaces: ReadonlyArray<DemoWorkspaceSpec>;\n}\n\n/**\n * The full demo-tenant graph. Four entries: the placeholder tenant the\n * JWT-claim fallback resolves to, plus the three v1 demo scenarios\n * (OPS-009 §\"v1 scenarios\"):\n *\n * 0. Placeholder tenant — dereferences the JWT-claim fallback in\n * `pre-token-generation.handler.ts` and acts as every dev user's\n * `currentTenant`/`currentWorkspace` so Post-Confirmation skips\n * default provisioning when a seeded User signs in.\n * 1. Single-workspace wound-care tenant.\n * 2. Single-workspace primary-care tenant.\n * 3. Two-workspace mixed tenant — exercises the cross-workspace\n * isolation flow that single-workspace tenants cannot.\n */\nexport const DEMO_TENANT_SPECS: ReadonlyArray<DemoTenantSpec> = [\n {\n scenario: \"placeholder\",\n tenantId: PLACEHOLDER_TENANT_ID,\n tenantName: \"OpenHI Placeholder Tenant\",\n workspaces: [\n {\n id: PLACEHOLDER_WORKSPACE_ID,\n name: \"OpenHI Placeholder Workspace\",\n roleSuffix: \"workspace\",\n },\n ],\n },\n {\n scenario: \"demo-wound-care\",\n tenantId: \"demo-wound-care-tenant\",\n tenantName: \"Cedarbrook Wound Healing Institute\",\n workspaces: [\n {\n id: \"demo-wound-care-workspace\",\n name: \"Cedarbrook Outpatient Wound Clinic\",\n roleSuffix: \"workspace\",\n },\n ],\n },\n {\n scenario: \"demo-primary-care\",\n tenantId: \"demo-primary-care-tenant\",\n tenantName: \"Maple Ridge Family Medicine\",\n workspaces: [\n {\n id: \"demo-primary-care-workspace\",\n name: \"Maple Ridge Main Street Office\",\n roleSuffix: \"workspace\",\n },\n ],\n },\n {\n scenario: \"demo-mixed\",\n tenantId: \"demo-mixed-tenant\",\n tenantName: \"Northbridge Health Network\",\n workspaces: [\n {\n id: \"demo-mixed-workspace-wound-care\",\n name: \"Northbridge Wound Care Center\",\n roleSuffix: \"workspace-wound-care\",\n },\n {\n id: \"demo-mixed-workspace-primary-care\",\n name: \"Northbridge Family Practice\",\n roleSuffix: \"workspace-primary-care\",\n },\n ],\n },\n];\n\n/** Stable Membership id derived from `(devUserId, tenantId)`. */\nexport const demoMembershipId = (devUserId: string, tenantId: string): string =>\n `demo-membership-${devUserId}-${tenantId}`;\n\n/**\n * Stable RoleAssignment id derived from `(devUserId, tenantId, roleCode)`.\n * Each (user, tenant, role) tuple maps to exactly one record — re-runs\n * upsert the same id.\n */\nexport const demoRoleAssignmentId = (\n devUserId: string,\n tenantId: string,\n roleCode: PlatformRoleCode,\n): string => `demo-roleassignment-${devUserId}-${tenantId}-${roleCode}`;\n\n/**\n * Demo-scenario FHIR `Identifier` entry — `urn:openhi:demo:<scenario>:<role>`.\n * Mirrors the `urn:openhi:fixture:<scenario>:<role>` pattern from\n * `@openhi/seed-fixtures/src/urn.ts`, renamed to the `demo` namespace.\n */\nexport const demoScenarioIdentifier = (\n scenario: string,\n roleSuffix: string,\n): { system: string; value: string } => ({\n system: DEMO_URN_SYSTEM,\n value: `${scenario}:${roleSuffix}`,\n});\n\n/**\n * Canonical OpenHI resource FHIR `Identifier` entry per ADR\n * 2026-03-12-01. `workspaceId` is empty for both Tenant resources and\n * Workspace resources — for a Tenant, the resource is tenant-scoped\n * with no workspace context; for a Workspace, the resource IS the\n * workspace identity rather than living inside one.\n */\nexport const openhiResourceIdentifier = (params: {\n tenantId: string;\n workspaceId: string;\n resourceType: string;\n id: string;\n}): { use: string; system: string; value: string } => ({\n use: \"unversioned\",\n system: OPENHI_RESOURCE_URN_SYSTEM,\n value: `urn:ohi:${params.tenantId}:${params.workspaceId}:${params.resourceType}:${params.id}`,\n});\n\n/**\n * Roles every dev user holds in every tenant they belong to. Per scope\n * decision Q3, every dev user is `tenant-admin` in every tenant — there\n * is no per-(user, tenant) variance to drive from.\n */\nexport const demoRolesForUserInTenant = (\n _user: DemoDevUser,\n _tenantId: string,\n): ReadonlyArray<PlatformRoleCode> => {\n void _user;\n void _tenantId;\n return [PLATFORM_ROLE_CODE.TENANT_ADMIN];\n};\n\n/**\n * DynamoDB single-table partition-key builders. The IAM grant in\n * `seed-demo-data-lambda.ts` uses these to enumerate exact-match\n * `dynamodb:LeadingKeys` values; the entity definitions in\n * `data/dynamo/entities/control/` own the canonical key templates.\n *\n * These builders MUST emit the keys ElectroDB actually writes — not\n * the entity definition's pretty template. None of the control-plane\n * entities sets `casing: \"none\"` on the base-table PK template, so\n * ElectroDB applies its default lowercase casing at runtime: the\n * entity's `ROLE#ID#${id}` becomes `role#id#<id>` on the wire. A\n * builder that returns the uppercase template form produces a\n * silently-broken IAM grant (every PutItem denied with \"no\n * identity-based policy allows\" because the request's leading-key\n * never matches a policy value).\n */\nexport const rolePartitionKey = (roleId: string): string => `role#id#${roleId}`;\n\nexport const demoTenantPartitionKey = (tenantId: string): string =>\n `tenant#id#${tenantId}`;\n\nexport const demoWorkspacePartitionKey = (\n tenantId: string,\n workspaceId: string,\n): string => `tid#${tenantId}#workspace#id#${workspaceId}`;\n\nexport const demoMembershipPartitionKey = (\n tenantId: string,\n membershipId: string,\n): string => `tid#${tenantId}#membership#id#${membershipId}`;\n\nexport const demoRoleAssignmentPartitionKey = (\n tenantId: string,\n roleAssignmentId: string,\n): string => `tid#${tenantId}#roleassignment#id#${roleAssignmentId}`;\n\n/** User entity PK template — `USER#ID#<id>` → `user#id#<id>` on the wire. */\nexport const demoUserPartitionKey = (userId: string): string =>\n `user#id#${userId}`;\n\n/**\n * Tenant + Workspace PKs the workflow writes on every fire: the 4\n * tenant PKs (placeholder + 3 demo) plus their workspaces (1 + 1 + 1 + 2 = 5).\n */\nexport const demoBasePartitionKeys = (): ReadonlyArray<string> => {\n const keys: string[] = [];\n for (const spec of DEMO_TENANT_SPECS) {\n keys.push(demoTenantPartitionKey(spec.tenantId));\n for (const workspace of spec.workspaces) {\n keys.push(demoWorkspacePartitionKey(spec.tenantId, workspace.id));\n }\n }\n return keys;\n};\n\n/**\n * Membership + RoleAssignment + User PKs the workflow writes per dev\n * user. Empty when `devUsers` is empty (used by tests). The list\n * mirrors the handler's iteration order so the IAM grant covers every\n * write the handler can make.\n *\n * Per dev user the function emits:\n * - one User PK,\n * - per tenant in {@link DEMO_TENANT_SPECS}: one Membership PK plus\n * one `tenant-admin` RoleAssignment PK,\n * - one platform-scoped `system-admin` RoleAssignment PK keyed by\n * {@link PLATFORM_SCOPE_TENANT_ID}.\n */\nexport const demoDevUserPartitionKeys = (\n devUsers: ReadonlyArray<DemoDevUser>,\n): ReadonlyArray<string> => {\n const keys: string[] = [];\n for (const user of devUsers) {\n keys.push(demoUserPartitionKey(user.id));\n for (const spec of DEMO_TENANT_SPECS) {\n keys.push(\n demoMembershipPartitionKey(\n spec.tenantId,\n demoMembershipId(user.id, spec.tenantId),\n ),\n );\n for (const roleCode of demoRolesForUserInTenant(user, spec.tenantId)) {\n keys.push(\n demoRoleAssignmentPartitionKey(\n spec.tenantId,\n demoRoleAssignmentId(user.id, spec.tenantId, roleCode),\n ),\n );\n }\n }\n // Platform-scoped system-admin RoleAssignment.\n keys.push(\n demoRoleAssignmentPartitionKey(\n PLATFORM_SCOPE_TENANT_ID,\n demoRoleAssignmentId(\n user.id,\n PLATFORM_SCOPE_TENANT_ID,\n PLATFORM_ROLE_CODE.SYSTEM_ADMIN,\n ),\n ),\n );\n }\n return keys;\n};\n\n/**\n * The trigger this workflow subscribes to on the control event bus.\n * The `seed-system-data` workflow publishes\n * `platform.system-data-seeded.v1` after it has finished re-asserting\n * the platform-singleton Role records; on every fire this workflow\n * re-asserts the demo-tenant graph.\n *\n * The indirection (subscribing to `system-data-seeded` rather than to\n * the raw `platform.deployment-completed.v1` event) enforces a strict\n * happens-before edge between the system-data seed and the demo-data\n * seed. Without it, both workflows would fire in parallel from the\n * same deploy event and seed-demo-data's pre-flight Role check would\n * race seed-system-data's puts — a race that EventBridge retries\n * resolve, but only after firing the failure alarm at least once on a\n * fresh environment's first deploy.\n *\n * Re-exported from `@openhi/workflows` for symmetry with the handler's\n * import — keep the construct + handler reading from the same registry\n * entry so a rename upstream surfaces at both call sites.\n */\nexport { PlatformSystemDataSeededV1 };\n"],"mappings":"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","names":["import_workflows","PLATFORM_ROLE_CODE","PLATFORM_ROLE_CODE"]}