@openhi/constructs 0.0.90 → 0.0.92

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/lib/index.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  __commonJS,
9
9
  __toESM
10
- } from "./chunk-LZOMFHX3.mjs";
10
+ } from "./chunk-3QS3WKRC.mjs";
11
11
 
12
12
  // ../config/lib/open-hi-config.js
13
13
  var require_open_hi_config = __commonJS({
@@ -699,13 +699,13 @@ var PostAuthenticationLambda = class extends Construct {
699
699
  }
700
700
  };
701
701
 
702
- // src/components/cognito/pre-token-generation-lambda.ts
702
+ // src/components/cognito/post-confirmation-lambda.ts
703
703
  import fs2 from "fs";
704
704
  import path2 from "path";
705
705
  import { Runtime as Runtime2 } from "aws-cdk-lib/aws-lambda";
706
706
  import { NodejsFunction as NodejsFunction2 } from "aws-cdk-lib/aws-lambda-nodejs";
707
707
  import { Construct as Construct2 } from "constructs";
708
- var HANDLER_NAME2 = "pre-token-generation.handler.js";
708
+ var HANDLER_NAME2 = "post-confirmation.handler.js";
709
709
  function resolveHandlerEntry2(dirname) {
710
710
  const sameDir = path2.join(dirname, HANDLER_NAME2);
711
711
  if (fs2.existsSync(sameDir)) {
@@ -714,35 +714,64 @@ function resolveHandlerEntry2(dirname) {
714
714
  const fromLib = path2.join(dirname, "..", "..", "..", "lib", HANDLER_NAME2);
715
715
  return fromLib;
716
716
  }
717
- var PreTokenGenerationLambda = class extends Construct2 {
718
- constructor(scope) {
719
- super(scope, "pre-token-generation-lambda");
717
+ var PostConfirmationLambda = class extends Construct2 {
718
+ constructor(scope, props) {
719
+ super(scope, "post-confirmation-lambda");
720
720
  this.lambda = new NodejsFunction2(this, "handler", {
721
721
  entry: resolveHandlerEntry2(__dirname),
722
722
  runtime: Runtime2.NODEJS_LATEST,
723
- memorySize: 1024
723
+ memorySize: 1024,
724
+ environment: {
725
+ DYNAMO_TABLE_NAME: props.dynamoTableName
726
+ }
724
727
  });
725
728
  }
726
729
  };
727
730
 
728
- // src/components/dynamodb/data-store-historical-archive.ts
731
+ // src/components/cognito/pre-token-generation-lambda.ts
729
732
  import fs3 from "fs";
730
733
  import path3 from "path";
731
- import { Duration as Duration2, RemovalPolicy as RemovalPolicy2, Size } from "aws-cdk-lib";
732
- import * as kinesisfirehose from "aws-cdk-lib/aws-kinesisfirehose";
733
734
  import { Runtime as Runtime3 } from "aws-cdk-lib/aws-lambda";
734
735
  import { NodejsFunction as NodejsFunction3 } from "aws-cdk-lib/aws-lambda-nodejs";
735
- import * as s3 from "aws-cdk-lib/aws-s3";
736
736
  import { Construct as Construct3 } from "constructs";
737
- var HANDLER_NAME3 = "firehose-archive-transform.handler.js";
737
+ var HANDLER_NAME3 = "pre-token-generation.handler.js";
738
738
  function resolveHandlerEntry3(dirname) {
739
739
  const sameDir = path3.join(dirname, HANDLER_NAME3);
740
740
  if (fs3.existsSync(sameDir)) {
741
741
  return sameDir;
742
742
  }
743
- return path3.join(dirname, "..", "..", "..", "lib", HANDLER_NAME3);
743
+ const fromLib = path3.join(dirname, "..", "..", "..", "lib", HANDLER_NAME3);
744
+ return fromLib;
744
745
  }
745
- var DataStoreHistoricalArchive = class extends Construct3 {
746
+ var PreTokenGenerationLambda = class extends Construct3 {
747
+ constructor(scope) {
748
+ super(scope, "pre-token-generation-lambda");
749
+ this.lambda = new NodejsFunction3(this, "handler", {
750
+ entry: resolveHandlerEntry3(__dirname),
751
+ runtime: Runtime3.NODEJS_LATEST,
752
+ memorySize: 1024
753
+ });
754
+ }
755
+ };
756
+
757
+ // src/components/dynamodb/data-store-historical-archive.ts
758
+ import fs4 from "fs";
759
+ import path4 from "path";
760
+ import { Duration as Duration2, RemovalPolicy as RemovalPolicy2, Size } from "aws-cdk-lib";
761
+ import * as kinesisfirehose from "aws-cdk-lib/aws-kinesisfirehose";
762
+ import { Runtime as Runtime4 } from "aws-cdk-lib/aws-lambda";
763
+ import { NodejsFunction as NodejsFunction4 } from "aws-cdk-lib/aws-lambda-nodejs";
764
+ import * as s3 from "aws-cdk-lib/aws-s3";
765
+ import { Construct as Construct4 } from "constructs";
766
+ var HANDLER_NAME4 = "firehose-archive-transform.handler.js";
767
+ function resolveHandlerEntry4(dirname) {
768
+ const sameDir = path4.join(dirname, HANDLER_NAME4);
769
+ if (fs4.existsSync(sameDir)) {
770
+ return sameDir;
771
+ }
772
+ return path4.join(dirname, "..", "..", "..", "lib", HANDLER_NAME4);
773
+ }
774
+ var DataStoreHistoricalArchive = class extends Construct4 {
746
775
  constructor(scope, id, props) {
747
776
  super(scope, id);
748
777
  this.archiveBucket = new s3.Bucket(this, "ArchiveBucket", {
@@ -762,9 +791,9 @@ var DataStoreHistoricalArchive = class extends Construct3 {
762
791
  versioned: false
763
792
  }) : void 0;
764
793
  this.putEventsFailureDlqBucket = putEventsFailureDlqBucket;
765
- this.transformFunction = new NodejsFunction3(this, "FirehoseTransform", {
766
- entry: resolveHandlerEntry3(__dirname),
767
- runtime: Runtime3.NODEJS_LATEST,
794
+ this.transformFunction = new NodejsFunction4(this, "FirehoseTransform", {
795
+ entry: resolveHandlerEntry4(__dirname),
796
+ runtime: Runtime4.NODEJS_LATEST,
768
797
  memorySize: 512,
769
798
  timeout: Duration2.minutes(1),
770
799
  description: "Firehose transform: filter CURRENT resource rows, S3 keys, EventBridge PutEvents",
@@ -860,13 +889,20 @@ var DynamoDbDataStore = class extends Table {
860
889
  },
861
890
  projectionType: ProjectionType.INCLUDE,
862
891
  nonKeyAttributes: [
892
+ "id",
863
893
  "summary",
864
894
  "vid",
865
895
  "lastUpdated",
866
896
  "createdDate",
867
897
  "modifiedDate",
868
898
  "createdById",
869
- "modifiedById"
899
+ "modifiedById",
900
+ // ElectroDB filters every query result through `ownsItem`, which
901
+ // verifies `__edb_e__` (entity name) and `__edb_v__` (version) match
902
+ // the entity. Without these projected, every GSI1 query returns 0
903
+ // results — list endpoints silently return empty bundles.
904
+ "__edb_e__",
905
+ "__edb_v__"
870
906
  ]
871
907
  });
872
908
  this.addGlobalSecondaryIndex({
@@ -884,7 +920,12 @@ var DynamoDbDataStore = class extends Table {
884
920
  "id",
885
921
  "currentTenant",
886
922
  "currentWorkspace",
887
- "displayName"
923
+ "displayName",
924
+ // See GSI1 above: ElectroDB's `ownsItem` filter rejects items
925
+ // without these, so any query against GSI2 returns 0 results
926
+ // unless they're projected.
927
+ "__edb_e__",
928
+ "__edb_v__"
888
929
  ]
889
930
  });
890
931
  }
@@ -935,27 +976,27 @@ var OpsEventBus = class _OpsEventBus extends EventBus2 {
935
976
  };
936
977
 
937
978
  // src/components/postgres/data-store-postgres-replica.ts
938
- import fs4 from "fs";
939
- import path4 from "path";
979
+ import fs5 from "fs";
980
+ import path5 from "path";
940
981
  import { Duration as Duration3, Stack as Stack2 } from "aws-cdk-lib";
941
982
  import * as ec2 from "aws-cdk-lib/aws-ec2";
942
- import { Runtime as Runtime4, StartingPosition } from "aws-cdk-lib/aws-lambda";
983
+ import { Runtime as Runtime5, StartingPosition } from "aws-cdk-lib/aws-lambda";
943
984
  import { KinesisEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
944
- import { NodejsFunction as NodejsFunction4 } from "aws-cdk-lib/aws-lambda-nodejs";
985
+ import { NodejsFunction as NodejsFunction5 } from "aws-cdk-lib/aws-lambda-nodejs";
945
986
  import * as rds from "aws-cdk-lib/aws-rds";
946
- import { Construct as Construct4 } from "constructs";
947
- var HANDLER_NAME4 = "data-store-postgres-replication.handler.js";
987
+ import { Construct as Construct5 } from "constructs";
988
+ var HANDLER_NAME5 = "data-store-postgres-replication.handler.js";
948
989
  var DEFAULT_DATABASE_NAME = "openhi";
949
990
  var SCHEMA_NAME_PATTERN = /^[a-z_][a-z0-9_]{0,62}$/;
950
991
  var POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME = "POSTGRES_REPLICA_CLUSTER_ARN";
951
992
  var POSTGRES_REPLICA_SECRET_ARN_SSM_NAME = "POSTGRES_REPLICA_SECRET_ARN";
952
993
  var POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME = "POSTGRES_REPLICA_DATABASE_NAME";
953
- function resolveHandlerEntry4(dirname) {
954
- const sameDir = path4.join(dirname, HANDLER_NAME4);
955
- if (fs4.existsSync(sameDir)) {
994
+ function resolveHandlerEntry5(dirname) {
995
+ const sameDir = path5.join(dirname, HANDLER_NAME5);
996
+ if (fs5.existsSync(sameDir)) {
956
997
  return sameDir;
957
998
  }
958
- return path4.join(dirname, "..", "..", "..", "lib", HANDLER_NAME4);
999
+ return path5.join(dirname, "..", "..", "..", "lib", HANDLER_NAME5);
959
1000
  }
960
1001
  function getPostgresReplicaSchemaName(branchHash) {
961
1002
  const candidate = `b_${branchHash.toLowerCase()}`;
@@ -966,7 +1007,7 @@ function getPostgresReplicaSchemaName(branchHash) {
966
1007
  }
967
1008
  return candidate;
968
1009
  }
969
- var DataStorePostgresReplica = class extends Construct4 {
1010
+ var DataStorePostgresReplica = class extends Construct5 {
970
1011
  /**
971
1012
  * Resolve the cluster ARN published by an upstream {@link DataStorePostgresReplica}.
972
1013
  * Use from any stack that needs to grant `rds-data:ExecuteStatement` against
@@ -1035,9 +1076,9 @@ var DataStorePostgresReplica = class extends Construct4 {
1035
1076
  enableDataApi: true
1036
1077
  });
1037
1078
  this.publishCoordinatesToSsm();
1038
- this.replicationFunction = new NodejsFunction4(this, "ReplicationFunction", {
1039
- entry: resolveHandlerEntry4(__dirname),
1040
- runtime: Runtime4.NODEJS_LATEST,
1079
+ this.replicationFunction = new NodejsFunction5(this, "ReplicationFunction", {
1080
+ entry: resolveHandlerEntry5(__dirname),
1081
+ runtime: Runtime5.NODEJS_LATEST,
1041
1082
  memorySize: 512,
1042
1083
  timeout: Duration3.minutes(1),
1043
1084
  vpc: this.vpc,
@@ -1121,8 +1162,8 @@ var ChildHostedZone = class extends HostedZone {
1121
1162
  ChildHostedZone.SSM_PARAM_NAME = "CHILDHOSTEDZONE";
1122
1163
 
1123
1164
  // src/components/route-53/root-hosted-zone.ts
1124
- import { Construct as Construct5 } from "constructs";
1125
- var RootHostedZone = class extends Construct5 {
1165
+ import { Construct as Construct6 } from "constructs";
1166
+ var RootHostedZone = class extends Construct6 {
1126
1167
  };
1127
1168
 
1128
1169
  // src/components/static-hosting/static-hosting.ts
@@ -1133,9 +1174,9 @@ import {
1133
1174
  import { S3BucketOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
1134
1175
  import { Bucket as Bucket2 } from "aws-cdk-lib/aws-s3";
1135
1176
  import { Duration as Duration5 } from "aws-cdk-lib/core";
1136
- import { Construct as Construct6 } from "constructs";
1177
+ import { Construct as Construct7 } from "constructs";
1137
1178
  var STATIC_HOSTING_SERVICE_TYPE = "website";
1138
- var _StaticHosting = class _StaticHosting extends Construct6 {
1179
+ var _StaticHosting = class _StaticHosting extends Construct7 {
1139
1180
  constructor(scope, id, props = {}) {
1140
1181
  super(scope, id);
1141
1182
  const stack = OpenHiService.of(scope);
@@ -1195,10 +1236,134 @@ import {
1195
1236
  UserPoolDomain as UserPoolDomain2,
1196
1237
  UserPoolOperation
1197
1238
  } from "aws-cdk-lib/aws-cognito";
1198
- import { PolicyStatement } from "aws-cdk-lib/aws-iam";
1239
+ import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
1199
1240
  import { Key as Key2 } from "aws-cdk-lib/aws-kms";
1200
1241
  import { Stack as Stack3 } from "aws-cdk-lib/core";
1242
+
1243
+ // src/services/open-hi-data-service.ts
1244
+ import { StreamViewType, Table as Table2 } from "aws-cdk-lib/aws-dynamodb";
1245
+ import { EventBus as EventBus3 } from "aws-cdk-lib/aws-events";
1246
+ import * as kinesis from "aws-cdk-lib/aws-kinesis";
1247
+ var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
1248
+ /**
1249
+ * Returns the data event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
1250
+ */
1251
+ static dataEventBusFromConstruct(scope) {
1252
+ return EventBus3.fromEventBusName(
1253
+ scope,
1254
+ "data-event-bus",
1255
+ DataEventBus.getEventBusName(scope)
1256
+ );
1257
+ }
1258
+ /**
1259
+ * Returns the ops event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
1260
+ */
1261
+ static opsEventBusFromConstruct(scope) {
1262
+ return EventBus3.fromEventBusName(
1263
+ scope,
1264
+ "ops-event-bus",
1265
+ OpsEventBus.getEventBusName(scope)
1266
+ );
1267
+ }
1268
+ /**
1269
+ * Returns the data store table by name. Use from other stacks (e.g. REST API Lambda) to obtain an ITable reference.
1270
+ */
1271
+ static dynamoDbDataStoreFromConstruct(scope, id = "dynamo-db-data-store") {
1272
+ return Table2.fromTableName(scope, id, getDynamoDbDataStoreTableName(scope));
1273
+ }
1274
+ get serviceType() {
1275
+ return _OpenHiDataService.SERVICE_TYPE;
1276
+ }
1277
+ constructor(ohEnv, props = {}) {
1278
+ super(ohEnv, _OpenHiDataService.SERVICE_TYPE, props);
1279
+ this.props = props;
1280
+ this.dataEventBus = this.createDataEventBus();
1281
+ this.opsEventBus = this.createOpsEventBus();
1282
+ this.dataStoreChangeStream = new kinesis.Stream(
1283
+ this,
1284
+ "data-store-change-stream",
1285
+ {
1286
+ streamName: `openhi-dstore-cdc-${this.branchHash}`,
1287
+ streamMode: kinesis.StreamMode.ON_DEMAND,
1288
+ // CDK default for kinesis.Stream is RETAIN, which strands the stream
1289
+ // when a non-prod stack is destroyed. Use the service's policy so
1290
+ // non-prod tears down cleanly while prod retains.
1291
+ removalPolicy: this.removalPolicy
1292
+ }
1293
+ );
1294
+ this.dataStore = this.createDataStore();
1295
+ this.dataStoreHistoricalArchive = new DataStoreHistoricalArchive(
1296
+ this,
1297
+ "data-store-historical-archive",
1298
+ {
1299
+ kinesisStream: this.dataStoreChangeStream,
1300
+ removalPolicy: this.removalPolicy,
1301
+ stackHash: this.stackHash,
1302
+ dataEventBus: this.dataEventBus
1303
+ }
1304
+ );
1305
+ this.dataStorePostgresReplica = new DataStorePostgresReplica(
1306
+ this,
1307
+ "data-store-postgres-replica",
1308
+ {
1309
+ kinesisStream: this.dataStoreChangeStream,
1310
+ removalPolicy: this.removalPolicy,
1311
+ stackHash: this.stackHash,
1312
+ branchHash: this.branchHash
1313
+ }
1314
+ );
1315
+ }
1316
+ /**
1317
+ * Creates the data event bus.
1318
+ * Override to customize.
1319
+ */
1320
+ createDataEventBus() {
1321
+ return new DataEventBus(this);
1322
+ }
1323
+ /**
1324
+ * Creates the ops event bus.
1325
+ * Override to customize.
1326
+ */
1327
+ createOpsEventBus() {
1328
+ return new OpsEventBus(this);
1329
+ }
1330
+ /**
1331
+ * Creates the single-table DynamoDB data store.
1332
+ * Override to customize.
1333
+ */
1334
+ createDataStore() {
1335
+ return new DynamoDbDataStore(this, "dynamo-db-data-store", {
1336
+ kinesisStream: this.dataStoreChangeStream,
1337
+ stream: StreamViewType.NEW_AND_OLD_IMAGES
1338
+ });
1339
+ }
1340
+ };
1341
+ _OpenHiDataService.SERVICE_TYPE = "data";
1342
+ var OpenHiDataService = _OpenHiDataService;
1343
+
1344
+ // src/services/open-hi-auth-service.ts
1201
1345
  var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
1346
+ constructor(ohEnv, props = {}) {
1347
+ super(ohEnv, _OpenHiAuthService.SERVICE_TYPE, props);
1348
+ /**
1349
+ * Cross-stack reference to the data store table. Cached so repeated
1350
+ * lookups share a single CDK construct id ("dynamo-db-data-store") in
1351
+ * this stack — a second `Table.fromTableName` call under the same scope
1352
+ * would collide.
1353
+ */
1354
+ this._dataStoreTable = null;
1355
+ this.props = props;
1356
+ this.userPoolKmsKey = this.createUserPoolKmsKey();
1357
+ this.preTokenGenerationLambda = this.createPreTokenGenerationLambda();
1358
+ this.postAuthenticationLambda = this.createPostAuthenticationLambda();
1359
+ this.postConfirmationLambda = this.createPostConfirmationLambda();
1360
+ this.userPool = this.createUserPool();
1361
+ this.grantPostAuthenticationPermissions();
1362
+ this.grantPostConfirmationPermissions();
1363
+ this.userPoolClient = this.createUserPoolClient();
1364
+ this.userPoolDomain = this.createUserPoolDomain();
1365
+ this.fixtureSeederClient = this.createFixtureSeederClient();
1366
+ }
1202
1367
  /**
1203
1368
  * Returns an IUserPool by looking up the Auth stack's User Pool ID from SSM.
1204
1369
  */
@@ -1270,18 +1435,6 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
1270
1435
  get serviceType() {
1271
1436
  return _OpenHiAuthService.SERVICE_TYPE;
1272
1437
  }
1273
- constructor(ohEnv, props = {}) {
1274
- super(ohEnv, _OpenHiAuthService.SERVICE_TYPE, props);
1275
- this.props = props;
1276
- this.userPoolKmsKey = this.createUserPoolKmsKey();
1277
- this.preTokenGenerationLambda = this.createPreTokenGenerationLambda();
1278
- this.postAuthenticationLambda = this.createPostAuthenticationLambda();
1279
- this.userPool = this.createUserPool();
1280
- this.grantPostAuthenticationPermissions();
1281
- this.userPoolClient = this.createUserPoolClient();
1282
- this.userPoolDomain = this.createUserPoolDomain();
1283
- this.fixtureSeederClient = this.createFixtureSeederClient();
1284
- }
1285
1438
  /**
1286
1439
  * Creates the KMS key for the Cognito User Pool and exports its ARN to SSM.
1287
1440
  * Look up via {@link OpenHiAuthService.userPoolKmsKeyFromConstruct}.
@@ -1313,6 +1466,25 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
1313
1466
  const construct = new PostAuthenticationLambda(this);
1314
1467
  return construct.lambda;
1315
1468
  }
1469
+ /**
1470
+ * Creates the Post Confirmation Lambda (Cognito trigger). On sign-up
1471
+ * confirmation, writes the new user's default Tenant, Workspace,
1472
+ * Memberships, and `tenant-user` RoleAssignment, plus a User record
1473
+ * carrying the Cognito `sub` and current tenant/workspace pointers
1474
+ * (ADR 2026-03-17-01 invariants).
1475
+ */
1476
+ createPostConfirmationLambda() {
1477
+ const construct = new PostConfirmationLambda(this, {
1478
+ dynamoTableName: this.dataStoreTable().tableName
1479
+ });
1480
+ return construct.lambda;
1481
+ }
1482
+ dataStoreTable() {
1483
+ if (this._dataStoreTable === null) {
1484
+ this._dataStoreTable = OpenHiDataService.dynamoDbDataStoreFromConstruct(this);
1485
+ }
1486
+ return this._dataStoreTable;
1487
+ }
1316
1488
  /**
1317
1489
  * Creates the Cognito User Pool and exports its ID to SSM.
1318
1490
  * Look up via {@link OpenHiAuthService.userPoolFromConstruct}.
@@ -1332,6 +1504,10 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
1332
1504
  UserPoolOperation.POST_AUTHENTICATION,
1333
1505
  this.postAuthenticationLambda
1334
1506
  );
1507
+ userPool.addTrigger(
1508
+ UserPoolOperation.POST_CONFIRMATION,
1509
+ this.postConfirmationLambda
1510
+ );
1335
1511
  new DiscoverableStringParameter(this, "user-pool-param", {
1336
1512
  ssmParamName: CognitoUserPool.SSM_PARAM_NAME,
1337
1513
  stringValue: userPool.userPoolId,
@@ -1366,6 +1542,28 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
1366
1542
  })
1367
1543
  );
1368
1544
  }
1545
+ /**
1546
+ * Grants the Post Confirmation Lambda write access to the data store
1547
+ * table (and its GSIs) so it can seed the new user's Tenant, Workspace,
1548
+ * Memberships, RoleAssignment, and User records on sign-up confirmation.
1549
+ */
1550
+ grantPostConfirmationPermissions() {
1551
+ const dataStoreTable = this.dataStoreTable();
1552
+ const dynamoActions = [
1553
+ "dynamodb:PutItem",
1554
+ "dynamodb:UpdateItem",
1555
+ "dynamodb:BatchWriteItem",
1556
+ "dynamodb:DescribeTable"
1557
+ ];
1558
+ dataStoreTable.grant(this.postConfirmationLambda, ...dynamoActions);
1559
+ this.postConfirmationLambda.addToRolePolicy(
1560
+ new PolicyStatement({
1561
+ effect: Effect.ALLOW,
1562
+ actions: [...dynamoActions],
1563
+ resources: [`${dataStoreTable.tableArn}/index/*`]
1564
+ })
1565
+ );
1566
+ }
1369
1567
  /**
1370
1568
  * Creates the User Pool Client and exports its ID to SSM (AUTH service type).
1371
1569
  * Look up via {@link OpenHiAuthService.userPoolClientFromConstruct}.
@@ -1550,7 +1748,7 @@ import {
1550
1748
  } from "aws-cdk-lib/aws-apigatewayv2";
1551
1749
  import { HttpUserPoolAuthorizer } from "aws-cdk-lib/aws-apigatewayv2-authorizers";
1552
1750
  import { HttpLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations";
1553
- import { Effect, PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
1751
+ import { Effect as Effect2, PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
1554
1752
  import {
1555
1753
  ARecord,
1556
1754
  HostedZone as HostedZone3,
@@ -1559,154 +1757,53 @@ import {
1559
1757
  import { ApiGatewayv2DomainProperties } from "aws-cdk-lib/aws-route53-targets";
1560
1758
  import { Duration as Duration6 } from "aws-cdk-lib/core";
1561
1759
 
1562
- // src/services/open-hi-data-service.ts
1563
- import { StreamViewType, Table as Table2 } from "aws-cdk-lib/aws-dynamodb";
1564
- import { EventBus as EventBus3 } from "aws-cdk-lib/aws-events";
1565
- import * as kinesis from "aws-cdk-lib/aws-kinesis";
1566
- var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
1567
- /**
1568
- * Returns the data event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
1569
- */
1570
- static dataEventBusFromConstruct(scope) {
1571
- return EventBus3.fromEventBusName(
1572
- scope,
1573
- "data-event-bus",
1574
- DataEventBus.getEventBusName(scope)
1575
- );
1576
- }
1577
- /**
1578
- * Returns the ops event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
1579
- */
1580
- static opsEventBusFromConstruct(scope) {
1581
- return EventBus3.fromEventBusName(
1582
- scope,
1583
- "ops-event-bus",
1584
- OpsEventBus.getEventBusName(scope)
1585
- );
1586
- }
1587
- /**
1588
- * Returns the data store table by name. Use from other stacks (e.g. REST API Lambda) to obtain an ITable reference.
1589
- */
1590
- static dynamoDbDataStoreFromConstruct(scope, id = "dynamo-db-data-store") {
1591
- return Table2.fromTableName(scope, id, getDynamoDbDataStoreTableName(scope));
1592
- }
1593
- get serviceType() {
1594
- return _OpenHiDataService.SERVICE_TYPE;
1595
- }
1596
- constructor(ohEnv, props = {}) {
1597
- super(ohEnv, _OpenHiDataService.SERVICE_TYPE, props);
1598
- this.props = props;
1599
- this.dataEventBus = this.createDataEventBus();
1600
- this.opsEventBus = this.createOpsEventBus();
1601
- this.dataStoreChangeStream = new kinesis.Stream(
1602
- this,
1603
- "data-store-change-stream",
1604
- {
1605
- streamName: `openhi-dstore-cdc-${this.branchHash}`,
1606
- streamMode: kinesis.StreamMode.ON_DEMAND,
1607
- // CDK default for kinesis.Stream is RETAIN, which strands the stream
1608
- // when a non-prod stack is destroyed. Use the service's policy so
1609
- // non-prod tears down cleanly while prod retains.
1610
- removalPolicy: this.removalPolicy
1611
- }
1612
- );
1613
- this.dataStore = this.createDataStore();
1614
- this.dataStoreHistoricalArchive = new DataStoreHistoricalArchive(
1615
- this,
1616
- "data-store-historical-archive",
1617
- {
1618
- kinesisStream: this.dataStoreChangeStream,
1619
- removalPolicy: this.removalPolicy,
1620
- stackHash: this.stackHash,
1621
- dataEventBus: this.dataEventBus
1622
- }
1623
- );
1624
- this.dataStorePostgresReplica = new DataStorePostgresReplica(
1625
- this,
1626
- "data-store-postgres-replica",
1627
- {
1628
- kinesisStream: this.dataStoreChangeStream,
1629
- removalPolicy: this.removalPolicy,
1630
- stackHash: this.stackHash,
1631
- branchHash: this.branchHash
1632
- }
1633
- );
1634
- }
1635
- /**
1636
- * Creates the data event bus.
1637
- * Override to customize.
1638
- */
1639
- createDataEventBus() {
1640
- return new DataEventBus(this);
1641
- }
1642
- /**
1643
- * Creates the ops event bus.
1644
- * Override to customize.
1645
- */
1646
- createOpsEventBus() {
1647
- return new OpsEventBus(this);
1648
- }
1649
- /**
1650
- * Creates the single-table DynamoDB data store.
1651
- * Override to customize.
1652
- */
1653
- createDataStore() {
1654
- return new DynamoDbDataStore(this, "dynamo-db-data-store", {
1655
- kinesisStream: this.dataStoreChangeStream,
1656
- stream: StreamViewType.NEW_AND_OLD_IMAGES
1657
- });
1658
- }
1659
- };
1660
- _OpenHiDataService.SERVICE_TYPE = "data";
1661
- var OpenHiDataService = _OpenHiDataService;
1662
-
1663
1760
  // src/data/lambda/cors-options-lambda.ts
1664
- import fs5 from "fs";
1665
- import path5 from "path";
1666
- import { Runtime as Runtime5 } from "aws-cdk-lib/aws-lambda";
1667
- import { NodejsFunction as NodejsFunction5 } from "aws-cdk-lib/aws-lambda-nodejs";
1668
- import { Construct as Construct7 } from "constructs";
1669
- var HANDLER_NAME5 = "cors-options-lambda.handler.js";
1670
- function resolveHandlerEntry5(dirname) {
1671
- const sameDir = path5.join(dirname, HANDLER_NAME5);
1672
- if (fs5.existsSync(sameDir)) {
1761
+ import fs6 from "fs";
1762
+ import path6 from "path";
1763
+ import { Runtime as Runtime6 } from "aws-cdk-lib/aws-lambda";
1764
+ import { NodejsFunction as NodejsFunction6 } from "aws-cdk-lib/aws-lambda-nodejs";
1765
+ import { Construct as Construct8 } from "constructs";
1766
+ var HANDLER_NAME6 = "cors-options-lambda.handler.js";
1767
+ function resolveHandlerEntry6(dirname) {
1768
+ const sameDir = path6.join(dirname, HANDLER_NAME6);
1769
+ if (fs6.existsSync(sameDir)) {
1673
1770
  return sameDir;
1674
1771
  }
1675
- const fromLib = path5.join(dirname, "..", "..", "..", "lib", HANDLER_NAME5);
1772
+ const fromLib = path6.join(dirname, "..", "..", "..", "lib", HANDLER_NAME6);
1676
1773
  return fromLib;
1677
1774
  }
1678
- var CorsOptionsLambda = class extends Construct7 {
1775
+ var CorsOptionsLambda = class extends Construct8 {
1679
1776
  constructor(scope, id = "cors-options-lambda") {
1680
1777
  super(scope, id);
1681
- this.lambda = new NodejsFunction5(this, "handler", {
1682
- entry: resolveHandlerEntry5(__dirname),
1683
- runtime: Runtime5.NODEJS_LATEST,
1778
+ this.lambda = new NodejsFunction6(this, "handler", {
1779
+ entry: resolveHandlerEntry6(__dirname),
1780
+ runtime: Runtime6.NODEJS_LATEST,
1684
1781
  memorySize: 128
1685
1782
  });
1686
1783
  }
1687
1784
  };
1688
1785
 
1689
1786
  // src/data/lambda/rest-api-lambda.ts
1690
- import fs6 from "fs";
1691
- import path6 from "path";
1692
- import { Runtime as Runtime6 } from "aws-cdk-lib/aws-lambda";
1693
- import { NodejsFunction as NodejsFunction6 } from "aws-cdk-lib/aws-lambda-nodejs";
1694
- import { Construct as Construct8 } from "constructs";
1695
- var HANDLER_NAME6 = "rest-api-lambda.handler.js";
1696
- function resolveHandlerEntry6(dirname) {
1697
- const sameDir = path6.join(dirname, HANDLER_NAME6);
1698
- if (fs6.existsSync(sameDir)) {
1787
+ import fs7 from "fs";
1788
+ import path7 from "path";
1789
+ import { Runtime as Runtime7 } from "aws-cdk-lib/aws-lambda";
1790
+ import { NodejsFunction as NodejsFunction7 } from "aws-cdk-lib/aws-lambda-nodejs";
1791
+ import { Construct as Construct9 } from "constructs";
1792
+ var HANDLER_NAME7 = "rest-api-lambda.handler.js";
1793
+ function resolveHandlerEntry7(dirname) {
1794
+ const sameDir = path7.join(dirname, HANDLER_NAME7);
1795
+ if (fs7.existsSync(sameDir)) {
1699
1796
  return sameDir;
1700
1797
  }
1701
- const fromLib = path6.join(dirname, "..", "..", "..", "lib", HANDLER_NAME6);
1798
+ const fromLib = path7.join(dirname, "..", "..", "..", "lib", HANDLER_NAME7);
1702
1799
  return fromLib;
1703
1800
  }
1704
- var RestApiLambda = class extends Construct8 {
1801
+ var RestApiLambda = class extends Construct9 {
1705
1802
  constructor(scope, props) {
1706
1803
  super(scope, "rest-api-lambda");
1707
- this.lambda = new NodejsFunction6(this, "handler", {
1708
- entry: resolveHandlerEntry6(__dirname),
1709
- runtime: Runtime6.NODEJS_LATEST,
1804
+ this.lambda = new NodejsFunction7(this, "handler", {
1805
+ entry: resolveHandlerEntry7(__dirname),
1806
+ runtime: Runtime7.NODEJS_LATEST,
1710
1807
  memorySize: 1024,
1711
1808
  environment: {
1712
1809
  DYNAMO_TABLE_NAME: props.dynamoTableName,
@@ -1849,7 +1946,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
1849
1946
  });
1850
1947
  lambda.addToRolePolicy(
1851
1948
  new PolicyStatement2({
1852
- effect: Effect.ALLOW,
1949
+ effect: Effect2.ALLOW,
1853
1950
  actions: [
1854
1951
  "rds-data:ExecuteStatement",
1855
1952
  "rds-data:BatchExecuteStatement"
@@ -1859,7 +1956,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
1859
1956
  );
1860
1957
  lambda.addToRolePolicy(
1861
1958
  new PolicyStatement2({
1862
- effect: Effect.ALLOW,
1959
+ effect: Effect2.ALLOW,
1863
1960
  actions: ["secretsmanager:GetSecretValue"],
1864
1961
  resources: [postgresSecretArn]
1865
1962
  })
@@ -1878,14 +1975,14 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
1878
1975
  dataStoreTable.grant(lambda, ...dynamoActions);
1879
1976
  lambda.addToRolePolicy(
1880
1977
  new PolicyStatement2({
1881
- effect: Effect.ALLOW,
1978
+ effect: Effect2.ALLOW,
1882
1979
  actions: [...dynamoActions],
1883
1980
  resources: [`${dataStoreTable.tableArn}/index/*`]
1884
1981
  })
1885
1982
  );
1886
1983
  lambda.addToRolePolicy(
1887
1984
  new PolicyStatement2({
1888
- effect: Effect.ALLOW,
1985
+ effect: Effect2.ALLOW,
1889
1986
  actions: [
1890
1987
  "ssm:GetParameter",
1891
1988
  "ssm:GetParameters",
@@ -2064,6 +2161,7 @@ export {
2064
2161
  POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME,
2065
2162
  POSTGRES_REPLICA_SECRET_ARN_SSM_NAME,
2066
2163
  PostAuthenticationLambda,
2164
+ PostConfirmationLambda,
2067
2165
  PreTokenGenerationLambda,
2068
2166
  REST_API_BASE_URL_SSM_NAME,
2069
2167
  RootGraphqlApi,