@openhi/constructs 0.0.111 → 0.0.112

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 (111) hide show
  1. package/lib/chunk-23PUSHBV.mjs +24 -0
  2. package/lib/chunk-23PUSHBV.mjs.map +1 -0
  3. package/lib/{chunk-7FUAMZOF.mjs → chunk-53OHXLIL.mjs} +3 -3
  4. package/lib/chunk-6NBGYGFL.mjs +1803 -0
  5. package/lib/chunk-6NBGYGFL.mjs.map +1 -0
  6. package/lib/chunk-7RZHFI77.mjs +22 -0
  7. package/lib/chunk-7RZHFI77.mjs.map +1 -0
  8. package/lib/{chunk-7Q2IJ2J5.mjs → chunk-CUUKXDB2.mjs} +6 -6
  9. package/lib/chunk-FYHBHHWK.mjs +47 -0
  10. package/lib/chunk-FYHBHHWK.mjs.map +1 -0
  11. package/lib/{chunk-MULKGFIJ.mjs → chunk-GBDIGTNV.mjs} +165 -10
  12. package/lib/chunk-GBDIGTNV.mjs.map +1 -0
  13. package/lib/chunk-HQ67J7BP.mjs +199 -0
  14. package/lib/chunk-HQ67J7BP.mjs.map +1 -0
  15. package/lib/{chunk-AJ3G3THO.mjs → chunk-KO64HPWQ.mjs} +2 -2
  16. package/lib/{chunk-BB5MK4L3.mjs → chunk-KSFC72TT.mjs} +3 -3
  17. package/lib/{chunk-2TPJ6HOF.mjs → chunk-NZRW7ROK.mjs} +72 -54
  18. package/lib/chunk-NZRW7ROK.mjs.map +1 -0
  19. package/lib/chunk-QJDHVMKT.mjs +117 -0
  20. package/lib/chunk-QJDHVMKT.mjs.map +1 -0
  21. package/lib/{chunk-IS4VQRI4.mjs → chunk-QMBJ4VHC.mjs} +12 -47
  22. package/lib/chunk-QMBJ4VHC.mjs.map +1 -0
  23. package/lib/chunk-TRY7JGWO.mjs +16 -0
  24. package/lib/chunk-TRY7JGWO.mjs.map +1 -0
  25. package/lib/chunk-W4KR4CSL.mjs +236 -0
  26. package/lib/chunk-W4KR4CSL.mjs.map +1 -0
  27. package/lib/{chunk-AGF3RAAZ.mjs → chunk-WPCBVDFZ.mjs} +2 -2
  28. package/lib/chunk-WQWFVEVX.mjs +66 -0
  29. package/lib/chunk-WQWFVEVX.mjs.map +1 -0
  30. package/lib/{chunk-SYBADQXI.mjs → chunk-ZM4GDHHC.mjs} +77 -2
  31. package/lib/chunk-ZM4GDHHC.mjs.map +1 -0
  32. package/lib/delete-chunk.handler.d.mts +29 -0
  33. package/lib/delete-chunk.handler.d.ts +29 -0
  34. package/lib/delete-chunk.handler.js +2716 -0
  35. package/lib/delete-chunk.handler.js.map +1 -0
  36. package/lib/delete-chunk.handler.mjs +47 -0
  37. package/lib/delete-chunk.handler.mjs.map +1 -0
  38. package/lib/events-CjS-sm0W.d.mts +107 -0
  39. package/lib/events-CjS-sm0W.d.ts +107 -0
  40. package/lib/events-Da_cFgtc.d.mts +208 -0
  41. package/lib/events-Da_cFgtc.d.ts +208 -0
  42. package/lib/finalize.handler.d.mts +35 -0
  43. package/lib/finalize.handler.d.ts +35 -0
  44. package/lib/finalize.handler.js +875 -0
  45. package/lib/finalize.handler.js.map +1 -0
  46. package/lib/finalize.handler.mjs +166 -0
  47. package/lib/finalize.handler.mjs.map +1 -0
  48. package/lib/index.d.mts +189 -2
  49. package/lib/index.d.ts +500 -3
  50. package/lib/index.js +1753 -174
  51. package/lib/index.js.map +1 -1
  52. package/lib/index.mjs +571 -17
  53. package/lib/index.mjs.map +1 -1
  54. package/lib/list-chunks.handler.d.mts +28 -0
  55. package/lib/list-chunks.handler.d.ts +28 -0
  56. package/lib/list-chunks.handler.js +2746 -0
  57. package/lib/list-chunks.handler.js.map +1 -0
  58. package/lib/list-chunks.handler.mjs +54 -0
  59. package/lib/list-chunks.handler.mjs.map +1 -0
  60. package/lib/platform-deploy-bridge.handler.js +76 -1
  61. package/lib/platform-deploy-bridge.handler.js.map +1 -1
  62. package/lib/platform-deploy-bridge.handler.mjs +1 -1
  63. package/lib/pre-token-generation.handler.js +1106 -155
  64. package/lib/pre-token-generation.handler.js.map +1 -1
  65. package/lib/pre-token-generation.handler.mjs +6 -4
  66. package/lib/pre-token-generation.handler.mjs.map +1 -1
  67. package/lib/provision-default-workspace.handler.js +1529 -142
  68. package/lib/provision-default-workspace.handler.js.map +1 -1
  69. package/lib/provision-default-workspace.handler.mjs +8 -4
  70. package/lib/provision-default-workspace.handler.mjs.map +1 -1
  71. package/lib/rename-finalize.handler.d.mts +30 -0
  72. package/lib/rename-finalize.handler.d.ts +30 -0
  73. package/lib/rename-finalize.handler.js +795 -0
  74. package/lib/rename-finalize.handler.js.map +1 -0
  75. package/lib/rename-finalize.handler.mjs +90 -0
  76. package/lib/rename-finalize.handler.mjs.map +1 -0
  77. package/lib/rename-list-targets.handler.d.mts +26 -0
  78. package/lib/rename-list-targets.handler.d.ts +26 -0
  79. package/lib/rename-list-targets.handler.js +2985 -0
  80. package/lib/rename-list-targets.handler.js.map +1 -0
  81. package/lib/rename-list-targets.handler.mjs +431 -0
  82. package/lib/rename-list-targets.handler.mjs.map +1 -0
  83. package/lib/rename-rewrite-chunk.handler.d.mts +35 -0
  84. package/lib/rename-rewrite-chunk.handler.d.ts +35 -0
  85. package/lib/rename-rewrite-chunk.handler.js +2021 -0
  86. package/lib/rename-rewrite-chunk.handler.js.map +1 -0
  87. package/lib/rename-rewrite-chunk.handler.mjs +27 -0
  88. package/lib/rename-rewrite-chunk.handler.mjs.map +1 -0
  89. package/lib/rest-api-lambda.handler.js +4021 -932
  90. package/lib/rest-api-lambda.handler.js.map +1 -1
  91. package/lib/rest-api-lambda.handler.mjs +1786 -80
  92. package/lib/rest-api-lambda.handler.mjs.map +1 -1
  93. package/lib/seed-demo-data.handler.js +1588 -124
  94. package/lib/seed-demo-data.handler.js.map +1 -1
  95. package/lib/seed-demo-data.handler.mjs +10 -6
  96. package/lib/seed-system-data.handler.js +1179 -155
  97. package/lib/seed-system-data.handler.js.map +1 -1
  98. package/lib/seed-system-data.handler.mjs +5 -4
  99. package/lib/seed-system-data.handler.mjs.map +1 -1
  100. package/package.json +3 -3
  101. package/lib/chunk-2TPJ6HOF.mjs.map +0 -1
  102. package/lib/chunk-IS4VQRI4.mjs.map +0 -1
  103. package/lib/chunk-MULKGFIJ.mjs.map +0 -1
  104. package/lib/chunk-QR5JVSCF.mjs +0 -862
  105. package/lib/chunk-QR5JVSCF.mjs.map +0 -1
  106. package/lib/chunk-SYBADQXI.mjs.map +0 -1
  107. /package/lib/{chunk-7FUAMZOF.mjs.map → chunk-53OHXLIL.mjs.map} +0 -0
  108. /package/lib/{chunk-7Q2IJ2J5.mjs.map → chunk-CUUKXDB2.mjs.map} +0 -0
  109. /package/lib/{chunk-AJ3G3THO.mjs.map → chunk-KO64HPWQ.mjs.map} +0 -0
  110. /package/lib/{chunk-BB5MK4L3.mjs.map → chunk-KSFC72TT.mjs.map} +0 -0
  111. /package/lib/{chunk-AGF3RAAZ.mjs.map → chunk-WPCBVDFZ.mjs.map} +0 -0
