@openhi/constructs 0.0.159 → 0.0.161

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 (129) hide show
  1. package/lib/{chunk-HQ67J7BP.mjs → chunk-5S6VFBLT.mjs} +12 -70
  2. package/lib/chunk-5S6VFBLT.mjs.map +1 -0
  3. package/lib/{chunk-MVQWAIMC.mjs → chunk-6BB4CRSS.mjs} +3 -312
  4. package/lib/chunk-6BB4CRSS.mjs.map +1 -0
  5. package/lib/{chunk-WPCBVDFZ.mjs → chunk-76UM2LQ5.mjs} +2 -2
  6. package/lib/chunk-7TRO2STL.mjs +4616 -0
  7. package/lib/chunk-7TRO2STL.mjs.map +1 -0
  8. package/lib/chunk-BUAYVN3C.mjs +87 -0
  9. package/lib/chunk-BUAYVN3C.mjs.map +1 -0
  10. package/lib/{chunk-23PUSHBV.mjs → chunk-D2Y6DDOC.mjs} +2 -2
  11. package/lib/chunk-DWSWCUZR.mjs +123 -0
  12. package/lib/chunk-DWSWCUZR.mjs.map +1 -0
  13. package/lib/{chunk-VZCPGQXA.mjs → chunk-EUIP2U5F.mjs} +69 -1
  14. package/lib/{chunk-VZCPGQXA.mjs.map → chunk-EUIP2U5F.mjs.map} +1 -1
  15. package/lib/chunk-GJTPXJKD.mjs +46 -0
  16. package/lib/chunk-GJTPXJKD.mjs.map +1 -0
  17. package/lib/chunk-I6LUPJUY.mjs +61 -0
  18. package/lib/chunk-I6LUPJUY.mjs.map +1 -0
  19. package/lib/{chunk-KR2Y2CVQ.mjs → chunk-KA3OMP3X.mjs} +2 -2
  20. package/lib/{chunk-ZM4GDHHC.mjs → chunk-KMEWULMX.mjs} +51 -3
  21. package/lib/chunk-KMEWULMX.mjs.map +1 -0
  22. package/lib/chunk-LKKLO66E.mjs +25 -0
  23. package/lib/chunk-LKKLO66E.mjs.map +1 -0
  24. package/lib/{chunk-CFJDATDK.mjs → chunk-MLFMW5IF.mjs} +43 -9
  25. package/lib/chunk-MLFMW5IF.mjs.map +1 -0
  26. package/lib/chunk-O5VQWB6U.mjs +315 -0
  27. package/lib/chunk-O5VQWB6U.mjs.map +1 -0
  28. package/lib/{chunk-7BQHLC7U.mjs → chunk-P3CTZWC2.mjs} +8 -40
  29. package/lib/chunk-P3CTZWC2.mjs.map +1 -0
  30. package/lib/chunk-P3NFCKTZ.mjs +502 -0
  31. package/lib/chunk-P3NFCKTZ.mjs.map +1 -0
  32. package/lib/{chunk-M7Y3BOQW.mjs → chunk-Q3MKITPY.mjs} +5 -5
  33. package/lib/chunk-Q64MOYJ7.mjs +218 -0
  34. package/lib/chunk-Q64MOYJ7.mjs.map +1 -0
  35. package/lib/chunk-RQKJNMX5.mjs +89 -0
  36. package/lib/chunk-RQKJNMX5.mjs.map +1 -0
  37. package/lib/{chunk-ZWSGM6PZ.mjs → chunk-SD7J3N3C.mjs} +2 -2
  38. package/lib/{chunk-7RZHFI77.mjs → chunk-VESULYQQ.mjs} +2 -2
  39. package/lib/{chunk-AOSEKL7U.mjs → chunk-WOTU36P3.mjs} +6 -103
  40. package/lib/chunk-WOTU36P3.mjs.map +1 -0
  41. package/lib/{chunk-X5E4YJGZ.mjs → chunk-YPTJJ35S.mjs} +2 -2
  42. package/lib/counter-apply-operation-DZM3MIDm.d.mts +63 -0
  43. package/lib/counter-apply-operation-DZM3MIDm.d.ts +63 -0
  44. package/lib/counter-maintenance.handler.d.mts +38 -0
  45. package/lib/counter-maintenance.handler.d.ts +38 -0
  46. package/lib/counter-maintenance.handler.js +2885 -0
  47. package/lib/counter-maintenance.handler.js.map +1 -0
  48. package/lib/counter-maintenance.handler.mjs +180 -0
  49. package/lib/counter-maintenance.handler.mjs.map +1 -0
  50. package/lib/counter-reconciliation.handler.d.mts +116 -0
  51. package/lib/counter-reconciliation.handler.d.ts +116 -0
  52. package/lib/counter-reconciliation.handler.js +3324 -0
  53. package/lib/counter-reconciliation.handler.js.map +1 -0
  54. package/lib/counter-reconciliation.handler.mjs +295 -0
  55. package/lib/counter-reconciliation.handler.mjs.map +1 -0
  56. package/lib/data-store-postgres-replication.handler.js +50 -2
  57. package/lib/data-store-postgres-replication.handler.js.map +1 -1
  58. package/lib/data-store-postgres-replication.handler.mjs +2 -2
  59. package/lib/delete-chunk.handler.js +118 -2
  60. package/lib/delete-chunk.handler.js.map +1 -1
  61. package/lib/delete-chunk.handler.mjs +3 -3
  62. package/lib/{events-DTgo2dcW.d.mts → events-TG654e7L.d.mts} +68 -19
  63. package/lib/{events-DTgo2dcW.d.ts → events-TG654e7L.d.ts} +68 -19
  64. package/lib/finalize.handler.js +50 -2
  65. package/lib/finalize.handler.js.map +1 -1
  66. package/lib/finalize.handler.mjs +4 -4
  67. package/lib/firehose-archive-transform.handler.js +50 -2
  68. package/lib/firehose-archive-transform.handler.js.map +1 -1
  69. package/lib/firehose-archive-transform.handler.mjs +2 -2
  70. package/lib/index.d.mts +1283 -4
  71. package/lib/index.d.ts +1389 -24
  72. package/lib/index.js +4113 -320
  73. package/lib/index.js.map +1 -1
  74. package/lib/index.mjs +602 -195
  75. package/lib/index.mjs.map +1 -1
  76. package/lib/list-chunks.handler.js +118 -2
  77. package/lib/list-chunks.handler.js.map +1 -1
  78. package/lib/list-chunks.handler.mjs +3 -3
  79. package/lib/platform-deploy-bridge.handler.js +50 -2
  80. package/lib/platform-deploy-bridge.handler.js.map +1 -1
  81. package/lib/platform-deploy-bridge.handler.mjs +1 -1
  82. package/lib/pre-token-generation.handler.js +68 -0
  83. package/lib/pre-token-generation.handler.js.map +1 -1
  84. package/lib/pre-token-generation.handler.mjs +9 -5
  85. package/lib/pre-token-generation.handler.mjs.map +1 -1
  86. package/lib/provision-default-workspace.handler.js +887 -4
  87. package/lib/provision-default-workspace.handler.js.map +1 -1
  88. package/lib/provision-default-workspace.handler.mjs +14 -9
  89. package/lib/provision-default-workspace.handler.mjs.map +1 -1
  90. package/lib/rename-finalize.handler.js +50 -2
  91. package/lib/rename-finalize.handler.js.map +1 -1
  92. package/lib/rename-finalize.handler.mjs +2 -2
  93. package/lib/rename-list-targets.handler.js +118 -2
  94. package/lib/rename-list-targets.handler.js.map +1 -1
  95. package/lib/rename-list-targets.handler.mjs +11 -9
  96. package/lib/rename-list-targets.handler.mjs.map +1 -1
  97. package/lib/rename-rewrite-chunk.handler.js +68 -0
  98. package/lib/rename-rewrite-chunk.handler.js.map +1 -1
  99. package/lib/rename-rewrite-chunk.handler.mjs +2 -2
  100. package/lib/rest-api-lambda.handler.js +1454 -251
  101. package/lib/rest-api-lambda.handler.js.map +1 -1
  102. package/lib/rest-api-lambda.handler.mjs +673 -821
  103. package/lib/rest-api-lambda.handler.mjs.map +1 -1
  104. package/lib/seed-demo-data.handler.d.mts +1 -1
  105. package/lib/seed-demo-data.handler.d.ts +1 -1
  106. package/lib/seed-demo-data.handler.js +4004 -201
  107. package/lib/seed-demo-data.handler.js.map +1 -1
  108. package/lib/seed-demo-data.handler.mjs +10 -7
  109. package/lib/seed-system-data.handler.js +118 -2
  110. package/lib/seed-system-data.handler.js.map +1 -1
  111. package/lib/seed-system-data.handler.mjs +5 -5
  112. package/package.json +1 -1
  113. package/lib/chunk-7BQHLC7U.mjs.map +0 -1
  114. package/lib/chunk-AOSEKL7U.mjs.map +0 -1
  115. package/lib/chunk-BQMJSDOD.mjs +0 -1136
  116. package/lib/chunk-BQMJSDOD.mjs.map +0 -1
  117. package/lib/chunk-CFJDATDK.mjs.map +0 -1
  118. package/lib/chunk-E6MCKJVS.mjs +0 -212
  119. package/lib/chunk-E6MCKJVS.mjs.map +0 -1
  120. package/lib/chunk-HQ67J7BP.mjs.map +0 -1
  121. package/lib/chunk-MVQWAIMC.mjs.map +0 -1
  122. package/lib/chunk-ZM4GDHHC.mjs.map +0 -1
  123. /package/lib/{chunk-WPCBVDFZ.mjs.map → chunk-76UM2LQ5.mjs.map} +0 -0
  124. /package/lib/{chunk-23PUSHBV.mjs.map → chunk-D2Y6DDOC.mjs.map} +0 -0
  125. /package/lib/{chunk-KR2Y2CVQ.mjs.map → chunk-KA3OMP3X.mjs.map} +0 -0
  126. /package/lib/{chunk-M7Y3BOQW.mjs.map → chunk-Q3MKITPY.mjs.map} +0 -0
  127. /package/lib/{chunk-ZWSGM6PZ.mjs.map → chunk-SD7J3N3C.mjs.map} +0 -0
  128. /package/lib/{chunk-7RZHFI77.mjs.map → chunk-VESULYQQ.mjs.map} +0 -0
  129. /package/lib/{chunk-X5E4YJGZ.mjs.map → chunk-YPTJJ35S.mjs.map} +0 -0
