@openhi/constructs 0.0.104 → 0.0.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/lib/chunk-2PM2NGXI.mjs +31 -0
- package/lib/chunk-2PM2NGXI.mjs.map +1 -0
- package/lib/chunk-AGF3RAAZ.mjs +20 -0
- package/lib/chunk-AGF3RAAZ.mjs.map +1 -0
- package/lib/chunk-AO3E22CS.mjs +108 -0
- package/lib/chunk-AO3E22CS.mjs.map +1 -0
- package/lib/chunk-CHPEQRXU.mjs +45 -0
- package/lib/chunk-CHPEQRXU.mjs.map +1 -0
- package/lib/chunk-JUNL76HF.mjs +428 -0
- package/lib/chunk-JUNL76HF.mjs.map +1 -0
- package/lib/chunk-L6UAP4KP.mjs +27 -0
- package/lib/chunk-L6UAP4KP.mjs.map +1 -0
- package/lib/{chunk-3QS3WKRC.mjs → chunk-LZOMFHX3.mjs} +9 -2
- package/lib/chunk-QMIOLLAS.mjs +531 -0
- package/lib/chunk-QMIOLLAS.mjs.map +1 -0
- package/lib/chunk-SYBADQXI.mjs +607 -0
- package/lib/chunk-SYBADQXI.mjs.map +1 -0
- package/lib/chunk-VXX4I3EF.mjs +19 -0
- package/lib/chunk-VXX4I3EF.mjs.map +1 -0
- package/lib/{chunk-MLTYFMSE.mjs → chunk-VYDIGFIX.mjs} +74 -29
- package/lib/chunk-VYDIGFIX.mjs.map +1 -0
- package/lib/chunk-YU2HRNUP.mjs +33 -0
- package/lib/chunk-YU2HRNUP.mjs.map +1 -0
- package/lib/chunk-YZZDUJHI.mjs +37 -0
- package/lib/chunk-YZZDUJHI.mjs.map +1 -0
- package/lib/cors-options-lambda.handler.mjs +1 -1
- package/lib/data-store-postgres-replication.handler.mjs +1 -1
- package/lib/events-BfrkMoBD.d.mts +44 -0
- package/lib/events-BfrkMoBD.d.ts +44 -0
- package/lib/events-CVA3_eEB.d.mts +23 -0
- package/lib/events-CVA3_eEB.d.ts +23 -0
- package/lib/events-DGep6C7w.d.mts +207 -0
- package/lib/events-DGep6C7w.d.ts +207 -0
- package/lib/firehose-archive-transform.handler.mjs +1 -1
- package/lib/index.d.mts +508 -29
- package/lib/index.d.ts +773 -30
- package/lib/index.js +2536 -105
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +899 -106
- package/lib/index.mjs.map +1 -1
- package/lib/openhi-context-CaBH8SFo.d.mts +39 -0
- package/lib/openhi-context-CaBH8SFo.d.ts +39 -0
- package/lib/platform-deploy-bridge.handler.d.mts +14 -0
- package/lib/platform-deploy-bridge.handler.d.ts +14 -0
- package/lib/platform-deploy-bridge.handler.js +762 -0
- package/lib/platform-deploy-bridge.handler.js.map +1 -0
- package/lib/platform-deploy-bridge.handler.mjs +134 -0
- package/lib/platform-deploy-bridge.handler.mjs.map +1 -0
- package/lib/post-authentication.handler.mjs +1 -1
- package/lib/post-confirmation.handler.js +50 -904
- package/lib/post-confirmation.handler.js.map +1 -1
- package/lib/post-confirmation.handler.mjs +37 -112
- package/lib/post-confirmation.handler.mjs.map +1 -1
- package/lib/pre-token-generation.handler.js +135 -55
- package/lib/pre-token-generation.handler.js.map +1 -1
- package/lib/pre-token-generation.handler.mjs +25 -32
- package/lib/pre-token-generation.handler.mjs.map +1 -1
- package/lib/provision-default-workspace.handler.d.mts +13 -0
- package/lib/provision-default-workspace.handler.d.ts +13 -0
- package/lib/provision-default-workspace.handler.js +1172 -0
- package/lib/provision-default-workspace.handler.js.map +1 -0
- package/lib/provision-default-workspace.handler.mjs +175 -0
- package/lib/provision-default-workspace.handler.mjs.map +1 -0
- package/lib/rest-api-lambda.handler.js +114 -59
- package/lib/rest-api-lambda.handler.js.map +1 -1
- package/lib/rest-api-lambda.handler.mjs +60 -587
- package/lib/rest-api-lambda.handler.mjs.map +1 -1
- package/lib/seed-demo-data.handler.d.mts +107 -0
- package/lib/seed-demo-data.handler.d.ts +107 -0
- package/lib/seed-demo-data.handler.js +2037 -0
- package/lib/seed-demo-data.handler.js.map +1 -0
- package/lib/seed-demo-data.handler.mjs +23 -0
- package/lib/seed-demo-data.handler.mjs.map +1 -0
- package/lib/seed-system-data.handler.d.mts +64 -0
- package/lib/seed-system-data.handler.d.ts +64 -0
- package/lib/seed-system-data.handler.js +1631 -0
- package/lib/seed-system-data.handler.js.map +1 -0
- package/lib/seed-system-data.handler.mjs +135 -0
- package/lib/seed-system-data.handler.mjs.map +1 -0
- package/package.json +4 -2
- package/lib/chunk-MLTYFMSE.mjs.map +0 -1
- /package/lib/{chunk-3QS3WKRC.mjs.map → chunk-LZOMFHX3.mjs.map} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/platform-deploy-bridge/index.md
|
|
3
|
+
*/
|
|
4
|
+
/** EventBridge `source` for the AWS-native CloudFormation events the bridge listens to. */
|
|
5
|
+
declare const CLOUDFORMATION_EVENT_SOURCE: "aws.cloudformation";
|
|
6
|
+
/** EventBridge `detail-type` for terminal stack status events. */
|
|
7
|
+
declare const CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE: "CloudFormation Stack Status Change";
|
|
8
|
+
/** Stack statuses the bridge republishes. Other statuses are pre-filtered at the rule. */
|
|
9
|
+
declare const BRIDGED_STATUSES: readonly ["CREATE_COMPLETE", "UPDATE_COMPLETE"];
|
|
10
|
+
type BridgedStatus = (typeof BRIDGED_STATUSES)[number];
|
|
11
|
+
/** Env var the bridge handler reads to discover the control event bus name. */
|
|
12
|
+
declare const CONTROL_EVENT_BUS_NAME_ENV_VAR = "CONTROL_EVENT_BUS_NAME";
|
|
13
|
+
/**
|
|
14
|
+
* Env var the bridge handler reads for the resolved
|
|
15
|
+
* `openhi:repo-name`-shaped tag key. Resolved at synth time from the host
|
|
16
|
+
* stack's `appName` + {@link OPENHI_TAG_SUFFIX_REPO_NAME}.
|
|
17
|
+
*/
|
|
18
|
+
declare const OPENHI_REPO_TAG_KEY_ENV_VAR = "OPENHI_REPO_TAG_KEY";
|
|
19
|
+
/**
|
|
20
|
+
* Env var the bridge handler reads for the resolved `openhi:` tag prefix.
|
|
21
|
+
* Resolved at synth time from the host stack's `appName`. Used to project
|
|
22
|
+
* the relevant stack tags into the published envelope.
|
|
23
|
+
*/
|
|
24
|
+
declare const OPENHI_TAG_KEY_PREFIX_ENV_VAR = "OPENHI_TAG_KEY_PREFIX";
|
|
25
|
+
/** Free-form `actor.system` value per TR-016 § Decision points #1 (bootstrap-role pattern). */
|
|
26
|
+
declare const PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM = "platform-deploy-bridge";
|
|
27
|
+
/**
|
|
28
|
+
* Subset of the CloudFormation Stack Status Change `detail` field the
|
|
29
|
+
* bridge handler reads. AWS-side schema lives at
|
|
30
|
+
* <https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/monitoring-cloudformation.html>.
|
|
31
|
+
*/
|
|
32
|
+
interface CloudFormationStackStatusChangeDetail {
|
|
33
|
+
readonly "stack-id": string;
|
|
34
|
+
readonly "logical-resource-id"?: string;
|
|
35
|
+
readonly "physical-resource-id"?: string;
|
|
36
|
+
readonly "status-details": {
|
|
37
|
+
readonly status: string;
|
|
38
|
+
readonly "status-reason"?: string;
|
|
39
|
+
};
|
|
40
|
+
readonly "resource-type"?: string;
|
|
41
|
+
readonly "client-request-token"?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { BRIDGED_STATUSES as B, CLOUDFORMATION_EVENT_SOURCE as C, OPENHI_REPO_TAG_KEY_ENV_VAR as O, PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM as P, type BridgedStatus as a, CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE as b, CONTROL_EVENT_BUS_NAME_ENV_VAR as c, type CloudFormationStackStatusChangeDetail as d, OPENHI_TAG_KEY_PREFIX_ENV_VAR as e };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/platform-deploy-bridge/index.md
|
|
3
|
+
*/
|
|
4
|
+
/** EventBridge `source` for the AWS-native CloudFormation events the bridge listens to. */
|
|
5
|
+
declare const CLOUDFORMATION_EVENT_SOURCE: "aws.cloudformation";
|
|
6
|
+
/** EventBridge `detail-type` for terminal stack status events. */
|
|
7
|
+
declare const CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE: "CloudFormation Stack Status Change";
|
|
8
|
+
/** Stack statuses the bridge republishes. Other statuses are pre-filtered at the rule. */
|
|
9
|
+
declare const BRIDGED_STATUSES: readonly ["CREATE_COMPLETE", "UPDATE_COMPLETE"];
|
|
10
|
+
type BridgedStatus = (typeof BRIDGED_STATUSES)[number];
|
|
11
|
+
/** Env var the bridge handler reads to discover the control event bus name. */
|
|
12
|
+
declare const CONTROL_EVENT_BUS_NAME_ENV_VAR = "CONTROL_EVENT_BUS_NAME";
|
|
13
|
+
/**
|
|
14
|
+
* Env var the bridge handler reads for the resolved
|
|
15
|
+
* `openhi:repo-name`-shaped tag key. Resolved at synth time from the host
|
|
16
|
+
* stack's `appName` + {@link OPENHI_TAG_SUFFIX_REPO_NAME}.
|
|
17
|
+
*/
|
|
18
|
+
declare const OPENHI_REPO_TAG_KEY_ENV_VAR = "OPENHI_REPO_TAG_KEY";
|
|
19
|
+
/**
|
|
20
|
+
* Env var the bridge handler reads for the resolved `openhi:` tag prefix.
|
|
21
|
+
* Resolved at synth time from the host stack's `appName`. Used to project
|
|
22
|
+
* the relevant stack tags into the published envelope.
|
|
23
|
+
*/
|
|
24
|
+
declare const OPENHI_TAG_KEY_PREFIX_ENV_VAR = "OPENHI_TAG_KEY_PREFIX";
|
|
25
|
+
/** Free-form `actor.system` value per TR-016 § Decision points #1 (bootstrap-role pattern). */
|
|
26
|
+
declare const PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM = "platform-deploy-bridge";
|
|
27
|
+
/**
|
|
28
|
+
* Subset of the CloudFormation Stack Status Change `detail` field the
|
|
29
|
+
* bridge handler reads. AWS-side schema lives at
|
|
30
|
+
* <https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/monitoring-cloudformation.html>.
|
|
31
|
+
*/
|
|
32
|
+
interface CloudFormationStackStatusChangeDetail {
|
|
33
|
+
readonly "stack-id": string;
|
|
34
|
+
readonly "logical-resource-id"?: string;
|
|
35
|
+
readonly "physical-resource-id"?: string;
|
|
36
|
+
readonly "status-details": {
|
|
37
|
+
readonly status: string;
|
|
38
|
+
readonly "status-reason"?: string;
|
|
39
|
+
};
|
|
40
|
+
readonly "resource-type"?: string;
|
|
41
|
+
readonly "client-request-token"?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { BRIDGED_STATUSES as B, CLOUDFORMATION_EVENT_SOURCE as C, OPENHI_REPO_TAG_KEY_ENV_VAR as O, PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM as P, type BridgedStatus as a, CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE as b, CONTROL_EVENT_BUS_NAME_ENV_VAR as c, type CloudFormationStackStatusChangeDetail as d, OPENHI_TAG_KEY_PREFIX_ENV_VAR as e };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PostConfirmationTriggerEvent } from 'aws-lambda';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/user-onboarding/events.md
|
|
5
|
+
*/
|
|
6
|
+
declare const USER_ONBOARDING_EVENT_SOURCE = "openhi.control.user-onboarding";
|
|
7
|
+
declare const PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE = "ProvisionDefaultWorkspaceRequested";
|
|
8
|
+
interface ProvisionDefaultWorkspaceRequestedDetail {
|
|
9
|
+
readonly cognitoSub: string;
|
|
10
|
+
readonly userId?: string;
|
|
11
|
+
readonly email?: string;
|
|
12
|
+
readonly displayName?: string;
|
|
13
|
+
readonly trigger: {
|
|
14
|
+
readonly source: "cognito.post-confirmation";
|
|
15
|
+
readonly triggerSource?: string;
|
|
16
|
+
readonly userPoolId?: string;
|
|
17
|
+
readonly userName?: string;
|
|
18
|
+
readonly clientId?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
declare const buildProvisionDefaultWorkspaceRequestedDetail: (event: PostConfirmationTriggerEvent) => ProvisionDefaultWorkspaceRequestedDetail | undefined;
|
|
22
|
+
|
|
23
|
+
export { PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE as P, USER_ONBOARDING_EVENT_SOURCE as U, type ProvisionDefaultWorkspaceRequestedDetail as a, buildProvisionDefaultWorkspaceRequestedDetail as b };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PostConfirmationTriggerEvent } from 'aws-lambda';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/user-onboarding/events.md
|
|
5
|
+
*/
|
|
6
|
+
declare const USER_ONBOARDING_EVENT_SOURCE = "openhi.control.user-onboarding";
|
|
7
|
+
declare const PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE = "ProvisionDefaultWorkspaceRequested";
|
|
8
|
+
interface ProvisionDefaultWorkspaceRequestedDetail {
|
|
9
|
+
readonly cognitoSub: string;
|
|
10
|
+
readonly userId?: string;
|
|
11
|
+
readonly email?: string;
|
|
12
|
+
readonly displayName?: string;
|
|
13
|
+
readonly trigger: {
|
|
14
|
+
readonly source: "cognito.post-confirmation";
|
|
15
|
+
readonly triggerSource?: string;
|
|
16
|
+
readonly userPoolId?: string;
|
|
17
|
+
readonly userName?: string;
|
|
18
|
+
readonly clientId?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
declare const buildProvisionDefaultWorkspaceRequestedDetail: (event: PostConfirmationTriggerEvent) => ProvisionDefaultWorkspaceRequestedDetail | undefined;
|
|
22
|
+
|
|
23
|
+
export { PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE as P, USER_ONBOARDING_EVENT_SOURCE as U, type ProvisionDefaultWorkspaceRequestedDetail as a, buildProvisionDefaultWorkspaceRequestedDetail as b };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { ControlPlaneRoleCode } from '@openhi/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/seed-demo-data/events.md
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Stable logical name this workflow registers with the shared
|
|
8
|
+
* `WorkflowDedupTable` (TR-015). Used in both the construct grant
|
|
9
|
+
* (`workflowDedupTable.grantConsumer(lambda, SEED_DEMO_DATA_CONSUMER_NAME)`)
|
|
10
|
+
* and the handler's runtime `recordIfAbsent` call — keep them aligned by
|
|
11
|
+
* importing this constant in both places.
|
|
12
|
+
*/
|
|
13
|
+
declare const SEED_DEMO_DATA_CONSUMER_NAME = "seed-demo-data";
|
|
14
|
+
/** FHIR `Identifier.system` for the demo-scenario URN scheme. */
|
|
15
|
+
declare const DEMO_URN_SYSTEM = "urn:openhi:demo";
|
|
16
|
+
/**
|
|
17
|
+
* FHIR `Identifier.system` for the canonical OpenHI resource URN
|
|
18
|
+
* (ADR 2026-03-12-01). The value form is
|
|
19
|
+
* `urn:ohi:<tenantId>:<workspaceId>:<resourceType>:<id>`; empty
|
|
20
|
+
* workspaceId means the resource has tenant-wide scope (or is itself
|
|
21
|
+
* the workspace identity, in the Workspace case).
|
|
22
|
+
*/
|
|
23
|
+
declare const OPENHI_RESOURCE_URN_SYSTEM = "http://openhi.org/";
|
|
24
|
+
/**
|
|
25
|
+
* Period stamped on every demo Membership and RoleAssignment. Fixed
|
|
26
|
+
* start so re-runs produce byte-identical bodies (decision #4); no
|
|
27
|
+
* end so demo memberships are open-ended.
|
|
28
|
+
*/
|
|
29
|
+
declare const DEMO_PERIOD: {
|
|
30
|
+
readonly start: "2026-01-01T00:00:00Z";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Sentinel `tenantId` used on every dev user's `system-admin`
|
|
34
|
+
* RoleAssignment. A `system-admin` RA is platform-scoped (it spans
|
|
35
|
+
* every tenant), but the RoleAssignment entity requires a tenantId on
|
|
36
|
+
* its key for sharding — there is no real tenant to point at. The
|
|
37
|
+
* `"platform"` literal is a reserved value that never matches a real
|
|
38
|
+
* Tenant id and signals "this RA scopes across all tenants".
|
|
39
|
+
*
|
|
40
|
+
* Renaming this constant is a wire-format break — the IAM grant in
|
|
41
|
+
* `seed-demo-data-lambda.ts` enumerates exact-match `LeadingKeys`
|
|
42
|
+
* computed from this value, and the in-band records written under it
|
|
43
|
+
* become unreachable if the sentinel changes.
|
|
44
|
+
*/
|
|
45
|
+
declare const PLATFORM_SCOPE_TENANT_ID = "platform";
|
|
46
|
+
/** Placeholder Tenant id seeded by the workflow as the dev-user `currentTenant`. */
|
|
47
|
+
declare const PLACEHOLDER_TENANT_ID = "placeholder-tenant-id";
|
|
48
|
+
/** Placeholder Workspace id seeded by the workflow as the dev-user `currentWorkspace`. */
|
|
49
|
+
declare const PLACEHOLDER_WORKSPACE_ID = "placeholder-workspace-id";
|
|
50
|
+
/**
|
|
51
|
+
* Dev-user descriptor. Every entry produces:
|
|
52
|
+
* - one Cognito user (idempotent create-then-skip),
|
|
53
|
+
* - one DynamoDB User record (id = `dev-<email-local-part>`),
|
|
54
|
+
* - four Memberships (placeholder + the three demo tenants),
|
|
55
|
+
* - four `tenant-admin` RoleAssignments (one per tenant the user
|
|
56
|
+
* belongs to),
|
|
57
|
+
* - one `system-admin` RoleAssignment scoped to {@link PLATFORM_SCOPE_TENANT_ID}.
|
|
58
|
+
*/
|
|
59
|
+
interface DemoDevUser {
|
|
60
|
+
/** Stable DynamoDB User id. */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Email used as the Cognito `Username` and as the seed for the password algorithm. */
|
|
63
|
+
readonly email: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Hardcoded dev-user roster. Adding a new developer is a one-line
|
|
67
|
+
* change here plus a re-deploy. The list intentionally lives in-source
|
|
68
|
+
* (not behind an env-var seam) so the IAM grant in
|
|
69
|
+
* `seed-demo-data-lambda.ts` can enumerate per-user PKs at synth time.
|
|
70
|
+
*/
|
|
71
|
+
declare const DEV_USERS: ReadonlyArray<DemoDevUser>;
|
|
72
|
+
/**
|
|
73
|
+
* A single workspace inside a demo tenant. The mixed tenant has two
|
|
74
|
+
* workspaces (wound-care and primary-care sub-workspaces); the other
|
|
75
|
+
* two tenants have one each.
|
|
76
|
+
*/
|
|
77
|
+
interface DemoWorkspaceSpec {
|
|
78
|
+
/** Stable id (DynamoDB record id; also drives the canonical OHI URN). */
|
|
79
|
+
readonly id: string;
|
|
80
|
+
/** FHIR `Workspace.name`. */
|
|
81
|
+
readonly name: string;
|
|
82
|
+
/**
|
|
83
|
+
* Role suffix used in the demo URN value (`<scenario>:<roleSuffix>`).
|
|
84
|
+
* Mirrors seed-fixtures' role suffix convention: `workspace` for
|
|
85
|
+
* single-workspace tenants, `workspace-<sub>` for the mixed tenant.
|
|
86
|
+
*/
|
|
87
|
+
readonly roleSuffix: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* One demo tenant + the workspaces it owns. Re-exported via {@link
|
|
91
|
+
* DEMO_TENANT_SPECS} as the canonical list; iterate that constant in
|
|
92
|
+
* the handler and the IAM-grant builder so the value sets agree.
|
|
93
|
+
*/
|
|
94
|
+
interface DemoTenantSpec {
|
|
95
|
+
/**
|
|
96
|
+
* Scenario slug — `placeholder`, `demo-wound-care`, `demo-primary-care`,
|
|
97
|
+
* `demo-mixed`. The placeholder tenant's slug is `placeholder`; the
|
|
98
|
+
* three demo tenants mirror seed-fixtures' `fixture-*` slugs renamed
|
|
99
|
+
* to `demo-*`.
|
|
100
|
+
*/
|
|
101
|
+
readonly scenario: string;
|
|
102
|
+
/** Stable id (DynamoDB record id; also drives the canonical OHI URN). */
|
|
103
|
+
readonly tenantId: string;
|
|
104
|
+
/** FHIR `Tenant.name`. */
|
|
105
|
+
readonly tenantName: string;
|
|
106
|
+
/** Workspaces owned by this tenant. */
|
|
107
|
+
readonly workspaces: ReadonlyArray<DemoWorkspaceSpec>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The full demo-tenant graph. Four entries: the placeholder tenant the
|
|
111
|
+
* JWT-claim fallback resolves to, plus the three v1 demo scenarios
|
|
112
|
+
* (OPS-009 §"v1 scenarios"):
|
|
113
|
+
*
|
|
114
|
+
* 0. Placeholder tenant — dereferences the JWT-claim fallback in
|
|
115
|
+
* `pre-token-generation.handler.ts` and acts as every dev user's
|
|
116
|
+
* `currentTenant`/`currentWorkspace` so Post-Confirmation skips
|
|
117
|
+
* default provisioning when a seeded User signs in.
|
|
118
|
+
* 1. Single-workspace wound-care tenant.
|
|
119
|
+
* 2. Single-workspace primary-care tenant.
|
|
120
|
+
* 3. Two-workspace mixed tenant — exercises the cross-workspace
|
|
121
|
+
* isolation flow that single-workspace tenants cannot.
|
|
122
|
+
*/
|
|
123
|
+
declare const DEMO_TENANT_SPECS: ReadonlyArray<DemoTenantSpec>;
|
|
124
|
+
/** Stable Membership id derived from `(devUserId, tenantId)`. */
|
|
125
|
+
declare const demoMembershipId: (devUserId: string, tenantId: string) => string;
|
|
126
|
+
/**
|
|
127
|
+
* Stable RoleAssignment id derived from `(devUserId, tenantId, roleCode)`.
|
|
128
|
+
* Each (user, tenant, role) tuple maps to exactly one record — re-runs
|
|
129
|
+
* upsert the same id.
|
|
130
|
+
*/
|
|
131
|
+
declare const demoRoleAssignmentId: (devUserId: string, tenantId: string, roleCode: ControlPlaneRoleCode) => string;
|
|
132
|
+
/**
|
|
133
|
+
* Demo-scenario FHIR `Identifier` entry — `urn:openhi:demo:<scenario>:<role>`.
|
|
134
|
+
* Mirrors the `urn:openhi:fixture:<scenario>:<role>` pattern from
|
|
135
|
+
* `@openhi/seed-fixtures/src/urn.ts`, renamed to the `demo` namespace.
|
|
136
|
+
*/
|
|
137
|
+
declare const demoScenarioIdentifier: (scenario: string, roleSuffix: string) => {
|
|
138
|
+
system: string;
|
|
139
|
+
value: string;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Canonical OpenHI resource FHIR `Identifier` entry per ADR
|
|
143
|
+
* 2026-03-12-01. `workspaceId` is empty for both Tenant resources and
|
|
144
|
+
* Workspace resources — for a Tenant, the resource is tenant-scoped
|
|
145
|
+
* with no workspace context; for a Workspace, the resource IS the
|
|
146
|
+
* workspace identity rather than living inside one.
|
|
147
|
+
*/
|
|
148
|
+
declare const openhiResourceIdentifier: (params: {
|
|
149
|
+
tenantId: string;
|
|
150
|
+
workspaceId: string;
|
|
151
|
+
resourceType: string;
|
|
152
|
+
id: string;
|
|
153
|
+
}) => {
|
|
154
|
+
use: string;
|
|
155
|
+
system: string;
|
|
156
|
+
value: string;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Roles every dev user holds in every tenant they belong to. Per scope
|
|
160
|
+
* decision Q3, every dev user is `tenant-admin` in every tenant — there
|
|
161
|
+
* is no per-(user, tenant) variance to drive from.
|
|
162
|
+
*/
|
|
163
|
+
declare const demoRolesForUserInTenant: (_user: DemoDevUser, _tenantId: string) => ReadonlyArray<ControlPlaneRoleCode>;
|
|
164
|
+
/**
|
|
165
|
+
* DynamoDB single-table partition-key builders. The IAM grant in
|
|
166
|
+
* `seed-demo-data-lambda.ts` uses these to enumerate exact-match
|
|
167
|
+
* `dynamodb:LeadingKeys` values; the entity definitions in
|
|
168
|
+
* `data/dynamo/entities/control/` own the canonical key templates.
|
|
169
|
+
*
|
|
170
|
+
* These builders MUST emit the keys ElectroDB actually writes — not
|
|
171
|
+
* the entity definition's pretty template. None of the control-plane
|
|
172
|
+
* entities sets `casing: "none"` on the base-table PK template, so
|
|
173
|
+
* ElectroDB applies its default lowercase casing at runtime: the
|
|
174
|
+
* entity's `ROLE#ID#${id}` becomes `role#id#<id>` on the wire. A
|
|
175
|
+
* builder that returns the uppercase template form produces a
|
|
176
|
+
* silently-broken IAM grant (every PutItem denied with "no
|
|
177
|
+
* identity-based policy allows" because the request's leading-key
|
|
178
|
+
* never matches a policy value).
|
|
179
|
+
*/
|
|
180
|
+
declare const rolePartitionKey: (roleId: string) => string;
|
|
181
|
+
declare const demoTenantPartitionKey: (tenantId: string) => string;
|
|
182
|
+
declare const demoWorkspacePartitionKey: (tenantId: string, workspaceId: string) => string;
|
|
183
|
+
declare const demoMembershipPartitionKey: (tenantId: string, membershipId: string) => string;
|
|
184
|
+
declare const demoRoleAssignmentPartitionKey: (tenantId: string, roleAssignmentId: string) => string;
|
|
185
|
+
/** User entity PK template — `USER#ID#<id>` → `user#id#<id>` on the wire. */
|
|
186
|
+
declare const demoUserPartitionKey: (userId: string) => string;
|
|
187
|
+
/**
|
|
188
|
+
* Tenant + Workspace PKs the workflow writes on every fire: the 4
|
|
189
|
+
* tenant PKs (placeholder + 3 demo) plus their workspaces (1 + 1 + 1 + 2 = 5).
|
|
190
|
+
*/
|
|
191
|
+
declare const demoBasePartitionKeys: () => ReadonlyArray<string>;
|
|
192
|
+
/**
|
|
193
|
+
* Membership + RoleAssignment + User PKs the workflow writes per dev
|
|
194
|
+
* user. Empty when `devUsers` is empty (used by tests). The list
|
|
195
|
+
* mirrors the handler's iteration order so the IAM grant covers every
|
|
196
|
+
* write the handler can make.
|
|
197
|
+
*
|
|
198
|
+
* Per dev user the function emits:
|
|
199
|
+
* - one User PK,
|
|
200
|
+
* - per tenant in {@link DEMO_TENANT_SPECS}: one Membership PK plus
|
|
201
|
+
* one `tenant-admin` RoleAssignment PK,
|
|
202
|
+
* - one platform-scoped `system-admin` RoleAssignment PK keyed by
|
|
203
|
+
* {@link PLATFORM_SCOPE_TENANT_ID}.
|
|
204
|
+
*/
|
|
205
|
+
declare const demoDevUserPartitionKeys: (devUsers: ReadonlyArray<DemoDevUser>) => ReadonlyArray<string>;
|
|
206
|
+
|
|
207
|
+
export { DEMO_PERIOD as D, OPENHI_RESOURCE_URN_SYSTEM as O, PLACEHOLDER_TENANT_ID as P, SEED_DEMO_DATA_CONSUMER_NAME as S, DEMO_TENANT_SPECS as a, DEMO_URN_SYSTEM as b, DEV_USERS as c, type DemoDevUser as d, type DemoTenantSpec as e, type DemoWorkspaceSpec as f, PLACEHOLDER_WORKSPACE_ID as g, PLATFORM_SCOPE_TENANT_ID as h, demoBasePartitionKeys as i, demoDevUserPartitionKeys as j, demoMembershipId as k, demoMembershipPartitionKey as l, demoRoleAssignmentId as m, demoRoleAssignmentPartitionKey as n, demoRolesForUserInTenant as o, demoScenarioIdentifier as p, demoTenantPartitionKey as q, demoUserPartitionKey as r, demoWorkspacePartitionKey as s, openhiResourceIdentifier as t, rolePartitionKey as u };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { ControlPlaneRoleCode } from '@openhi/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see sites/www-docs/content/packages/@openhi/constructs/workflows/control-plane/seed-demo-data/events.md
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Stable logical name this workflow registers with the shared
|
|
8
|
+
* `WorkflowDedupTable` (TR-015). Used in both the construct grant
|
|
9
|
+
* (`workflowDedupTable.grantConsumer(lambda, SEED_DEMO_DATA_CONSUMER_NAME)`)
|
|
10
|
+
* and the handler's runtime `recordIfAbsent` call — keep them aligned by
|
|
11
|
+
* importing this constant in both places.
|
|
12
|
+
*/
|
|
13
|
+
declare const SEED_DEMO_DATA_CONSUMER_NAME = "seed-demo-data";
|
|
14
|
+
/** FHIR `Identifier.system` for the demo-scenario URN scheme. */
|
|
15
|
+
declare const DEMO_URN_SYSTEM = "urn:openhi:demo";
|
|
16
|
+
/**
|
|
17
|
+
* FHIR `Identifier.system` for the canonical OpenHI resource URN
|
|
18
|
+
* (ADR 2026-03-12-01). The value form is
|
|
19
|
+
* `urn:ohi:<tenantId>:<workspaceId>:<resourceType>:<id>`; empty
|
|
20
|
+
* workspaceId means the resource has tenant-wide scope (or is itself
|
|
21
|
+
* the workspace identity, in the Workspace case).
|
|
22
|
+
*/
|
|
23
|
+
declare const OPENHI_RESOURCE_URN_SYSTEM = "http://openhi.org/";
|
|
24
|
+
/**
|
|
25
|
+
* Period stamped on every demo Membership and RoleAssignment. Fixed
|
|
26
|
+
* start so re-runs produce byte-identical bodies (decision #4); no
|
|
27
|
+
* end so demo memberships are open-ended.
|
|
28
|
+
*/
|
|
29
|
+
declare const DEMO_PERIOD: {
|
|
30
|
+
readonly start: "2026-01-01T00:00:00Z";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Sentinel `tenantId` used on every dev user's `system-admin`
|
|
34
|
+
* RoleAssignment. A `system-admin` RA is platform-scoped (it spans
|
|
35
|
+
* every tenant), but the RoleAssignment entity requires a tenantId on
|
|
36
|
+
* its key for sharding — there is no real tenant to point at. The
|
|
37
|
+
* `"platform"` literal is a reserved value that never matches a real
|
|
38
|
+
* Tenant id and signals "this RA scopes across all tenants".
|
|
39
|
+
*
|
|
40
|
+
* Renaming this constant is a wire-format break — the IAM grant in
|
|
41
|
+
* `seed-demo-data-lambda.ts` enumerates exact-match `LeadingKeys`
|
|
42
|
+
* computed from this value, and the in-band records written under it
|
|
43
|
+
* become unreachable if the sentinel changes.
|
|
44
|
+
*/
|
|
45
|
+
declare const PLATFORM_SCOPE_TENANT_ID = "platform";
|
|
46
|
+
/** Placeholder Tenant id seeded by the workflow as the dev-user `currentTenant`. */
|
|
47
|
+
declare const PLACEHOLDER_TENANT_ID = "placeholder-tenant-id";
|
|
48
|
+
/** Placeholder Workspace id seeded by the workflow as the dev-user `currentWorkspace`. */
|
|
49
|
+
declare const PLACEHOLDER_WORKSPACE_ID = "placeholder-workspace-id";
|
|
50
|
+
/**
|
|
51
|
+
* Dev-user descriptor. Every entry produces:
|
|
52
|
+
* - one Cognito user (idempotent create-then-skip),
|
|
53
|
+
* - one DynamoDB User record (id = `dev-<email-local-part>`),
|
|
54
|
+
* - four Memberships (placeholder + the three demo tenants),
|
|
55
|
+
* - four `tenant-admin` RoleAssignments (one per tenant the user
|
|
56
|
+
* belongs to),
|
|
57
|
+
* - one `system-admin` RoleAssignment scoped to {@link PLATFORM_SCOPE_TENANT_ID}.
|
|
58
|
+
*/
|
|
59
|
+
interface DemoDevUser {
|
|
60
|
+
/** Stable DynamoDB User id. */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Email used as the Cognito `Username` and as the seed for the password algorithm. */
|
|
63
|
+
readonly email: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Hardcoded dev-user roster. Adding a new developer is a one-line
|
|
67
|
+
* change here plus a re-deploy. The list intentionally lives in-source
|
|
68
|
+
* (not behind an env-var seam) so the IAM grant in
|
|
69
|
+
* `seed-demo-data-lambda.ts` can enumerate per-user PKs at synth time.
|
|
70
|
+
*/
|
|
71
|
+
declare const DEV_USERS: ReadonlyArray<DemoDevUser>;
|
|
72
|
+
/**
|
|
73
|
+
* A single workspace inside a demo tenant. The mixed tenant has two
|
|
74
|
+
* workspaces (wound-care and primary-care sub-workspaces); the other
|
|
75
|
+
* two tenants have one each.
|
|
76
|
+
*/
|
|
77
|
+
interface DemoWorkspaceSpec {
|
|
78
|
+
/** Stable id (DynamoDB record id; also drives the canonical OHI URN). */
|
|
79
|
+
readonly id: string;
|
|
80
|
+
/** FHIR `Workspace.name`. */
|
|
81
|
+
readonly name: string;
|
|
82
|
+
/**
|
|
83
|
+
* Role suffix used in the demo URN value (`<scenario>:<roleSuffix>`).
|
|
84
|
+
* Mirrors seed-fixtures' role suffix convention: `workspace` for
|
|
85
|
+
* single-workspace tenants, `workspace-<sub>` for the mixed tenant.
|
|
86
|
+
*/
|
|
87
|
+
readonly roleSuffix: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* One demo tenant + the workspaces it owns. Re-exported via {@link
|
|
91
|
+
* DEMO_TENANT_SPECS} as the canonical list; iterate that constant in
|
|
92
|
+
* the handler and the IAM-grant builder so the value sets agree.
|
|
93
|
+
*/
|
|
94
|
+
interface DemoTenantSpec {
|
|
95
|
+
/**
|
|
96
|
+
* Scenario slug — `placeholder`, `demo-wound-care`, `demo-primary-care`,
|
|
97
|
+
* `demo-mixed`. The placeholder tenant's slug is `placeholder`; the
|
|
98
|
+
* three demo tenants mirror seed-fixtures' `fixture-*` slugs renamed
|
|
99
|
+
* to `demo-*`.
|
|
100
|
+
*/
|
|
101
|
+
readonly scenario: string;
|
|
102
|
+
/** Stable id (DynamoDB record id; also drives the canonical OHI URN). */
|
|
103
|
+
readonly tenantId: string;
|
|
104
|
+
/** FHIR `Tenant.name`. */
|
|
105
|
+
readonly tenantName: string;
|
|
106
|
+
/** Workspaces owned by this tenant. */
|
|
107
|
+
readonly workspaces: ReadonlyArray<DemoWorkspaceSpec>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The full demo-tenant graph. Four entries: the placeholder tenant the
|
|
111
|
+
* JWT-claim fallback resolves to, plus the three v1 demo scenarios
|
|
112
|
+
* (OPS-009 §"v1 scenarios"):
|
|
113
|
+
*
|
|
114
|
+
* 0. Placeholder tenant — dereferences the JWT-claim fallback in
|
|
115
|
+
* `pre-token-generation.handler.ts` and acts as every dev user's
|
|
116
|
+
* `currentTenant`/`currentWorkspace` so Post-Confirmation skips
|
|
117
|
+
* default provisioning when a seeded User signs in.
|
|
118
|
+
* 1. Single-workspace wound-care tenant.
|
|
119
|
+
* 2. Single-workspace primary-care tenant.
|
|
120
|
+
* 3. Two-workspace mixed tenant — exercises the cross-workspace
|
|
121
|
+
* isolation flow that single-workspace tenants cannot.
|
|
122
|
+
*/
|
|
123
|
+
declare const DEMO_TENANT_SPECS: ReadonlyArray<DemoTenantSpec>;
|
|
124
|
+
/** Stable Membership id derived from `(devUserId, tenantId)`. */
|
|
125
|
+
declare const demoMembershipId: (devUserId: string, tenantId: string) => string;
|
|
126
|
+
/**
|
|
127
|
+
* Stable RoleAssignment id derived from `(devUserId, tenantId, roleCode)`.
|
|
128
|
+
* Each (user, tenant, role) tuple maps to exactly one record — re-runs
|
|
129
|
+
* upsert the same id.
|
|
130
|
+
*/
|
|
131
|
+
declare const demoRoleAssignmentId: (devUserId: string, tenantId: string, roleCode: ControlPlaneRoleCode) => string;
|
|
132
|
+
/**
|
|
133
|
+
* Demo-scenario FHIR `Identifier` entry — `urn:openhi:demo:<scenario>:<role>`.
|
|
134
|
+
* Mirrors the `urn:openhi:fixture:<scenario>:<role>` pattern from
|
|
135
|
+
* `@openhi/seed-fixtures/src/urn.ts`, renamed to the `demo` namespace.
|
|
136
|
+
*/
|
|
137
|
+
declare const demoScenarioIdentifier: (scenario: string, roleSuffix: string) => {
|
|
138
|
+
system: string;
|
|
139
|
+
value: string;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Canonical OpenHI resource FHIR `Identifier` entry per ADR
|
|
143
|
+
* 2026-03-12-01. `workspaceId` is empty for both Tenant resources and
|
|
144
|
+
* Workspace resources — for a Tenant, the resource is tenant-scoped
|
|
145
|
+
* with no workspace context; for a Workspace, the resource IS the
|
|
146
|
+
* workspace identity rather than living inside one.
|
|
147
|
+
*/
|
|
148
|
+
declare const openhiResourceIdentifier: (params: {
|
|
149
|
+
tenantId: string;
|
|
150
|
+
workspaceId: string;
|
|
151
|
+
resourceType: string;
|
|
152
|
+
id: string;
|
|
153
|
+
}) => {
|
|
154
|
+
use: string;
|
|
155
|
+
system: string;
|
|
156
|
+
value: string;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Roles every dev user holds in every tenant they belong to. Per scope
|
|
160
|
+
* decision Q3, every dev user is `tenant-admin` in every tenant — there
|
|
161
|
+
* is no per-(user, tenant) variance to drive from.
|
|
162
|
+
*/
|
|
163
|
+
declare const demoRolesForUserInTenant: (_user: DemoDevUser, _tenantId: string) => ReadonlyArray<ControlPlaneRoleCode>;
|
|
164
|
+
/**
|
|
165
|
+
* DynamoDB single-table partition-key builders. The IAM grant in
|
|
166
|
+
* `seed-demo-data-lambda.ts` uses these to enumerate exact-match
|
|
167
|
+
* `dynamodb:LeadingKeys` values; the entity definitions in
|
|
168
|
+
* `data/dynamo/entities/control/` own the canonical key templates.
|
|
169
|
+
*
|
|
170
|
+
* These builders MUST emit the keys ElectroDB actually writes — not
|
|
171
|
+
* the entity definition's pretty template. None of the control-plane
|
|
172
|
+
* entities sets `casing: "none"` on the base-table PK template, so
|
|
173
|
+
* ElectroDB applies its default lowercase casing at runtime: the
|
|
174
|
+
* entity's `ROLE#ID#${id}` becomes `role#id#<id>` on the wire. A
|
|
175
|
+
* builder that returns the uppercase template form produces a
|
|
176
|
+
* silently-broken IAM grant (every PutItem denied with "no
|
|
177
|
+
* identity-based policy allows" because the request's leading-key
|
|
178
|
+
* never matches a policy value).
|
|
179
|
+
*/
|
|
180
|
+
declare const rolePartitionKey: (roleId: string) => string;
|
|
181
|
+
declare const demoTenantPartitionKey: (tenantId: string) => string;
|
|
182
|
+
declare const demoWorkspacePartitionKey: (tenantId: string, workspaceId: string) => string;
|
|
183
|
+
declare const demoMembershipPartitionKey: (tenantId: string, membershipId: string) => string;
|
|
184
|
+
declare const demoRoleAssignmentPartitionKey: (tenantId: string, roleAssignmentId: string) => string;
|
|
185
|
+
/** User entity PK template — `USER#ID#<id>` → `user#id#<id>` on the wire. */
|
|
186
|
+
declare const demoUserPartitionKey: (userId: string) => string;
|
|
187
|
+
/**
|
|
188
|
+
* Tenant + Workspace PKs the workflow writes on every fire: the 4
|
|
189
|
+
* tenant PKs (placeholder + 3 demo) plus their workspaces (1 + 1 + 1 + 2 = 5).
|
|
190
|
+
*/
|
|
191
|
+
declare const demoBasePartitionKeys: () => ReadonlyArray<string>;
|
|
192
|
+
/**
|
|
193
|
+
* Membership + RoleAssignment + User PKs the workflow writes per dev
|
|
194
|
+
* user. Empty when `devUsers` is empty (used by tests). The list
|
|
195
|
+
* mirrors the handler's iteration order so the IAM grant covers every
|
|
196
|
+
* write the handler can make.
|
|
197
|
+
*
|
|
198
|
+
* Per dev user the function emits:
|
|
199
|
+
* - one User PK,
|
|
200
|
+
* - per tenant in {@link DEMO_TENANT_SPECS}: one Membership PK plus
|
|
201
|
+
* one `tenant-admin` RoleAssignment PK,
|
|
202
|
+
* - one platform-scoped `system-admin` RoleAssignment PK keyed by
|
|
203
|
+
* {@link PLATFORM_SCOPE_TENANT_ID}.
|
|
204
|
+
*/
|
|
205
|
+
declare const demoDevUserPartitionKeys: (devUsers: ReadonlyArray<DemoDevUser>) => ReadonlyArray<string>;
|
|
206
|
+
|
|
207
|
+
export { DEMO_PERIOD as D, OPENHI_RESOURCE_URN_SYSTEM as O, PLACEHOLDER_TENANT_ID as P, SEED_DEMO_DATA_CONSUMER_NAME as S, DEMO_TENANT_SPECS as a, DEMO_URN_SYSTEM as b, DEV_USERS as c, type DemoDevUser as d, type DemoTenantSpec as e, type DemoWorkspaceSpec as f, PLACEHOLDER_WORKSPACE_ID as g, PLATFORM_SCOPE_TENANT_ID as h, demoBasePartitionKeys as i, demoDevUserPartitionKeys as j, demoMembershipId as k, demoMembershipPartitionKey as l, demoRoleAssignmentId as m, demoRoleAssignmentPartitionKey as n, demoRolesForUserInTenant as o, demoScenarioIdentifier as p, demoTenantPartitionKey as q, demoUserPartitionKey as r, demoWorkspacePartitionKey as s, openhiResourceIdentifier as t, rolePartitionKey as u };
|