package/lib/index.mjs CHANGED
@@ -1,9 +1,15 @@
1
+ import {
2
+ DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES,
3
+ DATA_STORE_CHANGE_DETAIL_TYPE,
4
+ DATA_STORE_CHANGE_EVENT_SOURCE,
5
+ buildFhirCurrentResourceChangeDetail
6
+ } from "./chunk-CEOAGPYY.mjs";
1
7
  import {
2
8
  SEED_SYSTEM_DATA_ACTOR_SYSTEM,
3
9
  SEED_SYSTEM_DATA_CONSUMER_NAME,
4
10
  SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR,
5
11
  import_workflows as import_workflows2
6
- } from "./chunk-AGF3RAAZ.mjs";
12
+ } from "./chunk-WPCBVDFZ.mjs";
7
13
  import {
8
14
  DEMO_PERIOD,
9
15
  DEMO_TENANT_SPECS,
@@ -29,14 +35,23 @@ import {
29
35
  import_workflows,
30
36
  openhiResourceIdentifier,
31
37
  rolePartitionKey
32
- } from "./chunk-7Q2IJ2J5.mjs";
38
+ } from "./chunk-CUUKXDB2.mjs";
33
39
  import {
34
- DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES,
35
- DATA_STORE_CHANGE_DETAIL_TYPE,
36
- DATA_STORE_CHANGE_EVENT_SOURCE,
37
- buildFhirCurrentResourceChangeDetail
38
- } from "./chunk-CEOAGPYY.mjs";
39
- import "./chunk-7FUAMZOF.mjs";
40
+ OWNING_DELETE_CASCADE_CONSUMER_NAME,
41
+ OWNING_DELETE_CASCADE_DEFAULT_CONCURRENCY,
42
+ OWNING_DELETE_CASCADE_STUCK_THRESHOLD_MINUTES,
43
+ OWNING_DELETE_OPS_EVENT_BUS_ENV_VAR,
44
+ import_workflows as import_workflows3
45
+ } from "./chunk-7RZHFI77.mjs";
46
+ import {
47
+ RENAME_CASCADE_CONSUMER_NAME,
48
+ RENAME_CASCADE_DEFAULT_CONCURRENCY,
49
+ RENAME_CASCADE_FAILED_THRESHOLD,
50
+ RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR,
51
+ RENAME_CASCADE_SLOW_THRESHOLD_SECONDS,
52
+ import_workflows as import_workflows4
53
+ } from "./chunk-23PUSHBV.mjs";
54
+ import "./chunk-53OHXLIL.mjs";
40
55
  import {
41
56
  PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE,
42
57
  USER_ONBOARDING_EVENT_SOURCE,
@@ -53,10 +68,14 @@ import {
53
68
  } from "./chunk-VXX4I3EF.mjs";
54
69
  import {
55
70
  require_lib
56
- } from "./chunk-SYBADQXI.mjs";
57
- import "./chunk-MULKGFIJ.mjs";
58
- import "./chunk-IS4VQRI4.mjs";
59
- import "./chunk-QR5JVSCF.mjs";
71
+ } from "./chunk-ZM4GDHHC.mjs";
72
+ import "./chunk-GBDIGTNV.mjs";
73
+ import "./chunk-HQ67J7BP.mjs";
74
+ import "./chunk-QJDHVMKT.mjs";
75
+ import "./chunk-QMBJ4VHC.mjs";
76
+ import "./chunk-FYHBHHWK.mjs";
77
+ import "./chunk-6NBGYGFL.mjs";
78
+ import "./chunk-TRY7JGWO.mjs";
60
79
  import {
61
80
  __commonJS,
62
81
  __toESM
@@ -1006,7 +1025,7 @@ var DynamoDbDataStore = class extends Table {
1006
1025
  };
1007
1026
 
1008
1027
  // src/components/dynamodb/workflow-dedup-table.ts
1009
- var import_workflows3 = __toESM(require_lib());
1028
+ var import_workflows5 = __toESM(require_lib());
1010
1029
  import { Annotations } from "aws-cdk-lib";
1011
1030
  import { AttributeType as AttributeType2, BillingMode as BillingMode2, Table as Table2 } from "aws-cdk-lib/aws-dynamodb";
1012
1031
  import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
@@ -1082,7 +1101,7 @@ var _WorkflowDedupTable = class _WorkflowDedupTable extends Construct5 {
1082
1101
  _WorkflowDedupTable.assertConsumerNameStatic(consumerName);
1083
1102
  const tableName = _WorkflowDedupTable.tableNameFromLookup(scope);
1084
1103
  const tableArn = _WorkflowDedupTable.tableArnFromLookup(scope);
1085
- fn.addEnvironment(import_workflows3.WORKFLOW_DEDUP_TABLE_NAME_ENV_VAR, tableName);
1104
+ fn.addEnvironment(import_workflows5.WORKFLOW_DEDUP_TABLE_NAME_ENV_VAR, tableName);
1086
1105
  if (options.defaultTtlSeconds !== void 0) {
1087
1106
  fn.addEnvironment(
1088
1107
  "OPENHI_WORKFLOW_DEDUP_DEFAULT_TTL_SECONDS",
@@ -1118,9 +1137,9 @@ var _WorkflowDedupTable = class _WorkflowDedupTable extends Construct5 {
1118
1137
  "consumerName must be non-empty."
1119
1138
  );
1120
1139
  }
1121
- if (consumerName.length > import_workflows3.WORKFLOW_DEDUP_MAX_CONSUMER_NAME_LENGTH) {
1140
+ if (consumerName.length > import_workflows5.WORKFLOW_DEDUP_MAX_CONSUMER_NAME_LENGTH) {
1122
1141
  throw new WorkflowDedupConsumerNameInvalidError(
1123
- `consumerName must be at most ${import_workflows3.WORKFLOW_DEDUP_MAX_CONSUMER_NAME_LENGTH} chars; got ${consumerName.length}.`
1142
+ `consumerName must be at most ${import_workflows5.WORKFLOW_DEDUP_MAX_CONSUMER_NAME_LENGTH} chars; got ${consumerName.length}.`
1124
1143
  );
1125
1144
  }
1126
1145
  if (/\s/.test(consumerName)) {
@@ -1143,7 +1162,7 @@ var _WorkflowDedupTable = class _WorkflowDedupTable extends Construct5 {
1143
1162
  );
1144
1163
  }
1145
1164
  this.registeredConsumers.add(consumerName);
1146
- fn.addEnvironment(import_workflows3.WORKFLOW_DEDUP_TABLE_NAME_ENV_VAR, this.table.tableName);
1165
+ fn.addEnvironment(import_workflows5.WORKFLOW_DEDUP_TABLE_NAME_ENV_VAR, this.table.tableName);
1147
1166
  if (options.defaultTtlSeconds !== void 0) {
1148
1167
  fn.addEnvironment(
1149
1168
  "OPENHI_WORKFLOW_DEDUP_DEFAULT_TTL_SECONDS",
@@ -2904,7 +2923,521 @@ var _OpenHiGraphqlService = class _OpenHiGraphqlService extends OpenHiService {
2904
2923
  };
2905
2924
  _OpenHiGraphqlService.SERVICE_TYPE = "graphql-api";
2906
2925
  var OpenHiGraphqlService = _OpenHiGraphqlService;
2926
+
2927
+ // src/workflows/control-plane/owning-delete-cascade/owning-delete-cascade-lambdas.ts
2928
+ import fs12 from "fs";
2929
+ import path12 from "path";
2930
+ import { Duration as Duration11 } from "aws-cdk-lib";
2931
+ import { Effect as Effect8, PolicyStatement as PolicyStatement8 } from "aws-cdk-lib/aws-iam";
2932
+ import { Runtime as Runtime12 } from "aws-cdk-lib/aws-lambda";
2933
+ import { NodejsFunction as NodejsFunction12 } from "aws-cdk-lib/aws-lambda-nodejs";
2934
+ import { Construct as Construct19 } from "constructs";
2935
+ function resolveHandlerEntry12(dirname, handlerName) {
2936
+ const sameDir = path12.join(dirname, handlerName);
2937
+ if (fs12.existsSync(sameDir)) {
2938
+ return { entry: sameDir, handler: "handler" };
2939
+ }
2940
+ const libDir = path12.join(dirname, "..", "..", "..", "..", "lib", handlerName);
2941
+ return { entry: libDir, handler: "handler" };
2942
+ }
2943
+ var OwningDeleteCascadeLambdas = class extends Construct19 {
2944
+ constructor(scope, props) {
2945
+ super(scope, "owning-delete-cascade-lambdas");
2946
+ const listResolved = resolveHandlerEntry12(
2947
+ __dirname,
2948
+ "list-chunks.handler.js"
2949
+ );
2950
+ this.listChunks = new NodejsFunction12(this, "list-chunks-handler", {
2951
+ entry: listResolved.entry,
2952
+ runtime: Runtime12.NODEJS_LATEST,
2953
+ memorySize: 512,
2954
+ timeout: Duration11.minutes(1),
2955
+ environment: {
2956
+ DYNAMO_TABLE_NAME: props.dataStoreTable.tableName
2957
+ }
2958
+ });
2959
+ props.dataStoreTable.grant(this.listChunks, "dynamodb:Query");
2960
+ const deleteResolved = resolveHandlerEntry12(
2961
+ __dirname,
2962
+ "delete-chunk.handler.js"
2963
+ );
2964
+ this.deleteChunk = new NodejsFunction12(this, "delete-chunk-handler", {
2965
+ entry: deleteResolved.entry,
2966
+ runtime: Runtime12.NODEJS_LATEST,
2967
+ memorySize: 512,
2968
+ timeout: Duration11.minutes(1),
2969
+ environment: {
2970
+ DYNAMO_TABLE_NAME: props.dataStoreTable.tableName
2971
+ }
2972
+ });
2973
+ props.dataStoreTable.grant(
2974
+ this.deleteChunk,
2975
+ "dynamodb:DeleteItem",
2976
+ "dynamodb:UpdateItem",
2977
+ "dynamodb:PutItem"
2978
+ );
2979
+ const finalizeResolved = resolveHandlerEntry12(
2980
+ __dirname,
2981
+ "finalize.handler.js"
2982
+ );
2983
+ this.finalize = new NodejsFunction12(this, "finalize-handler", {
2984
+ entry: finalizeResolved.entry,
2985
+ runtime: Runtime12.NODEJS_LATEST,
2986
+ memorySize: 512,
2987
+ timeout: Duration11.minutes(1),
2988
+ environment: {
2989
+ DYNAMO_TABLE_NAME: props.dataStoreTable.tableName,
2990
+ [OWNING_DELETE_OPS_EVENT_BUS_ENV_VAR]: props.opsEventBus.eventBusName
2991
+ }
2992
+ });
2993
+ props.dataStoreTable.grant(this.finalize, "dynamodb:DeleteItem");
2994
+ this.finalize.addToRolePolicy(
2995
+ new PolicyStatement8({
2996
+ effect: Effect8.ALLOW,
2997
+ actions: ["events:PutEvents"],
2998
+ resources: [props.opsEventBus.eventBusArn]
2999
+ })
3000
+ );
3001
+ }
3002
+ };
3003
+
3004
+ // src/workflows/control-plane/owning-delete-cascade/owning-delete-cascade-workflow.ts
3005
+ import { Duration as Duration12 } from "aws-cdk-lib";
3006
+ import { Rule as Rule5 } from "aws-cdk-lib/aws-events";
3007
+ import { SfnStateMachine } from "aws-cdk-lib/aws-events-targets";
3008
+ import {
3009
+ Choice,
3010
+ Condition,
3011
+ CustomState,
3012
+ DefinitionBody,
3013
+ Pass,
3014
+ StateMachine,
3015
+ Succeed,
3016
+ TaskInput,
3017
+ Wait,
3018
+ WaitTime
3019
+ } from "aws-cdk-lib/aws-stepfunctions";
3020
+ import { LambdaInvoke } from "aws-cdk-lib/aws-stepfunctions-tasks";
3021
+ import { Construct as Construct20 } from "constructs";
3022
+ var OwningDeleteCascadeWorkflow = class extends Construct20 {
3023
+ constructor(scope, props) {
3024
+ super(scope, "owning-delete-cascade-workflow");
3025
+ this.lambdas = new OwningDeleteCascadeLambdas(this, {
3026
+ dataStoreTable: props.dataStoreTable,
3027
+ opsEventBus: props.opsEventBus
3028
+ });
3029
+ const concurrency = props.cascadeMapConcurrency ?? OWNING_DELETE_CASCADE_DEFAULT_CONCURRENCY;
3030
+ const initState = new Pass(this, "init-state", {
3031
+ parameters: {
3032
+ "ownerType.$": "$.detail.payload.ownerType",
3033
+ "ownerId.$": "$.detail.payload.ownerId",
3034
+ "tenantId.$": "$.detail.payload.tenantId",
3035
+ cursors: {},
3036
+ projectionsRemoved: 0,
3037
+ chunkCount: 0,
3038
+ // Used by the finalize step to compute `durationMs`.
3039
+ "startedAt.$": "$$.Execution.StartTime",
3040
+ // Propagate envelope identity for ADR-016 causation chaining.
3041
+ "eventId.$": "$.detail.eventId",
3042
+ "correlationId.$": "$.detail.correlationId",
3043
+ "causationId.$": "$.detail.eventId"
3044
+ }
3045
+ });
3046
+ const listChunks = new LambdaInvoke(this, "list-chunks", {
3047
+ lambdaFunction: this.lambdas.listChunks,
3048
+ resultPath: "$.listResult",
3049
+ retryOnServiceExceptions: true
3050
+ });
3051
+ const updateAfterList = new Pass(this, "update-after-list", {
3052
+ parameters: {
3053
+ "ownerType.$": "$.ownerType",
3054
+ "ownerId.$": "$.ownerId",
3055
+ "tenantId.$": "$.tenantId",
3056
+ "cursors.$": "$.listResult.Payload.cursors",
3057
+ "projectionsRemoved.$": "$.listResult.Payload.projectionsRemoved",
3058
+ "chunkCount.$": "$.listResult.Payload.chunkCount",
3059
+ "exhausted.$": "$.listResult.Payload.exhausted",
3060
+ "chunks.$": "$.listResult.Payload.chunks",
3061
+ "startedAt.$": "$.startedAt",
3062
+ "eventId.$": "$.eventId",
3063
+ "correlationId.$": "$.correlationId",
3064
+ "causationId.$": "$.causationId"
3065
+ }
3066
+ });
3067
+ const rewriteChunks = new CustomState(this, "rewrite-chunks", {
3068
+ stateJson: {
3069
+ Type: "Map",
3070
+ ItemsPath: "$.chunks",
3071
+ MaxConcurrency: concurrency,
3072
+ ResultPath: "$.rewriteResults",
3073
+ ItemSelector: {
3074
+ // The handler receives `CascadeChunkInput` verbatim from the
3075
+ // `listChunks` output, no additional wrapping.
3076
+ "ownerType.$": "$$.Map.Item.Value.ownerType",
3077
+ "ownerId.$": "$$.Map.Item.Value.ownerId",
3078
+ "tenantId.$": "$$.Map.Item.Value.tenantId",
3079
+ "rows.$": "$$.Map.Item.Value.rows",
3080
+ "chunkToken.$": "$$.Map.Item.Value.chunkToken"
3081
+ },
3082
+ ItemProcessor: {
3083
+ ProcessorConfig: {
3084
+ // Inline mode (NOT Distributed). Per TR-022 Choice 2A.
3085
+ Mode: "INLINE"
3086
+ },
3087
+ StartAt: "DeleteChunk",
3088
+ States: {
3089
+ DeleteChunk: {
3090
+ Type: "Task",
3091
+ Resource: "arn:aws:states:::lambda:invoke",
3092
+ Parameters: {
3093
+ FunctionName: this.lambdas.deleteChunk.functionArn,
3094
+ "Payload.$": "$"
3095
+ },
3096
+ Retry: [
3097
+ {
3098
+ ErrorEquals: [
3099
+ "DynamoDB.ProvisionedThroughputExceededException",
3100
+ "DynamoDB.ThrottlingException",
3101
+ "DynamoDB.TransactionConflictException",
3102
+ "Lambda.ServiceException",
3103
+ "Lambda.AWSLambdaException",
3104
+ "Lambda.SdkClientException"
3105
+ ],
3106
+ IntervalSeconds: 1,
3107
+ MaxAttempts: 3,
3108
+ BackoffRate: 2,
3109
+ MaxDelaySeconds: 30
3110
+ }
3111
+ ],
3112
+ Catch: [
3113
+ {
3114
+ // Replay path: the rows in this chunk are already
3115
+ // gone. Treat as a no-op success so the outer loop
3116
+ // keeps draining the partition.
3117
+ ErrorEquals: ["DynamoDB.TransactionCanceledException"],
3118
+ Next: "ChunkAlreadyDeleted"
3119
+ }
3120
+ ],
3121
+ End: true
3122
+ },
3123
+ ChunkAlreadyDeleted: {
3124
+ Type: "Succeed"
3125
+ }
3126
+ }
3127
+ }
3128
+ }
3129
+ });
3130
+ const interPageWait = new Wait(this, "inter-page-wait", {
3131
+ time: WaitTime.duration(Duration12.seconds(0))
3132
+ });
3133
+ const isExhausted = new Choice(this, "is-exhausted");
3134
+ const finalize = new LambdaInvoke(this, "finalize", {
3135
+ lambdaFunction: this.lambdas.finalize,
3136
+ payload: TaskInput.fromObject({
3137
+ "ownerType.$": "$.ownerType",
3138
+ "ownerId.$": "$.ownerId",
3139
+ "tenantId.$": "$.tenantId",
3140
+ "projectionsRemoved.$": "$.projectionsRemoved",
3141
+ "chunkCount.$": "$.chunkCount",
3142
+ "startedAt.$": "$.startedAt",
3143
+ "eventId.$": "$.eventId",
3144
+ "correlationId.$": "$.correlationId",
3145
+ "causationId.$": "$.causationId"
3146
+ }),
3147
+ resultPath: "$.finalizeResult",
3148
+ retryOnServiceExceptions: true
3149
+ });
3150
+ const success = new Succeed(this, "success");
3151
+ const definition = initState.next(listChunks).next(updateAfterList).next(rewriteChunks).next(interPageWait).next(
3152
+ isExhausted.when(
3153
+ Condition.booleanEquals("$.exhausted", true),
3154
+ finalize.next(success)
3155
+ ).otherwise(listChunks)
3156
+ );
3157
+ this.stateMachine = new StateMachine(this, "state-machine", {
3158
+ definitionBody: DefinitionBody.fromChainable(definition),
3159
+ // Long timeout because real-world cascades can run minutes when
3160
+ // a workspace has thousands of members. The stuck-cascade alarm
3161
+ // fires at 15 minutes; the state machine itself does not abort.
3162
+ timeout: Duration12.hours(2)
3163
+ });
3164
+ this.rule = new Rule5(this, "rule", {
3165
+ eventBus: props.dataEventBus,
3166
+ eventPattern: {
3167
+ source: [import_workflows3.OPENHI_DATA_SOURCE],
3168
+ detailType: [import_workflows3.ControlPlaneOwningDeleteV1.detailType]
3169
+ },
3170
+ targets: [
3171
+ new SfnStateMachine(this.stateMachine, {
3172
+ retryAttempts: 2,
3173
+ maxEventAge: Duration12.hours(2)
3174
+ })
3175
+ ]
3176
+ });
3177
+ }
3178
+ };
3179
+
3180
+ // src/workflows/control-plane/rename-cascade/rename-cascade-lambdas.ts
3181
+ import fs13 from "fs";
3182
+ import path13 from "path";
3183
+ import { Duration as Duration13 } from "aws-cdk-lib";
3184
+ import { Effect as Effect9, PolicyStatement as PolicyStatement9 } from "aws-cdk-lib/aws-iam";
3185
+ import { Runtime as Runtime13 } from "aws-cdk-lib/aws-lambda";
3186
+ import { NodejsFunction as NodejsFunction13 } from "aws-cdk-lib/aws-lambda-nodejs";
3187
+ import { Construct as Construct21 } from "constructs";
3188
+ function resolveHandlerEntry13(dirname, handlerName) {
3189
+ const sameDir = path13.join(dirname, handlerName);
3190
+ if (fs13.existsSync(sameDir)) {
3191
+ return { entry: sameDir, handler: "handler" };
3192
+ }
3193
+ const libDir = path13.join(dirname, "..", "..", "..", "..", "lib", handlerName);
3194
+ return { entry: libDir, handler: "handler" };
3195
+ }
3196
+ var RenameCascadeLambdas = class extends Construct21 {
3197
+ constructor(scope, props) {
3198
+ super(scope, "rename-cascade-lambdas");
3199
+ const listResolved = resolveHandlerEntry13(
3200
+ __dirname,
3201
+ "rename-list-targets.handler.js"
3202
+ );
3203
+ this.listTargets = new NodejsFunction13(this, "list-targets-handler", {
3204
+ entry: listResolved.entry,
3205
+ runtime: Runtime13.NODEJS_LATEST,
3206
+ memorySize: 512,
3207
+ timeout: Duration13.minutes(1),
3208
+ environment: {
3209
+ DYNAMO_TABLE_NAME: props.dataStoreTable.tableName
3210
+ }
3211
+ });
3212
+ props.dataStoreTable.grant(this.listTargets, "dynamodb:Query");
3213
+ const rewriteResolved = resolveHandlerEntry13(
3214
+ __dirname,
3215
+ "rename-rewrite-chunk.handler.js"
3216
+ );
3217
+ this.rewriteChunk = new NodejsFunction13(this, "rewrite-chunk-handler", {
3218
+ entry: rewriteResolved.entry,
3219
+ runtime: Runtime13.NODEJS_LATEST,
3220
+ memorySize: 512,
3221
+ timeout: Duration13.minutes(1),
3222
+ environment: {
3223
+ DYNAMO_TABLE_NAME: props.dataStoreTable.tableName
3224
+ }
3225
+ });
3226
+ props.dataStoreTable.grant(
3227
+ this.rewriteChunk,
3228
+ "dynamodb:DeleteItem",
3229
+ "dynamodb:PutItem",
3230
+ "dynamodb:UpdateItem"
3231
+ );
3232
+ const finalizeResolved = resolveHandlerEntry13(
3233
+ __dirname,
3234
+ "rename-finalize.handler.js"
3235
+ );
3236
+ this.finalize = new NodejsFunction13(this, "finalize-handler", {
3237
+ entry: finalizeResolved.entry,
3238
+ runtime: Runtime13.NODEJS_LATEST,
3239
+ memorySize: 512,
3240
+ timeout: Duration13.minutes(1),
3241
+ environment: {
3242
+ [RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR]: props.opsEventBus.eventBusName
3243
+ }
3244
+ });
3245
+ this.finalize.addToRolePolicy(
3246
+ new PolicyStatement9({
3247
+ effect: Effect9.ALLOW,
3248
+ actions: ["events:PutEvents"],
3249
+ resources: [props.opsEventBus.eventBusArn]
3250
+ })
3251
+ );
3252
+ }
3253
+ };
3254
+
3255
+ // src/workflows/control-plane/rename-cascade/rename-cascade-workflow.ts
3256
+ import { Duration as Duration14 } from "aws-cdk-lib";
3257
+ import { Rule as Rule6 } from "aws-cdk-lib/aws-events";
3258
+ import { SfnStateMachine as SfnStateMachine2 } from "aws-cdk-lib/aws-events-targets";
3259
+ import {
3260
+ Choice as Choice2,
3261
+ Condition as Condition2,
3262
+ CustomState as CustomState2,
3263
+ DefinitionBody as DefinitionBody2,
3264
+ Pass as Pass2,
3265
+ StateMachine as StateMachine2,
3266
+ Succeed as Succeed2,
3267
+ TaskInput as TaskInput2
3268
+ } from "aws-cdk-lib/aws-stepfunctions";
3269
+ import { LambdaInvoke as LambdaInvoke2 } from "aws-cdk-lib/aws-stepfunctions-tasks";
3270
+ import { Construct as Construct22 } from "constructs";
3271
+ var RenameCascadeWorkflow = class extends Construct22 {
3272
+ constructor(scope, props) {
3273
+ super(scope, "rename-cascade-workflow");
3274
+ this.lambdas = new RenameCascadeLambdas(this, {
3275
+ dataStoreTable: props.dataStoreTable,
3276
+ opsEventBus: props.opsEventBus
3277
+ });
3278
+ const concurrency = props.cascadeMapConcurrency ?? RENAME_CASCADE_DEFAULT_CONCURRENCY;
3279
+ const initState = new Pass2(this, "init-state", {
3280
+ parameters: {
3281
+ "entityType.$": "$.detail.payload.entityType",
3282
+ "entityId.$": "$.detail.payload.entityId",
3283
+ "tenantId.$": "$.detail.payload.tenantId",
3284
+ "oldName.$": "$.detail.payload.oldName",
3285
+ "newName.$": "$.detail.payload.newName",
3286
+ "oldNormalizedName.$": "$.detail.payload.oldNormalizedName",
3287
+ "newNormalizedName.$": "$.detail.payload.newNormalizedName",
3288
+ cursors: {},
3289
+ itemsRewritten: 0,
3290
+ chunkCount: 0,
3291
+ "startedAt.$": "$$.Execution.StartTime",
3292
+ "eventId.$": "$.detail.eventId",
3293
+ "correlationId.$": "$.detail.correlationId",
3294
+ "causationId.$": "$.detail.eventId"
3295
+ }
3296
+ });
3297
+ const listTargets = new LambdaInvoke2(this, "list-targets", {
3298
+ lambdaFunction: this.lambdas.listTargets,
3299
+ resultPath: "$.listResult",
3300
+ retryOnServiceExceptions: true
3301
+ });
3302
+ const updateAfterList = new Pass2(this, "update-after-list", {
3303
+ parameters: {
3304
+ "entityType.$": "$.entityType",
3305
+ "entityId.$": "$.entityId",
3306
+ "tenantId.$": "$.tenantId",
3307
+ "oldName.$": "$.oldName",
3308
+ "newName.$": "$.newName",
3309
+ "oldNormalizedName.$": "$.oldNormalizedName",
3310
+ "newNormalizedName.$": "$.newNormalizedName",
3311
+ "cursors.$": "$.listResult.Payload.cursors",
3312
+ "itemsRewritten.$": "$.listResult.Payload.itemsRewritten",
3313
+ "chunkCount.$": "$.listResult.Payload.chunkCount",
3314
+ "exhausted.$": "$.listResult.Payload.exhausted",
3315
+ "chunks.$": "$.listResult.Payload.chunks",
3316
+ "startedAt.$": "$.startedAt",
3317
+ "eventId.$": "$.eventId",
3318
+ "correlationId.$": "$.correlationId",
3319
+ "causationId.$": "$.causationId"
3320
+ }
3321
+ });
3322
+ const rewriteChunks = new CustomState2(this, "rewrite-chunks", {
3323
+ stateJson: {
3324
+ Type: "Map",
3325
+ ItemsPath: "$.chunks",
3326
+ MaxConcurrency: concurrency,
3327
+ ResultPath: "$.rewriteResults",
3328
+ ItemSelector: {
3329
+ "entityType.$": "$$.Map.Item.Value.entityType",
3330
+ "entityId.$": "$$.Map.Item.Value.entityId",
3331
+ "tenantId.$": "$$.Map.Item.Value.tenantId",
3332
+ "targets.$": "$$.Map.Item.Value.targets",
3333
+ "chunkToken.$": "$$.Map.Item.Value.chunkToken"
3334
+ },
3335
+ ItemProcessor: {
3336
+ ProcessorConfig: {
3337
+ // DISTRIBUTED mode — per TR-023 (NOT INLINE; that is
3338
+ // TR-022's territory).
3339
+ Mode: "DISTRIBUTED",
3340
+ ExecutionType: "STANDARD"
3341
+ },
3342
+ StartAt: "RewriteChunk",
3343
+ States: {
3344
+ RewriteChunk: {
3345
+ Type: "Task",
3346
+ Resource: "arn:aws:states:::lambda:invoke",
3347
+ Parameters: {
3348
+ FunctionName: this.lambdas.rewriteChunk.functionArn,
3349
+ "Payload.$": "$"
3350
+ },
3351
+ Retry: [
3352
+ {
3353
+ ErrorEquals: [
3354
+ "DynamoDB.ProvisionedThroughputExceededException",
3355
+ "DynamoDB.ThrottlingException",
3356
+ "DynamoDB.TransactionConflictException",
3357
+ "Lambda.ServiceException",
3358
+ "Lambda.AWSLambdaException",
3359
+ "Lambda.SdkClientException"
3360
+ ],
3361
+ IntervalSeconds: 1,
3362
+ MaxAttempts: 5,
3363
+ BackoffRate: 2,
3364
+ MaxDelaySeconds: 30
3365
+ }
3366
+ ],
3367
+ Catch: [
3368
+ {
3369
+ // Replay path: the rewrite race "lost to a later
3370
+ // write" per TR-023 idempotency. Treat as a no-op
3371
+ // success so the outer loop keeps draining the page.
3372
+ ErrorEquals: ["DynamoDB.TransactionCanceledException"],
3373
+ Next: "ChunkAlreadyRewritten"
3374
+ }
3375
+ ],
3376
+ End: true
3377
+ },
3378
+ ChunkAlreadyRewritten: {
3379
+ Type: "Succeed"
3380
+ }
3381
+ }
3382
+ }
3383
+ }
3384
+ });
3385
+ const isExhausted = new Choice2(this, "is-exhausted");
3386
+ const finalize = new LambdaInvoke2(this, "finalize", {
3387
+ lambdaFunction: this.lambdas.finalize,
3388
+ payload: TaskInput2.fromObject({
3389
+ "entityType.$": "$.entityType",
3390
+ "entityId.$": "$.entityId",
3391
+ "tenantId.$": "$.tenantId",
3392
+ "newName.$": "$.newName",
3393
+ "itemsRewritten.$": "$.itemsRewritten",
3394
+ "chunkCount.$": "$.chunkCount",
3395
+ "startedAt.$": "$.startedAt",
3396
+ "eventId.$": "$.eventId",
3397
+ "correlationId.$": "$.correlationId",
3398
+ "causationId.$": "$.causationId"
3399
+ }),
3400
+ resultPath: "$.finalizeResult",
3401
+ retryOnServiceExceptions: true
3402
+ });
3403
+ const success = new Succeed2(this, "success");
3404
+ const definition = initState.next(listTargets).next(updateAfterList).next(rewriteChunks).next(
3405
+ isExhausted.when(
3406
+ Condition2.booleanEquals("$.exhausted", true),
3407
+ finalize.next(success)
3408
+ ).otherwise(listTargets)
3409
+ );
3410
+ this.stateMachine = new StateMachine2(this, "state-machine", {
3411
+ definitionBody: DefinitionBody2.fromChainable(definition),
3412
+ // Long timeout — large renames may rewrite thousands of rows;
3413
+ // the `CascadeSlow` alarm fires at 300s p99 but the state
3414
+ // machine itself does not abort.
3415
+ timeout: Duration14.hours(2)
3416
+ });
3417
+ this.rule = new Rule6(this, "rule", {
3418
+ eventBus: props.dataEventBus,
3419
+ eventPattern: {
3420
+ source: [import_workflows4.OPENHI_DATA_SOURCE],
3421
+ detailType: [import_workflows4.ControlPlaneRenameV1.detailType]
3422
+ },
3423
+ targets: [
3424
+ new SfnStateMachine2(this.stateMachine, {
3425
+ retryAttempts: 2,
3426
+ maxEventAge: Duration14.hours(2)
3427
+ })
3428
+ ]
3429
+ });
3430
+ }
3431
+ };
3432
+ var export_ControlPlaneOwningDeleteCompleteV1 = import_workflows3.ControlPlaneOwningDeleteCompleteV1;
3433
+ var export_ControlPlaneOwningDeleteFailedV1 = import_workflows3.ControlPlaneOwningDeleteFailedV1;
3434
+ var export_ControlPlaneOwningDeleteV1 = import_workflows3.ControlPlaneOwningDeleteV1;
3435
+ var export_ControlPlaneRenameCompleteV1 = import_workflows4.ControlPlaneRenameCompleteV1;
3436
+ var export_ControlPlaneRenameFailedV1 = import_workflows4.ControlPlaneRenameFailedV1;
3437
+ var export_ControlPlaneRenameV1 = import_workflows4.ControlPlaneRenameV1;
3438
+ var export_OWNING_ENTITY_TYPE = import_workflows3.OWNING_ENTITY_TYPE;
2907
3439
  var export_PlatformDeploymentCompletedV1 = import_workflows2.PlatformDeploymentCompletedV1;
3440
+ var export_RENAMABLE_ENTITY_TYPE = import_workflows4.RENAMABLE_ENTITY_TYPE;
2908
3441
  export {
2909
3442
  BRIDGED_STATUSES,
2910
3443
  CLOUDFORMATION_EVENT_SOURCE,
@@ -2917,6 +3450,12 @@ export {
2917
3450
  CognitoUserPoolDomain,
2918
3451
  CognitoUserPoolKmsKey,
2919
3452
  ControlEventBus,
3453
+ export_ControlPlaneOwningDeleteCompleteV1 as ControlPlaneOwningDeleteCompleteV1,
3454
+ export_ControlPlaneOwningDeleteFailedV1 as ControlPlaneOwningDeleteFailedV1,
3455
+ export_ControlPlaneOwningDeleteV1 as ControlPlaneOwningDeleteV1,
3456
+ export_ControlPlaneRenameCompleteV1 as ControlPlaneRenameCompleteV1,
3457
+ export_ControlPlaneRenameFailedV1 as ControlPlaneRenameFailedV1,
3458
+ export_ControlPlaneRenameV1 as ControlPlaneRenameV1,
2920
3459
  DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES,
2921
3460
  DATA_STORE_CHANGE_DETAIL_TYPE,
2922
3461
  DATA_STORE_CHANGE_EVENT_SOURCE,
@@ -2936,6 +3475,11 @@ export {
2936
3475
  OPENHI_TAG_SUFFIX_REPO_NAME,
2937
3476
  OPENHI_TAG_SUFFIX_SERVICE_TYPE,
2938
3477
  OPENHI_TAG_SUFFIX_STAGE_TYPE,
3478
+ OWNING_DELETE_CASCADE_CONSUMER_NAME,
3479
+ OWNING_DELETE_CASCADE_DEFAULT_CONCURRENCY,
3480
+ OWNING_DELETE_CASCADE_STUCK_THRESHOLD_MINUTES,
3481
+ OWNING_DELETE_OPS_EVENT_BUS_ENV_VAR,
3482
+ export_OWNING_ENTITY_TYPE as OWNING_ENTITY_TYPE,
2939
3483
  OpenHiApp,
2940
3484
  OpenHiAuthService,
2941
3485
  OpenHiDataService,
@@ -2946,6 +3490,8 @@ export {
2946
3490
  OpenHiService,
2947
3491
  OpenHiStage,
2948
3492
  OpsEventBus,
3493
+ OwningDeleteCascadeLambdas,
3494
+ OwningDeleteCascadeWorkflow,
2949
3495
  PLACEHOLDER_TENANT_ID,
2950
3496
  PLACEHOLDER_WORKSPACE_ID,
2951
3497
  PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM,
@@ -2961,7 +3507,15 @@ export {
2961
3507
  PostConfirmationLambda,
2962
3508
  PreTokenGenerationLambda,
2963
3509
  ProvisionDefaultWorkspaceLambda,
3510
+ export_RENAMABLE_ENTITY_TYPE as RENAMABLE_ENTITY_TYPE,
3511
+ RENAME_CASCADE_CONSUMER_NAME,
3512
+ RENAME_CASCADE_DEFAULT_CONCURRENCY,
3513
+ RENAME_CASCADE_FAILED_THRESHOLD,
3514
+ RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR,
3515
+ RENAME_CASCADE_SLOW_THRESHOLD_SECONDS,
2964
3516
  REST_API_BASE_URL_SSM_NAME,
3517
+ RenameCascadeLambdas,
3518
+ RenameCascadeWorkflow,
2965
3519
  RootGraphqlApi,
2966
3520
  RootHostedZone,
2967
3521
  RootHttpApi,