@@ -0,0 +1,4616 @@
1
+ import {
2
+ createAccountOperation,
3
+ createAppointmentOperation,
4
+ createClaimOperation,
5
+ createConditionOperation,
6
+ createCoverageOperation,
7
+ createEncounterOperation,
8
+ createLocationOperation,
9
+ createObservationOperation,
10
+ createOrganizationOperation,
11
+ createPatientOperation,
12
+ createPaymentNoticeOperation,
13
+ createPractitionerOperation,
14
+ createProcedureOperation,
15
+ getRoleByIdOperation
16
+ } from "./chunk-P3NFCKTZ.mjs";
17
+ import {
18
+ PLATFORM_SCOPE_TENANT_ID,
19
+ createMembershipOperation,
20
+ createRoleAssignmentOperation,
21
+ createTenantOperation,
22
+ createWorkspaceOperation
23
+ } from "./chunk-MLFMW5IF.mjs";
24
+ import {
25
+ NotFoundError
26
+ } from "./chunk-FYHBHHWK.mjs";
27
+ import {
28
+ getDynamoControlService
29
+ } from "./chunk-EUIP2U5F.mjs";
30
+ import {
31
+ require_lib
32
+ } from "./chunk-KMEWULMX.mjs";
33
+ import {
34
+ __toESM
35
+ } from "./chunk-LZOMFHX3.mjs";
36
+
37
+ // src/workflows/control-plane/seed-demo-data/seed-demo-data.handler.ts
38
+ var import_workflows2 = __toESM(require_lib());
39
+ import {
40
+ AdminCreateUserCommand,
41
+ AdminGetUserCommand,
42
+ AdminSetUserPasswordCommand,
43
+ CognitoIdentityProviderClient,
44
+ UsernameExistsException
45
+ } from "@aws-sdk/client-cognito-identity-provider";
46
+ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
47
+ import {
48
+ GetParameterCommand,
49
+ ParameterNotFound,
50
+ SSMClient
51
+ } from "@aws-sdk/client-ssm";
52
+ import {
53
+ PLATFORM_ROLE_CODE as PLATFORM_ROLE_CODE2,
54
+ PLATFORM_ROLE_CONCEPTS,
55
+ PLATFORM_ROLE_IDS,
56
+ extractSummary
57
+ } from "@openhi/types";
58
+
59
+ // src/workflows/control-plane/seed-demo-data/events.ts
60
+ var import_workflows = __toESM(require_lib());
61
+ import { PLATFORM_ROLE_CODE } from "@openhi/types";
62
+ var SEED_DEMO_DATA_CONSUMER_NAME = "seed-demo-data";
63
+ var DEMO_URN_SYSTEM = "urn:openhi:demo";
64
+ var OPENHI_RESOURCE_URN_SYSTEM = "http://openhi.org/";
65
+ var DEMO_PERIOD = { start: "2026-01-01T00:00:00Z" };
66
+ var PLACEHOLDER_TENANT_ID = "placeholder-tenant-id";
67
+ var PLACEHOLDER_WORKSPACE_ID = "placeholder-workspace-id";
68
+ var ON_SITE_DEMO_TENANT_ID = "on-site-demo-tenant";
69
+ var ON_SITE_DEMO_WORKSPACE_ID = "on-site-demo-workspace";
70
+ var DEV_USERS = [
71
+ {
72
+ id: "dev-russell",
73
+ email: "russell@codedrifters.com",
74
+ firstName: "Russell",
75
+ lastName: "Ingram"
76
+ },
77
+ {
78
+ id: "dev-cameron",
79
+ email: "cameron@codedrifters.com",
80
+ firstName: "Cameron",
81
+ lastName: "Childress"
82
+ },
83
+ {
84
+ id: "dev-neelima",
85
+ email: "neelima@codedrifters.com",
86
+ firstName: "Neelima",
87
+ lastName: "Ramaraju"
88
+ },
89
+ {
90
+ id: "dev-garon",
91
+ email: "garon@codedrifters.com",
92
+ firstName: "Garon",
93
+ lastName: "Bailey"
94
+ },
95
+ {
96
+ id: "dev-dave",
97
+ email: "dave@codedrifters.com",
98
+ firstName: "Dave",
99
+ lastName: "Finlay"
100
+ },
101
+ {
102
+ id: "dev-drew",
103
+ email: "drew@codedrifters.com",
104
+ firstName: "Drew",
105
+ lastName: "Morris"
106
+ },
107
+ {
108
+ id: "dev-jessica",
109
+ email: "jessica@codedrifters.com",
110
+ firstName: "Jessica",
111
+ lastName: "Branks"
112
+ },
113
+ {
114
+ id: "dev-jared",
115
+ email: "jared@codedrifters.com",
116
+ firstName: "Jared",
117
+ lastName: "Trotter"
118
+ },
119
+ {
120
+ id: "dev-goddess",
121
+ email: "goddess@codedrifters.com",
122
+ firstName: "Goddess",
123
+ lastName: "Culberson"
124
+ },
125
+ // Dedicated end-to-end test principal for admin-console Playwright
126
+ // specs (issue #1275). Reuses the standard DEV_USERS plumbing
127
+ // (Cognito user + DynamoDB User + per-tenant Memberships +
128
+ // tenant-admin RAs + platform-scoped system-admin RA) and the
129
+ // existing SSM-sourced password convention from #1249 — the
130
+ // operator provisions the SecureString at
131
+ // /openhi/seed/users/e2e-admin-console_at_codedrifters.com/password
132
+ // out of band, and the seeded Cognito user picks it up via
133
+ // AdminSetUserPassword on every seed run.
134
+ {
135
+ id: "dev-e2e-admin-console",
136
+ email: "e2e-admin-console@codedrifters.com",
137
+ firstName: "E2E",
138
+ lastName: "AdminConsole"
139
+ }
140
+ ];
141
+ var DEMO_TENANT_SPECS = [
142
+ {
143
+ scenario: "placeholder",
144
+ tenantId: PLACEHOLDER_TENANT_ID,
145
+ tenantName: "OpenHI Placeholder Tenant",
146
+ workspaces: [
147
+ {
148
+ id: PLACEHOLDER_WORKSPACE_ID,
149
+ name: "OpenHI Placeholder Workspace",
150
+ roleSuffix: "workspace"
151
+ }
152
+ ]
153
+ },
154
+ {
155
+ scenario: "on-site-demo",
156
+ tenantId: ON_SITE_DEMO_TENANT_ID,
157
+ tenantName: "On-Site Medical \u2014 Demo",
158
+ workspaces: [
159
+ {
160
+ id: ON_SITE_DEMO_WORKSPACE_ID,
161
+ name: "On-Site Medical \u2014 Primary Workspace",
162
+ roleSuffix: "workspace"
163
+ }
164
+ ]
165
+ },
166
+ {
167
+ scenario: "demo-wound-care",
168
+ tenantId: "demo-wound-care-tenant",
169
+ tenantName: "Cedarbrook Wound Healing Institute",
170
+ workspaces: [
171
+ {
172
+ id: "demo-wound-care-workspace",
173
+ name: "Cedarbrook Outpatient Wound Clinic",
174
+ roleSuffix: "workspace"
175
+ }
176
+ ]
177
+ },
178
+ {
179
+ scenario: "demo-primary-care",
180
+ tenantId: "demo-primary-care-tenant",
181
+ tenantName: "Maple Ridge Family Medicine",
182
+ workspaces: [
183
+ {
184
+ id: "demo-primary-care-workspace",
185
+ name: "Maple Ridge Main Street Office",
186
+ roleSuffix: "workspace"
187
+ }
188
+ ]
189
+ },
190
+ {
191
+ scenario: "demo-mixed",
192
+ tenantId: "demo-mixed-tenant",
193
+ tenantName: "Northbridge Health Network",
194
+ workspaces: [
195
+ {
196
+ id: "demo-mixed-workspace-wound-care",
197
+ name: "Northbridge Wound Care Center",
198
+ roleSuffix: "workspace-wound-care"
199
+ },
200
+ {
201
+ id: "demo-mixed-workspace-primary-care",
202
+ name: "Northbridge Family Practice",
203
+ roleSuffix: "workspace-primary-care"
204
+ }
205
+ ]
206
+ }
207
+ ];
208
+ var demoMembershipId = (devUserId, tenantId) => `demo-membership-${devUserId}-${tenantId}`;
209
+ var demoRoleAssignmentId = (devUserId, tenantId, roleCode) => `demo-roleassignment-${devUserId}-${tenantId}-${roleCode}`;
210
+ var demoScenarioIdentifier = (scenario, roleSuffix) => ({
211
+ system: DEMO_URN_SYSTEM,
212
+ value: `${scenario}:${roleSuffix}`
213
+ });
214
+ var openhiResourceIdentifier = (params) => ({
215
+ use: "unversioned",
216
+ system: OPENHI_RESOURCE_URN_SYSTEM,
217
+ value: `urn:ohi:${params.tenantId}:${params.workspaceId}:${params.resourceType}:${params.id}`
218
+ });
219
+ var demoRolesForUserInTenant = (_user, _tenantId) => {
220
+ void _user;
221
+ void _tenantId;
222
+ return [PLATFORM_ROLE_CODE.TENANT_ADMIN];
223
+ };
224
+
225
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-facilities.ts
226
+ var DIRECTOR_OF_NURSING_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/director-of-nursing";
227
+ var DIRECTOR_OF_NURSING_NAME_EXTENSION_URL = "name";
228
+ var DIRECTOR_OF_NURSING_PHONE_EXTENSION_URL = "phone";
229
+ var DIRECTOR_OF_NURSING_EMAIL_EXTENSION_URL = "email";
230
+ var ON_SITE_SCENARIO = "on-site-demo";
231
+ var FACILITY_SPECS = [
232
+ {
233
+ id: "on-site-demo-facility-001",
234
+ name: "Druid Hills Skilled Nursing",
235
+ phone: "+14045550301",
236
+ email: "frontdesk@druidhills.on-site-demo.example.com",
237
+ addressLine: "1455 Clifton Road NE",
238
+ addressCity: "Atlanta",
239
+ addressState: "GA",
240
+ addressPostalCode: "30322",
241
+ directorOfNursingName: "Patricia Lambert, RN",
242
+ directorOfNursingPhone: "+14045550311",
243
+ directorOfNursingEmail: "p.lambert@druidhills.on-site-demo.example.com"
244
+ },
245
+ {
246
+ id: "on-site-demo-facility-002",
247
+ name: "Buckhead Rehabilitation Center",
248
+ phone: "+14045550302",
249
+ email: "frontdesk@buckhead.on-site-demo.example.com",
250
+ addressLine: "3193 Howell Mill Road NW",
251
+ addressCity: "Atlanta",
252
+ addressState: "GA",
253
+ addressPostalCode: "30327",
254
+ directorOfNursingName: "Karen Whitfield, RN",
255
+ directorOfNursingPhone: "+14045550312",
256
+ directorOfNursingEmail: "k.whitfield@buckhead.on-site-demo.example.com"
257
+ },
258
+ {
259
+ id: "on-site-demo-facility-003",
260
+ name: "Decatur Senior Living",
261
+ phone: "+14045550303",
262
+ email: "frontdesk@decatur.on-site-demo.example.com",
263
+ addressLine: "920 Church Street",
264
+ addressCity: "Decatur",
265
+ addressState: "GA",
266
+ addressPostalCode: "30030",
267
+ directorOfNursingName: "Monique Beaumont, RN",
268
+ directorOfNursingPhone: "+14045550313",
269
+ directorOfNursingEmail: "m.beaumont@decatur.on-site-demo.example.com"
270
+ }
271
+ ];
272
+ var buildIdentifierPair = (locationId, roleSuffix) => [
273
+ demoScenarioIdentifier(ON_SITE_SCENARIO, roleSuffix),
274
+ openhiResourceIdentifier({
275
+ tenantId: ON_SITE_DEMO_TENANT_ID,
276
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
277
+ resourceType: "Location",
278
+ id: locationId
279
+ })
280
+ ];
281
+ var buildFacilityResource = (spec) => ({
282
+ resourceType: "Location",
283
+ id: spec.id,
284
+ status: "active",
285
+ name: spec.name,
286
+ identifier: buildIdentifierPair(spec.id, `facility-${spec.id}`),
287
+ type: [{ text: "facility" }],
288
+ telecom: [
289
+ { system: "phone", value: spec.phone, use: "work" },
290
+ { system: "email", value: spec.email, use: "work" }
291
+ ],
292
+ address: {
293
+ use: "work",
294
+ line: [spec.addressLine],
295
+ city: spec.addressCity,
296
+ state: spec.addressState,
297
+ postalCode: spec.addressPostalCode,
298
+ country: "US"
299
+ },
300
+ extension: [
301
+ {
302
+ url: DIRECTOR_OF_NURSING_EXTENSION_URL,
303
+ extension: [
304
+ {
305
+ url: DIRECTOR_OF_NURSING_NAME_EXTENSION_URL,
306
+ valueString: spec.directorOfNursingName
307
+ },
308
+ {
309
+ url: DIRECTOR_OF_NURSING_PHONE_EXTENSION_URL,
310
+ valueString: spec.directorOfNursingPhone
311
+ },
312
+ {
313
+ url: DIRECTOR_OF_NURSING_EMAIL_EXTENSION_URL,
314
+ valueString: spec.directorOfNursingEmail
315
+ }
316
+ ]
317
+ }
318
+ ]
319
+ });
320
+ var ON_SITE_DEMO_FACILITIES = FACILITY_SPECS.map(buildFacilityResource);
321
+ var ON_SITE_DEMO_FACILITY_IDS = FACILITY_SPECS.map((f) => f.id);
322
+
323
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-blocks.ts
324
+ var ON_SITE_DEMO_BLOCK_CAPACITY_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/block-capacity";
325
+ var ON_SITE_APPOINTMENT_TYPE_SYSTEM = "https://onsite-medical.org/appointment-type";
326
+ var BLOCK_OCCURRENCE_WEEKS_PAST = 4;
327
+ var BLOCK_OCCURRENCE_WEEKS_FUTURE = 8;
328
+ var BLOCK_OCCURRENCES_PER_TEMPLATE = BLOCK_OCCURRENCE_WEEKS_PAST + 1 + BLOCK_OCCURRENCE_WEEKS_FUTURE;
329
+ var BLOCK_TEMPLATES = [
330
+ {
331
+ id: "on-site-demo-block-001",
332
+ facilityId: "on-site-demo-facility-001",
333
+ // Druid Hills
334
+ displayName: "Druid Hills \u2014 Tuesday rounds",
335
+ dayOfWeek: 2,
336
+ // Tuesday
337
+ startHourUtc: 14,
338
+ // 09:00 ET (EST: 14:00 UTC; EDT: 13:00 UTC) — fixed UTC keeps demo deterministic
339
+ endHourUtc: 18,
340
+ // 4-hour block
341
+ doctorId: "on-site-demo-doctor-001",
342
+ scribeId: "on-site-demo-scribe-001",
343
+ capacity: 16
344
+ },
345
+ {
346
+ id: "on-site-demo-block-002",
347
+ facilityId: "on-site-demo-facility-001",
348
+ // Druid Hills (same facility, different weekday)
349
+ displayName: "Druid Hills \u2014 Thursday rounds",
350
+ dayOfWeek: 4,
351
+ // Thursday
352
+ startHourUtc: 14,
353
+ endHourUtc: 18,
354
+ doctorId: "on-site-demo-doctor-002",
355
+ scribeId: "on-site-demo-scribe-002",
356
+ capacity: 16
357
+ },
358
+ {
359
+ id: "on-site-demo-block-003",
360
+ facilityId: "on-site-demo-facility-002",
361
+ // Buckhead
362
+ displayName: "Buckhead \u2014 Wednesday rounds",
363
+ dayOfWeek: 3,
364
+ // Wednesday
365
+ startHourUtc: 14,
366
+ endHourUtc: 18,
367
+ doctorId: "on-site-demo-doctor-003",
368
+ scribeId: "on-site-demo-scribe-003",
369
+ capacity: 14
370
+ },
371
+ {
372
+ id: "on-site-demo-block-004",
373
+ facilityId: "on-site-demo-facility-003",
374
+ // Decatur
375
+ displayName: "Decatur \u2014 Monday rounds",
376
+ dayOfWeek: 1,
377
+ // Monday
378
+ startHourUtc: 14,
379
+ endHourUtc: 18,
380
+ doctorId: "on-site-demo-doctor-004",
381
+ scribeId: "on-site-demo-scribe-004",
382
+ capacity: 12
383
+ }
384
+ ];
385
+ var validateBlockTemplateReferences = () => {
386
+ const facilitySet = new Set(ON_SITE_DEMO_FACILITY_IDS);
387
+ const doctorSet = new Set(ON_SITE_DEMO_DOCTOR_IDS);
388
+ const scribeSet = new Set(ON_SITE_DEMO_SCRIBE_IDS);
389
+ for (const template of BLOCK_TEMPLATES) {
390
+ if (!facilitySet.has(template.facilityId)) {
391
+ throw new Error(
392
+ `Block template "${template.id}" references unknown facility id "${template.facilityId}".`
393
+ );
394
+ }
395
+ if (!doctorSet.has(template.doctorId)) {
396
+ throw new Error(
397
+ `Block template "${template.id}" references unknown doctor id "${template.doctorId}".`
398
+ );
399
+ }
400
+ if (!scribeSet.has(template.scribeId)) {
401
+ throw new Error(
402
+ `Block template "${template.id}" references unknown scribe id "${template.scribeId}".`
403
+ );
404
+ }
405
+ }
406
+ };
407
+ var ON_SITE_DEMO_BLOCK_TEMPLATE_IDS = BLOCK_TEMPLATES.map((t) => t.id);
408
+ var ON_SITE_SCENARIO2 = "on-site-demo";
409
+ var mondayOfIsoWeekUtc = (referenceIso) => {
410
+ const ref = new Date(referenceIso);
411
+ if (Number.isNaN(ref.getTime())) {
412
+ throw new Error(
413
+ `mondayOfIsoWeekUtc: invalid reference date "${referenceIso}".`
414
+ );
415
+ }
416
+ const utcDay = ref.getUTCDay() === 0 ? 7 : ref.getUTCDay();
417
+ const monday = new Date(
418
+ Date.UTC(ref.getUTCFullYear(), ref.getUTCMonth(), ref.getUTCDate())
419
+ );
420
+ monday.setUTCDate(monday.getUTCDate() - (utcDay - 1));
421
+ return monday;
422
+ };
423
+ var occurrenceId = (templateId, weekOffset) => {
424
+ const sign = weekOffset >= 0 ? "p" : "m";
425
+ const magnitude = Math.abs(weekOffset).toString().padStart(2, "0");
426
+ return `${templateId}-w${sign}${magnitude}`;
427
+ };
428
+ var buildIdentifierPair2 = (appointmentId, roleSuffix) => [
429
+ demoScenarioIdentifier(ON_SITE_SCENARIO2, roleSuffix),
430
+ openhiResourceIdentifier({
431
+ tenantId: ON_SITE_DEMO_TENANT_ID,
432
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
433
+ resourceType: "Appointment",
434
+ id: appointmentId
435
+ })
436
+ ];
437
+ var toIsoZ = (d) => (
438
+ // toISOString() always emits a `Z` suffix on UTC times.
439
+ d.toISOString()
440
+ );
441
+ var buildOccurrenceAppointment = (template, anchorMondayUtc, weekOffset) => {
442
+ const occurrenceDay = new Date(anchorMondayUtc);
443
+ occurrenceDay.setUTCDate(
444
+ occurrenceDay.getUTCDate() + weekOffset * 7 + (template.dayOfWeek - 1)
445
+ );
446
+ const start = new Date(occurrenceDay);
447
+ start.setUTCHours(template.startHourUtc, 0, 0, 0);
448
+ const end = new Date(occurrenceDay);
449
+ end.setUTCHours(template.endHourUtc, 0, 0, 0);
450
+ const id = occurrenceId(template.id, weekOffset);
451
+ return {
452
+ resourceType: "Appointment",
453
+ id,
454
+ status: "booked",
455
+ identifier: buildIdentifierPair2(id, `block-${id}`),
456
+ appointmentType: {
457
+ coding: [
458
+ {
459
+ system: ON_SITE_APPOINTMENT_TYPE_SYSTEM,
460
+ code: "block",
461
+ display: "Block"
462
+ }
463
+ ],
464
+ text: "Block"
465
+ },
466
+ description: template.displayName,
467
+ start: toIsoZ(start),
468
+ end: toIsoZ(end),
469
+ minutesDuration: (template.endHourUtc - template.startHourUtc) * 60,
470
+ participant: [
471
+ {
472
+ actor: {
473
+ reference: `Location/${template.facilityId}`,
474
+ type: "Location"
475
+ },
476
+ status: "accepted"
477
+ },
478
+ {
479
+ actor: {
480
+ reference: `Practitioner/${template.doctorId}`,
481
+ type: "Practitioner"
482
+ },
483
+ status: "accepted"
484
+ },
485
+ {
486
+ actor: {
487
+ reference: `Practitioner/${template.scribeId}`,
488
+ type: "Practitioner"
489
+ },
490
+ status: "accepted"
491
+ }
492
+ ],
493
+ extension: [
494
+ {
495
+ url: ON_SITE_DEMO_BLOCK_CAPACITY_EXTENSION_URL,
496
+ valueInteger: template.capacity
497
+ }
498
+ ]
499
+ };
500
+ };
501
+ var buildOnSiteDemoBlockAppointments = (referenceIso) => {
502
+ validateBlockTemplateReferences();
503
+ const anchorMonday = mondayOfIsoWeekUtc(referenceIso);
504
+ const out = [];
505
+ for (const template of BLOCK_TEMPLATES) {
506
+ for (let weekOffset = -BLOCK_OCCURRENCE_WEEKS_PAST; weekOffset <= BLOCK_OCCURRENCE_WEEKS_FUTURE; weekOffset += 1) {
507
+ out.push(buildOccurrenceAppointment(template, anchorMonday, weekOffset));
508
+ }
509
+ }
510
+ return out;
511
+ };
512
+ var findOnSiteDemoBlockTemplate = (templateId) => {
513
+ const t = BLOCK_TEMPLATES.find((tt) => tt.id === templateId);
514
+ if (!t) {
515
+ return void 0;
516
+ }
517
+ return {
518
+ id: t.id,
519
+ facilityId: t.facilityId,
520
+ displayName: t.displayName,
521
+ doctorId: t.doctorId,
522
+ scribeId: t.scribeId,
523
+ capacity: t.capacity,
524
+ dayOfWeek: t.dayOfWeek
525
+ };
526
+ };
527
+
528
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-facility-patients.ts
529
+ var PATIENT_DEFAULT_CARE_SETTING_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-default-care-setting";
530
+ var PATIENT_DEFAULT_CARE_LOCATION_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-default-care-location";
531
+ var PATIENT_RESIDENCY_ADMISSION_DATE_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-residency-admission-date";
532
+ var PATIENT_RESIDENCY_ROOM_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-residency-room";
533
+ var PATIENT_ASSIGNED_BLOCK_TEMPLATE_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-assigned-block-template";
534
+ var PATIENT_HOSPICE_STATUS_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-hospice-status";
535
+ var HOSPICE_STATUS_VALUE_SUB_EXTENSION_URL = "status";
536
+ var HOSPICE_EFFECTIVE_DATE_SUB_EXTENSION_URL = "effectiveDate";
537
+ var COVERAGE_VERIFICATION_DATE_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/coverage-verification-date";
538
+ var COVERAGE_QMB_STATUS_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/coverage-qmb-status";
539
+ var QMB_STATUS_VALUE_SUB_EXTENSION_URL = "status";
540
+ var QMB_EFFECTIVE_DATE_SUB_EXTENSION_URL = "effectiveDate";
541
+ var COVERAGE_PAYOR_TYPE_SYSTEM = "https://on-site-medical.app/fhir/CodeSystem/coverage-payor-type";
542
+ var PAYOR_TYPE_COMMERCIAL = "commercial";
543
+ var PAYOR_TYPE_MEDICARE = "medicare";
544
+ var PAYOR_TYPE_MEDICARE_ADVANTAGE = "medicare-advantage";
545
+ var PATIENTS_PER_BLOCK = [
546
+ { blockTemplateId: "on-site-demo-block-001", count: 16 },
547
+ { blockTemplateId: "on-site-demo-block-002", count: 14 },
548
+ { blockTemplateId: "on-site-demo-block-003", count: 18 },
549
+ { blockTemplateId: "on-site-demo-block-004", count: 12 }
550
+ ];
551
+ var INTAKE_ONLY_PATIENTS_PER_FACILITY = 2;
552
+ var PRIMARY_PAYOR_OPTIONS = [
553
+ { type: PAYOR_TYPE_COMMERCIAL, display: "Aetna PPO" },
554
+ { type: PAYOR_TYPE_COMMERCIAL, display: "Blue Cross Blue Shield of Georgia" },
555
+ { type: PAYOR_TYPE_COMMERCIAL, display: "UnitedHealthcare Choice Plus" },
556
+ { type: PAYOR_TYPE_COMMERCIAL, display: "Cigna OAP" },
557
+ { type: PAYOR_TYPE_MEDICARE, display: "Medicare Part B" },
558
+ { type: PAYOR_TYPE_MEDICARE_ADVANTAGE, display: "Humana Medicare Advantage" },
559
+ {
560
+ type: PAYOR_TYPE_MEDICARE_ADVANTAGE,
561
+ display: "Wellcare by Allwell HMO"
562
+ }
563
+ ];
564
+ var SECONDARY_PAYOR_OPTIONS = [
565
+ { display: "AARP Medigap Plan G" },
566
+ { display: "Mutual of Omaha Medicare Supplement" },
567
+ { display: "Cigna Supplemental Health" },
568
+ { display: "AFLAC Supplemental" }
569
+ ];
570
+ var PATIENT_LAST_NAMES = [
571
+ "Anderson",
572
+ "Bennett",
573
+ "Brennan",
574
+ "Carter",
575
+ "Chen",
576
+ "Coleman",
577
+ "Cooper",
578
+ "Davis",
579
+ "Diaz",
580
+ "Edwards",
581
+ "Fisher",
582
+ "Foster",
583
+ "Garcia",
584
+ "Garrett",
585
+ "Gonzalez",
586
+ "Graham",
587
+ "Greene",
588
+ "Hall",
589
+ "Harper",
590
+ "Harris",
591
+ "Hayes",
592
+ "Hernandez",
593
+ "Holloway",
594
+ "Hughes",
595
+ "Jackson",
596
+ "Jenkins",
597
+ "Johnson",
598
+ "Jones",
599
+ "Kelly",
600
+ "Kim",
601
+ "Lambert",
602
+ "Lawson",
603
+ "Lee",
604
+ "Lopez",
605
+ "Marshall",
606
+ "Martin",
607
+ "Mason",
608
+ "McKenzie",
609
+ "Mendez",
610
+ "Miller",
611
+ "Mitchell",
612
+ "Moore",
613
+ "Morgan",
614
+ "Morris",
615
+ "Murphy",
616
+ "Nguyen",
617
+ "Nichols",
618
+ "Norton",
619
+ "O'Brien",
620
+ "Ortiz",
621
+ "Owens",
622
+ "Park",
623
+ "Patel",
624
+ "Pearson",
625
+ "Perez",
626
+ "Phillips",
627
+ "Porter",
628
+ "Powell",
629
+ "Ramirez",
630
+ "Reed",
631
+ "Reyes",
632
+ "Robinson",
633
+ "Rodriguez",
634
+ "Russell",
635
+ "Sanders",
636
+ "Schultz",
637
+ "Singh",
638
+ "Stewart",
639
+ "Sullivan",
640
+ "Tanaka",
641
+ "Taylor",
642
+ "Thompson",
643
+ "Torres",
644
+ "Walker",
645
+ "Wallace",
646
+ "Watson",
647
+ "Webb",
648
+ "Williams",
649
+ "Wilson",
650
+ "Wong",
651
+ "Wright"
652
+ ];
653
+ var PATIENT_FIRST_NAMES = [
654
+ { name: "Margaret", gender: "female" },
655
+ { name: "Robert", gender: "male" },
656
+ { name: "Dorothy", gender: "female" },
657
+ { name: "William", gender: "male" },
658
+ { name: "Helen", gender: "female" },
659
+ { name: "Charles", gender: "male" },
660
+ { name: "Patricia", gender: "female" },
661
+ { name: "Richard", gender: "male" },
662
+ { name: "Barbara", gender: "female" },
663
+ { name: "James", gender: "male" },
664
+ { name: "Linda", gender: "female" },
665
+ { name: "George", gender: "male" },
666
+ { name: "Mary", gender: "female" },
667
+ { name: "Joseph", gender: "male" },
668
+ { name: "Elizabeth", gender: "female" },
669
+ { name: "Thomas", gender: "male" },
670
+ { name: "Susan", gender: "female" },
671
+ { name: "Frank", gender: "male" },
672
+ { name: "Ruth", gender: "female" },
673
+ { name: "Walter", gender: "male" },
674
+ { name: "Carol", gender: "female" },
675
+ { name: "Donald", gender: "male" },
676
+ { name: "Janet", gender: "female" },
677
+ { name: "Harold", gender: "male" },
678
+ { name: "Joan", gender: "female" },
679
+ { name: "Edward", gender: "male" },
680
+ { name: "Nancy", gender: "female" },
681
+ { name: "Henry", gender: "male" },
682
+ { name: "Betty", gender: "female" },
683
+ { name: "Arthur", gender: "male" }
684
+ ];
685
+ var ON_SITE_SCENARIO3 = "on-site-demo";
686
+ var PATIENT_ANCHOR_DATE = "2026-05-01T00:00:00Z";
687
+ var padIndex = (n) => n.toString().padStart(3, "0");
688
+ var deterministicBirthDate = (index) => {
689
+ const baseYear = 1935;
690
+ const yearSpan = 30;
691
+ const year = baseYear + index % yearSpan;
692
+ const month = index * 7 % 12 + 1;
693
+ const day = index * 11 % 28 + 1;
694
+ const mm = month.toString().padStart(2, "0");
695
+ const dd = day.toString().padStart(2, "0");
696
+ return `${year}-${mm}-${dd}`;
697
+ };
698
+ var deterministicVerificationDate = (index) => {
699
+ const dayOffset = index % 30 + 1;
700
+ const anchor = new Date(PATIENT_ANCHOR_DATE);
701
+ const verifyAt = new Date(anchor);
702
+ verifyAt.setUTCDate(verifyAt.getUTCDate() - dayOffset);
703
+ return verifyAt.toISOString();
704
+ };
705
+ var deterministicAdmissionDate = (index) => {
706
+ const dayOffset = index * 13 % 365 + 1;
707
+ const anchor = new Date(PATIENT_ANCHOR_DATE);
708
+ const admitAt = new Date(anchor);
709
+ admitAt.setUTCDate(admitAt.getUTCDate() - dayOffset);
710
+ return admitAt.toISOString().slice(0, 10);
711
+ };
712
+ var deterministicPhone = (index) => {
713
+ const last4 = (400 + index).toString().padStart(4, "0");
714
+ return `+1404555${last4}`;
715
+ };
716
+ var deterministicEmail = (firstName, lastName, index) => {
717
+ const local = `${firstName}.${lastName}.${padIndex(index)}`.toLowerCase().replace(/[^a-z0-9.]/g, "");
718
+ return `${local}@on-site-demo.example.com`;
719
+ };
720
+ var FACILITY_STREET_NAMES = [
721
+ "Peachtree Street NE",
722
+ "Ponce de Leon Avenue",
723
+ "Piedmont Avenue",
724
+ "Howell Mill Road NW",
725
+ "Northside Drive NW",
726
+ "Edgewood Avenue SE",
727
+ "Spring Street NW",
728
+ "Clifton Road NE"
729
+ ];
730
+ var deterministicAddressLine = (index) => {
731
+ const houseNumber = 100 + index * 7;
732
+ const streetIndex = index % FACILITY_STREET_NAMES.length;
733
+ return `${houseNumber} ${FACILITY_STREET_NAMES[streetIndex]}`;
734
+ };
735
+ var deterministicPrimaryPayor = (index) => {
736
+ const bucket = index % 10;
737
+ if (bucket <= 3) {
738
+ return PRIMARY_PAYOR_OPTIONS[bucket % 4];
739
+ }
740
+ if (bucket <= 6) {
741
+ return PRIMARY_PAYOR_OPTIONS[4];
742
+ }
743
+ return PRIMARY_PAYOR_OPTIONS[5 + (bucket - 7) % 2];
744
+ };
745
+ var hasSecondaryCoverage = (index) => {
746
+ return index % 5 < 2;
747
+ };
748
+ var hasQmbStatus = (index) => {
749
+ return index % 2 === 0;
750
+ };
751
+ var isHospicePatient = (index) => {
752
+ return index % 5 === 0;
753
+ };
754
+ var buildIdentifierPair3 = (patientId, roleSuffix) => [
755
+ demoScenarioIdentifier(ON_SITE_SCENARIO3, roleSuffix),
756
+ openhiResourceIdentifier({
757
+ tenantId: ON_SITE_DEMO_TENANT_ID,
758
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
759
+ resourceType: "Patient",
760
+ id: patientId
761
+ })
762
+ ];
763
+ var buildCoverageIdentifierPair = (coverageId, roleSuffix) => [
764
+ demoScenarioIdentifier(ON_SITE_SCENARIO3, roleSuffix),
765
+ openhiResourceIdentifier({
766
+ tenantId: ON_SITE_DEMO_TENANT_ID,
767
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
768
+ resourceType: "Coverage",
769
+ id: coverageId
770
+ })
771
+ ];
772
+ var buildFacilityPatientResource = (spec) => {
773
+ const firstNameEntry = PATIENT_FIRST_NAMES[spec.index % PATIENT_FIRST_NAMES.length];
774
+ const lastName = PATIENT_LAST_NAMES[spec.index * 3 % PATIENT_LAST_NAMES.length];
775
+ const fullText = `${firstNameEntry.name} ${lastName}`;
776
+ const admissionDate = deterministicAdmissionDate(spec.index);
777
+ const blockExtension = spec.blockTemplateId ? [
778
+ {
779
+ url: PATIENT_ASSIGNED_BLOCK_TEMPLATE_EXTENSION_URL,
780
+ valueString: spec.blockTemplateId
781
+ }
782
+ ] : [];
783
+ const hospiceExtension = isHospicePatient(spec.index) ? [
784
+ {
785
+ url: PATIENT_HOSPICE_STATUS_EXTENSION_URL,
786
+ extension: [
787
+ {
788
+ url: HOSPICE_STATUS_VALUE_SUB_EXTENSION_URL,
789
+ valueCode: "in_hospice"
790
+ },
791
+ {
792
+ url: HOSPICE_EFFECTIVE_DATE_SUB_EXTENSION_URL,
793
+ valueDate: admissionDate
794
+ }
795
+ ]
796
+ }
797
+ ] : [];
798
+ return {
799
+ resourceType: "Patient",
800
+ id: spec.id,
801
+ active: true,
802
+ identifier: buildIdentifierPair3(spec.id, `patient-${spec.id}`),
803
+ name: [
804
+ {
805
+ use: "official",
806
+ text: fullText,
807
+ given: [firstNameEntry.name],
808
+ family: lastName
809
+ }
810
+ ],
811
+ gender: firstNameEntry.gender,
812
+ birthDate: deterministicBirthDate(spec.index),
813
+ telecom: [
814
+ {
815
+ system: "phone",
816
+ value: deterministicPhone(spec.index),
817
+ use: "home"
818
+ },
819
+ {
820
+ system: "email",
821
+ value: deterministicEmail(firstNameEntry.name, lastName, spec.index),
822
+ use: "home"
823
+ }
824
+ ],
825
+ address: [
826
+ {
827
+ use: "home",
828
+ line: [deterministicAddressLine(spec.index)],
829
+ city: "Atlanta",
830
+ state: "GA",
831
+ postalCode: "30303",
832
+ country: "US"
833
+ }
834
+ ],
835
+ extension: [
836
+ {
837
+ url: PATIENT_DEFAULT_CARE_SETTING_EXTENSION_URL,
838
+ valueCode: "facility"
839
+ },
840
+ {
841
+ url: PATIENT_DEFAULT_CARE_LOCATION_EXTENSION_URL,
842
+ valueReference: { reference: `Location/${spec.facilityId}` }
843
+ },
844
+ {
845
+ url: PATIENT_RESIDENCY_ADMISSION_DATE_EXTENSION_URL,
846
+ valueDate: admissionDate
847
+ },
848
+ {
849
+ url: PATIENT_RESIDENCY_ROOM_EXTENSION_URL,
850
+ // Pad to 3 digits so room numbers look like 100..600.
851
+ valueString: `${100 + spec.index % 500}`
852
+ },
853
+ ...blockExtension,
854
+ ...hospiceExtension
855
+ ]
856
+ };
857
+ };
858
+ var buildPrimaryCoverageResource = (spec) => {
859
+ const id = `${spec.id}-coverage-primary`;
860
+ const payor = deterministicPrimaryPayor(spec.index);
861
+ const verificationDate = deterministicVerificationDate(spec.index);
862
+ const isMedicarePrimary = payor.type === PAYOR_TYPE_MEDICARE;
863
+ const qmbExtension = isMedicarePrimary && hasQmbStatus(spec.index) ? [
864
+ {
865
+ url: COVERAGE_QMB_STATUS_EXTENSION_URL,
866
+ extension: [
867
+ {
868
+ url: QMB_STATUS_VALUE_SUB_EXTENSION_URL,
869
+ valueCode: "active"
870
+ },
871
+ {
872
+ url: QMB_EFFECTIVE_DATE_SUB_EXTENSION_URL,
873
+ valueDate: deterministicAdmissionDate(spec.index)
874
+ }
875
+ ]
876
+ }
877
+ ] : [];
878
+ return {
879
+ resourceType: "Coverage",
880
+ id,
881
+ status: "active",
882
+ identifier: buildCoverageIdentifierPair(id, `coverage-primary-${spec.id}`),
883
+ beneficiary: { reference: `Patient/${spec.id}`, type: "Patient" },
884
+ subscriber: { reference: `Patient/${spec.id}`, type: "Patient" },
885
+ subscriberId: `MBR-${padIndex(spec.index)}-PRI`,
886
+ relationship: { text: "self" },
887
+ payor: [
888
+ {
889
+ display: payor.display
890
+ }
891
+ ],
892
+ type: {
893
+ coding: [
894
+ {
895
+ system: COVERAGE_PAYOR_TYPE_SYSTEM,
896
+ code: payor.type,
897
+ display: payor.display
898
+ }
899
+ ],
900
+ text: payor.display
901
+ },
902
+ order: 1,
903
+ extension: [
904
+ {
905
+ url: COVERAGE_VERIFICATION_DATE_EXTENSION_URL,
906
+ valueDateTime: verificationDate
907
+ },
908
+ ...qmbExtension
909
+ ]
910
+ };
911
+ };
912
+ var buildSecondaryCoverageResource = (spec) => {
913
+ if (!hasSecondaryCoverage(spec.index)) {
914
+ return void 0;
915
+ }
916
+ const id = `${spec.id}-coverage-secondary`;
917
+ const payor = SECONDARY_PAYOR_OPTIONS[spec.index % SECONDARY_PAYOR_OPTIONS.length];
918
+ const verificationDate = deterministicVerificationDate(spec.index);
919
+ return {
920
+ resourceType: "Coverage",
921
+ id,
922
+ status: "active",
923
+ identifier: buildCoverageIdentifierPair(
924
+ id,
925
+ `coverage-secondary-${spec.id}`
926
+ ),
927
+ beneficiary: { reference: `Patient/${spec.id}`, type: "Patient" },
928
+ subscriber: { reference: `Patient/${spec.id}`, type: "Patient" },
929
+ subscriberId: `MBR-${padIndex(spec.index)}-SEC`,
930
+ relationship: { text: "self" },
931
+ payor: [
932
+ {
933
+ display: payor.display
934
+ }
935
+ ],
936
+ type: {
937
+ text: payor.display
938
+ },
939
+ order: 2,
940
+ extension: [
941
+ {
942
+ url: COVERAGE_VERIFICATION_DATE_EXTENSION_URL,
943
+ valueDateTime: verificationDate
944
+ }
945
+ ]
946
+ };
947
+ };
948
+ var buildAllFacilityPatientSpecs = () => {
949
+ validateBlockReferences();
950
+ const specs = [];
951
+ let nextIndex = 0;
952
+ for (const { blockTemplateId, count } of PATIENTS_PER_BLOCK) {
953
+ const template = findOnSiteDemoBlockTemplate(blockTemplateId);
954
+ if (!template) {
955
+ throw new Error(
956
+ `Block template "${blockTemplateId}" not found while seeding facility patients.`
957
+ );
958
+ }
959
+ for (let i = 0; i < count; i += 1) {
960
+ const index = nextIndex;
961
+ specs.push({
962
+ id: `on-site-demo-facility-patient-${padIndex(index + 1)}`,
963
+ index,
964
+ facilityId: template.facilityId,
965
+ blockTemplateId
966
+ });
967
+ nextIndex += 1;
968
+ }
969
+ }
970
+ for (const facilityId of ON_SITE_DEMO_FACILITY_IDS) {
971
+ for (let i = 0; i < INTAKE_ONLY_PATIENTS_PER_FACILITY; i += 1) {
972
+ const index = nextIndex;
973
+ specs.push({
974
+ id: `on-site-demo-facility-patient-${padIndex(index + 1)}`,
975
+ index,
976
+ facilityId,
977
+ blockTemplateId: void 0
978
+ });
979
+ nextIndex += 1;
980
+ }
981
+ }
982
+ return specs;
983
+ };
984
+ var validateBlockReferences = () => {
985
+ const blockSet = new Set(ON_SITE_DEMO_BLOCK_TEMPLATE_IDS);
986
+ for (const entry of PATIENTS_PER_BLOCK) {
987
+ if (!blockSet.has(entry.blockTemplateId)) {
988
+ throw new Error(
989
+ `Facility-patient generator references unknown block template id "${entry.blockTemplateId}".`
990
+ );
991
+ }
992
+ }
993
+ };
994
+ var cachedSpecs;
995
+ var getFacilityPatientSpecs = () => {
996
+ if (!cachedSpecs) {
997
+ cachedSpecs = buildAllFacilityPatientSpecs();
998
+ }
999
+ return cachedSpecs;
1000
+ };
1001
+ var buildOnSiteDemoFacilityPatients = () => getFacilityPatientSpecs().map(buildFacilityPatientResource);
1002
+ var buildOnSiteDemoFacilityCoverages = () => {
1003
+ const out = [];
1004
+ for (const spec of getFacilityPatientSpecs()) {
1005
+ out.push(buildPrimaryCoverageResource(spec));
1006
+ const secondary = buildSecondaryCoverageResource(spec);
1007
+ if (secondary) {
1008
+ out.push(secondary);
1009
+ }
1010
+ }
1011
+ return out;
1012
+ };
1013
+ var onSiteDemoFacilityPatientIds = () => getFacilityPatientSpecs().map((s) => s.id);
1014
+ var onSiteDemoScheduledFacilityPatientIds = () => getFacilityPatientSpecs().filter((s) => s.blockTemplateId !== void 0).map((s) => s.id);
1015
+ var onSiteDemoIntakeOnlyFacilityPatientIds = () => getFacilityPatientSpecs().filter((s) => s.blockTemplateId === void 0).map((s) => s.id);
1016
+ var findOnSiteDemoFacilityPatientBlock = (patientId) => {
1017
+ const spec = getFacilityPatientSpecs().find((s) => s.id === patientId);
1018
+ return spec?.blockTemplateId;
1019
+ };
1020
+ var facilityPatientsForBlock = (blockTemplateId) => getFacilityPatientSpecs().filter((s) => s.blockTemplateId === blockTemplateId).map((s) => s.id);
1021
+
1022
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-home-health-patients.ts
1023
+ var PATIENT_ASSIGNED_HOME_HEALTH_PROVIDER_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/patient-assigned-home-health-provider";
1024
+ var HOME_HEALTH_VISIT_CADENCE_DAYS_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/home-health-visit-cadence-days";
1025
+ var HOME_HEALTH_VISIT_CADENCE_OPTIONS = [
1026
+ 7,
1027
+ 14,
1028
+ 28
1029
+ ];
1030
+ var SCHEDULED_HOME_HEALTH_PATIENTS = 17;
1031
+ var INTAKE_ONLY_HOME_HEALTH_PATIENTS = 3;
1032
+ var TOTAL_HOME_HEALTH_PATIENTS = SCHEDULED_HOME_HEALTH_PATIENTS + INTAKE_ONLY_HOME_HEALTH_PATIENTS;
1033
+ var PRIMARY_PAYOR_OPTIONS2 = [
1034
+ { type: PAYOR_TYPE_COMMERCIAL, display: "Aetna PPO" },
1035
+ { type: PAYOR_TYPE_COMMERCIAL, display: "Blue Cross Blue Shield of Georgia" },
1036
+ { type: PAYOR_TYPE_COMMERCIAL, display: "UnitedHealthcare Choice Plus" },
1037
+ { type: PAYOR_TYPE_COMMERCIAL, display: "Cigna OAP" },
1038
+ { type: PAYOR_TYPE_MEDICARE, display: "Medicare Part B" },
1039
+ { type: PAYOR_TYPE_MEDICARE_ADVANTAGE, display: "Humana Medicare Advantage" },
1040
+ {
1041
+ type: PAYOR_TYPE_MEDICARE_ADVANTAGE,
1042
+ display: "Wellcare by Allwell HMO"
1043
+ }
1044
+ ];
1045
+ var SECONDARY_PAYOR_OPTIONS2 = [
1046
+ { display: "AARP Medigap Plan G" },
1047
+ { display: "Mutual of Omaha Medicare Supplement" },
1048
+ { display: "Cigna Supplemental Health" },
1049
+ { display: "AFLAC Supplemental" }
1050
+ ];
1051
+ var PATIENT_LAST_NAMES2 = [
1052
+ "Acosta",
1053
+ "Barnett",
1054
+ "Bryant",
1055
+ "Castillo",
1056
+ "Conway",
1057
+ "Delgado",
1058
+ "Eldridge",
1059
+ "Fitzgerald",
1060
+ "Garza",
1061
+ "Hicks",
1062
+ "Ingram",
1063
+ "Jensen",
1064
+ "Klein",
1065
+ "Larson",
1066
+ "McCarthy",
1067
+ "Nash",
1068
+ "O'Connor",
1069
+ "Pierce",
1070
+ "Quintana",
1071
+ "Reilly",
1072
+ "Salazar",
1073
+ "Tate",
1074
+ "Underwood",
1075
+ "Vega",
1076
+ "Whitaker"
1077
+ ];
1078
+ var PATIENT_FIRST_NAMES2 = [
1079
+ { name: "Eleanor", gender: "female" },
1080
+ { name: "Albert", gender: "male" },
1081
+ { name: "Florence", gender: "female" },
1082
+ { name: "Bernard", gender: "male" },
1083
+ { name: "Marjorie", gender: "female" },
1084
+ { name: "Stanley", gender: "male" },
1085
+ { name: "Gladys", gender: "female" },
1086
+ { name: "Norman", gender: "male" },
1087
+ { name: "Pauline", gender: "female" },
1088
+ { name: "Raymond", gender: "male" },
1089
+ { name: "Lillian", gender: "female" },
1090
+ { name: "Howard", gender: "male" },
1091
+ { name: "Mildred", gender: "female" },
1092
+ { name: "Russell", gender: "male" },
1093
+ { name: "Frances", gender: "female" },
1094
+ { name: "Eugene", gender: "male" },
1095
+ { name: "Bernice", gender: "female" },
1096
+ { name: "Leonard", gender: "male" },
1097
+ { name: "Eileen", gender: "female" },
1098
+ { name: "Clifford", gender: "male" }
1099
+ ];
1100
+ var ON_SITE_SCENARIO4 = "on-site-demo";
1101
+ var PATIENT_ANCHOR_DATE2 = "2026-05-01T00:00:00Z";
1102
+ var padIndex2 = (n) => n.toString().padStart(3, "0");
1103
+ var deterministicBirthDate2 = (index) => {
1104
+ const baseYear = 1932;
1105
+ const yearSpan = 25;
1106
+ const year = baseYear + index % yearSpan;
1107
+ const month = index * 7 % 12 + 1;
1108
+ const day = index * 11 % 28 + 1;
1109
+ const mm = month.toString().padStart(2, "0");
1110
+ const dd = day.toString().padStart(2, "0");
1111
+ return `${year}-${mm}-${dd}`;
1112
+ };
1113
+ var deterministicVerificationDate2 = (index) => {
1114
+ const dayOffset = index % 30 + 1;
1115
+ const anchor = new Date(PATIENT_ANCHOR_DATE2);
1116
+ const verifyAt = new Date(anchor);
1117
+ verifyAt.setUTCDate(verifyAt.getUTCDate() - dayOffset);
1118
+ return verifyAt.toISOString();
1119
+ };
1120
+ var deterministicEffectiveDate = (index) => {
1121
+ const dayOffset = index * 13 % 365 + 1;
1122
+ const anchor = new Date(PATIENT_ANCHOR_DATE2);
1123
+ const eff = new Date(anchor);
1124
+ eff.setUTCDate(eff.getUTCDate() - dayOffset);
1125
+ return eff.toISOString().slice(0, 10);
1126
+ };
1127
+ var deterministicPhone2 = (index) => {
1128
+ const last4 = (600 + index).toString().padStart(4, "0");
1129
+ return `+1404555${last4}`;
1130
+ };
1131
+ var deterministicEmail2 = (firstName, lastName, index) => {
1132
+ const local = `${firstName}.${lastName}.${padIndex2(index)}`.toLowerCase().replace(/[^a-z0-9.]/g, "");
1133
+ return `${local}@on-site-demo.example.com`;
1134
+ };
1135
+ var HOME_STREET_NAMES = [
1136
+ "Briarcliff Road NE",
1137
+ "Cheshire Bridge Road",
1138
+ "Dekalb Avenue NE",
1139
+ "Lavista Road",
1140
+ "Memorial Drive SE",
1141
+ "Moreland Avenue NE",
1142
+ "North Decatur Road",
1143
+ "Roswell Road",
1144
+ "Virginia Avenue NE",
1145
+ "West Paces Ferry Road"
1146
+ ];
1147
+ var deterministicAddressLine2 = (index) => {
1148
+ const houseNumber = 200 + index * 11;
1149
+ const streetIndex = index % HOME_STREET_NAMES.length;
1150
+ return `${houseNumber} ${HOME_STREET_NAMES[streetIndex]}`;
1151
+ };
1152
+ var HOME_POSTAL_CODES = [
1153
+ "30306",
1154
+ "30307",
1155
+ "30324",
1156
+ "30329",
1157
+ "30033",
1158
+ "30030",
1159
+ "30342",
1160
+ "30327",
1161
+ "30319",
1162
+ "30305"
1163
+ ];
1164
+ var deterministicPostalCode = (index) => HOME_POSTAL_CODES[index % HOME_POSTAL_CODES.length];
1165
+ var deterministicPrimaryPayor2 = (index) => {
1166
+ const bucket = index % 10;
1167
+ if (bucket <= 3) {
1168
+ return PRIMARY_PAYOR_OPTIONS2[bucket % 4];
1169
+ }
1170
+ if (bucket <= 6) {
1171
+ return PRIMARY_PAYOR_OPTIONS2[4];
1172
+ }
1173
+ return PRIMARY_PAYOR_OPTIONS2[5 + (bucket - 7) % 2];
1174
+ };
1175
+ var hasSecondaryCoverage2 = (index) => {
1176
+ return index % 5 < 2;
1177
+ };
1178
+ var hasQmbStatus2 = (index) => {
1179
+ return index % 2 === 0;
1180
+ };
1181
+ var isHospicePatient2 = (index) => {
1182
+ return index % 5 === 0;
1183
+ };
1184
+ var deterministicVisitCadenceDays = (index) => HOME_HEALTH_VISIT_CADENCE_OPTIONS[index % HOME_HEALTH_VISIT_CADENCE_OPTIONS.length];
1185
+ var buildIdentifierPair4 = (patientId, roleSuffix) => [
1186
+ demoScenarioIdentifier(ON_SITE_SCENARIO4, roleSuffix),
1187
+ openhiResourceIdentifier({
1188
+ tenantId: ON_SITE_DEMO_TENANT_ID,
1189
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
1190
+ resourceType: "Patient",
1191
+ id: patientId
1192
+ })
1193
+ ];
1194
+ var buildCoverageIdentifierPair2 = (coverageId, roleSuffix) => [
1195
+ demoScenarioIdentifier(ON_SITE_SCENARIO4, roleSuffix),
1196
+ openhiResourceIdentifier({
1197
+ tenantId: ON_SITE_DEMO_TENANT_ID,
1198
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
1199
+ resourceType: "Coverage",
1200
+ id: coverageId
1201
+ })
1202
+ ];
1203
+ var buildHomeHealthPatientResource = (spec) => {
1204
+ const firstNameEntry = PATIENT_FIRST_NAMES2[spec.index % PATIENT_FIRST_NAMES2.length];
1205
+ const lastName = PATIENT_LAST_NAMES2[spec.index * 3 % PATIENT_LAST_NAMES2.length];
1206
+ const fullText = `${firstNameEntry.name} ${lastName}`;
1207
+ const effectiveDate = deterministicEffectiveDate(spec.index);
1208
+ const providerExtension = spec.providerId ? [
1209
+ {
1210
+ url: PATIENT_ASSIGNED_HOME_HEALTH_PROVIDER_EXTENSION_URL,
1211
+ valueReference: {
1212
+ reference: `Practitioner/${spec.providerId}`,
1213
+ type: "Practitioner"
1214
+ }
1215
+ }
1216
+ ] : [];
1217
+ const cadenceExtension = typeof spec.visitCadenceDays === "number" ? [
1218
+ {
1219
+ url: HOME_HEALTH_VISIT_CADENCE_DAYS_EXTENSION_URL,
1220
+ valueInteger: spec.visitCadenceDays
1221
+ }
1222
+ ] : [];
1223
+ const hospiceExtension = isHospicePatient2(spec.index) ? [
1224
+ {
1225
+ url: PATIENT_HOSPICE_STATUS_EXTENSION_URL,
1226
+ extension: [
1227
+ {
1228
+ url: HOSPICE_STATUS_VALUE_SUB_EXTENSION_URL,
1229
+ valueCode: "in_hospice"
1230
+ },
1231
+ {
1232
+ url: HOSPICE_EFFECTIVE_DATE_SUB_EXTENSION_URL,
1233
+ valueDate: effectiveDate
1234
+ }
1235
+ ]
1236
+ }
1237
+ ] : [];
1238
+ return {
1239
+ resourceType: "Patient",
1240
+ id: spec.id,
1241
+ active: true,
1242
+ identifier: buildIdentifierPair4(spec.id, `patient-${spec.id}`),
1243
+ name: [
1244
+ {
1245
+ use: "official",
1246
+ text: fullText,
1247
+ given: [firstNameEntry.name],
1248
+ family: lastName
1249
+ }
1250
+ ],
1251
+ gender: firstNameEntry.gender,
1252
+ birthDate: deterministicBirthDate2(spec.index),
1253
+ telecom: [
1254
+ {
1255
+ system: "phone",
1256
+ value: deterministicPhone2(spec.index),
1257
+ use: "home"
1258
+ },
1259
+ {
1260
+ system: "email",
1261
+ value: deterministicEmail2(firstNameEntry.name, lastName, spec.index),
1262
+ use: "home"
1263
+ }
1264
+ ],
1265
+ address: [
1266
+ {
1267
+ use: "home",
1268
+ line: [deterministicAddressLine2(spec.index)],
1269
+ city: "Atlanta",
1270
+ state: "GA",
1271
+ postalCode: deterministicPostalCode(spec.index),
1272
+ country: "US"
1273
+ }
1274
+ ],
1275
+ extension: [
1276
+ {
1277
+ url: PATIENT_DEFAULT_CARE_SETTING_EXTENSION_URL,
1278
+ valueCode: "home"
1279
+ },
1280
+ // No `patient-default-care-location` extension — home-health
1281
+ // patients have no facility Location reference (mirrors the
1282
+ // on-site `buildDefaultCareSettingExtensions` helper, which
1283
+ // only emits the location extension when setting === "facility").
1284
+ ...providerExtension,
1285
+ ...cadenceExtension,
1286
+ ...hospiceExtension
1287
+ ]
1288
+ };
1289
+ };
1290
+ var buildPrimaryCoverageResource2 = (spec) => {
1291
+ const id = `${spec.id}-coverage-primary`;
1292
+ const payor = deterministicPrimaryPayor2(spec.index);
1293
+ const verificationDate = deterministicVerificationDate2(spec.index);
1294
+ const isMedicarePrimary = payor.type === PAYOR_TYPE_MEDICARE;
1295
+ const qmbExtension = isMedicarePrimary && hasQmbStatus2(spec.index) ? [
1296
+ {
1297
+ url: COVERAGE_QMB_STATUS_EXTENSION_URL,
1298
+ extension: [
1299
+ {
1300
+ url: QMB_STATUS_VALUE_SUB_EXTENSION_URL,
1301
+ valueCode: "active"
1302
+ },
1303
+ {
1304
+ url: QMB_EFFECTIVE_DATE_SUB_EXTENSION_URL,
1305
+ valueDate: deterministicEffectiveDate(spec.index)
1306
+ }
1307
+ ]
1308
+ }
1309
+ ] : [];
1310
+ return {
1311
+ resourceType: "Coverage",
1312
+ id,
1313
+ status: "active",
1314
+ identifier: buildCoverageIdentifierPair2(id, `coverage-primary-${spec.id}`),
1315
+ beneficiary: { reference: `Patient/${spec.id}`, type: "Patient" },
1316
+ subscriber: { reference: `Patient/${spec.id}`, type: "Patient" },
1317
+ subscriberId: `MBR-HH-${padIndex2(spec.index)}-PRI`,
1318
+ relationship: { text: "self" },
1319
+ payor: [
1320
+ {
1321
+ display: payor.display
1322
+ }
1323
+ ],
1324
+ type: {
1325
+ coding: [
1326
+ {
1327
+ system: COVERAGE_PAYOR_TYPE_SYSTEM,
1328
+ code: payor.type,
1329
+ display: payor.display
1330
+ }
1331
+ ],
1332
+ text: payor.display
1333
+ },
1334
+ order: 1,
1335
+ extension: [
1336
+ {
1337
+ url: COVERAGE_VERIFICATION_DATE_EXTENSION_URL,
1338
+ valueDateTime: verificationDate
1339
+ },
1340
+ ...qmbExtension
1341
+ ]
1342
+ };
1343
+ };
1344
+ var buildSecondaryCoverageResource2 = (spec) => {
1345
+ if (!hasSecondaryCoverage2(spec.index)) {
1346
+ return void 0;
1347
+ }
1348
+ const id = `${spec.id}-coverage-secondary`;
1349
+ const payor = SECONDARY_PAYOR_OPTIONS2[spec.index % SECONDARY_PAYOR_OPTIONS2.length];
1350
+ const verificationDate = deterministicVerificationDate2(spec.index);
1351
+ return {
1352
+ resourceType: "Coverage",
1353
+ id,
1354
+ status: "active",
1355
+ identifier: buildCoverageIdentifierPair2(
1356
+ id,
1357
+ `coverage-secondary-${spec.id}`
1358
+ ),
1359
+ beneficiary: { reference: `Patient/${spec.id}`, type: "Patient" },
1360
+ subscriber: { reference: `Patient/${spec.id}`, type: "Patient" },
1361
+ subscriberId: `MBR-HH-${padIndex2(spec.index)}-SEC`,
1362
+ relationship: { text: "self" },
1363
+ payor: [
1364
+ {
1365
+ display: payor.display
1366
+ }
1367
+ ],
1368
+ type: {
1369
+ text: payor.display
1370
+ },
1371
+ order: 2,
1372
+ extension: [
1373
+ {
1374
+ url: COVERAGE_VERIFICATION_DATE_EXTENSION_URL,
1375
+ valueDateTime: verificationDate
1376
+ }
1377
+ ]
1378
+ };
1379
+ };
1380
+ var buildAllHomeHealthPatientSpecs = () => {
1381
+ const eligibleDoctors = homeHealthEligibleDoctors();
1382
+ if (eligibleDoctors.length === 0) {
1383
+ throw new Error(
1384
+ "No home-health-eligible doctors found \u2014 cannot seed home-health patients."
1385
+ );
1386
+ }
1387
+ const specs = [];
1388
+ for (let i = 0; i < SCHEDULED_HOME_HEALTH_PATIENTS; i += 1) {
1389
+ const index = i;
1390
+ const providerId = eligibleDoctors[i % eligibleDoctors.length].id;
1391
+ if (!providerId) {
1392
+ throw new Error(
1393
+ "Home-health-eligible doctor is missing an id; cannot seed."
1394
+ );
1395
+ }
1396
+ specs.push({
1397
+ id: `on-site-demo-home-health-patient-${padIndex2(index + 1)}`,
1398
+ index,
1399
+ providerId,
1400
+ visitCadenceDays: deterministicVisitCadenceDays(index)
1401
+ });
1402
+ }
1403
+ for (let i = 0; i < INTAKE_ONLY_HOME_HEALTH_PATIENTS; i += 1) {
1404
+ const index = SCHEDULED_HOME_HEALTH_PATIENTS + i;
1405
+ specs.push({
1406
+ id: `on-site-demo-home-health-patient-${padIndex2(index + 1)}`,
1407
+ index,
1408
+ providerId: void 0,
1409
+ visitCadenceDays: void 0
1410
+ });
1411
+ }
1412
+ return specs;
1413
+ };
1414
+ var cachedSpecs2;
1415
+ var getHomeHealthPatientSpecs = () => {
1416
+ if (!cachedSpecs2) {
1417
+ cachedSpecs2 = buildAllHomeHealthPatientSpecs();
1418
+ }
1419
+ return cachedSpecs2;
1420
+ };
1421
+ var buildOnSiteDemoHomeHealthPatients = () => getHomeHealthPatientSpecs().map(buildHomeHealthPatientResource);
1422
+ var buildOnSiteDemoHomeHealthCoverages = () => {
1423
+ const out = [];
1424
+ for (const spec of getHomeHealthPatientSpecs()) {
1425
+ out.push(buildPrimaryCoverageResource2(spec));
1426
+ const secondary = buildSecondaryCoverageResource2(spec);
1427
+ if (secondary) {
1428
+ out.push(secondary);
1429
+ }
1430
+ }
1431
+ return out;
1432
+ };
1433
+ var onSiteDemoHomeHealthPatientIds = () => getHomeHealthPatientSpecs().map((s) => s.id);
1434
+ var onSiteDemoScheduledHomeHealthPatientIds = () => getHomeHealthPatientSpecs().filter((s) => s.providerId !== void 0).map((s) => s.id);
1435
+ var onSiteDemoIntakeOnlyHomeHealthPatientIds = () => getHomeHealthPatientSpecs().filter((s) => s.providerId === void 0).map((s) => s.id);
1436
+ var findOnSiteDemoHomeHealthPatientProvider = (patientId) => {
1437
+ const spec = getHomeHealthPatientSpecs().find((s) => s.id === patientId);
1438
+ return spec?.providerId;
1439
+ };
1440
+ var findOnSiteDemoHomeHealthPatientVisitCadenceDays = (patientId) => {
1441
+ const spec = getHomeHealthPatientSpecs().find((s) => s.id === patientId);
1442
+ return spec?.visitCadenceDays;
1443
+ };
1444
+
1445
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-encounters.ts
1446
+ var ENCOUNTER_CLASS_SYSTEM = "http://terminology.hl7.org/CodeSystem/v3-ActCode";
1447
+ var ENCOUNTER_CLASS_FACILITY = {
1448
+ system: ENCOUNTER_CLASS_SYSTEM,
1449
+ code: "IMP",
1450
+ display: "Facility"
1451
+ };
1452
+ var ENCOUNTER_CLASS_HOME_HEALTH = {
1453
+ system: ENCOUNTER_CLASS_SYSTEM,
1454
+ code: "HH",
1455
+ display: "Home Health"
1456
+ };
1457
+ var LOINC_SYSTEM = "http://loinc.org";
1458
+ var SNOMED_SYSTEM = "http://snomed.info/sct";
1459
+ var CPT_SYSTEM = "http://www.ama-assn.org/go/cpt";
1460
+ var WOUND_EXAM_PANEL_CODE = "39135-9";
1461
+ var WOUND_EXAM_PANEL_DISPLAY = "Wound assessment panel";
1462
+ var WOUND_LENGTH_CODE = "39126-8";
1463
+ var WOUND_WIDTH_CODE = "39125-0";
1464
+ var WOUND_DEPTH_CODE = "39127-6";
1465
+ var WOUND_STATUS_CODE = "72311-4";
1466
+ var CONDITION_CLINICAL_STATUS_SYSTEM = "http://terminology.hl7.org/CodeSystem/condition-clinical";
1467
+ var HOME_HEALTH_VISITS_PAST = 4;
1468
+ var WOUND_BEARING_PATIENT_THRESHOLD = 70;
1469
+ var WOUND_PROCEDURE_PATIENT_THRESHOLD = 25;
1470
+ var WOUND_TYPE_OPTIONS = [
1471
+ { code: "421076008", display: "Pressure ulcer" },
1472
+ { code: "402863003", display: "Venous stasis ulcer" },
1473
+ { code: "371087003", display: "Diabetic foot ulcer" },
1474
+ { code: "262528002", display: "Arterial ulcer of lower extremity" },
1475
+ { code: "283682007", display: "Traumatic wound of lower extremity" }
1476
+ ];
1477
+ var WOUND_BODY_SITE_OPTIONS = [
1478
+ { code: "118473006", display: "Left lower limb" },
1479
+ { code: "32153003", display: "Left foot" },
1480
+ { code: "239043009", display: "Left heel" },
1481
+ { code: "61685007", display: "Lower limb" },
1482
+ { code: "118474000", display: "Right lower limb" },
1483
+ { code: "78791008", display: "Right foot" },
1484
+ { code: "239044003", display: "Right heel" }
1485
+ ];
1486
+ var WOUND_DEBRIDEMENT_PRESETS = [
1487
+ { id: "sharp-debridement", display: "Sharp Debridement", cptCode: "97597" },
1488
+ {
1489
+ id: "enzymatic-debridement",
1490
+ display: "Enzymatic Debridement",
1491
+ cptCode: "97602"
1492
+ },
1493
+ { id: "wound-irrigation", display: "Wound Irrigation", cptCode: "97605" },
1494
+ {
1495
+ id: "skin-substitute",
1496
+ display: "Skin Substitute Application",
1497
+ cptCode: "15271"
1498
+ }
1499
+ ];
1500
+ var ON_SITE_SCENARIO5 = "on-site-demo";
1501
+ var padIndex3 = (n) => n.toString().padStart(3, "0");
1502
+ var hashString = (input) => {
1503
+ let h = 0;
1504
+ for (let i = 0; i < input.length; i += 1) {
1505
+ h = h * 31 + input.charCodeAt(i) | 0;
1506
+ }
1507
+ return Math.abs(h);
1508
+ };
1509
+ var isWoundBearingPatient = (patientId) => hashString(`${patientId}:wound-bearing`) % 100 < WOUND_BEARING_PATIENT_THRESHOLD;
1510
+ var getsWoundProcedure = (patientId) => hashString(`${patientId}:procedure`) % 100 < WOUND_PROCEDURE_PATIENT_THRESHOLD;
1511
+ var getWoundTrajectory = (patientId) => hashString(`${patientId}:trajectory`) % 5 < 3 ? "healing" : "worsening";
1512
+ var getWoundType = (patientId) => WOUND_TYPE_OPTIONS[hashString(`${patientId}:type`) % WOUND_TYPE_OPTIONS.length];
1513
+ var getWoundBodySite = (patientId) => WOUND_BODY_SITE_OPTIONS[hashString(`${patientId}:bodysite`) % WOUND_BODY_SITE_OPTIONS.length];
1514
+ var getWoundProcedurePreset = (patientId) => WOUND_DEBRIDEMENT_PRESETS[hashString(`${patientId}:cpt`) % WOUND_DEBRIDEMENT_PRESETS.length];
1515
+ var woundConditionIdForPatient = (patientId) => `${patientId}-wound-001`;
1516
+ var buildIdentifierPair5 = (resourceType, resourceId, roleSuffix) => [
1517
+ demoScenarioIdentifier(ON_SITE_SCENARIO5, roleSuffix),
1518
+ openhiResourceIdentifier({
1519
+ tenantId: ON_SITE_DEMO_TENANT_ID,
1520
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
1521
+ resourceType,
1522
+ id: resourceId
1523
+ })
1524
+ ];
1525
+ var mondayOfIsoWeekUtc2 = (referenceIso) => {
1526
+ const ref = new Date(referenceIso);
1527
+ if (Number.isNaN(ref.getTime())) {
1528
+ throw new Error(
1529
+ `mondayOfIsoWeekUtc: invalid reference date "${referenceIso}".`
1530
+ );
1531
+ }
1532
+ const utcDay = ref.getUTCDay() === 0 ? 7 : ref.getUTCDay();
1533
+ const monday = new Date(
1534
+ Date.UTC(ref.getUTCFullYear(), ref.getUTCMonth(), ref.getUTCDate())
1535
+ );
1536
+ monday.setUTCDate(monday.getUTCDate() - (utcDay - 1));
1537
+ return monday;
1538
+ };
1539
+ var toIsoZ2 = (d) => d.toISOString();
1540
+ var buildFacilityEncounterSpecs = (referenceIso) => {
1541
+ const anchorMonday = mondayOfIsoWeekUtc2(referenceIso);
1542
+ const out = [];
1543
+ for (const patientId of onSiteDemoScheduledFacilityPatientIds()) {
1544
+ const block = findBlockForPatient(patientId);
1545
+ if (!block) {
1546
+ continue;
1547
+ }
1548
+ const total = BLOCK_OCCURRENCE_WEEKS_PAST;
1549
+ for (let i = 0; i < total; i += 1) {
1550
+ const weekOffset = -(BLOCK_OCCURRENCE_WEEKS_PAST - i);
1551
+ const occurrenceDay = new Date(anchorMonday);
1552
+ occurrenceDay.setUTCDate(
1553
+ occurrenceDay.getUTCDate() + weekOffset * 7 + (block.dayOfWeek - 1)
1554
+ );
1555
+ const start = new Date(occurrenceDay);
1556
+ start.setUTCHours(14, 0, 0, 0);
1557
+ const end = new Date(occurrenceDay);
1558
+ end.setUTCHours(18, 0, 0, 0);
1559
+ const sign = "m";
1560
+ const magnitude = Math.abs(weekOffset).toString().padStart(2, "0");
1561
+ const appointmentId = `${block.id}-w${sign}${magnitude}`;
1562
+ out.push({
1563
+ id: `${patientId}-encounter-${padIndex3(i + 1)}`,
1564
+ patientId,
1565
+ sequence: i + 1,
1566
+ totalEncounters: total,
1567
+ periodStart: toIsoZ2(start),
1568
+ periodEnd: toIsoZ2(end),
1569
+ doctorId: block.doctorId,
1570
+ scribeId: block.scribeId,
1571
+ classCoding: ENCOUNTER_CLASS_FACILITY,
1572
+ facilityId: block.facilityId,
1573
+ appointmentId
1574
+ });
1575
+ }
1576
+ }
1577
+ return out;
1578
+ };
1579
+ var patientToBlockCache;
1580
+ var findBlockForPatient = (patientId) => {
1581
+ if (!patientToBlockCache) {
1582
+ const cache = /* @__PURE__ */ new Map();
1583
+ const scheduledIds = new Set(onSiteDemoScheduledFacilityPatientIds());
1584
+ const blockIds = [
1585
+ "on-site-demo-block-001",
1586
+ "on-site-demo-block-002",
1587
+ "on-site-demo-block-003",
1588
+ "on-site-demo-block-004"
1589
+ ];
1590
+ for (const blockId of blockIds) {
1591
+ const block = findOnSiteDemoBlockTemplate(blockId);
1592
+ if (!block) {
1593
+ continue;
1594
+ }
1595
+ for (const pid of facilityPatientsForBlock(blockId)) {
1596
+ if (scheduledIds.has(pid)) {
1597
+ cache.set(pid, block);
1598
+ }
1599
+ }
1600
+ }
1601
+ patientToBlockCache = cache;
1602
+ }
1603
+ return patientToBlockCache.get(patientId);
1604
+ };
1605
+ var buildHomeHealthEncounterSpecs = (referenceIso) => {
1606
+ const reference = new Date(referenceIso);
1607
+ if (Number.isNaN(reference.getTime())) {
1608
+ throw new Error(
1609
+ `buildHomeHealthEncounterSpecs: invalid reference date "${referenceIso}".`
1610
+ );
1611
+ }
1612
+ const out = [];
1613
+ for (const patientId of onSiteDemoScheduledHomeHealthPatientIds()) {
1614
+ const providerId = findOnSiteDemoHomeHealthPatientProvider(patientId);
1615
+ const cadenceDays = findOnSiteDemoHomeHealthPatientVisitCadenceDays(patientId);
1616
+ if (!providerId || typeof cadenceDays !== "number") {
1617
+ continue;
1618
+ }
1619
+ const total = HOME_HEALTH_VISITS_PAST;
1620
+ for (let i = 0; i < total; i += 1) {
1621
+ const visitsBack = total - i;
1622
+ const visitDay = new Date(reference);
1623
+ visitDay.setUTCDate(visitDay.getUTCDate() - visitsBack * cadenceDays);
1624
+ const start = new Date(visitDay);
1625
+ start.setUTCHours(14, 0, 0, 0);
1626
+ const end = new Date(visitDay);
1627
+ end.setUTCHours(15, 0, 0, 0);
1628
+ out.push({
1629
+ id: `${patientId}-encounter-${padIndex3(i + 1)}`,
1630
+ patientId,
1631
+ sequence: i + 1,
1632
+ totalEncounters: total,
1633
+ periodStart: toIsoZ2(start),
1634
+ periodEnd: toIsoZ2(end),
1635
+ doctorId: providerId,
1636
+ scribeId: void 0,
1637
+ classCoding: ENCOUNTER_CLASS_HOME_HEALTH,
1638
+ facilityId: void 0,
1639
+ appointmentId: void 0
1640
+ });
1641
+ }
1642
+ }
1643
+ return out;
1644
+ };
1645
+ var buildEncounterResource = (spec) => {
1646
+ const participant = [
1647
+ {
1648
+ individual: {
1649
+ reference: `Practitioner/${spec.doctorId}`,
1650
+ type: "Practitioner"
1651
+ }
1652
+ }
1653
+ ];
1654
+ if (spec.scribeId) {
1655
+ participant.push({
1656
+ individual: {
1657
+ reference: `Practitioner/${spec.scribeId}`,
1658
+ type: "Practitioner"
1659
+ }
1660
+ });
1661
+ }
1662
+ const encounter = {
1663
+ resourceType: "Encounter",
1664
+ id: spec.id,
1665
+ identifier: buildIdentifierPair5(
1666
+ "Encounter",
1667
+ spec.id,
1668
+ `encounter-${spec.id}`
1669
+ ),
1670
+ status: "finished",
1671
+ class: { ...spec.classCoding },
1672
+ subject: { reference: `Patient/${spec.patientId}`, type: "Patient" },
1673
+ period: { start: spec.periodStart, end: spec.periodEnd },
1674
+ participant
1675
+ };
1676
+ if (spec.facilityId) {
1677
+ encounter.location = [
1678
+ {
1679
+ location: {
1680
+ reference: `Location/${spec.facilityId}`,
1681
+ type: "Location"
1682
+ }
1683
+ }
1684
+ ];
1685
+ }
1686
+ if (spec.appointmentId) {
1687
+ encounter.appointment = [
1688
+ {
1689
+ reference: `Appointment/${spec.appointmentId}`,
1690
+ type: "Appointment"
1691
+ }
1692
+ ];
1693
+ }
1694
+ return encounter;
1695
+ };
1696
+ var buildWoundConditionResource = (patientId, firstEncounterStart) => {
1697
+ const woundType = getWoundType(patientId);
1698
+ const bodySite = getWoundBodySite(patientId);
1699
+ const id = woundConditionIdForPatient(patientId);
1700
+ return {
1701
+ resourceType: "Condition",
1702
+ id,
1703
+ identifier: buildIdentifierPair5("Condition", id, `wound-${patientId}`),
1704
+ clinicalStatus: {
1705
+ coding: [
1706
+ {
1707
+ system: CONDITION_CLINICAL_STATUS_SYSTEM,
1708
+ code: "active",
1709
+ display: "Active"
1710
+ }
1711
+ ]
1712
+ },
1713
+ category: [{ text: "wound" }],
1714
+ code: {
1715
+ text: woundType.display,
1716
+ coding: [
1717
+ {
1718
+ system: SNOMED_SYSTEM,
1719
+ code: woundType.code,
1720
+ display: woundType.display
1721
+ }
1722
+ ]
1723
+ },
1724
+ bodySite: [
1725
+ {
1726
+ coding: [
1727
+ {
1728
+ system: SNOMED_SYSTEM,
1729
+ code: bodySite.code,
1730
+ display: bodySite.display
1731
+ }
1732
+ ],
1733
+ text: bodySite.display
1734
+ }
1735
+ ],
1736
+ subject: { reference: `Patient/${patientId}`, type: "Patient" },
1737
+ onsetDateTime: firstEncounterStart,
1738
+ recordedDate: firstEncounterStart
1739
+ };
1740
+ };
1741
+ var woundSizeAtSequence = (patientId, sequence, totalEncounters) => {
1742
+ const baseLength = 4 + hashString(`${patientId}:length`) % 4;
1743
+ const baseWidth = 3 + hashString(`${patientId}:width`) % 3;
1744
+ const baseDepthTenths = 3 + hashString(`${patientId}:depth`) % 6;
1745
+ const trajectory = getWoundTrajectory(patientId);
1746
+ const denom = Math.max(1, totalEncounters - 1);
1747
+ const progress = (sequence - 1) / denom;
1748
+ const sign = trajectory === "healing" ? -1 : 1;
1749
+ const shrinkOrGrow = trajectory === "healing" ? 0.4 : 0.3;
1750
+ const length = +(baseLength * (1 + sign * shrinkOrGrow * progress)).toFixed(
1751
+ 1
1752
+ );
1753
+ const width = +(baseWidth * (1 + sign * shrinkOrGrow * progress)).toFixed(1);
1754
+ const depth = +(baseDepthTenths / 10 * (1 + sign * shrinkOrGrow * progress)).toFixed(2);
1755
+ const status = trajectory === "healing" && sequence > 1 ? "improving" : trajectory === "worsening" && sequence > 1 ? "declining" : "stagnant";
1756
+ return { length, width, depth, status };
1757
+ };
1758
+ var buildWoundExamObservation = (patientId, encounterId, sequence, totalEncounters, effectiveDateTime) => {
1759
+ const size = woundSizeAtSequence(patientId, sequence, totalEncounters);
1760
+ const woundConditionId = woundConditionIdForPatient(patientId);
1761
+ const id = `${encounterId}-wound-exam`;
1762
+ return {
1763
+ resourceType: "Observation",
1764
+ id,
1765
+ identifier: buildIdentifierPair5(
1766
+ "Observation",
1767
+ id,
1768
+ `wound-exam-${encounterId}`
1769
+ ),
1770
+ status: "final",
1771
+ code: {
1772
+ coding: [
1773
+ {
1774
+ system: LOINC_SYSTEM,
1775
+ code: WOUND_EXAM_PANEL_CODE,
1776
+ display: WOUND_EXAM_PANEL_DISPLAY
1777
+ }
1778
+ ]
1779
+ },
1780
+ subject: { reference: `Patient/${patientId}`, type: "Patient" },
1781
+ encounter: { reference: `Encounter/${encounterId}`, type: "Encounter" },
1782
+ focus: [
1783
+ {
1784
+ reference: `Condition/${woundConditionId}`,
1785
+ type: "Condition"
1786
+ }
1787
+ ],
1788
+ effectiveDateTime,
1789
+ component: [
1790
+ {
1791
+ code: {
1792
+ coding: [
1793
+ {
1794
+ system: LOINC_SYSTEM,
1795
+ code: WOUND_LENGTH_CODE,
1796
+ display: "Length"
1797
+ }
1798
+ ]
1799
+ },
1800
+ valueQuantity: { value: size.length, unit: "cm" }
1801
+ },
1802
+ {
1803
+ code: {
1804
+ coding: [
1805
+ { system: LOINC_SYSTEM, code: WOUND_WIDTH_CODE, display: "Width" }
1806
+ ]
1807
+ },
1808
+ valueQuantity: { value: size.width, unit: "cm" }
1809
+ },
1810
+ {
1811
+ code: {
1812
+ coding: [
1813
+ { system: LOINC_SYSTEM, code: WOUND_DEPTH_CODE, display: "Depth" }
1814
+ ]
1815
+ },
1816
+ valueQuantity: { value: size.depth, unit: "cm" }
1817
+ },
1818
+ {
1819
+ code: {
1820
+ coding: [
1821
+ {
1822
+ system: LOINC_SYSTEM,
1823
+ code: WOUND_STATUS_CODE,
1824
+ display: "Status"
1825
+ }
1826
+ ]
1827
+ },
1828
+ valueCodeableConcept: {
1829
+ coding: [{ code: size.status, display: size.status }]
1830
+ }
1831
+ }
1832
+ ]
1833
+ };
1834
+ };
1835
+ var buildWoundProcedureResource = (patientId, encounterId, performedDateTime) => {
1836
+ const preset = getWoundProcedurePreset(patientId);
1837
+ const woundConditionId = woundConditionIdForPatient(patientId);
1838
+ const id = `${encounterId}-procedure`;
1839
+ return {
1840
+ resourceType: "Procedure",
1841
+ id,
1842
+ identifier: buildIdentifierPair5(
1843
+ "Procedure",
1844
+ id,
1845
+ `procedure-${encounterId}`
1846
+ ),
1847
+ status: "completed",
1848
+ code: {
1849
+ text: preset.display,
1850
+ coding: [
1851
+ {
1852
+ system: CPT_SYSTEM,
1853
+ code: preset.cptCode,
1854
+ display: preset.display
1855
+ }
1856
+ ]
1857
+ },
1858
+ subject: { reference: `Patient/${patientId}`, type: "Patient" },
1859
+ encounter: { reference: `Encounter/${encounterId}`, type: "Encounter" },
1860
+ reasonReference: [
1861
+ {
1862
+ reference: `Condition/${woundConditionId}`,
1863
+ type: "Condition"
1864
+ }
1865
+ ],
1866
+ performedDateTime
1867
+ };
1868
+ };
1869
+ var encounterSpecsCache = /* @__PURE__ */ new Map();
1870
+ var getAllEncounterSpecs = (referenceIso) => {
1871
+ const cached = encounterSpecsCache.get(referenceIso);
1872
+ if (cached) {
1873
+ return cached;
1874
+ }
1875
+ const all = [
1876
+ ...buildFacilityEncounterSpecs(referenceIso),
1877
+ ...buildHomeHealthEncounterSpecs(referenceIso)
1878
+ ];
1879
+ encounterSpecsCache.set(referenceIso, all);
1880
+ return all;
1881
+ };
1882
+ var __resetOnSiteDemoEncounterCachesForTests = () => {
1883
+ encounterSpecsCache.clear();
1884
+ patientToBlockCache = void 0;
1885
+ };
1886
+ var buildOnSiteDemoEncounters = (referenceIso) => getAllEncounterSpecs(referenceIso).map(buildEncounterResource);
1887
+ var buildOnSiteDemoWoundConditions = (referenceIso) => {
1888
+ const specs = getAllEncounterSpecs(referenceIso);
1889
+ const firstByPatient = /* @__PURE__ */ new Map();
1890
+ for (const spec of specs) {
1891
+ if (!isWoundBearingPatient(spec.patientId)) {
1892
+ continue;
1893
+ }
1894
+ const existing = firstByPatient.get(spec.patientId);
1895
+ if (!existing || spec.periodStart < existing) {
1896
+ firstByPatient.set(spec.patientId, spec.periodStart);
1897
+ }
1898
+ }
1899
+ const out = [];
1900
+ for (const [patientId, firstStart] of firstByPatient.entries()) {
1901
+ out.push(buildWoundConditionResource(patientId, firstStart));
1902
+ }
1903
+ return out;
1904
+ };
1905
+ var buildOnSiteDemoWoundObservations = (referenceIso) => {
1906
+ const specs = getAllEncounterSpecs(referenceIso);
1907
+ const out = [];
1908
+ for (const spec of specs) {
1909
+ if (!isWoundBearingPatient(spec.patientId)) {
1910
+ continue;
1911
+ }
1912
+ out.push(
1913
+ buildWoundExamObservation(
1914
+ spec.patientId,
1915
+ spec.id,
1916
+ spec.sequence,
1917
+ spec.totalEncounters,
1918
+ spec.periodStart
1919
+ )
1920
+ );
1921
+ }
1922
+ return out;
1923
+ };
1924
+ var buildOnSiteDemoWoundProcedures = (referenceIso) => {
1925
+ const specs = getAllEncounterSpecs(referenceIso);
1926
+ const lastByPatient = /* @__PURE__ */ new Map();
1927
+ for (const spec of specs) {
1928
+ if (!isWoundBearingPatient(spec.patientId)) {
1929
+ continue;
1930
+ }
1931
+ if (!getsWoundProcedure(spec.patientId)) {
1932
+ continue;
1933
+ }
1934
+ const existing = lastByPatient.get(spec.patientId);
1935
+ if (!existing || spec.sequence > existing.sequence) {
1936
+ lastByPatient.set(spec.patientId, spec);
1937
+ }
1938
+ }
1939
+ const out = [];
1940
+ for (const spec of lastByPatient.values()) {
1941
+ out.push(
1942
+ buildWoundProcedureResource(spec.patientId, spec.id, spec.periodStart)
1943
+ );
1944
+ }
1945
+ return out;
1946
+ };
1947
+ var onSiteDemoEncounterIds = (referenceIso) => getAllEncounterSpecs(referenceIso).map((s) => s.id);
1948
+ var onSiteDemoEncountersForPatient = (patientId, referenceIso) => getAllEncounterSpecs(referenceIso).filter((s) => s.patientId === patientId).map((s) => s.id);
1949
+ var onSiteDemoEncounterMetadata = (referenceIso) => {
1950
+ const specs = getAllEncounterSpecs(referenceIso);
1951
+ const lastEncounterByPatient = /* @__PURE__ */ new Map();
1952
+ for (const spec of specs) {
1953
+ const existing = lastEncounterByPatient.get(spec.patientId);
1954
+ if (!existing) {
1955
+ lastEncounterByPatient.set(spec.patientId, spec.id);
1956
+ continue;
1957
+ }
1958
+ if (spec.sequence > specs.find((s) => s.id === existing).sequence) {
1959
+ lastEncounterByPatient.set(spec.patientId, spec.id);
1960
+ }
1961
+ }
1962
+ const procedurePatients = new Set(onSiteDemoWoundProcedurePatientIds());
1963
+ return specs.map((spec) => ({
1964
+ id: spec.id,
1965
+ patientId: spec.patientId,
1966
+ sequence: spec.sequence,
1967
+ totalEncounters: spec.totalEncounters,
1968
+ periodStart: spec.periodStart,
1969
+ hasWoundProcedure: procedurePatients.has(spec.patientId) && lastEncounterByPatient.get(spec.patientId) === spec.id
1970
+ }));
1971
+ };
1972
+ var onSiteDemoWoundBearingPatientIds = () => {
1973
+ const out = [];
1974
+ for (const id of onSiteDemoScheduledFacilityPatientIds()) {
1975
+ if (isWoundBearingPatient(id)) {
1976
+ out.push(id);
1977
+ }
1978
+ }
1979
+ for (const id of onSiteDemoScheduledHomeHealthPatientIds()) {
1980
+ if (isWoundBearingPatient(id)) {
1981
+ out.push(id);
1982
+ }
1983
+ }
1984
+ return out;
1985
+ };
1986
+ var onSiteDemoWoundProcedurePatientIds = () => onSiteDemoWoundBearingPatientIds().filter((id) => getsWoundProcedure(id));
1987
+
1988
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-claims.ts
1989
+ var CLAIM_WORKFLOW_STATUS_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/claim-workflow-status";
1990
+ var CLAIM_WORKFLOW_STATUS_VALUE_SUB_EXTENSION_URL = "status";
1991
+ var CLAIM_WORKFLOW_STATUS_LAST_TRANSITION_SUB_EXTENSION_URL = "lastTransition";
1992
+ var CLAIM_WORKFLOW_STATUS = {
1993
+ SUBMITTED: "submitted",
1994
+ ACCEPTED: "accepted",
1995
+ REJECTED: "rejected",
1996
+ REWORKED: "reworked",
1997
+ RESUBMITTED: "resubmitted"
1998
+ };
1999
+ var PAYMENT_STATUS = {
2000
+ PARTIAL: "partial",
2001
+ FULL: "full",
2002
+ WRITE_OFF: "write-off"
2003
+ };
2004
+ var PAYMENT_STATUS_SYSTEM = "https://on-site-medical.app/fhir/CodeSystem/payment-status";
2005
+ var EM_VISIT_CODES = [
2006
+ {
2007
+ code: "99213",
2008
+ display: "Office visit, established patient, low",
2009
+ amount: 110
2010
+ },
2011
+ {
2012
+ code: "99214",
2013
+ display: "Office visit, established patient, moderate",
2014
+ amount: 165
2015
+ },
2016
+ {
2017
+ code: "99215",
2018
+ display: "Office visit, established patient, high",
2019
+ amount: 220
2020
+ }
2021
+ ];
2022
+ var PROCEDURE_CPT_AMOUNTS = {
2023
+ "97597": { display: "Sharp Debridement", amount: 145 },
2024
+ "97602": { display: "Enzymatic Debridement", amount: 95 },
2025
+ "97605": { display: "Wound Irrigation (NPWT)", amount: 175 },
2026
+ "15271": { display: "Skin Substitute Application", amount: 410 }
2027
+ };
2028
+ var ON_SITE_SCENARIO6 = "on-site-demo";
2029
+ var hashString2 = (input) => {
2030
+ let h = 0;
2031
+ for (let i = 0; i < input.length; i += 1) {
2032
+ h = h * 31 + input.charCodeAt(i) | 0;
2033
+ }
2034
+ return Math.abs(h);
2035
+ };
2036
+ var UNBILLED_BUCKET_THRESHOLD = 15;
2037
+ var SUBMITTED_BUCKET_THRESHOLD = 35;
2038
+ var ACCEPTED_BUCKET_THRESHOLD = 80;
2039
+ var REJECTED_BUCKET_THRESHOLD = 90;
2040
+ var REWORKED_BUCKET_THRESHOLD = 100;
2041
+ var isEncounterUnbilled = (encounterId) => hashString2(`${encounterId}:billed`) % 100 < UNBILLED_BUCKET_THRESHOLD;
2042
+ var workflowStatusForEncounter = (encounterId) => {
2043
+ const bucket = hashString2(`${encounterId}:status`) % 100;
2044
+ if (bucket < SUBMITTED_BUCKET_THRESHOLD - UNBILLED_BUCKET_THRESHOLD) {
2045
+ return CLAIM_WORKFLOW_STATUS.SUBMITTED;
2046
+ }
2047
+ if (bucket < ACCEPTED_BUCKET_THRESHOLD - UNBILLED_BUCKET_THRESHOLD) {
2048
+ return CLAIM_WORKFLOW_STATUS.ACCEPTED;
2049
+ }
2050
+ if (bucket < REJECTED_BUCKET_THRESHOLD - UNBILLED_BUCKET_THRESHOLD) {
2051
+ return CLAIM_WORKFLOW_STATUS.REJECTED;
2052
+ }
2053
+ if (bucket < REWORKED_BUCKET_THRESHOLD - UNBILLED_BUCKET_THRESHOLD) {
2054
+ return CLAIM_WORKFLOW_STATUS.REWORKED;
2055
+ }
2056
+ return CLAIM_WORKFLOW_STATUS.RESUBMITTED;
2057
+ };
2058
+ var paymentStatusForEncounter = (encounterId) => {
2059
+ const bucket = hashString2(`${encounterId}:payment`) % 10;
2060
+ if (bucket < 4) {
2061
+ return PAYMENT_STATUS.PARTIAL;
2062
+ }
2063
+ if (bucket < 8) {
2064
+ return PAYMENT_STATUS.FULL;
2065
+ }
2066
+ return PAYMENT_STATUS.WRITE_OFF;
2067
+ };
2068
+ var cachedPrimaryCoverageByPatient;
2069
+ var getPrimaryCoverageByPatient = () => {
2070
+ if (!cachedPrimaryCoverageByPatient) {
2071
+ const map = /* @__PURE__ */ new Map();
2072
+ const allCoverages = [
2073
+ ...buildOnSiteDemoFacilityCoverages(),
2074
+ ...buildOnSiteDemoHomeHealthCoverages()
2075
+ ];
2076
+ for (const cov of allCoverages) {
2077
+ if (cov.order !== 1) {
2078
+ continue;
2079
+ }
2080
+ const ref = cov.beneficiary.reference;
2081
+ if (typeof ref !== "string") {
2082
+ continue;
2083
+ }
2084
+ const patientId = ref.replace(/^Patient\//, "");
2085
+ map.set(patientId, cov);
2086
+ }
2087
+ cachedPrimaryCoverageByPatient = map;
2088
+ }
2089
+ return cachedPrimaryCoverageByPatient;
2090
+ };
2091
+ var __resetOnSiteDemoClaimCachesForTests = () => {
2092
+ cachedPrimaryCoverageByPatient = void 0;
2093
+ };
2094
+ var buildIdentifierPair6 = (resourceType, resourceId, roleSuffix) => [
2095
+ demoScenarioIdentifier(ON_SITE_SCENARIO6, roleSuffix),
2096
+ openhiResourceIdentifier({
2097
+ tenantId: ON_SITE_DEMO_TENANT_ID,
2098
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
2099
+ resourceType,
2100
+ id: resourceId
2101
+ })
2102
+ ];
2103
+ var emCodeForEncounter = (encounterId) => EM_VISIT_CODES[hashString2(`${encounterId}:em`) % EM_VISIT_CODES.length];
2104
+ var cptForProcedureEncounter = (encounterId) => {
2105
+ const cptKeys = Object.keys(PROCEDURE_CPT_AMOUNTS);
2106
+ const code = cptKeys[hashString2(`${encounterId}:procedure-cpt`) % cptKeys.length];
2107
+ const entry = PROCEDURE_CPT_AMOUNTS[code];
2108
+ if (!entry) {
2109
+ return EM_VISIT_CODES[0];
2110
+ }
2111
+ return { code, display: entry.display, amount: entry.amount };
2112
+ };
2113
+ var usdMoney = (amount) => ({
2114
+ value: +amount.toFixed(2),
2115
+ currency: "USD"
2116
+ });
2117
+ var buildClaimResource = (meta, status, primaryCoverageId, insurerDisplay) => {
2118
+ const claimId = `${meta.id}-claim`;
2119
+ const line = meta.hasWoundProcedure ? cptForProcedureEncounter(meta.id) : emCodeForEncounter(meta.id);
2120
+ const total = usdMoney(line.amount);
2121
+ const lastTransition = meta.periodStart;
2122
+ return {
2123
+ resourceType: "Claim",
2124
+ id: claimId,
2125
+ identifier: buildIdentifierPair6("Claim", claimId, `claim-${meta.id}`),
2126
+ status: "active",
2127
+ type: {
2128
+ coding: [
2129
+ {
2130
+ system: "http://terminology.hl7.org/CodeSystem/claim-type",
2131
+ code: "professional",
2132
+ display: "Professional"
2133
+ }
2134
+ ],
2135
+ text: "Professional"
2136
+ },
2137
+ use: "claim",
2138
+ patient: { reference: `Patient/${meta.patientId}`, type: "Patient" },
2139
+ created: meta.periodStart,
2140
+ insurer: { display: insurerDisplay },
2141
+ provider: { reference: `Patient/${meta.patientId}`, type: "Patient" },
2142
+ priority: {
2143
+ coding: [
2144
+ {
2145
+ system: "http://terminology.hl7.org/CodeSystem/processpriority",
2146
+ code: "normal",
2147
+ display: "Normal"
2148
+ }
2149
+ ],
2150
+ text: "Normal"
2151
+ },
2152
+ insurance: [
2153
+ {
2154
+ sequence: 1,
2155
+ focal: true,
2156
+ coverage: {
2157
+ reference: `Coverage/${primaryCoverageId}`,
2158
+ type: "Coverage"
2159
+ }
2160
+ }
2161
+ ],
2162
+ item: [
2163
+ {
2164
+ sequence: 1,
2165
+ productOrService: {
2166
+ coding: [
2167
+ { system: CPT_SYSTEM, code: line.code, display: line.display }
2168
+ ],
2169
+ text: line.display
2170
+ },
2171
+ servicedDate: meta.periodStart.slice(0, 10),
2172
+ unitPrice: total,
2173
+ net: total,
2174
+ encounter: [{ reference: `Encounter/${meta.id}`, type: "Encounter" }]
2175
+ }
2176
+ ],
2177
+ total,
2178
+ extension: [
2179
+ {
2180
+ url: CLAIM_WORKFLOW_STATUS_EXTENSION_URL,
2181
+ extension: [
2182
+ {
2183
+ url: CLAIM_WORKFLOW_STATUS_VALUE_SUB_EXTENSION_URL,
2184
+ valueCode: status
2185
+ },
2186
+ {
2187
+ url: CLAIM_WORKFLOW_STATUS_LAST_TRANSITION_SUB_EXTENSION_URL,
2188
+ valueDateTime: lastTransition
2189
+ }
2190
+ ]
2191
+ }
2192
+ ]
2193
+ };
2194
+ };
2195
+ var buildPaymentNoticeResource = (meta, status, claimId, totalCharged, insurerDisplay) => {
2196
+ const paymentId = `${meta.id}-payment`;
2197
+ const charged = totalCharged.value ?? 0;
2198
+ let paid;
2199
+ if (status === PAYMENT_STATUS.FULL) {
2200
+ paid = charged;
2201
+ } else if (status === PAYMENT_STATUS.PARTIAL) {
2202
+ const fraction = 0.4 + hashString2(`${meta.id}:partial`) % 31 / 100;
2203
+ paid = +(charged * fraction).toFixed(2);
2204
+ } else {
2205
+ paid = 0;
2206
+ }
2207
+ return {
2208
+ resourceType: "PaymentNotice",
2209
+ id: paymentId,
2210
+ identifier: buildIdentifierPair6(
2211
+ "PaymentNotice",
2212
+ paymentId,
2213
+ `payment-${meta.id}`
2214
+ ),
2215
+ status: "active",
2216
+ request: { reference: `Claim/${claimId}`, type: "Claim" },
2217
+ created: meta.periodStart,
2218
+ // FHIR R4 PaymentNotice.payment is Reference(PaymentReconciliation).
2219
+ // Demo seeding does not produce PaymentReconciliation resources;
2220
+ // we point at the Claim so the reference is at least resolvable on
2221
+ // read paths. The `request` field above is the FHIR-correct link
2222
+ // from PaymentNotice back to the originating Claim.
2223
+ payment: { reference: `Claim/${claimId}`, type: "Claim" },
2224
+ paymentDate: meta.periodStart.slice(0, 10),
2225
+ recipient: { display: insurerDisplay },
2226
+ amount: usdMoney(paid),
2227
+ paymentStatus: {
2228
+ coding: [
2229
+ {
2230
+ system: PAYMENT_STATUS_SYSTEM,
2231
+ code: status,
2232
+ display: status
2233
+ }
2234
+ ],
2235
+ text: status
2236
+ }
2237
+ };
2238
+ };
2239
+ var insurerDisplayForCoverage = (cov) => {
2240
+ const payor = cov.payor?.[0];
2241
+ if (payor && typeof payor.display === "string" && payor.display.length > 0) {
2242
+ return payor.display;
2243
+ }
2244
+ if (typeof cov.type?.text === "string" && cov.type.text.length > 0) {
2245
+ return cov.type.text;
2246
+ }
2247
+ return "Unknown Insurer";
2248
+ };
2249
+ var buildOnSiteDemoClaims = (referenceIso) => {
2250
+ const primaryByPatient = getPrimaryCoverageByPatient();
2251
+ const out = [];
2252
+ for (const meta of onSiteDemoEncounterMetadata(referenceIso)) {
2253
+ if (isEncounterUnbilled(meta.id)) {
2254
+ continue;
2255
+ }
2256
+ const coverage = primaryByPatient.get(meta.patientId);
2257
+ if (!coverage || !coverage.id) {
2258
+ continue;
2259
+ }
2260
+ const status = workflowStatusForEncounter(meta.id);
2261
+ out.push(
2262
+ buildClaimResource(
2263
+ meta,
2264
+ status,
2265
+ coverage.id,
2266
+ insurerDisplayForCoverage(coverage)
2267
+ )
2268
+ );
2269
+ }
2270
+ return out;
2271
+ };
2272
+ var buildOnSiteDemoPaymentNotices = (referenceIso) => {
2273
+ const primaryByPatient = getPrimaryCoverageByPatient();
2274
+ const out = [];
2275
+ for (const meta of onSiteDemoEncounterMetadata(referenceIso)) {
2276
+ if (isEncounterUnbilled(meta.id)) {
2277
+ continue;
2278
+ }
2279
+ const status = workflowStatusForEncounter(meta.id);
2280
+ if (status !== CLAIM_WORKFLOW_STATUS.ACCEPTED) {
2281
+ continue;
2282
+ }
2283
+ const coverage = primaryByPatient.get(meta.patientId);
2284
+ if (!coverage || !coverage.id) {
2285
+ continue;
2286
+ }
2287
+ const paymentStatus = paymentStatusForEncounter(meta.id);
2288
+ const line = meta.hasWoundProcedure ? cptForProcedureEncounter(meta.id) : emCodeForEncounter(meta.id);
2289
+ const total = usdMoney(line.amount);
2290
+ const claimId = `${meta.id}-claim`;
2291
+ out.push(
2292
+ buildPaymentNoticeResource(
2293
+ meta,
2294
+ paymentStatus,
2295
+ claimId,
2296
+ total,
2297
+ insurerDisplayForCoverage(coverage)
2298
+ )
2299
+ );
2300
+ }
2301
+ return out;
2302
+ };
2303
+ var onSiteDemoClaimIds = (referenceIso) => buildOnSiteDemoClaims(referenceIso).map((c) => c.id ?? "");
2304
+ var onSiteDemoPaymentNoticeIds = (referenceIso) => buildOnSiteDemoPaymentNotices(referenceIso).map((p) => p.id ?? "");
2305
+ var onSiteDemoUnbilledEncounterIds = (referenceIso) => onSiteDemoEncounterMetadata(referenceIso).filter((m) => isEncounterUnbilled(m.id)).map((m) => m.id);
2306
+ var onSiteDemoBilledEncounterIds = (referenceIso) => onSiteDemoEncounterMetadata(referenceIso).filter((m) => !isEncounterUnbilled(m.id)).map((m) => m.id);
2307
+
2308
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-directory.ts
2309
+ var ON_SITE_SCENARIO7 = "on-site-demo";
2310
+ var FHIR_ORGANIZATION_TYPE_SYSTEM = "http://terminology.hl7.org/CodeSystem/organization-type";
2311
+ var ON_SITE_DIRECTORY_CATEGORY_SYSTEM = "https://on-site-medical.app/fhir/CodeSystem/directory-category";
2312
+ var DME_SUPPLIER_CATEGORY_CODE = "dme-supplier";
2313
+ var INSURANCE_PAYOR_CATEGORY_CODE = "insurance-payor";
2314
+ var INSURANCE_PAYOR_PLAN_TYPE_SYSTEM = "https://on-site-medical.app/fhir/CodeSystem/payor-plan-type";
2315
+ var PAYOR_PLAN_TYPE_COMMERCIAL = "commercial";
2316
+ var PAYOR_PLAN_TYPE_MEDICARE = "medicare";
2317
+ var PAYOR_PLAN_TYPE_MEDICARE_ADVANTAGE = "medicare-advantage";
2318
+ var PRACTITIONER_CREDENTIALING_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/practitioner-credentialing";
2319
+ var PRACTITIONER_CREDENTIALING_STATE_SUB_EXTENSION_URL = "state";
2320
+ var PRACTITIONER_CREDENTIALING_STATUS_SUB_EXTENSION_URL = "status";
2321
+ var CREDENTIALING_STATUS = {
2322
+ ACTIVE: "active",
2323
+ SUSPENDED: "suspended",
2324
+ EXPIRED: "expired"
2325
+ };
2326
+ var STATE_MEDICAL_LICENSE_SYSTEM = "https://on-site-medical.app/fhir/sid/state-medical-license";
2327
+ var DME_SUPPLIER_SPECS = [
2328
+ {
2329
+ id: "on-site-demo-dme-supplier-001",
2330
+ name: "Apria Healthcare",
2331
+ phone: "+18004554111",
2332
+ email: "orders@apria.on-site-demo.example.com",
2333
+ addressLine: "12230 El Camino Real",
2334
+ addressCity: "San Diego",
2335
+ addressState: "CA",
2336
+ addressPostalCode: "92130",
2337
+ contactName: "Marcus Whitfield",
2338
+ contactPhone: "+18004554112",
2339
+ contactEmail: "m.whitfield@apria.on-site-demo.example.com"
2340
+ },
2341
+ {
2342
+ id: "on-site-demo-dme-supplier-002",
2343
+ name: "Lincare Holdings",
2344
+ phone: "+17275301700",
2345
+ email: "intake@lincare.on-site-demo.example.com",
2346
+ addressLine: "19387 US Highway 19 North",
2347
+ addressCity: "Clearwater",
2348
+ addressState: "FL",
2349
+ addressPostalCode: "33764",
2350
+ contactName: "Rachel Donovan",
2351
+ contactPhone: "+17275301701",
2352
+ contactEmail: "r.donovan@lincare.on-site-demo.example.com"
2353
+ },
2354
+ {
2355
+ id: "on-site-demo-dme-supplier-003",
2356
+ name: "AdaptHealth",
2357
+ phone: "+16104840700",
2358
+ email: "referrals@adapthealth.on-site-demo.example.com",
2359
+ addressLine: "220 West Germantown Pike",
2360
+ addressCity: "Plymouth Meeting",
2361
+ addressState: "PA",
2362
+ addressPostalCode: "19462",
2363
+ contactName: "Brian Calloway",
2364
+ contactPhone: "+16104840701",
2365
+ contactEmail: "b.calloway@adapthealth.on-site-demo.example.com"
2366
+ },
2367
+ {
2368
+ id: "on-site-demo-dme-supplier-004",
2369
+ name: "Rotech Healthcare",
2370
+ phone: "+14072629230",
2371
+ email: "support@rotech.on-site-demo.example.com",
2372
+ addressLine: "3600 Vineland Road",
2373
+ addressCity: "Orlando",
2374
+ addressState: "FL",
2375
+ addressPostalCode: "32811",
2376
+ contactName: "Elena Marsh",
2377
+ contactPhone: "+14072629231",
2378
+ contactEmail: "e.marsh@rotech.on-site-demo.example.com"
2379
+ },
2380
+ {
2381
+ id: "on-site-demo-dme-supplier-005",
2382
+ name: "Byram Healthcare",
2383
+ phone: "+18004220606",
2384
+ email: "orders@byram.on-site-demo.example.com",
2385
+ addressLine: "120 Bloomingdale Road",
2386
+ addressCity: "White Plains",
2387
+ addressState: "NY",
2388
+ addressPostalCode: "10605",
2389
+ contactName: "Thomas Pritchard",
2390
+ contactPhone: "+18004220607",
2391
+ contactEmail: "t.pritchard@byram.on-site-demo.example.com"
2392
+ },
2393
+ {
2394
+ id: "on-site-demo-dme-supplier-006",
2395
+ name: "Medline Industries",
2396
+ phone: "+18476434400",
2397
+ email: "wound-care@medline.on-site-demo.example.com",
2398
+ addressLine: "Three Lakes Drive",
2399
+ addressCity: "Northfield",
2400
+ addressState: "IL",
2401
+ addressPostalCode: "60093",
2402
+ contactName: "Jacqueline Vance",
2403
+ contactPhone: "+18476434401",
2404
+ contactEmail: "j.vance@medline.on-site-demo.example.com"
2405
+ },
2406
+ {
2407
+ id: "on-site-demo-dme-supplier-007",
2408
+ name: "McKesson Medical-Surgical",
2409
+ phone: "+18044703300",
2410
+ email: "service@mckesson-ms.on-site-demo.example.com",
2411
+ addressLine: "9954 Mayland Drive",
2412
+ addressCity: "Richmond",
2413
+ addressState: "VA",
2414
+ addressPostalCode: "23233",
2415
+ contactName: "Andre Holloway",
2416
+ contactPhone: "+18044703301",
2417
+ contactEmail: "a.holloway@mckesson-ms.on-site-demo.example.com"
2418
+ },
2419
+ {
2420
+ id: "on-site-demo-dme-supplier-008",
2421
+ name: "Cardinal Health at-Home Solutions",
2422
+ phone: "+16147573030",
2423
+ email: "home@cardinal.on-site-demo.example.com",
2424
+ addressLine: "7000 Cardinal Place",
2425
+ addressCity: "Dublin",
2426
+ addressState: "OH",
2427
+ addressPostalCode: "43017",
2428
+ contactName: "Naomi Sutherland",
2429
+ contactPhone: "+16147573031",
2430
+ contactEmail: "n.sutherland@cardinal.on-site-demo.example.com"
2431
+ },
2432
+ {
2433
+ id: "on-site-demo-dme-supplier-009",
2434
+ name: "Edgepark Medical Supplies",
2435
+ phone: "+18003217828",
2436
+ email: "orders@edgepark.on-site-demo.example.com",
2437
+ addressLine: "1810 Summit Commerce Park",
2438
+ addressCity: "Twinsburg",
2439
+ addressState: "OH",
2440
+ addressPostalCode: "44087",
2441
+ contactName: "Derek Ashford",
2442
+ contactPhone: "+18003217829",
2443
+ contactEmail: "d.ashford@edgepark.on-site-demo.example.com"
2444
+ },
2445
+ {
2446
+ id: "on-site-demo-dme-supplier-010",
2447
+ name: "Numotion",
2448
+ phone: "+18006240498",
2449
+ email: "intake@numotion.on-site-demo.example.com",
2450
+ addressLine: "5117 W Terrace Drive",
2451
+ addressCity: "Brentwood",
2452
+ addressState: "TN",
2453
+ addressPostalCode: "37027",
2454
+ contactName: "Sienna Lockhart",
2455
+ contactPhone: "+18006240499",
2456
+ contactEmail: "s.lockhart@numotion.on-site-demo.example.com"
2457
+ },
2458
+ {
2459
+ id: "on-site-demo-dme-supplier-011",
2460
+ name: "Pride Mobility",
2461
+ phone: "+18008003636",
2462
+ email: "service@pridemobility.on-site-demo.example.com",
2463
+ addressLine: "182 Susquehanna Avenue",
2464
+ addressCity: "Exeter",
2465
+ addressState: "PA",
2466
+ addressPostalCode: "18643",
2467
+ contactName: "Vincent Marlowe",
2468
+ contactPhone: "+18008003637",
2469
+ contactEmail: "v.marlowe@pridemobility.on-site-demo.example.com"
2470
+ },
2471
+ {
2472
+ id: "on-site-demo-dme-supplier-012",
2473
+ name: "Hollister Wound Care",
2474
+ phone: "+18003234060",
2475
+ email: "wound@hollister.on-site-demo.example.com",
2476
+ addressLine: "2000 Hollister Drive",
2477
+ addressCity: "Libertyville",
2478
+ addressState: "IL",
2479
+ addressPostalCode: "60048",
2480
+ contactName: "Priscilla Hawthorne",
2481
+ contactPhone: "+18003234061",
2482
+ contactEmail: "p.hawthorne@hollister.on-site-demo.example.com"
2483
+ },
2484
+ {
2485
+ id: "on-site-demo-dme-supplier-013",
2486
+ name: "Smith & Nephew Advanced Wound Management",
2487
+ phone: "+18008765556",
2488
+ email: "wound@smith-nephew.on-site-demo.example.com",
2489
+ addressLine: "5600 Clearfork Main Street",
2490
+ addressCity: "Fort Worth",
2491
+ addressState: "TX",
2492
+ addressPostalCode: "76109",
2493
+ contactName: "Gregory Eastland",
2494
+ contactPhone: "+18008765557",
2495
+ contactEmail: "g.eastland@smith-nephew.on-site-demo.example.com"
2496
+ }
2497
+ ];
2498
+ var INSURANCE_PAYOR_SPECS = [
2499
+ {
2500
+ id: "on-site-demo-insurance-payor-001",
2501
+ name: "Aetna",
2502
+ planType: PAYOR_PLAN_TYPE_COMMERCIAL,
2503
+ phone: "+18008721414",
2504
+ email: "provider-services@aetna.on-site-demo.example.com",
2505
+ addressLine: "151 Farmington Avenue",
2506
+ addressCity: "Hartford",
2507
+ addressState: "CT",
2508
+ addressPostalCode: "06156",
2509
+ contactName: "Stephanie Wakefield",
2510
+ contactPhone: "+18008721415",
2511
+ contactEmail: "s.wakefield@aetna.on-site-demo.example.com"
2512
+ },
2513
+ {
2514
+ id: "on-site-demo-insurance-payor-002",
2515
+ name: "Cigna Healthcare",
2516
+ planType: PAYOR_PLAN_TYPE_COMMERCIAL,
2517
+ phone: "+18002442488",
2518
+ email: "provider-services@cigna.on-site-demo.example.com",
2519
+ addressLine: "900 Cottage Grove Road",
2520
+ addressCity: "Bloomfield",
2521
+ addressState: "CT",
2522
+ addressPostalCode: "06002",
2523
+ contactName: "Howard Greenberg",
2524
+ contactPhone: "+18002442489",
2525
+ contactEmail: "h.greenberg@cigna.on-site-demo.example.com"
2526
+ },
2527
+ {
2528
+ id: "on-site-demo-insurance-payor-003",
2529
+ name: "UnitedHealthcare",
2530
+ planType: PAYOR_PLAN_TYPE_COMMERCIAL,
2531
+ phone: "+18778425539",
2532
+ email: "provider-services@uhc.on-site-demo.example.com",
2533
+ addressLine: "9900 Bren Road East",
2534
+ addressCity: "Minnetonka",
2535
+ addressState: "MN",
2536
+ addressPostalCode: "55343",
2537
+ contactName: "Cassandra Bellamy",
2538
+ contactPhone: "+18778425540",
2539
+ contactEmail: "c.bellamy@uhc.on-site-demo.example.com"
2540
+ },
2541
+ {
2542
+ id: "on-site-demo-insurance-payor-004",
2543
+ name: "Anthem Blue Cross Blue Shield",
2544
+ planType: PAYOR_PLAN_TYPE_COMMERCIAL,
2545
+ phone: "+18004504000",
2546
+ email: "provider-services@anthem.on-site-demo.example.com",
2547
+ addressLine: "220 Virginia Avenue",
2548
+ addressCity: "Indianapolis",
2549
+ addressState: "IN",
2550
+ addressPostalCode: "46204",
2551
+ contactName: "Maurice Pendleton",
2552
+ contactPhone: "+18004504001",
2553
+ contactEmail: "m.pendleton@anthem.on-site-demo.example.com"
2554
+ },
2555
+ {
2556
+ id: "on-site-demo-insurance-payor-005",
2557
+ name: "CMS \u2014 Medicare",
2558
+ planType: PAYOR_PLAN_TYPE_MEDICARE,
2559
+ phone: "+18006334227",
2560
+ email: "provider-services@cms.on-site-demo.example.com",
2561
+ addressLine: "7500 Security Boulevard",
2562
+ addressCity: "Baltimore",
2563
+ addressState: "MD",
2564
+ addressPostalCode: "21244",
2565
+ contactName: "Theresa Kavanagh",
2566
+ contactPhone: "+18006334228",
2567
+ contactEmail: "t.kavanagh@cms.on-site-demo.example.com"
2568
+ },
2569
+ {
2570
+ id: "on-site-demo-insurance-payor-006",
2571
+ name: "Humana Medicare Advantage",
2572
+ planType: PAYOR_PLAN_TYPE_MEDICARE_ADVANTAGE,
2573
+ phone: "+18004574708",
2574
+ email: "provider-services@humana.on-site-demo.example.com",
2575
+ addressLine: "500 West Main Street",
2576
+ addressCity: "Louisville",
2577
+ addressState: "KY",
2578
+ addressPostalCode: "40202",
2579
+ contactName: "Lawrence Whitmore",
2580
+ contactPhone: "+18004574709",
2581
+ contactEmail: "l.whitmore@humana.on-site-demo.example.com"
2582
+ },
2583
+ {
2584
+ id: "on-site-demo-insurance-payor-007",
2585
+ name: "Wellcare by Centene",
2586
+ planType: PAYOR_PLAN_TYPE_MEDICARE_ADVANTAGE,
2587
+ phone: "+18886353224",
2588
+ email: "provider-services@wellcare.on-site-demo.example.com",
2589
+ addressLine: "8735 Henderson Road",
2590
+ addressCity: "Tampa",
2591
+ addressState: "FL",
2592
+ addressPostalCode: "33634",
2593
+ contactName: "Yolanda Caldwell",
2594
+ contactPhone: "+18886353225",
2595
+ contactEmail: "y.caldwell@wellcare.on-site-demo.example.com"
2596
+ },
2597
+ {
2598
+ id: "on-site-demo-insurance-payor-008",
2599
+ name: "Kaiser Permanente",
2600
+ planType: PAYOR_PLAN_TYPE_COMMERCIAL,
2601
+ phone: "+18004646000",
2602
+ email: "provider-services@kaiser.on-site-demo.example.com",
2603
+ addressLine: "1 Kaiser Plaza",
2604
+ addressCity: "Oakland",
2605
+ addressState: "CA",
2606
+ addressPostalCode: "94612",
2607
+ contactName: "Bradford Tennyson",
2608
+ contactPhone: "+18004646001",
2609
+ contactEmail: "b.tennyson@kaiser.on-site-demo.example.com"
2610
+ }
2611
+ ];
2612
+ var buildOrganizationIdentifierPair = (organizationId, roleSuffix) => [
2613
+ demoScenarioIdentifier(ON_SITE_SCENARIO7, roleSuffix),
2614
+ openhiResourceIdentifier({
2615
+ tenantId: ON_SITE_DEMO_TENANT_ID,
2616
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
2617
+ resourceType: "Organization",
2618
+ id: organizationId
2619
+ })
2620
+ ];
2621
+ var buildDmeSupplierResource = (spec) => ({
2622
+ resourceType: "Organization",
2623
+ id: spec.id,
2624
+ active: true,
2625
+ identifier: buildOrganizationIdentifierPair(
2626
+ spec.id,
2627
+ `dme-supplier-${spec.id}`
2628
+ ),
2629
+ name: spec.name,
2630
+ type: [
2631
+ {
2632
+ coding: [
2633
+ {
2634
+ system: FHIR_ORGANIZATION_TYPE_SYSTEM,
2635
+ code: "prov",
2636
+ display: "Healthcare Provider"
2637
+ },
2638
+ {
2639
+ system: ON_SITE_DIRECTORY_CATEGORY_SYSTEM,
2640
+ code: DME_SUPPLIER_CATEGORY_CODE,
2641
+ display: "DME Supplier"
2642
+ }
2643
+ ],
2644
+ text: "DME Supplier"
2645
+ }
2646
+ ],
2647
+ telecom: [
2648
+ { system: "phone", value: spec.phone, use: "work" },
2649
+ { system: "email", value: spec.email, use: "work" }
2650
+ ],
2651
+ address: [
2652
+ {
2653
+ use: "work",
2654
+ line: [spec.addressLine],
2655
+ city: spec.addressCity,
2656
+ state: spec.addressState,
2657
+ postalCode: spec.addressPostalCode,
2658
+ country: "US"
2659
+ }
2660
+ ],
2661
+ contact: [
2662
+ {
2663
+ purpose: { text: "Primary Contact" },
2664
+ name: {
2665
+ text: spec.contactName,
2666
+ given: [spec.contactName.split(" ")[0] ?? spec.contactName],
2667
+ family: spec.contactName.split(" ").slice(-1)[0] ?? spec.contactName
2668
+ },
2669
+ telecom: [
2670
+ { system: "phone", value: spec.contactPhone, use: "work" },
2671
+ { system: "email", value: spec.contactEmail, use: "work" }
2672
+ ]
2673
+ }
2674
+ ]
2675
+ });
2676
+ var planTypeDisplayLabel = (planType) => {
2677
+ if (planType === PAYOR_PLAN_TYPE_COMMERCIAL) {
2678
+ return "Commercial";
2679
+ }
2680
+ if (planType === PAYOR_PLAN_TYPE_MEDICARE) {
2681
+ return "Medicare";
2682
+ }
2683
+ return "Medicare Advantage";
2684
+ };
2685
+ var buildInsurancePayorResource = (spec) => ({
2686
+ resourceType: "Organization",
2687
+ id: spec.id,
2688
+ active: true,
2689
+ identifier: buildOrganizationIdentifierPair(
2690
+ spec.id,
2691
+ `insurance-payor-${spec.id}`
2692
+ ),
2693
+ name: spec.name,
2694
+ type: [
2695
+ {
2696
+ coding: [
2697
+ {
2698
+ system: FHIR_ORGANIZATION_TYPE_SYSTEM,
2699
+ code: "pay",
2700
+ display: "Payer"
2701
+ },
2702
+ {
2703
+ system: ON_SITE_DIRECTORY_CATEGORY_SYSTEM,
2704
+ code: INSURANCE_PAYOR_CATEGORY_CODE,
2705
+ display: "Insurance Payor"
2706
+ },
2707
+ {
2708
+ system: INSURANCE_PAYOR_PLAN_TYPE_SYSTEM,
2709
+ code: spec.planType,
2710
+ display: planTypeDisplayLabel(spec.planType)
2711
+ }
2712
+ ],
2713
+ text: planTypeDisplayLabel(spec.planType)
2714
+ }
2715
+ ],
2716
+ telecom: [
2717
+ { system: "phone", value: spec.phone, use: "work" },
2718
+ { system: "email", value: spec.email, use: "work" }
2719
+ ],
2720
+ address: [
2721
+ {
2722
+ use: "work",
2723
+ line: [spec.addressLine],
2724
+ city: spec.addressCity,
2725
+ state: spec.addressState,
2726
+ postalCode: spec.addressPostalCode,
2727
+ country: "US"
2728
+ }
2729
+ ],
2730
+ contact: [
2731
+ {
2732
+ purpose: { text: "Provider Services" },
2733
+ name: {
2734
+ text: spec.contactName,
2735
+ given: [spec.contactName.split(" ")[0] ?? spec.contactName],
2736
+ family: spec.contactName.split(" ").slice(-1)[0] ?? spec.contactName
2737
+ },
2738
+ telecom: [
2739
+ { system: "phone", value: spec.contactPhone, use: "work" },
2740
+ { system: "email", value: spec.contactEmail, use: "work" }
2741
+ ]
2742
+ }
2743
+ ]
2744
+ });
2745
+ var ON_SITE_DEMO_DME_SUPPLIERS = DME_SUPPLIER_SPECS.map(buildDmeSupplierResource);
2746
+ var ON_SITE_DEMO_INSURANCE_PAYORS = INSURANCE_PAYOR_SPECS.map(buildInsurancePayorResource);
2747
+ var onSiteDemoDmeSupplierIds = () => DME_SUPPLIER_SPECS.map((s) => s.id);
2748
+ var onSiteDemoInsurancePayorIds = () => INSURANCE_PAYOR_SPECS.map((s) => s.id);
2749
+ var ON_SITE_DEMO_DIRECTORY_ORGANIZATIONS = [...ON_SITE_DEMO_DME_SUPPLIERS, ...ON_SITE_DEMO_INSURANCE_PAYORS];
2750
+ var PRACTITIONER_CREDENTIALING_BY_DOCTOR = {
2751
+ "on-site-demo-doctor-001": [
2752
+ {
2753
+ state: "GA",
2754
+ stateBoardDisplay: "Georgia Composite Medical Board",
2755
+ licenseNumber: "GA-MD-082431",
2756
+ issued: "2014-06-12",
2757
+ expires: "2027-06-30",
2758
+ status: CREDENTIALING_STATUS.ACTIVE
2759
+ },
2760
+ {
2761
+ state: "AL",
2762
+ stateBoardDisplay: "Alabama Board of Medical Examiners",
2763
+ licenseNumber: "AL-MD-MD031298",
2764
+ issued: "2016-04-02",
2765
+ expires: "2026-12-31",
2766
+ status: CREDENTIALING_STATUS.ACTIVE
2767
+ },
2768
+ {
2769
+ state: "TN",
2770
+ stateBoardDisplay: "Tennessee Board of Medical Examiners",
2771
+ licenseNumber: "TN-MD-MD51227",
2772
+ issued: "2017-09-21",
2773
+ expires: "2026-09-30",
2774
+ status: CREDENTIALING_STATUS.ACTIVE
2775
+ }
2776
+ ],
2777
+ "on-site-demo-doctor-002": [
2778
+ {
2779
+ state: "GA",
2780
+ stateBoardDisplay: "Georgia Composite Medical Board",
2781
+ licenseNumber: "GA-MD-076120",
2782
+ issued: "2012-08-04",
2783
+ expires: "2027-08-31",
2784
+ status: CREDENTIALING_STATUS.ACTIVE
2785
+ },
2786
+ {
2787
+ state: "FL",
2788
+ stateBoardDisplay: "Florida Board of Medicine",
2789
+ licenseNumber: "FL-MD-ME128443",
2790
+ issued: "2018-02-18",
2791
+ expires: "2026-02-28",
2792
+ status: CREDENTIALING_STATUS.ACTIVE
2793
+ }
2794
+ ],
2795
+ "on-site-demo-doctor-003": [
2796
+ {
2797
+ state: "GA",
2798
+ stateBoardDisplay: "Georgia Composite Medical Board",
2799
+ licenseNumber: "GA-MD-091047",
2800
+ issued: "2015-11-22",
2801
+ expires: "2027-11-30",
2802
+ status: CREDENTIALING_STATUS.ACTIVE
2803
+ },
2804
+ {
2805
+ state: "SC",
2806
+ stateBoardDisplay: "South Carolina Board of Medical Examiners",
2807
+ licenseNumber: "SC-MD-32788",
2808
+ issued: "2019-05-10",
2809
+ expires: "2027-05-31",
2810
+ status: CREDENTIALING_STATUS.ACTIVE
2811
+ }
2812
+ ],
2813
+ "on-site-demo-doctor-004": [
2814
+ {
2815
+ state: "GA",
2816
+ stateBoardDisplay: "Georgia Composite Medical Board",
2817
+ licenseNumber: "GA-MD-064118",
2818
+ issued: "2009-07-14",
2819
+ expires: "2027-07-31",
2820
+ status: CREDENTIALING_STATUS.ACTIVE
2821
+ },
2822
+ {
2823
+ state: "NC",
2824
+ stateBoardDisplay: "North Carolina Medical Board",
2825
+ licenseNumber: "NC-MD-2014-00892",
2826
+ issued: "2014-03-08",
2827
+ expires: "2027-03-31",
2828
+ status: CREDENTIALING_STATUS.ACTIVE
2829
+ }
2830
+ ],
2831
+ "on-site-demo-doctor-005": [
2832
+ {
2833
+ state: "GA",
2834
+ stateBoardDisplay: "Georgia Composite Medical Board",
2835
+ licenseNumber: "GA-MD-098712",
2836
+ issued: "2017-01-19",
2837
+ expires: "2027-01-31",
2838
+ status: CREDENTIALING_STATUS.ACTIVE
2839
+ },
2840
+ {
2841
+ state: "AL",
2842
+ stateBoardDisplay: "Alabama Board of Medical Examiners",
2843
+ licenseNumber: "AL-MD-MD040115",
2844
+ issued: "2020-06-30",
2845
+ expires: "2026-06-30",
2846
+ status: CREDENTIALING_STATUS.ACTIVE
2847
+ }
2848
+ ],
2849
+ "on-site-demo-doctor-006": [
2850
+ {
2851
+ state: "GA",
2852
+ stateBoardDisplay: "Georgia Composite Medical Board",
2853
+ licenseNumber: "GA-MD-052901",
2854
+ issued: "2004-09-02",
2855
+ expires: "2027-09-30",
2856
+ status: CREDENTIALING_STATUS.ACTIVE
2857
+ },
2858
+ {
2859
+ state: "TN",
2860
+ stateBoardDisplay: "Tennessee Board of Medical Examiners",
2861
+ licenseNumber: "TN-MD-MD43091",
2862
+ issued: "2011-05-15",
2863
+ expires: "2027-05-31",
2864
+ status: CREDENTIALING_STATUS.ACTIVE
2865
+ }
2866
+ ],
2867
+ "on-site-demo-doctor-007": [
2868
+ {
2869
+ state: "GA",
2870
+ stateBoardDisplay: "Georgia Composite Medical Board",
2871
+ licenseNumber: "GA-MD-073445",
2872
+ issued: "2013-04-27",
2873
+ expires: "2027-04-30",
2874
+ status: CREDENTIALING_STATUS.ACTIVE
2875
+ },
2876
+ {
2877
+ state: "FL",
2878
+ stateBoardDisplay: "Florida Board of Medicine",
2879
+ licenseNumber: "FL-MD-ME119001",
2880
+ issued: "2015-12-12",
2881
+ expires: "2026-12-31",
2882
+ status: CREDENTIALING_STATUS.SUSPENDED
2883
+ }
2884
+ ],
2885
+ "on-site-demo-doctor-008": [
2886
+ {
2887
+ state: "GA",
2888
+ stateBoardDisplay: "Georgia Composite Medical Board",
2889
+ licenseNumber: "GA-MD-101203",
2890
+ issued: "2018-08-09",
2891
+ expires: "2027-08-31",
2892
+ status: CREDENTIALING_STATUS.ACTIVE
2893
+ },
2894
+ {
2895
+ state: "SC",
2896
+ stateBoardDisplay: "South Carolina Board of Medical Examiners",
2897
+ licenseNumber: "SC-MD-35112",
2898
+ issued: "2021-02-01",
2899
+ expires: "2027-02-28",
2900
+ status: CREDENTIALING_STATUS.ACTIVE
2901
+ }
2902
+ ],
2903
+ "on-site-demo-doctor-009": [
2904
+ {
2905
+ state: "GA",
2906
+ stateBoardDisplay: "Georgia Composite Medical Board",
2907
+ licenseNumber: "GA-MD-061887",
2908
+ issued: "2010-11-30",
2909
+ expires: "2026-11-30",
2910
+ status: CREDENTIALING_STATUS.ACTIVE
2911
+ },
2912
+ {
2913
+ state: "TN",
2914
+ stateBoardDisplay: "Tennessee Board of Medical Examiners",
2915
+ licenseNumber: "TN-MD-MD38712",
2916
+ issued: "2012-06-04",
2917
+ expires: "2024-06-30",
2918
+ status: CREDENTIALING_STATUS.EXPIRED
2919
+ }
2920
+ ],
2921
+ "on-site-demo-doctor-010": [
2922
+ {
2923
+ state: "GA",
2924
+ stateBoardDisplay: "Georgia Composite Medical Board",
2925
+ licenseNumber: "GA-MD-108901",
2926
+ issued: "2020-03-15",
2927
+ expires: "2027-03-31",
2928
+ status: CREDENTIALING_STATUS.ACTIVE
2929
+ }
2930
+ ]
2931
+ };
2932
+ var practitionerCredentialingForDoctor = (practitionerId) => PRACTITIONER_CREDENTIALING_BY_DOCTOR[practitionerId] ?? [];
2933
+ var practitionerCredentialingForState = (practitionerId, stateCode) => practitionerCredentialingForDoctor(practitionerId).find(
2934
+ (entry) => entry.state === stateCode
2935
+ );
2936
+ var buildCredentialingQualifications = (practitionerId) => practitionerCredentialingForDoctor(practitionerId).map((cred) => ({
2937
+ identifier: [
2938
+ {
2939
+ system: STATE_MEDICAL_LICENSE_SYSTEM,
2940
+ value: cred.licenseNumber
2941
+ }
2942
+ ],
2943
+ code: {
2944
+ text: "Medical License"
2945
+ },
2946
+ period: {
2947
+ start: cred.issued,
2948
+ end: cred.expires
2949
+ },
2950
+ issuer: {
2951
+ display: cred.stateBoardDisplay
2952
+ },
2953
+ extension: [
2954
+ {
2955
+ url: PRACTITIONER_CREDENTIALING_EXTENSION_URL,
2956
+ extension: [
2957
+ {
2958
+ url: PRACTITIONER_CREDENTIALING_STATE_SUB_EXTENSION_URL,
2959
+ valueCode: cred.state
2960
+ },
2961
+ {
2962
+ url: PRACTITIONER_CREDENTIALING_STATUS_SUB_EXTENSION_URL,
2963
+ valueCode: cred.status
2964
+ }
2965
+ ]
2966
+ }
2967
+ ]
2968
+ }));
2969
+
2970
+ // src/workflows/control-plane/seed-demo-data/on-site-demo-fixtures.ts
2971
+ var US_NPI_SYSTEM = "http://hl7.org/fhir/sid/us-npi";
2972
+ var HOME_HEALTH_ELIGIBLE_EXTENSION_URL = "https://on-site-medical.app/fhir/StructureDefinition/home-health-eligible";
2973
+ var PRACTITIONER_ROLE_PHYSICIAN = "Physician";
2974
+ var PRACTITIONER_ROLE_SCRIBE = "Scribe";
2975
+ var ON_SITE_STAFF_ID_SYSTEM = "https://on-site-medical.app/fhir/sid/staff-id";
2976
+ var DOCTOR_SPECS = [
2977
+ {
2978
+ id: "on-site-demo-doctor-001",
2979
+ firstName: "Sarah",
2980
+ lastName: "Patel",
2981
+ suffix: "MD",
2982
+ gender: "female",
2983
+ birthDate: "1978-03-14",
2984
+ phone: "+14045550101",
2985
+ email: "sarah.patel@on-site-demo.example.com",
2986
+ npi: "1003000001",
2987
+ addressLine: "120 Peachtree Street NE",
2988
+ addressCity: "Atlanta",
2989
+ addressState: "GA",
2990
+ addressPostalCode: "30303",
2991
+ homeHealthEligible: true
2992
+ },
2993
+ {
2994
+ id: "on-site-demo-doctor-002",
2995
+ firstName: "Michael",
2996
+ lastName: "Brennan",
2997
+ suffix: "DO",
2998
+ gender: "male",
2999
+ birthDate: "1972-08-22",
3000
+ phone: "+14045550102",
3001
+ email: "michael.brennan@on-site-demo.example.com",
3002
+ npi: "1003000002",
3003
+ addressLine: "300 Ponce de Leon Avenue",
3004
+ addressCity: "Atlanta",
3005
+ addressState: "GA",
3006
+ addressPostalCode: "30308",
3007
+ homeHealthEligible: true
3008
+ },
3009
+ {
3010
+ id: "on-site-demo-doctor-003",
3011
+ firstName: "Linda",
3012
+ lastName: "Nguyen",
3013
+ suffix: "MD",
3014
+ gender: "female",
3015
+ birthDate: "1981-11-05",
3016
+ phone: "+14045550103",
3017
+ email: "linda.nguyen@on-site-demo.example.com",
3018
+ npi: "1003000003",
3019
+ addressLine: "75 Piedmont Avenue",
3020
+ addressCity: "Atlanta",
3021
+ addressState: "GA",
3022
+ addressPostalCode: "30303",
3023
+ homeHealthEligible: true
3024
+ },
3025
+ {
3026
+ id: "on-site-demo-doctor-004",
3027
+ firstName: "James",
3028
+ lastName: "Ortiz",
3029
+ suffix: "MD",
3030
+ gender: "male",
3031
+ birthDate: "1969-04-30",
3032
+ phone: "+14045550104",
3033
+ email: "james.ortiz@on-site-demo.example.com",
3034
+ npi: "1003000004",
3035
+ addressLine: "1825 Howell Mill Road",
3036
+ addressCity: "Atlanta",
3037
+ addressState: "GA",
3038
+ addressPostalCode: "30318",
3039
+ homeHealthEligible: true
3040
+ },
3041
+ {
3042
+ id: "on-site-demo-doctor-005",
3043
+ firstName: "Olivia",
3044
+ lastName: "Carter",
3045
+ suffix: "MD",
3046
+ gender: "female",
3047
+ birthDate: "1985-07-19",
3048
+ phone: "+14045550105",
3049
+ email: "olivia.carter@on-site-demo.example.com",
3050
+ npi: "1003000005",
3051
+ addressLine: "999 Peachtree Street NE",
3052
+ addressCity: "Atlanta",
3053
+ addressState: "GA",
3054
+ addressPostalCode: "30309",
3055
+ homeHealthEligible: true
3056
+ },
3057
+ {
3058
+ id: "on-site-demo-doctor-006",
3059
+ firstName: "David",
3060
+ lastName: "Sullivan",
3061
+ suffix: "MD",
3062
+ gender: "male",
3063
+ birthDate: "1965-12-02",
3064
+ phone: "+14045550106",
3065
+ email: "david.sullivan@on-site-demo.example.com",
3066
+ npi: "1003000006",
3067
+ addressLine: "550 Pharr Road",
3068
+ addressCity: "Atlanta",
3069
+ addressState: "GA",
3070
+ addressPostalCode: "30305",
3071
+ homeHealthEligible: false
3072
+ },
3073
+ {
3074
+ id: "on-site-demo-doctor-007",
3075
+ firstName: "Maria",
3076
+ lastName: "Hernandez",
3077
+ suffix: "MD",
3078
+ gender: "female",
3079
+ birthDate: "1976-06-11",
3080
+ phone: "+14045550107",
3081
+ email: "maria.hernandez@on-site-demo.example.com",
3082
+ npi: "1003000007",
3083
+ addressLine: "2200 Northside Drive NW",
3084
+ addressCity: "Atlanta",
3085
+ addressState: "GA",
3086
+ addressPostalCode: "30318",
3087
+ homeHealthEligible: false
3088
+ },
3089
+ {
3090
+ id: "on-site-demo-doctor-008",
3091
+ firstName: "Robert",
3092
+ lastName: "Kim",
3093
+ suffix: "DO",
3094
+ gender: "male",
3095
+ birthDate: "1983-02-27",
3096
+ phone: "+14045550108",
3097
+ email: "robert.kim@on-site-demo.example.com",
3098
+ npi: "1003000008",
3099
+ addressLine: "400 West Peachtree Street",
3100
+ addressCity: "Atlanta",
3101
+ addressState: "GA",
3102
+ addressPostalCode: "30308",
3103
+ homeHealthEligible: false
3104
+ },
3105
+ {
3106
+ id: "on-site-demo-doctor-009",
3107
+ firstName: "Jennifer",
3108
+ lastName: "Williams",
3109
+ suffix: "MD",
3110
+ gender: "female",
3111
+ birthDate: "1970-10-16",
3112
+ phone: "+14045550109",
3113
+ email: "jennifer.williams@on-site-demo.example.com",
3114
+ npi: "1003000009",
3115
+ addressLine: "1364 Clifton Road NE",
3116
+ addressCity: "Atlanta",
3117
+ addressState: "GA",
3118
+ addressPostalCode: "30322",
3119
+ homeHealthEligible: false
3120
+ },
3121
+ {
3122
+ id: "on-site-demo-doctor-010",
3123
+ firstName: "Thomas",
3124
+ lastName: "Anderson",
3125
+ suffix: "MD",
3126
+ gender: "male",
3127
+ birthDate: "1988-09-08",
3128
+ phone: "+14045550110",
3129
+ email: "thomas.anderson@on-site-demo.example.com",
3130
+ npi: "1003000010",
3131
+ addressLine: "1900 The Exchange SE",
3132
+ addressCity: "Atlanta",
3133
+ addressState: "GA",
3134
+ addressPostalCode: "30339",
3135
+ homeHealthEligible: false
3136
+ }
3137
+ ];
3138
+ var SCRIBE_SPECS = [
3139
+ {
3140
+ id: "on-site-demo-scribe-001",
3141
+ firstName: "Emily",
3142
+ lastName: "Reed",
3143
+ gender: "female",
3144
+ birthDate: "1995-01-23",
3145
+ phone: "+14045550201",
3146
+ email: "emily.reed@on-site-demo.example.com",
3147
+ staffId: "SCR-0001",
3148
+ addressLine: "240 Edgewood Avenue SE",
3149
+ addressCity: "Atlanta",
3150
+ addressState: "GA",
3151
+ addressPostalCode: "30303"
3152
+ },
3153
+ {
3154
+ id: "on-site-demo-scribe-002",
3155
+ firstName: "Daniel",
3156
+ lastName: "Foster",
3157
+ gender: "male",
3158
+ birthDate: "1993-05-17",
3159
+ phone: "+14045550202",
3160
+ email: "daniel.foster@on-site-demo.example.com",
3161
+ staffId: "SCR-0002",
3162
+ addressLine: "780 Boulevard SE",
3163
+ addressCity: "Atlanta",
3164
+ addressState: "GA",
3165
+ addressPostalCode: "30312"
3166
+ },
3167
+ {
3168
+ id: "on-site-demo-scribe-003",
3169
+ firstName: "Ashley",
3170
+ lastName: "Garrett",
3171
+ gender: "female",
3172
+ birthDate: "1997-11-29",
3173
+ phone: "+14045550203",
3174
+ email: "ashley.garrett@on-site-demo.example.com",
3175
+ staffId: "SCR-0003",
3176
+ addressLine: "55 Allen Plaza",
3177
+ addressCity: "Atlanta",
3178
+ addressState: "GA",
3179
+ addressPostalCode: "30308"
3180
+ },
3181
+ {
3182
+ id: "on-site-demo-scribe-004",
3183
+ firstName: "Brandon",
3184
+ lastName: "Murray",
3185
+ gender: "male",
3186
+ birthDate: "1991-07-04",
3187
+ phone: "+14045550204",
3188
+ email: "brandon.murray@on-site-demo.example.com",
3189
+ staffId: "SCR-0004",
3190
+ addressLine: "1100 Spring Street NW",
3191
+ addressCity: "Atlanta",
3192
+ addressState: "GA",
3193
+ addressPostalCode: "30309"
3194
+ },
3195
+ {
3196
+ id: "on-site-demo-scribe-005",
3197
+ firstName: "Sofia",
3198
+ lastName: "Bennett",
3199
+ gender: "female",
3200
+ birthDate: "1999-03-12",
3201
+ phone: "+14045550205",
3202
+ email: "sofia.bennett@on-site-demo.example.com",
3203
+ staffId: "SCR-0005",
3204
+ addressLine: "165 Courtland Street NE",
3205
+ addressCity: "Atlanta",
3206
+ addressState: "GA",
3207
+ addressPostalCode: "30303"
3208
+ }
3209
+ ];
3210
+ var ON_SITE_SCENARIO8 = "on-site-demo";
3211
+ var buildIdentifierPair7 = (practitionerId, roleSuffix) => [
3212
+ demoScenarioIdentifier(ON_SITE_SCENARIO8, roleSuffix),
3213
+ openhiResourceIdentifier({
3214
+ tenantId: ON_SITE_DEMO_TENANT_ID,
3215
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
3216
+ resourceType: "Practitioner",
3217
+ id: practitionerId
3218
+ })
3219
+ ];
3220
+ var buildDoctorResource = (spec) => {
3221
+ const fullText = `${spec.firstName} ${spec.lastName}${spec.suffix ? `, ${spec.suffix}` : ""}`;
3222
+ const baseIdentifiers = buildIdentifierPair7(
3223
+ spec.id,
3224
+ `practitioner-${spec.id}`
3225
+ );
3226
+ return {
3227
+ resourceType: "Practitioner",
3228
+ id: spec.id,
3229
+ active: true,
3230
+ identifier: [
3231
+ ...baseIdentifiers ?? [],
3232
+ {
3233
+ system: US_NPI_SYSTEM,
3234
+ value: spec.npi
3235
+ }
3236
+ ],
3237
+ name: [
3238
+ {
3239
+ use: "official",
3240
+ text: fullText,
3241
+ given: [spec.firstName],
3242
+ family: spec.lastName,
3243
+ prefix: ["Dr."],
3244
+ ...spec.suffix ? { suffix: [spec.suffix] } : {}
3245
+ }
3246
+ ],
3247
+ gender: spec.gender,
3248
+ birthDate: spec.birthDate,
3249
+ telecom: [
3250
+ { system: "phone", value: spec.phone, use: "work" },
3251
+ { system: "email", value: spec.email, use: "work" }
3252
+ ],
3253
+ address: [
3254
+ {
3255
+ use: "work",
3256
+ line: [spec.addressLine],
3257
+ city: spec.addressCity,
3258
+ state: spec.addressState,
3259
+ postalCode: spec.addressPostalCode,
3260
+ country: "US"
3261
+ }
3262
+ ],
3263
+ qualification: [
3264
+ {
3265
+ code: {
3266
+ text: PRACTITIONER_ROLE_PHYSICIAN
3267
+ }
3268
+ },
3269
+ // Per-state credentialing entries appended after the role
3270
+ // label (#1308). Each on-site doctor carries 1-3 state
3271
+ // licenses with status / period / issuer fields populated
3272
+ // for the directory UI's credentialing column.
3273
+ ...buildCredentialingQualifications(spec.id)
3274
+ ],
3275
+ ...spec.homeHealthEligible ? {
3276
+ extension: [
3277
+ {
3278
+ url: HOME_HEALTH_ELIGIBLE_EXTENSION_URL,
3279
+ valueBoolean: true
3280
+ }
3281
+ ]
3282
+ } : {}
3283
+ };
3284
+ };
3285
+ var buildScribeResource = (spec) => {
3286
+ const fullText = `${spec.firstName} ${spec.lastName}`;
3287
+ const baseIdentifiers = buildIdentifierPair7(
3288
+ spec.id,
3289
+ `practitioner-${spec.id}`
3290
+ );
3291
+ return {
3292
+ resourceType: "Practitioner",
3293
+ id: spec.id,
3294
+ active: true,
3295
+ identifier: [
3296
+ ...baseIdentifiers ?? [],
3297
+ {
3298
+ system: ON_SITE_STAFF_ID_SYSTEM,
3299
+ value: spec.staffId
3300
+ }
3301
+ ],
3302
+ name: [
3303
+ {
3304
+ use: "official",
3305
+ text: fullText,
3306
+ given: [spec.firstName],
3307
+ family: spec.lastName
3308
+ }
3309
+ ],
3310
+ gender: spec.gender,
3311
+ birthDate: spec.birthDate,
3312
+ telecom: [
3313
+ { system: "phone", value: spec.phone, use: "work" },
3314
+ { system: "email", value: spec.email, use: "work" }
3315
+ ],
3316
+ address: [
3317
+ {
3318
+ use: "work",
3319
+ line: [spec.addressLine],
3320
+ city: spec.addressCity,
3321
+ state: spec.addressState,
3322
+ postalCode: spec.addressPostalCode,
3323
+ country: "US"
3324
+ }
3325
+ ],
3326
+ qualification: [
3327
+ {
3328
+ code: {
3329
+ text: PRACTITIONER_ROLE_SCRIBE
3330
+ }
3331
+ }
3332
+ ]
3333
+ };
3334
+ };
3335
+ var ON_SITE_DEMO_DOCTORS = DOCTOR_SPECS.map(buildDoctorResource);
3336
+ var ON_SITE_DEMO_SCRIBES = SCRIBE_SPECS.map(buildScribeResource);
3337
+ var ON_SITE_DEMO_DOCTOR_IDS = DOCTOR_SPECS.map(
3338
+ (d) => d.id
3339
+ );
3340
+ var ON_SITE_DEMO_SCRIBE_IDS = SCRIBE_SPECS.map(
3341
+ (s) => s.id
3342
+ );
3343
+ var homeHealthEligibleDoctors = () => ON_SITE_DEMO_DOCTORS.filter(
3344
+ (p) => (p.extension ?? []).some(
3345
+ (ext) => ext.url === HOME_HEALTH_ELIGIBLE_EXTENSION_URL && ext.valueBoolean === true
3346
+ )
3347
+ );
3348
+ var ON_SITE_DEMO_FIXTURES = {
3349
+ tenantId: ON_SITE_DEMO_TENANT_ID,
3350
+ workspaceId: ON_SITE_DEMO_WORKSPACE_ID,
3351
+ scenario: ON_SITE_SCENARIO8,
3352
+ // Patients + Coverages are materialised lazily via the
3353
+ // `buildPatients` / `buildCoverages` hooks below. Module-level
3354
+ // arrays would force a TDZ on the cross-module imports between
3355
+ // `on-site-demo-fixtures.ts`, `on-site-demo-blocks.ts`, and
3356
+ // `on-site-demo-facility-patients.ts`.
3357
+ patients: [],
3358
+ practitioners: [...ON_SITE_DEMO_DOCTORS, ...ON_SITE_DEMO_SCRIBES],
3359
+ observations: [],
3360
+ encounters: [],
3361
+ accounts: [],
3362
+ locations: [...ON_SITE_DEMO_FACILITIES],
3363
+ organizations: [...ON_SITE_DEMO_DIRECTORY_ORGANIZATIONS],
3364
+ buildPatients: () => [
3365
+ ...buildOnSiteDemoFacilityPatients(),
3366
+ ...buildOnSiteDemoHomeHealthPatients()
3367
+ ],
3368
+ buildCoverages: () => [
3369
+ ...buildOnSiteDemoFacilityCoverages(),
3370
+ ...buildOnSiteDemoHomeHealthCoverages()
3371
+ ],
3372
+ buildAppointments: (baseContext) => buildOnSiteDemoBlockAppointments(
3373
+ baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString()
3374
+ ),
3375
+ buildConditions: (baseContext) => buildOnSiteDemoWoundConditions(
3376
+ baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString()
3377
+ ),
3378
+ buildEncounters: (baseContext) => buildOnSiteDemoEncounters(baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString()),
3379
+ buildObservations: (baseContext) => buildOnSiteDemoWoundObservations(
3380
+ baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString()
3381
+ ),
3382
+ buildProcedures: (baseContext) => buildOnSiteDemoWoundProcedures(
3383
+ baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString()
3384
+ ),
3385
+ buildClaims: (baseContext) => buildOnSiteDemoClaims(baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString()),
3386
+ buildPaymentNotices: (baseContext) => buildOnSiteDemoPaymentNotices(baseContext.date ?? (/* @__PURE__ */ new Date()).toISOString())
3387
+ };
3388
+
3389
+ // src/workflows/control-plane/seed-demo-data/data-plane-fixtures.ts
3390
+ var fixtureIdentifiers = (scenario, tenantId, workspaceId, resourceType, id, roleSuffix) => [
3391
+ demoScenarioIdentifier(scenario, roleSuffix),
3392
+ openhiResourceIdentifier({
3393
+ tenantId,
3394
+ workspaceId,
3395
+ resourceType,
3396
+ id
3397
+ })
3398
+ ];
3399
+ var buildWoundCareFixtures = (scenario, tenantId, workspaceId, idPrefix) => ({
3400
+ tenantId,
3401
+ workspaceId,
3402
+ scenario,
3403
+ patients: [
3404
+ {
3405
+ resourceType: "Patient",
3406
+ id: `${idPrefix}-patient-1`,
3407
+ identifier: fixtureIdentifiers(
3408
+ scenario,
3409
+ tenantId,
3410
+ workspaceId,
3411
+ "Patient",
3412
+ `${idPrefix}-patient-1`,
3413
+ `patient-1`
3414
+ ),
3415
+ active: true,
3416
+ name: [{ family: "Carter", given: ["Eleanor"], use: "official" }],
3417
+ gender: "female",
3418
+ birthDate: "1952-04-18"
3419
+ },
3420
+ {
3421
+ resourceType: "Patient",
3422
+ id: `${idPrefix}-patient-2`,
3423
+ identifier: fixtureIdentifiers(
3424
+ scenario,
3425
+ tenantId,
3426
+ workspaceId,
3427
+ "Patient",
3428
+ `${idPrefix}-patient-2`,
3429
+ `patient-2`
3430
+ ),
3431
+ active: true,
3432
+ name: [{ family: "Nguyen", given: ["Hao"], use: "official" }],
3433
+ gender: "male",
3434
+ birthDate: "1968-11-02"
3435
+ }
3436
+ ],
3437
+ practitioners: [
3438
+ {
3439
+ resourceType: "Practitioner",
3440
+ id: `${idPrefix}-practitioner-1`,
3441
+ identifier: fixtureIdentifiers(
3442
+ scenario,
3443
+ tenantId,
3444
+ workspaceId,
3445
+ "Practitioner",
3446
+ `${idPrefix}-practitioner-1`,
3447
+ `practitioner-1`
3448
+ ),
3449
+ active: true,
3450
+ name: [{ family: "Reyes", given: ["Maria"], prefix: ["Dr."] }],
3451
+ gender: "female"
3452
+ },
3453
+ {
3454
+ resourceType: "Practitioner",
3455
+ id: `${idPrefix}-practitioner-2`,
3456
+ identifier: fixtureIdentifiers(
3457
+ scenario,
3458
+ tenantId,
3459
+ workspaceId,
3460
+ "Practitioner",
3461
+ `${idPrefix}-practitioner-2`,
3462
+ `practitioner-2`
3463
+ ),
3464
+ active: true,
3465
+ name: [{ family: "Okafor", given: ["Chinedu"], prefix: ["Dr."] }],
3466
+ gender: "male"
3467
+ }
3468
+ ],
3469
+ observations: [
3470
+ {
3471
+ resourceType: "Observation",
3472
+ id: `${idPrefix}-observation-1`,
3473
+ identifier: fixtureIdentifiers(
3474
+ scenario,
3475
+ tenantId,
3476
+ workspaceId,
3477
+ "Observation",
3478
+ `${idPrefix}-observation-1`,
3479
+ `observation-1`
3480
+ ),
3481
+ status: "final",
3482
+ code: {
3483
+ coding: [
3484
+ {
3485
+ system: "http://loinc.org",
3486
+ code: "39135-9",
3487
+ display: "Wound size"
3488
+ }
3489
+ ]
3490
+ },
3491
+ subject: { reference: `Patient/${idPrefix}-patient-1` },
3492
+ valueString: "3.2cm x 2.1cm"
3493
+ },
3494
+ {
3495
+ resourceType: "Observation",
3496
+ id: `${idPrefix}-observation-2`,
3497
+ identifier: fixtureIdentifiers(
3498
+ scenario,
3499
+ tenantId,
3500
+ workspaceId,
3501
+ "Observation",
3502
+ `${idPrefix}-observation-2`,
3503
+ `observation-2`
3504
+ ),
3505
+ status: "final",
3506
+ code: {
3507
+ coding: [
3508
+ {
3509
+ system: "http://loinc.org",
3510
+ code: "72287-2",
3511
+ display: "Wound exudate amount"
3512
+ }
3513
+ ]
3514
+ },
3515
+ subject: { reference: `Patient/${idPrefix}-patient-2` },
3516
+ valueString: "moderate"
3517
+ }
3518
+ ],
3519
+ encounters: [
3520
+ {
3521
+ resourceType: "Encounter",
3522
+ id: `${idPrefix}-encounter-1`,
3523
+ identifier: fixtureIdentifiers(
3524
+ scenario,
3525
+ tenantId,
3526
+ workspaceId,
3527
+ "Encounter",
3528
+ `${idPrefix}-encounter-1`,
3529
+ `encounter-1`
3530
+ ),
3531
+ status: "finished",
3532
+ class: {
3533
+ system: "http://terminology.hl7.org/CodeSystem/v3-ActCode",
3534
+ code: "AMB",
3535
+ display: "ambulatory"
3536
+ },
3537
+ subject: { reference: `Patient/${idPrefix}-patient-1` }
3538
+ },
3539
+ {
3540
+ resourceType: "Encounter",
3541
+ id: `${idPrefix}-encounter-2`,
3542
+ identifier: fixtureIdentifiers(
3543
+ scenario,
3544
+ tenantId,
3545
+ workspaceId,
3546
+ "Encounter",
3547
+ `${idPrefix}-encounter-2`,
3548
+ `encounter-2`
3549
+ ),
3550
+ status: "finished",
3551
+ class: {
3552
+ system: "http://terminology.hl7.org/CodeSystem/v3-ActCode",
3553
+ code: "AMB",
3554
+ display: "ambulatory"
3555
+ },
3556
+ subject: { reference: `Patient/${idPrefix}-patient-2` }
3557
+ }
3558
+ ],
3559
+ accounts: [
3560
+ {
3561
+ resourceType: "Account",
3562
+ id: `${idPrefix}-account-1`,
3563
+ identifier: fixtureIdentifiers(
3564
+ scenario,
3565
+ tenantId,
3566
+ workspaceId,
3567
+ "Account",
3568
+ `${idPrefix}-account-1`,
3569
+ `account-1`
3570
+ ),
3571
+ status: "active",
3572
+ name: "Wound-care self-pay account",
3573
+ subject: [{ reference: `Patient/${idPrefix}-patient-1` }]
3574
+ }
3575
+ ]
3576
+ });
3577
+ var buildPrimaryCareFixtures = (scenario, tenantId, workspaceId, idPrefix) => ({
3578
+ tenantId,
3579
+ workspaceId,
3580
+ scenario,
3581
+ patients: [
3582
+ {
3583
+ resourceType: "Patient",
3584
+ id: `${idPrefix}-patient-1`,
3585
+ identifier: fixtureIdentifiers(
3586
+ scenario,
3587
+ tenantId,
3588
+ workspaceId,
3589
+ "Patient",
3590
+ `${idPrefix}-patient-1`,
3591
+ `patient-1`
3592
+ ),
3593
+ active: true,
3594
+ name: [{ family: "Bennett", given: ["Sophia"], use: "official" }],
3595
+ gender: "female",
3596
+ birthDate: "1985-06-09"
3597
+ },
3598
+ {
3599
+ resourceType: "Patient",
3600
+ id: `${idPrefix}-patient-2`,
3601
+ identifier: fixtureIdentifiers(
3602
+ scenario,
3603
+ tenantId,
3604
+ workspaceId,
3605
+ "Patient",
3606
+ `${idPrefix}-patient-2`,
3607
+ `patient-2`
3608
+ ),
3609
+ active: true,
3610
+ name: [{ family: "Patel", given: ["Arjun"], use: "official" }],
3611
+ gender: "male",
3612
+ birthDate: "1979-02-21"
3613
+ }
3614
+ ],
3615
+ practitioners: [
3616
+ {
3617
+ resourceType: "Practitioner",
3618
+ id: `${idPrefix}-practitioner-1`,
3619
+ identifier: fixtureIdentifiers(
3620
+ scenario,
3621
+ tenantId,
3622
+ workspaceId,
3623
+ "Practitioner",
3624
+ `${idPrefix}-practitioner-1`,
3625
+ `practitioner-1`
3626
+ ),
3627
+ active: true,
3628
+ name: [{ family: "Lin", given: ["Wei"], prefix: ["Dr."] }],
3629
+ gender: "female"
3630
+ },
3631
+ {
3632
+ resourceType: "Practitioner",
3633
+ id: `${idPrefix}-practitioner-2`,
3634
+ identifier: fixtureIdentifiers(
3635
+ scenario,
3636
+ tenantId,
3637
+ workspaceId,
3638
+ "Practitioner",
3639
+ `${idPrefix}-practitioner-2`,
3640
+ `practitioner-2`
3641
+ ),
3642
+ active: true,
3643
+ name: [{ family: "Kowalski", given: ["Piotr"], prefix: ["Dr."] }],
3644
+ gender: "male"
3645
+ }
3646
+ ],
3647
+ observations: [
3648
+ {
3649
+ resourceType: "Observation",
3650
+ id: `${idPrefix}-observation-1`,
3651
+ identifier: fixtureIdentifiers(
3652
+ scenario,
3653
+ tenantId,
3654
+ workspaceId,
3655
+ "Observation",
3656
+ `${idPrefix}-observation-1`,
3657
+ `observation-1`
3658
+ ),
3659
+ status: "final",
3660
+ code: {
3661
+ coding: [
3662
+ {
3663
+ system: "http://loinc.org",
3664
+ code: "8480-6",
3665
+ display: "Systolic blood pressure"
3666
+ }
3667
+ ]
3668
+ },
3669
+ subject: { reference: `Patient/${idPrefix}-patient-1` },
3670
+ valueQuantity: { value: 122, unit: "mm[Hg]" }
3671
+ },
3672
+ {
3673
+ resourceType: "Observation",
3674
+ id: `${idPrefix}-observation-2`,
3675
+ identifier: fixtureIdentifiers(
3676
+ scenario,
3677
+ tenantId,
3678
+ workspaceId,
3679
+ "Observation",
3680
+ `${idPrefix}-observation-2`,
3681
+ `observation-2`
3682
+ ),
3683
+ status: "final",
3684
+ code: {
3685
+ coding: [
3686
+ {
3687
+ system: "http://loinc.org",
3688
+ code: "8462-4",
3689
+ display: "Diastolic blood pressure"
3690
+ }
3691
+ ]
3692
+ },
3693
+ subject: { reference: `Patient/${idPrefix}-patient-2` },
3694
+ valueQuantity: { value: 78, unit: "mm[Hg]" }
3695
+ }
3696
+ ],
3697
+ encounters: [
3698
+ {
3699
+ resourceType: "Encounter",
3700
+ id: `${idPrefix}-encounter-1`,
3701
+ identifier: fixtureIdentifiers(
3702
+ scenario,
3703
+ tenantId,
3704
+ workspaceId,
3705
+ "Encounter",
3706
+ `${idPrefix}-encounter-1`,
3707
+ `encounter-1`
3708
+ ),
3709
+ status: "finished",
3710
+ class: {
3711
+ system: "http://terminology.hl7.org/CodeSystem/v3-ActCode",
3712
+ code: "AMB",
3713
+ display: "ambulatory"
3714
+ },
3715
+ subject: { reference: `Patient/${idPrefix}-patient-1` }
3716
+ },
3717
+ {
3718
+ resourceType: "Encounter",
3719
+ id: `${idPrefix}-encounter-2`,
3720
+ identifier: fixtureIdentifiers(
3721
+ scenario,
3722
+ tenantId,
3723
+ workspaceId,
3724
+ "Encounter",
3725
+ `${idPrefix}-encounter-2`,
3726
+ `encounter-2`
3727
+ ),
3728
+ status: "in-progress",
3729
+ class: {
3730
+ system: "http://terminology.hl7.org/CodeSystem/v3-ActCode",
3731
+ code: "AMB",
3732
+ display: "ambulatory"
3733
+ },
3734
+ subject: { reference: `Patient/${idPrefix}-patient-2` }
3735
+ }
3736
+ ],
3737
+ accounts: [
3738
+ {
3739
+ resourceType: "Account",
3740
+ id: `${idPrefix}-account-1`,
3741
+ identifier: fixtureIdentifiers(
3742
+ scenario,
3743
+ tenantId,
3744
+ workspaceId,
3745
+ "Account",
3746
+ `${idPrefix}-account-1`,
3747
+ `account-1`
3748
+ ),
3749
+ status: "active",
3750
+ name: "Primary-care insurance account",
3751
+ subject: [{ reference: `Patient/${idPrefix}-patient-1` }]
3752
+ }
3753
+ ]
3754
+ });
3755
+ var DEMO_DATA_PLANE_FIXTURES = [
3756
+ // On-site-medical UAT demo workspace — practitioners only (issue
3757
+ // #1302). Patients, encounters, and other data-plane resources for
3758
+ // this tenant land in later tickets.
3759
+ ON_SITE_DEMO_FIXTURES,
3760
+ buildWoundCareFixtures(
3761
+ "demo-wound-care",
3762
+ "demo-wound-care-tenant",
3763
+ "demo-wound-care-workspace",
3764
+ "demo-wound-care"
3765
+ ),
3766
+ buildPrimaryCareFixtures(
3767
+ "demo-primary-care",
3768
+ "demo-primary-care-tenant",
3769
+ "demo-primary-care-workspace",
3770
+ "demo-primary-care"
3771
+ ),
3772
+ buildWoundCareFixtures(
3773
+ "demo-mixed",
3774
+ "demo-mixed-tenant",
3775
+ "demo-mixed-workspace-wound-care",
3776
+ "demo-mixed-wound-care"
3777
+ ),
3778
+ buildPrimaryCareFixtures(
3779
+ "demo-mixed",
3780
+ "demo-mixed-tenant",
3781
+ "demo-mixed-workspace-primary-care",
3782
+ "demo-mixed-primary-care"
3783
+ )
3784
+ ];
3785
+ var _validateFixturesAgainstTenantSpecs = () => {
3786
+ for (const group of DEMO_DATA_PLANE_FIXTURES) {
3787
+ if (group.tenantId === PLACEHOLDER_TENANT_ID) {
3788
+ throw new Error(
3789
+ "The placeholder tenant must not carry data-plane fixtures."
3790
+ );
3791
+ }
3792
+ const tenant = DEMO_TENANT_SPECS.find((s) => s.tenantId === group.tenantId);
3793
+ if (!tenant) {
3794
+ throw new Error(
3795
+ `Fixture references unknown tenantId "${group.tenantId}". Add a matching entry to DEMO_TENANT_SPECS first.`
3796
+ );
3797
+ }
3798
+ const workspace = tenant.workspaces.find(
3799
+ (ws) => ws.id === group.workspaceId
3800
+ );
3801
+ if (!workspace) {
3802
+ throw new Error(
3803
+ `Fixture references unknown workspaceId "${group.workspaceId}" for tenant "${group.tenantId}".`
3804
+ );
3805
+ }
3806
+ }
3807
+ };
3808
+ _validateFixturesAgainstTenantSpecs();
3809
+
3810
+ // src/workflows/control-plane/seed-demo-data/seed-demo-data.handler.ts
3811
+ var SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR = "SEED_DEMO_DATA_USER_POOL_ID";
3812
+ var errorMessage = (err) => {
3813
+ if (err instanceof Error) {
3814
+ return err.message;
3815
+ }
3816
+ return String(err);
3817
+ };
3818
+ var tryRun = async (failures, phase, scope, resourceType, resourceId, fn) => {
3819
+ try {
3820
+ await fn();
3821
+ return true;
3822
+ } catch (err) {
3823
+ failures.push({ phase, scope, resourceType, resourceId, error: err });
3824
+ return false;
3825
+ }
3826
+ };
3827
+ var aggregateFailureError = (failures) => {
3828
+ const summary = failures.map(
3829
+ (f) => `${f.phase} ${f.scope}/${f.resourceType}/${f.resourceId}: ${errorMessage(
3830
+ f.error
3831
+ )}`
3832
+ ).join("; ");
3833
+ return new Error(
3834
+ `seed-demo-data: ${failures.length} item(s) failed across phases: ${summary}`
3835
+ );
3836
+ };
3837
+ var idForRoleCode = (code) => {
3838
+ for (const key of Object.keys(PLATFORM_ROLE_IDS)) {
3839
+ if (PLATFORM_ROLE_CONCEPTS[key].code === code) {
3840
+ return PLATFORM_ROLE_IDS[key];
3841
+ }
3842
+ }
3843
+ throw new Error(`No id mapping for role code "${code}".`);
3844
+ };
3845
+ var verifySystemRolesExist = async () => {
3846
+ const probeContext = {
3847
+ tenantId: "",
3848
+ workspaceId: "",
3849
+ date: (/* @__PURE__ */ new Date(0)).toISOString(),
3850
+ actorId: "platform-deploy-bridge",
3851
+ actorName: "Platform Deploy Bridge",
3852
+ actorType: "internal-system",
3853
+ source: "step-function"
3854
+ };
3855
+ for (const id of Object.values(PLATFORM_ROLE_IDS)) {
3856
+ try {
3857
+ await getRoleByIdOperation({ context: probeContext, id });
3858
+ } catch (err) {
3859
+ if (err instanceof NotFoundError) {
3860
+ throw new Error(
3861
+ `seed-demo-data pre-flight: control-plane Role "${id}" is missing. Ensure seed-system-data has run on this environment before retrying.`
3862
+ );
3863
+ }
3864
+ throw err;
3865
+ }
3866
+ }
3867
+ };
3868
+ var tenantResourceBody = (spec) => ({
3869
+ name: spec.tenantName,
3870
+ active: true,
3871
+ identifier: [
3872
+ demoScenarioIdentifier(spec.scenario, "tenant"),
3873
+ openhiResourceIdentifier({
3874
+ tenantId: spec.tenantId,
3875
+ workspaceId: "",
3876
+ resourceType: "Tenant",
3877
+ id: spec.tenantId
3878
+ })
3879
+ ]
3880
+ });
3881
+ var workspaceResourceBody = (spec, workspace) => ({
3882
+ name: workspace.name,
3883
+ active: true,
3884
+ identifier: [
3885
+ demoScenarioIdentifier(spec.scenario, workspace.roleSuffix),
3886
+ openhiResourceIdentifier({
3887
+ tenantId: spec.tenantId,
3888
+ workspaceId: "",
3889
+ resourceType: "Workspace",
3890
+ id: workspace.id
3891
+ })
3892
+ ],
3893
+ tenant: { reference: `Tenant/${spec.tenantId}`, type: "Tenant" }
3894
+ });
3895
+ var membershipResourceBody = (spec, user, membershipId) => ({
3896
+ identifier: [
3897
+ demoScenarioIdentifier(spec.scenario, `membership-${user.id}`),
3898
+ openhiResourceIdentifier({
3899
+ tenantId: spec.tenantId,
3900
+ workspaceId: "",
3901
+ resourceType: "Membership",
3902
+ id: membershipId
3903
+ })
3904
+ ],
3905
+ user: { reference: `User/${user.id}`, type: "User" },
3906
+ tenant: { reference: `Tenant/${spec.tenantId}`, type: "Tenant" },
3907
+ period: DEMO_PERIOD
3908
+ });
3909
+ var roleAssignmentResourceBody = (scenario, tenantId, user, roleCode, roleAssignmentId) => ({
3910
+ identifier: [
3911
+ demoScenarioIdentifier(scenario, `roleassignment-${user.id}-${roleCode}`),
3912
+ openhiResourceIdentifier({
3913
+ tenantId,
3914
+ workspaceId: "",
3915
+ resourceType: "RoleAssignment",
3916
+ id: roleAssignmentId
3917
+ })
3918
+ ],
3919
+ user: { reference: `User/${user.id}`, type: "User" },
3920
+ role: { reference: `Role/${idForRoleCode(roleCode)}`, type: "Role" },
3921
+ tenant: { reference: `Tenant/${tenantId}`, type: "Tenant" },
3922
+ period: DEMO_PERIOD
3923
+ });
3924
+ var userResourceBody = (user, cognitoSub) => ({
3925
+ resourceType: "User",
3926
+ id: user.id,
3927
+ name: [
3928
+ {
3929
+ text: `${user.firstName} ${user.lastName}`,
3930
+ given: [user.firstName],
3931
+ family: user.lastName
3932
+ }
3933
+ ],
3934
+ telecom: [{ system: "email", value: user.email }],
3935
+ status: "active",
3936
+ cognitoSub,
3937
+ currentTenant: { reference: `Tenant/${ON_SITE_DEMO_TENANT_ID}` },
3938
+ currentWorkspace: { reference: `Workspace/${ON_SITE_DEMO_WORKSPACE_ID}` }
3939
+ });
3940
+ var upsertUser = async (context, user, cognitoSub) => {
3941
+ const service = getDynamoControlService();
3942
+ const resource = userResourceBody(user, cognitoSub);
3943
+ const summary = JSON.stringify(extractSummary(resource));
3944
+ await service.entities.user.put({
3945
+ id: user.id,
3946
+ cognitoSub,
3947
+ resource: JSON.stringify(resource),
3948
+ summary,
3949
+ vid: "1",
3950
+ lastUpdated: context.date ?? (/* @__PURE__ */ new Date()).toISOString()
3951
+ }).go();
3952
+ };
3953
+ var seedWorkspaceDataPlane = async (baseContext, group, failures) => {
3954
+ const workspaceContext = {
3955
+ ...baseContext,
3956
+ tenantId: group.tenantId,
3957
+ workspaceId: group.workspaceId
3958
+ };
3959
+ const scope = `${group.tenantId}/${group.workspaceId}`;
3960
+ for (const location of group.locations ?? []) {
3961
+ await tryRun(
3962
+ failures,
3963
+ "phase-3",
3964
+ scope,
3965
+ "Location",
3966
+ location.id ?? "",
3967
+ () => createLocationOperation({
3968
+ context: workspaceContext,
3969
+ body: location
3970
+ })
3971
+ );
3972
+ }
3973
+ for (const organization of group.organizations ?? []) {
3974
+ await tryRun(
3975
+ failures,
3976
+ "phase-3",
3977
+ scope,
3978
+ "Organization",
3979
+ organization.id ?? "",
3980
+ () => createOrganizationOperation({
3981
+ context: workspaceContext,
3982
+ body: organization
3983
+ })
3984
+ );
3985
+ }
3986
+ const patients = group.buildPatients ? group.buildPatients() : group.patients;
3987
+ for (const patient of patients) {
3988
+ await tryRun(
3989
+ failures,
3990
+ "phase-3",
3991
+ scope,
3992
+ "Patient",
3993
+ patient.id ?? "",
3994
+ () => createPatientOperation({
3995
+ context: workspaceContext,
3996
+ body: patient
3997
+ })
3998
+ );
3999
+ }
4000
+ const coverages = group.buildCoverages ? group.buildCoverages() : group.coverages ?? [];
4001
+ for (const coverage of coverages) {
4002
+ await tryRun(
4003
+ failures,
4004
+ "phase-3",
4005
+ scope,
4006
+ "Coverage",
4007
+ coverage.id ?? "",
4008
+ () => createCoverageOperation({
4009
+ context: workspaceContext,
4010
+ body: coverage
4011
+ })
4012
+ );
4013
+ }
4014
+ for (const practitioner of group.practitioners) {
4015
+ await tryRun(
4016
+ failures,
4017
+ "phase-3",
4018
+ scope,
4019
+ "Practitioner",
4020
+ practitioner.id ?? "",
4021
+ () => createPractitionerOperation({
4022
+ context: workspaceContext,
4023
+ body: practitioner
4024
+ })
4025
+ );
4026
+ }
4027
+ const conditions = group.buildConditions ? group.buildConditions(baseContext) : group.conditions ?? [];
4028
+ for (const condition of conditions) {
4029
+ await tryRun(
4030
+ failures,
4031
+ "phase-3",
4032
+ scope,
4033
+ "Condition",
4034
+ condition.id ?? "",
4035
+ () => createConditionOperation({
4036
+ context: workspaceContext,
4037
+ body: condition
4038
+ })
4039
+ );
4040
+ }
4041
+ const encounters = group.buildEncounters ? group.buildEncounters(baseContext) : group.encounters;
4042
+ for (const encounter of encounters) {
4043
+ await tryRun(
4044
+ failures,
4045
+ "phase-3",
4046
+ scope,
4047
+ "Encounter",
4048
+ encounter.id ?? "",
4049
+ () => createEncounterOperation({
4050
+ context: workspaceContext,
4051
+ body: encounter
4052
+ })
4053
+ );
4054
+ }
4055
+ const observations = group.buildObservations ? group.buildObservations(baseContext) : group.observations;
4056
+ for (const observation of observations) {
4057
+ await tryRun(
4058
+ failures,
4059
+ "phase-3",
4060
+ scope,
4061
+ "Observation",
4062
+ observation.id ?? "",
4063
+ () => createObservationOperation({
4064
+ context: workspaceContext,
4065
+ body: observation
4066
+ })
4067
+ );
4068
+ }
4069
+ const procedures = group.buildProcedures ? group.buildProcedures(baseContext) : group.procedures ?? [];
4070
+ for (const procedure of procedures) {
4071
+ await tryRun(
4072
+ failures,
4073
+ "phase-3",
4074
+ scope,
4075
+ "Procedure",
4076
+ procedure.id ?? "",
4077
+ () => createProcedureOperation({
4078
+ context: workspaceContext,
4079
+ body: procedure
4080
+ })
4081
+ );
4082
+ }
4083
+ const claims = group.buildClaims ? group.buildClaims(baseContext) : [];
4084
+ for (const claim of claims) {
4085
+ await tryRun(
4086
+ failures,
4087
+ "phase-3",
4088
+ scope,
4089
+ "Claim",
4090
+ claim.id ?? "",
4091
+ () => createClaimOperation({
4092
+ context: workspaceContext,
4093
+ body: claim
4094
+ })
4095
+ );
4096
+ }
4097
+ const paymentNotices = group.buildPaymentNotices ? group.buildPaymentNotices(baseContext) : [];
4098
+ for (const paymentNotice of paymentNotices) {
4099
+ await tryRun(
4100
+ failures,
4101
+ "phase-3",
4102
+ scope,
4103
+ "PaymentNotice",
4104
+ paymentNotice.id ?? "",
4105
+ () => createPaymentNoticeOperation({
4106
+ context: workspaceContext,
4107
+ body: paymentNotice
4108
+ })
4109
+ );
4110
+ }
4111
+ for (const account of group.accounts) {
4112
+ await tryRun(
4113
+ failures,
4114
+ "phase-3",
4115
+ scope,
4116
+ "Account",
4117
+ account.id ?? "",
4118
+ () => createAccountOperation({
4119
+ context: workspaceContext,
4120
+ body: account
4121
+ })
4122
+ );
4123
+ }
4124
+ const appointments = group.buildAppointments ? group.buildAppointments(baseContext) : [];
4125
+ for (const appointment of appointments) {
4126
+ await tryRun(
4127
+ failures,
4128
+ "phase-3",
4129
+ scope,
4130
+ "Appointment",
4131
+ appointment.id ?? "",
4132
+ () => createAppointmentOperation({
4133
+ context: workspaceContext,
4134
+ body: appointment
4135
+ })
4136
+ );
4137
+ }
4138
+ };
4139
+ var seedDemoGraph = async (params) => {
4140
+ const { baseContext, devUsers, cognito } = params;
4141
+ const failures = [];
4142
+ for (const spec of DEMO_TENANT_SPECS) {
4143
+ const tenantContext = {
4144
+ ...baseContext,
4145
+ tenantId: spec.tenantId
4146
+ };
4147
+ await tryRun(
4148
+ failures,
4149
+ "phase-1",
4150
+ spec.tenantId,
4151
+ "Tenant",
4152
+ spec.tenantId,
4153
+ () => createTenantOperation({
4154
+ context: tenantContext,
4155
+ body: { id: spec.tenantId, resource: tenantResourceBody(spec) }
4156
+ })
4157
+ );
4158
+ for (const workspace of spec.workspaces) {
4159
+ await tryRun(
4160
+ failures,
4161
+ "phase-1",
4162
+ spec.tenantId,
4163
+ "Workspace",
4164
+ workspace.id,
4165
+ () => createWorkspaceOperation({
4166
+ context: tenantContext,
4167
+ body: {
4168
+ id: workspace.id,
4169
+ resource: workspaceResourceBody(spec, workspace)
4170
+ }
4171
+ })
4172
+ );
4173
+ }
4174
+ }
4175
+ for (const user of devUsers) {
4176
+ let cognitoSub;
4177
+ try {
4178
+ cognitoSub = await cognito.ensureUser(user.email);
4179
+ } catch (err) {
4180
+ failures.push({
4181
+ phase: "phase-2",
4182
+ scope: user.id,
4183
+ resourceType: "CognitoUser",
4184
+ resourceId: user.email,
4185
+ error: err
4186
+ });
4187
+ continue;
4188
+ }
4189
+ await tryRun(
4190
+ failures,
4191
+ "phase-2",
4192
+ user.id,
4193
+ "User",
4194
+ user.id,
4195
+ () => upsertUser(baseContext, user, cognitoSub)
4196
+ );
4197
+ for (const spec of DEMO_TENANT_SPECS) {
4198
+ const tenantContext = {
4199
+ ...baseContext,
4200
+ tenantId: spec.tenantId
4201
+ };
4202
+ const userScope = `${user.id}@${spec.tenantId}`;
4203
+ const membershipId = demoMembershipId(user.id, spec.tenantId);
4204
+ await tryRun(
4205
+ failures,
4206
+ "phase-2",
4207
+ userScope,
4208
+ "Membership",
4209
+ membershipId,
4210
+ () => createMembershipOperation({
4211
+ context: tenantContext,
4212
+ body: {
4213
+ id: membershipId,
4214
+ resource: membershipResourceBody(spec, user, membershipId)
4215
+ }
4216
+ })
4217
+ );
4218
+ for (const roleCode of demoRolesForUserInTenant(user, spec.tenantId)) {
4219
+ const raId = demoRoleAssignmentId(user.id, spec.tenantId, roleCode);
4220
+ await tryRun(
4221
+ failures,
4222
+ "phase-2",
4223
+ userScope,
4224
+ "RoleAssignment",
4225
+ raId,
4226
+ () => createRoleAssignmentOperation({
4227
+ context: tenantContext,
4228
+ body: {
4229
+ id: raId,
4230
+ resource: roleAssignmentResourceBody(
4231
+ spec.scenario,
4232
+ spec.tenantId,
4233
+ user,
4234
+ roleCode,
4235
+ raId
4236
+ )
4237
+ }
4238
+ })
4239
+ );
4240
+ }
4241
+ }
4242
+ const platformContext = {
4243
+ ...baseContext,
4244
+ tenantId: PLATFORM_SCOPE_TENANT_ID
4245
+ };
4246
+ const platformRoleCode = PLATFORM_ROLE_CODE2.SYSTEM_ADMIN;
4247
+ const platformRaId = demoRoleAssignmentId(
4248
+ user.id,
4249
+ PLATFORM_SCOPE_TENANT_ID,
4250
+ platformRoleCode
4251
+ );
4252
+ await tryRun(
4253
+ failures,
4254
+ "phase-2",
4255
+ `${user.id}@${PLATFORM_SCOPE_TENANT_ID}`,
4256
+ "RoleAssignment",
4257
+ platformRaId,
4258
+ () => createRoleAssignmentOperation({
4259
+ context: platformContext,
4260
+ body: {
4261
+ id: platformRaId,
4262
+ resource: roleAssignmentResourceBody(
4263
+ "platform",
4264
+ PLATFORM_SCOPE_TENANT_ID,
4265
+ user,
4266
+ platformRoleCode,
4267
+ platformRaId
4268
+ )
4269
+ }
4270
+ })
4271
+ );
4272
+ }
4273
+ for (const group of DEMO_DATA_PLANE_FIXTURES) {
4274
+ try {
4275
+ await seedWorkspaceDataPlane(baseContext, group, failures);
4276
+ } catch (err) {
4277
+ failures.push({
4278
+ phase: "phase-3",
4279
+ scope: `${group.tenantId}/${group.workspaceId}`,
4280
+ resourceType: "Workspace",
4281
+ resourceId: group.workspaceId,
4282
+ error: err
4283
+ });
4284
+ }
4285
+ }
4286
+ if (failures.length > 0) {
4287
+ throw aggregateFailureError(failures);
4288
+ }
4289
+ };
4290
+ var runSeedDemoData = async (event, deps, devUsers) => {
4291
+ const parsed = (0, import_workflows2.parseWorkflowEvent)(event, import_workflows.PlatformSystemDataSeededV1);
4292
+ const recordResult = await deps.dedupClient.recordIfAbsent({
4293
+ consumerName: SEED_DEMO_DATA_CONSUMER_NAME,
4294
+ eventId: parsed.dedupKey.eventId,
4295
+ attempt: parsed.dedupKey.attempt
4296
+ });
4297
+ if (!recordResult.recorded) {
4298
+ return;
4299
+ }
4300
+ const baseContext = {
4301
+ tenantId: "",
4302
+ workspaceId: "",
4303
+ date: parsed.envelope.occurredAt,
4304
+ actorId: "platform-deploy-bridge",
4305
+ actorName: "Platform Deploy Bridge",
4306
+ actorType: "internal-system",
4307
+ source: "step-function"
4308
+ };
4309
+ try {
4310
+ await deps.verifyRoles();
4311
+ await deps.seedDemoGraph({
4312
+ baseContext,
4313
+ devUsers,
4314
+ cognito: deps.cognito
4315
+ });
4316
+ } catch (err) {
4317
+ await deps.dedupClient.markFailed({
4318
+ consumerName: SEED_DEMO_DATA_CONSUMER_NAME,
4319
+ eventId: parsed.dedupKey.eventId,
4320
+ attempt: parsed.dedupKey.attempt,
4321
+ reason: errorMessage(err)
4322
+ });
4323
+ throw err;
4324
+ }
4325
+ };
4326
+ var SEED_USER_PASSWORD_PARAMETER_PREFIX = "/openhi/seed/users/";
4327
+ var SSM_PATH_SEGMENT = /^[A-Za-z0-9_.-]+$/;
4328
+ var emailToSsmPath = (email) => {
4329
+ if (typeof email !== "string" || email.length === 0) {
4330
+ throw new Error(
4331
+ `emailToSsmPath: email must be a non-empty string (received "${String(email)}").`
4332
+ );
4333
+ }
4334
+ const atIdx = email.indexOf("@");
4335
+ if (atIdx === -1 || atIdx !== email.lastIndexOf("@")) {
4336
+ throw new Error(
4337
+ `emailToSsmPath: email "${email}" must contain exactly one "@" character.`
4338
+ );
4339
+ }
4340
+ const localPart = email.slice(0, atIdx);
4341
+ const domainPart = email.slice(atIdx + 1);
4342
+ if (localPart.length === 0 || domainPart.length === 0) {
4343
+ throw new Error(
4344
+ `emailToSsmPath: email "${email}" must have a non-empty local-part and domain.`
4345
+ );
4346
+ }
4347
+ if (!SSM_PATH_SEGMENT.test(localPart) || !SSM_PATH_SEGMENT.test(domainPart)) {
4348
+ throw new Error(
4349
+ `emailToSsmPath: email "${email}" contains characters that would produce an invalid SSM parameter path (only A-Z, a-z, 0-9, '.', '-', and '_' are allowed).`
4350
+ );
4351
+ }
4352
+ return `${SEED_USER_PASSWORD_PARAMETER_PREFIX}${localPart}_at_${domainPart}/password`;
4353
+ };
4354
+ var cachedSsmClient;
4355
+ var getSsmClient = () => {
4356
+ if (!cachedSsmClient) {
4357
+ cachedSsmClient = new SSMClient({});
4358
+ }
4359
+ return cachedSsmClient;
4360
+ };
4361
+ var __resetSsmClientForTests = () => {
4362
+ cachedSsmClient = void 0;
4363
+ };
4364
+ var fetchSeedUserPassword = async (email) => {
4365
+ const path = emailToSsmPath(email);
4366
+ const client = getSsmClient();
4367
+ try {
4368
+ const result = await client.send(
4369
+ new GetParameterCommand({ Name: path, WithDecryption: true })
4370
+ );
4371
+ const value = result.Parameter?.Value;
4372
+ if (typeof value !== "string" || value.length === 0) {
4373
+ throw new Error(
4374
+ `fetchSeedUserPassword: SSM parameter "${path}" returned an empty value.`
4375
+ );
4376
+ }
4377
+ return value;
4378
+ } catch (err) {
4379
+ if (err instanceof ParameterNotFound) {
4380
+ throw new Error(
4381
+ `fetchSeedUserPassword: SSM parameter "${path}" not found. Provision a SecureString at "${path}" with the dev user's password before re-running seed-demo-data.`
4382
+ );
4383
+ }
4384
+ throw err;
4385
+ }
4386
+ };
4387
+ var productionCognitoProvisioner = () => {
4388
+ const client = new CognitoIdentityProviderClient({});
4389
+ const userPoolId = process.env[SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR];
4390
+ if (!userPoolId || userPoolId.trim() === "") {
4391
+ throw new Error(
4392
+ `${SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR} is not set; the seed-demo-data Lambda cannot provision Cognito users without a user-pool id.`
4393
+ );
4394
+ }
4395
+ const subFromAttributes = (attrs) => {
4396
+ for (const attr of attrs ?? []) {
4397
+ if (attr.Name === "sub" && typeof attr.Value === "string") {
4398
+ return attr.Value;
4399
+ }
4400
+ }
4401
+ return void 0;
4402
+ };
4403
+ const setPassword = async (email, password) => {
4404
+ await client.send(
4405
+ new AdminSetUserPasswordCommand({
4406
+ UserPoolId: userPoolId,
4407
+ Username: email,
4408
+ Password: password,
4409
+ Permanent: true
4410
+ })
4411
+ );
4412
+ };
4413
+ return {
4414
+ ensureUser: async (email) => {
4415
+ const password = await fetchSeedUserPassword(email);
4416
+ try {
4417
+ const created = await client.send(
4418
+ new AdminCreateUserCommand({
4419
+ UserPoolId: userPoolId,
4420
+ Username: email,
4421
+ MessageAction: "SUPPRESS",
4422
+ UserAttributes: [
4423
+ { Name: "email", Value: email },
4424
+ { Name: "email_verified", Value: "true" }
4425
+ ]
4426
+ })
4427
+ );
4428
+ await setPassword(email, password);
4429
+ const sub = subFromAttributes(created.User?.Attributes);
4430
+ if (!sub) {
4431
+ throw new Error(
4432
+ `AdminCreateUser response for "${email}" did not carry a sub attribute.`
4433
+ );
4434
+ }
4435
+ return sub;
4436
+ } catch (err) {
4437
+ if (err instanceof UsernameExistsException) {
4438
+ await setPassword(email, password);
4439
+ const got = await client.send(
4440
+ new AdminGetUserCommand({
4441
+ UserPoolId: userPoolId,
4442
+ Username: email
4443
+ })
4444
+ );
4445
+ const sub = subFromAttributes(got.UserAttributes);
4446
+ if (!sub) {
4447
+ throw new Error(
4448
+ `AdminGetUser response for "${email}" did not carry a sub attribute.`
4449
+ );
4450
+ }
4451
+ return sub;
4452
+ }
4453
+ throw err;
4454
+ }
4455
+ }
4456
+ };
4457
+ };
4458
+ var productionDependencies = () => {
4459
+ const dynamodb = new DynamoDBClient({});
4460
+ const cognito = productionCognitoProvisioner();
4461
+ return {
4462
+ dedupClient: (0, import_workflows2.workflowDedupClient)(dynamodb),
4463
+ verifyRoles: verifySystemRolesExist,
4464
+ seedDemoGraph,
4465
+ cognito
4466
+ };
4467
+ };
4468
+ var handler = async (event) => runSeedDemoData(event, productionDependencies(), DEV_USERS);
4469
+
4470
+ export {
4471
+ import_workflows,
4472
+ SEED_DEMO_DATA_CONSUMER_NAME,
4473
+ DEMO_URN_SYSTEM,
4474
+ OPENHI_RESOURCE_URN_SYSTEM,
4475
+ DEMO_PERIOD,
4476
+ PLACEHOLDER_TENANT_ID,
4477
+ PLACEHOLDER_WORKSPACE_ID,
4478
+ ON_SITE_DEMO_TENANT_ID,
4479
+ ON_SITE_DEMO_WORKSPACE_ID,
4480
+ DEV_USERS,
4481
+ DEMO_TENANT_SPECS,
4482
+ demoMembershipId,
4483
+ demoRoleAssignmentId,
4484
+ demoScenarioIdentifier,
4485
+ openhiResourceIdentifier,
4486
+ demoRolesForUserInTenant,
4487
+ DIRECTOR_OF_NURSING_EXTENSION_URL,
4488
+ DIRECTOR_OF_NURSING_NAME_EXTENSION_URL,
4489
+ DIRECTOR_OF_NURSING_PHONE_EXTENSION_URL,
4490
+ DIRECTOR_OF_NURSING_EMAIL_EXTENSION_URL,
4491
+ ON_SITE_DEMO_FACILITIES,
4492
+ ON_SITE_DEMO_FACILITY_IDS,
4493
+ ON_SITE_DEMO_BLOCK_CAPACITY_EXTENSION_URL,
4494
+ ON_SITE_APPOINTMENT_TYPE_SYSTEM,
4495
+ BLOCK_OCCURRENCE_WEEKS_PAST,
4496
+ BLOCK_OCCURRENCE_WEEKS_FUTURE,
4497
+ BLOCK_OCCURRENCES_PER_TEMPLATE,
4498
+ ON_SITE_DEMO_BLOCK_TEMPLATE_IDS,
4499
+ buildOnSiteDemoBlockAppointments,
4500
+ findOnSiteDemoBlockTemplate,
4501
+ PATIENT_DEFAULT_CARE_SETTING_EXTENSION_URL,
4502
+ PATIENT_DEFAULT_CARE_LOCATION_EXTENSION_URL,
4503
+ PATIENT_RESIDENCY_ADMISSION_DATE_EXTENSION_URL,
4504
+ PATIENT_RESIDENCY_ROOM_EXTENSION_URL,
4505
+ PATIENT_ASSIGNED_BLOCK_TEMPLATE_EXTENSION_URL,
4506
+ PATIENT_HOSPICE_STATUS_EXTENSION_URL,
4507
+ HOSPICE_STATUS_VALUE_SUB_EXTENSION_URL,
4508
+ HOSPICE_EFFECTIVE_DATE_SUB_EXTENSION_URL,
4509
+ COVERAGE_VERIFICATION_DATE_EXTENSION_URL,
4510
+ COVERAGE_QMB_STATUS_EXTENSION_URL,
4511
+ QMB_STATUS_VALUE_SUB_EXTENSION_URL,
4512
+ QMB_EFFECTIVE_DATE_SUB_EXTENSION_URL,
4513
+ COVERAGE_PAYOR_TYPE_SYSTEM,
4514
+ PAYOR_TYPE_COMMERCIAL,
4515
+ PAYOR_TYPE_MEDICARE,
4516
+ PAYOR_TYPE_MEDICARE_ADVANTAGE,
4517
+ buildOnSiteDemoFacilityPatients,
4518
+ buildOnSiteDemoFacilityCoverages,
4519
+ onSiteDemoFacilityPatientIds,
4520
+ onSiteDemoScheduledFacilityPatientIds,
4521
+ onSiteDemoIntakeOnlyFacilityPatientIds,
4522
+ findOnSiteDemoFacilityPatientBlock,
4523
+ facilityPatientsForBlock,
4524
+ PATIENT_ASSIGNED_HOME_HEALTH_PROVIDER_EXTENSION_URL,
4525
+ HOME_HEALTH_VISIT_CADENCE_DAYS_EXTENSION_URL,
4526
+ HOME_HEALTH_VISIT_CADENCE_OPTIONS,
4527
+ TOTAL_HOME_HEALTH_PATIENTS,
4528
+ buildOnSiteDemoHomeHealthPatients,
4529
+ buildOnSiteDemoHomeHealthCoverages,
4530
+ onSiteDemoHomeHealthPatientIds,
4531
+ onSiteDemoScheduledHomeHealthPatientIds,
4532
+ onSiteDemoIntakeOnlyHomeHealthPatientIds,
4533
+ findOnSiteDemoHomeHealthPatientProvider,
4534
+ findOnSiteDemoHomeHealthPatientVisitCadenceDays,
4535
+ ENCOUNTER_CLASS_SYSTEM,
4536
+ ENCOUNTER_CLASS_FACILITY,
4537
+ ENCOUNTER_CLASS_HOME_HEALTH,
4538
+ LOINC_SYSTEM,
4539
+ SNOMED_SYSTEM,
4540
+ CPT_SYSTEM,
4541
+ WOUND_EXAM_PANEL_CODE,
4542
+ WOUND_EXAM_PANEL_DISPLAY,
4543
+ WOUND_LENGTH_CODE,
4544
+ WOUND_WIDTH_CODE,
4545
+ WOUND_DEPTH_CODE,
4546
+ WOUND_STATUS_CODE,
4547
+ CONDITION_CLINICAL_STATUS_SYSTEM,
4548
+ HOME_HEALTH_VISITS_PAST,
4549
+ woundConditionIdForPatient,
4550
+ __resetOnSiteDemoEncounterCachesForTests,
4551
+ buildOnSiteDemoEncounters,
4552
+ buildOnSiteDemoWoundConditions,
4553
+ buildOnSiteDemoWoundObservations,
4554
+ buildOnSiteDemoWoundProcedures,
4555
+ onSiteDemoEncounterIds,
4556
+ onSiteDemoEncountersForPatient,
4557
+ onSiteDemoEncounterMetadata,
4558
+ onSiteDemoWoundBearingPatientIds,
4559
+ onSiteDemoWoundProcedurePatientIds,
4560
+ CLAIM_WORKFLOW_STATUS_EXTENSION_URL,
4561
+ CLAIM_WORKFLOW_STATUS_VALUE_SUB_EXTENSION_URL,
4562
+ CLAIM_WORKFLOW_STATUS_LAST_TRANSITION_SUB_EXTENSION_URL,
4563
+ CLAIM_WORKFLOW_STATUS,
4564
+ PAYMENT_STATUS,
4565
+ PAYMENT_STATUS_SYSTEM,
4566
+ __resetOnSiteDemoClaimCachesForTests,
4567
+ buildOnSiteDemoClaims,
4568
+ buildOnSiteDemoPaymentNotices,
4569
+ onSiteDemoClaimIds,
4570
+ onSiteDemoPaymentNoticeIds,
4571
+ onSiteDemoUnbilledEncounterIds,
4572
+ onSiteDemoBilledEncounterIds,
4573
+ FHIR_ORGANIZATION_TYPE_SYSTEM,
4574
+ ON_SITE_DIRECTORY_CATEGORY_SYSTEM,
4575
+ DME_SUPPLIER_CATEGORY_CODE,
4576
+ INSURANCE_PAYOR_CATEGORY_CODE,
4577
+ INSURANCE_PAYOR_PLAN_TYPE_SYSTEM,
4578
+ PAYOR_PLAN_TYPE_COMMERCIAL,
4579
+ PAYOR_PLAN_TYPE_MEDICARE,
4580
+ PAYOR_PLAN_TYPE_MEDICARE_ADVANTAGE,
4581
+ PRACTITIONER_CREDENTIALING_EXTENSION_URL,
4582
+ PRACTITIONER_CREDENTIALING_STATE_SUB_EXTENSION_URL,
4583
+ PRACTITIONER_CREDENTIALING_STATUS_SUB_EXTENSION_URL,
4584
+ CREDENTIALING_STATUS,
4585
+ STATE_MEDICAL_LICENSE_SYSTEM,
4586
+ ON_SITE_DEMO_DME_SUPPLIERS,
4587
+ ON_SITE_DEMO_INSURANCE_PAYORS,
4588
+ onSiteDemoDmeSupplierIds,
4589
+ onSiteDemoInsurancePayorIds,
4590
+ ON_SITE_DEMO_DIRECTORY_ORGANIZATIONS,
4591
+ practitionerCredentialingForDoctor,
4592
+ practitionerCredentialingForState,
4593
+ buildCredentialingQualifications,
4594
+ US_NPI_SYSTEM,
4595
+ HOME_HEALTH_ELIGIBLE_EXTENSION_URL,
4596
+ PRACTITIONER_ROLE_PHYSICIAN,
4597
+ PRACTITIONER_ROLE_SCRIBE,
4598
+ ON_SITE_STAFF_ID_SYSTEM,
4599
+ ON_SITE_DEMO_DOCTORS,
4600
+ ON_SITE_DEMO_SCRIBES,
4601
+ ON_SITE_DEMO_DOCTOR_IDS,
4602
+ ON_SITE_DEMO_SCRIBE_IDS,
4603
+ homeHealthEligibleDoctors,
4604
+ ON_SITE_DEMO_FIXTURES,
4605
+ DEMO_DATA_PLANE_FIXTURES,
4606
+ SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR,
4607
+ seedDemoGraph,
4608
+ runSeedDemoData,
4609
+ SEED_USER_PASSWORD_PARAMETER_PREFIX,
4610
+ emailToSsmPath,
4611
+ __resetSsmClientForTests,
4612
+ fetchSeedUserPassword,
4613
+ productionCognitoProvisioner,
4614
+ handler
4615
+ };
4616
+ //# sourceMappingURL=chunk-7TRO2STL.mjs.map