@openhi/constructs 0.0.21 → 0.0.23
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
|
@@ -299,7 +299,7 @@ var OpenHiService = class extends Stack {
|
|
|
299
299
|
const appName = props.appName ?? ohEnv.ohStage.ohApp.appName ?? "openhi";
|
|
300
300
|
const repoName = props.repoName ?? findGitRepoName();
|
|
301
301
|
const defaultReleaseBranch = props.defaultReleaseBranch ?? "main";
|
|
302
|
-
const branchName = props.branchName ?? (process.env.JEST_WORKER_ID ? "test-branch" : ohEnv.ohStage.stageType === import_config3.OPEN_HI_STAGE.DEV ? findGitBranch() : defaultReleaseBranch);
|
|
302
|
+
const branchName = props.branchName ?? (process.env.JEST_WORKER_ID ? "test-branch" : process.env.GIT_BRANCH_NAME?.trim() || (ohEnv.ohStage.stageType === import_config3.OPEN_HI_STAGE.DEV ? findGitBranch() : defaultReleaseBranch));
|
|
303
303
|
const environmentHash = hashString(
|
|
304
304
|
[appName, ohEnv.deploymentTargetRole, account, region].join("-"),
|
|
305
305
|
6
|
|
@@ -1148,15 +1148,25 @@ _OpenHiDataService.SERVICE_TYPE = "data";
|
|
|
1148
1148
|
var OpenHiDataService = _OpenHiDataService;
|
|
1149
1149
|
|
|
1150
1150
|
// src/data/lambda/rest-api-lambda.ts
|
|
1151
|
+
import fs2 from "fs";
|
|
1151
1152
|
import path2 from "path";
|
|
1152
1153
|
import { Runtime as Runtime2 } from "aws-cdk-lib/aws-lambda";
|
|
1153
1154
|
import { NodejsFunction as NodejsFunction2 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
1154
1155
|
import { Construct as Construct3 } from "constructs";
|
|
1156
|
+
var HANDLER_NAME2 = "rest-api-lambda.handler.js";
|
|
1157
|
+
function resolveHandlerEntry2(dirname) {
|
|
1158
|
+
const sameDir = path2.join(dirname, HANDLER_NAME2);
|
|
1159
|
+
if (fs2.existsSync(sameDir)) {
|
|
1160
|
+
return sameDir;
|
|
1161
|
+
}
|
|
1162
|
+
const fromLib = path2.join(dirname, "..", "..", "..", "lib", HANDLER_NAME2);
|
|
1163
|
+
return fromLib;
|
|
1164
|
+
}
|
|
1155
1165
|
var RestApiLambda = class extends Construct3 {
|
|
1156
1166
|
constructor(scope, props) {
|
|
1157
1167
|
super(scope, "rest-api-lambda");
|
|
1158
1168
|
this.lambda = new NodejsFunction2(this, "handler", {
|
|
1159
|
-
entry:
|
|
1169
|
+
entry: resolveHandlerEntry2(__dirname),
|
|
1160
1170
|
runtime: Runtime2.NODEJS_LATEST,
|
|
1161
1171
|
memorySize: 1024,
|
|
1162
1172
|
environment: {
|
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../src/app/open-hi-app.ts","../src/app/open-hi-environment.ts","../src/app/open-hi-stage.ts","../src/app/open-hi-service.ts","../src/components/acm/root-wildcard-certificate.ts","../src/components/api-gateway/root-http-api.ts","../src/components/app-sync/root-graphql-api.ts","../src/components/ssm/discoverable-string-parameter.ts","../src/components/cognito/cognito-user-pool.ts","../src/components/cognito/cognito-user-pool-client.ts","../src/components/cognito/cognito-user-pool-domain.ts","../src/components/cognito/cognito-user-pool-kms-key.ts","../src/components/cognito/pre-token-generation-lambda.ts","../src/components/dynamodb/dynamo-db-data-store.ts","../src/components/event-bridge/data-event-bus.ts","../src/components/event-bridge/ops-event-bus.ts","../src/components/route-53/child-hosted-zone.ts","../src/components/route-53/root-hosted-zone.ts","../src/services/open-hi-auth-service.ts","../src/services/open-hi-global-service.ts","../src/services/open-hi-rest-api-service.ts","../src/services/open-hi-data-service.ts","../src/data/lambda/rest-api-lambda.ts","../src/services/open-hi-graphql-service.ts"],"sourcesContent":["/*******************************************************************************\n *\n * OpenHi Config\n *\n * These types are kept in their own package to prevent dependency conflicts and\n * conditions between @openhi/constructs and @openhi/platform..\n *\n ******************************************************************************/\n\n/**\n * Stage Types\n *\n * What stage of deployment is this? Dev, staging, or prod?\n */\nexport const OPEN_HI_STAGE = {\n /**\n * Development environment, typically used for testing and development.\n */\n DEV: \"dev\",\n /**\n * Staging environment, used for pre-production testing.\n */\n STAGE: \"stage\",\n /**\n * Production environment, used for live deployments.\n */\n PROD: \"prod\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiStageType =\n (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n\n/**\n * Deployment Target Role\n *\n * Is this (account, region) the primary or a secondary deployment target for the stage?\n * Works for both multi-region (different regions) and cellular (same region, different accounts).\n */\nexport const OPEN_HI_DEPLOYMENT_TARGET_ROLE = {\n /**\n * The primary deployment target for this stage (main account/region).\n * For example, the base DynamoDB region for global tables.\n */\n PRIMARY: \"primary\",\n\n /**\n * A secondary deployment target for this stage (additional account/region).\n * For example, a replica region for a global DynamoDB table, or another cell in the same region.\n */\n SECONDARY: \"secondary\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiDeploymentTargetRoleType =\n (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\nexport interface OpenHiEnvironmentConfig {\n account: string;\n region: string;\n /**\n * Route53 zone containing DNS for this service.\n */\n hostedZoneId?: string;\n zoneName?: string;\n}\n\n/**\n * Represents the configuration for OpenHi services across different stages and\n * deployment targets.\n */\nexport interface OpenHiConfig {\n versions?: {\n cdk?: {\n cdkLibVersion?: string;\n cdkCliVersion?: string;\n };\n };\n deploymentTargets?: {\n [OPEN_HI_STAGE.DEV]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.STAGE]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.PROD]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n };\n}\n","export * from \"./open-hi-config\";\n","import {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OPEN_HI_STAGE,\n OpenHiConfig,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { App, AppProps } from \"aws-cdk-lib\";\nimport { IConstruct } from \"constructs\";\nimport { OpenHiEnvironment } from \"./open-hi-environment\";\nimport { OpenHiStage } from \"./open-hi-stage\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-app.md\n */\n\n/**\n * Symbol used for runtime type checking to identify OpenHiApp instances.\n *\n * @internal\n */\nconst OPEN_HI_APP_SYMBOL = Symbol.for(\"@openhi/constructs/core.OpenHiApp\");\n\n/**\n * Properties for creating an OpenHiApp instance.\n */\nexport interface OpenHiAppProps extends AppProps {\n /**\n * Optional name for the application.\n * ```\n */\n readonly appName?: string;\n\n /**\n * The OpenHi configuration object that defines stages, environments, and\n * their associated AWS account and region settings.\n */\n readonly config: OpenHiConfig;\n}\n\n/**\n * Root application construct for OpenHi CDK applications.\n */\nexport class OpenHiApp extends App {\n /**\n * Finds the OpenHiApp instance that contains the given construct in its\n * construct tree.\n */\n public static of(construct: IConstruct): OpenHiApp | undefined {\n return construct.node.scopes.reverse().find(OpenHiApp.isOpenHiApp);\n }\n\n /**\n * Type guard that checks if a value is an OpenHiApp instance.\n */\n public static isOpenHiApp(this: void, x: any): x is OpenHiApp {\n return x !== null && typeof x === \"object\" && OPEN_HI_APP_SYMBOL in x;\n }\n\n /**\n * Name for the application.\n */\n readonly appName: string;\n\n /**\n * The OpenHi configuration object for this application.\n */\n readonly config: OpenHiConfig;\n\n /**\n * Creates a new OpenHiApp instance.\n */\n constructor(props: OpenHiAppProps) {\n super(props);\n\n // Set runtime symbol for type checking\n Object.defineProperty(this, OPEN_HI_APP_SYMBOL, { value: true });\n\n // Store app name, defaulting to \"openhi\" if not provided\n this.appName = props.appName ?? \"openhi\";\n\n // Store configuration for use by child constructs\n this.config = props.config;\n\n // Create stages and environments based on configuration\n // Iterate through all possible stage types (dev, stage, prod)\n Object.values(OPEN_HI_STAGE).forEach((stageType) => {\n // Only create a stage if it's configured in the config\n if (this.config.deploymentTargets?.[stageType]) {\n const stage = new OpenHiStage(this, { stageType });\n\n // Create primary deployment target if configured\n // Each stage can have at most one primary deployment target\n if (\n this.config.deploymentTargets?.[stageType]?.[\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY\n ]\n ) {\n const envConfig =\n this.config.deploymentTargets[stageType][\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY\n ]!;\n new OpenHiEnvironment(stage, {\n deploymentTargetRole: OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,\n config: envConfig,\n env: { account: envConfig.account, region: envConfig.region },\n });\n }\n\n // Create secondary deployment targets if configured\n // Each stage can have zero or more secondary deployment targets\n if (\n this.config.deploymentTargets?.[stageType]?.[\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY\n ]\n ) {\n this.config.deploymentTargets[stageType][\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY\n ]!.forEach((envConfig: OpenHiEnvironmentConfig) => {\n new OpenHiEnvironment(stage, {\n deploymentTargetRole: OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,\n config: envConfig,\n env: { account: envConfig.account, region: envConfig.region },\n });\n });\n }\n }\n });\n }\n\n /*****************************************************************************\n *\n * Stages\n *\n ****************************************************************************/\n\n /**\n * Gets all OpenHiStage instances that are direct children of this app.\n\n */\n public get stages(): Array<OpenHiStage> {\n return this.node.children.filter(OpenHiStage.isOpenHiStage);\n }\n\n /**\n * Gets the development stage, if it exists.\n */\n public get devStage(): OpenHiStage | undefined {\n return this.stages.find((stage) => stage.stageType === OPEN_HI_STAGE.DEV);\n }\n\n /**\n * Gets the staging stage, if it exists.\n */\n public get stageStage(): OpenHiStage | undefined {\n return this.stages.find((stage) => stage.stageType === OPEN_HI_STAGE.STAGE);\n }\n\n /**\n * Gets the production stage, if it exists.\n */\n public get prodStage(): OpenHiStage | undefined {\n return this.stages.find((stage) => stage.stageType === OPEN_HI_STAGE.PROD);\n }\n\n /*****************************************************************************\n *\n * Environments\n *\n ****************************************************************************/\n\n /**\n * Gets all OpenHiEnvironment instances across all stages in this app.\n */\n public get environments(): Array<OpenHiEnvironment> {\n return this.stages.flatMap((stage) => stage.environments);\n }\n\n /**\n * Gets all primary environments across all stages in this app.\n */\n public get primaryEnvironments(): Array<OpenHiEnvironment> {\n return this.environments.filter(\n (env) => env.deploymentTargetRole === \"primary\",\n );\n }\n\n /**\n * Gets all secondary environments across all stages in this app.\n */\n public get secondaryEnvironments(): Array<OpenHiEnvironment> {\n return this.environments.filter(\n (env) => env.deploymentTargetRole === \"secondary\",\n );\n }\n}\n","import {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { Stage, StageProps } from \"aws-cdk-lib\";\nimport { IConstruct } from \"constructs\";\nimport { OpenHiStage } from \"./open-hi-stage\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-environment.md\n */\n\n/**\n * Symbol used to identify OpenHiEnvironment instances at runtime.\n */\nconst OPEN_HI_ENVIRONMENT_SYMBOL = Symbol.for(\n \"@openhi/constructs/core.OpenHiEnvironment\",\n);\n\n/**\n * Properties for creating an OpenHiEnvironment.\n */\nexport interface OpenHiEnvironmentProps extends StageProps {\n /**\n * The deployment target role for this (account, region).\n */\n readonly deploymentTargetRole: (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\n /**\n * Configuration for this specific environment.\n */\n readonly config: OpenHiEnvironmentConfig;\n}\n\n/**\n * Represents an OpenHi environment within an AWS CDK stage.\n */\nexport class OpenHiEnvironment extends Stage {\n /**\n * Finds the OpenHiEnvironment that contains the given construct.\n * ```\n */\n public static of(construct: IConstruct): OpenHiEnvironment | undefined {\n return construct.node.scopes\n .reverse()\n .find(OpenHiEnvironment.isOpenHiEnvironment);\n }\n\n /**\n * Type guard to check if a value is an OpenHiEnvironment instance.\n */\n public static isOpenHiEnvironment(\n this: void,\n x: any,\n ): x is OpenHiEnvironment {\n return (\n x !== null && typeof x === \"object\" && OPEN_HI_ENVIRONMENT_SYMBOL in x\n );\n }\n\n /**\n * Configuration for this specific environment.\n */\n readonly config: OpenHiEnvironmentConfig;\n\n /**\n * The deployment target role for this (account, region).\n */\n public readonly deploymentTargetRole: (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\n /**\n * Creates a new OpenHiEnvironment.\n */\n constructor(\n /**\n * The OpenHiStage that contains this environment.\n */\n public ohStage: OpenHiStage,\n /**\n * Properties for creating the environment.\n */\n public props: OpenHiEnvironmentProps,\n ) {\n // Copy account and region from config into env, if provided.\n // This allows all resources in this environment to default to the correct\n // account and region without having to specify it on each stack or resource.\n if (props.config.account && props.config.region) {\n props = {\n ...props,\n env: {\n account: props.config.account,\n region: props.config.region,\n },\n };\n }\n\n // Determine the stage name:\n // - Primary environments use the environment type as the name\n // - Secondary deployment targets use \"{deploymentTargetRole}-{index}\" format\n const stageName =\n props.deploymentTargetRole === OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY\n ? props.deploymentTargetRole\n : [props.deploymentTargetRole, ohStage.environments.length].join(\"-\");\n\n super(ohStage, stageName, {\n env: props.env ?? ohStage.props.env,\n ...props,\n });\n\n // Mark this instance as an OpenHiEnvironment for runtime type checking\n Object.defineProperty(this, OPEN_HI_ENVIRONMENT_SYMBOL, { value: true });\n\n this.deploymentTargetRole = props.deploymentTargetRole;\n this.config = props.config;\n }\n}\n","import { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Stage, StageProps } from \"aws-cdk-lib\";\nimport { IConstruct } from \"constructs\";\nimport { OpenHiApp } from \"./open-hi-app\";\nimport { OpenHiEnvironment } from \"./open-hi-environment\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-stage.md\n */\n\n/**\n * Symbol used to identify OpenHiStage instances at runtime.\n *\n * @internal\n */\nconst OPEN_HI_STAGE_SYMBOL = Symbol.for(\"@openhi/constructs/core.OpenHiStage\");\n\n/**\n * Properties for creating an OpenHiStage instance.\n */\nexport interface OpenHiStageProps extends StageProps {\n /**\n * The type of the OpenHi stage.\n */\n readonly stageType: (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n}\n\n/**\n * Represents a deployment stage in the OpenHi infrastructure hierarchy.\n */\nexport class OpenHiStage extends Stage {\n /**\n * Finds the OpenHiStage that contains the given construct.\n */\n public static of(construct: IConstruct): OpenHiStage | undefined {\n return construct.node.scopes.reverse().find(OpenHiStage.isOpenHiStage);\n }\n\n /**\n * Type guard to check if a value is an OpenHiStage instance.\n */\n public static isOpenHiStage(this: void, x: any): x is OpenHiStage {\n return x !== null && typeof x === \"object\" && OPEN_HI_STAGE_SYMBOL in x;\n }\n\n /**\n * The type of this OpenHi stage.\n */\n public readonly stageType: (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n\n /**\n * Creates a new OpenHiStage instance.\n */\n constructor(\n /**\n * The OpenHiApp that this stage belongs to.\n *\n * @public\n */\n public ohApp: OpenHiApp,\n\n /**\n * Properties for configuring the stage.\n *\n * @public\n */\n public props: OpenHiStageProps,\n ) {\n super(ohApp, props.stageType, props);\n\n Object.defineProperty(this, OPEN_HI_STAGE_SYMBOL, { value: true });\n\n this.stageType = props.stageType;\n }\n\n /**\n * Gets all OpenHiEnvironment instances contained within this stage.\n */\n public get environments(): Array<OpenHiEnvironment> {\n return this.node.children.filter(OpenHiEnvironment.isOpenHiEnvironment);\n }\n\n /**\n * Gets the primary OpenHiEnvironment for this stage, if one exists.\n */\n public get primaryEnvironment(): OpenHiEnvironment | undefined {\n return this.environments.find(\n (env) => env.deploymentTargetRole === \"primary\",\n );\n }\n\n /**\n * Gets all secondary OpenHiEnvironment instances for this stage.\n */\n public get secondaryEnvironments(): Array<OpenHiEnvironment> {\n return this.environments.filter(\n (env) => env.deploymentTargetRole === \"secondary\",\n );\n }\n}\n","import {\n findGitBranch,\n findGitRepoName,\n hashString,\n} from \"@codedrifters/utils\";\nimport { OPEN_HI_STAGE, OpenHiEnvironmentConfig } from \"@openhi/config\";\nimport { RemovalPolicy, Stack, StackProps, Tags } from \"aws-cdk-lib\";\nimport { paramCase } from \"change-case\";\nimport { OpenHiEnvironment } from \"./open-hi-environment\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-service.md\n */\n\n/**\n * Known OpenHI service type strings. Each service class defines its own\n * static SERVICE_TYPE (e.g. OpenHiAuthService.SERVICE_TYPE === \"auth\").\n *\n * @public\n */\nexport type OpenHiServiceType =\n | \"auth\"\n | \"rest-api\"\n | \"data\"\n | \"global\"\n | \"graphql-api\";\n\n/**\n * Properties for creating an {@link OpenHiService} stack.\n *\n * @public\n */\nexport interface OpenHiServiceProps extends StackProps {\n /**\n * Optional branch name override.\n */\n readonly branchName?: string;\n\n /**\n * Optional repository name override.\n */\n readonly repoName?: string;\n\n /**\n * Optional application name override.\n */\n readonly appName?: string;\n\n /**\n * Default release branch name.\n */\n readonly defaultReleaseBranch?: string;\n\n /**\n * The removal policy for persistent stack resources.\n */\n readonly removalPolicy?: RemovalPolicy;\n\n /**\n * Environment configuration for this service.\n */\n readonly config?: OpenHiEnvironmentConfig;\n\n /**\n * A constant that identifies the service type.\n */\n readonly serviceType?: OpenHiServiceType;\n}\n\n/**\n * Represents an OpenHI service stack within the OpenHI platform.\n * Subclasses must override {@link serviceType} to return their static SERVICE_TYPE.\n */\nexport abstract class OpenHiService extends Stack {\n /**\n * The service/stack ID that was passed to the constructor.\n */\n public readonly serviceId: string;\n\n /**\n * The deployment target role identifier.\n */\n public readonly deploymentTargetRole: string;\n\n /**\n * Repository name used in resource tagging.\n */\n public readonly repoName: string;\n\n /**\n * Application name identifier.\n */\n public readonly appName: string;\n\n /**\n * Default release branch name.\n */\n public readonly defaultReleaseBranch: string;\n\n /**\n * Branch name used when calculating resource names and hashes.\n */\n public readonly branchName: string;\n\n /**\n * Short hash unique to the deployment target (app name, deployment target role, account, region).\n */\n public readonly environmentHash: string;\n\n /**\n * Short hash unique to the environment and branch combination.\n */\n public readonly branchHash: string;\n\n /**\n * Short hash unique to the specific stack/service.\n */\n public readonly stackHash: string;\n\n /**\n * The removal policy for persistent stack resources.\n */\n public readonly removalPolicy: RemovalPolicy;\n\n /**\n * Environment configuration for this service.\n * This is either the value passed in or the default config\n */\n public readonly config: OpenHiEnvironmentConfig;\n\n /**\n * Service type identifier. Override in subclasses to return the class's static SERVICE_TYPE.\n * Used for parameter names, tags, and service discovery.\n */\n abstract get serviceType(): OpenHiServiceType | string;\n\n /**\n * Creates a new OpenHI service stack.\n *\n * @param ohEnv - The OpenHI environment (stage) this service belongs to\n * @param id - Unique identifier for this service stack (e.g., \"user-service\")\n * @param props - Optional properties for configuring the service\n *\n * @throws {Error} If account and region are not defined in props or environment\n *\n */\n constructor(\n public ohEnv: OpenHiEnvironment,\n id: string,\n public props: OpenHiServiceProps = {},\n ) {\n // Determine the account and region based on environment or user passed props.\n // This must be done before calling super() as it's needed for stack naming.\n const { account, region } = props.env || ohEnv;\n if (!account || !region) {\n throw new Error(\n \"Account and region must be defined in OpenHiServiceProps or OpenHiEnvironment\",\n );\n }\n\n // Get app name from the app in the hierarchy (via environment -> stage -> app)\n const appName = props.appName ?? ohEnv.ohStage.ohApp.appName ?? \"openhi\";\n\n // Initialize deployment context properties\n // Repo name is used in tagging. This tag value is important for tracking\n // when tearing preview stacks back down. If not provided, detect from git.\n const repoName = props.repoName ?? findGitRepoName();\n\n // Default release branch is used when not in dev stage. Defaults to \"main\" if not provided.\n const defaultReleaseBranch = props.defaultReleaseBranch ?? \"main\";\n\n // Branch name is used to calculate hashes and names for resources.\n // Detection logic:\n // - If explicitly provided, use that value\n // - If Jest is running, use \"test-branch\" to avoid snapshot test issues\n // - If in dev stage, detect from git using findGitBranch()\n // - Otherwise (stage/prod), default to defaultReleaseBranch\n const branchName =\n props.branchName ??\n (process.env.JEST_WORKER_ID\n ? \"test-branch\"\n : ohEnv.ohStage.stageType === OPEN_HI_STAGE.DEV\n ? findGitBranch()\n : defaultReleaseBranch);\n\n // Compute environment hash: unique to deployment target (app name, role, account, region)\n // Mainly used for DNS names and deployment-target-scoped resources\n const environmentHash = hashString(\n [appName, ohEnv.deploymentTargetRole, account, region].join(\"-\"),\n 6,\n );\n\n // Compute branch hash: unique to deployment target and branch combination\n // Useful for resources shared across stacks within the same branch\n const branchHash = hashString(\n [appName, ohEnv.deploymentTargetRole, account, region, branchName].join(\n \"-\",\n ),\n 6,\n );\n\n // Compute stack hash: unique to the specific stack/service\n // Useful for stack-specific resources like S3 buckets, KMS key aliases\n // This ensures two PR builds or different services don't collide\n const stackHash = hashString(\n [\n appName,\n ohEnv.deploymentTargetRole,\n account,\n region,\n branchName,\n id,\n ].join(\"-\"),\n 6,\n );\n\n // Set the removal policy for this stack based on the deployment target role.\n // Production stages retain resources, others destroy them on stack deletion.\n const removalPolicy =\n props.removalPolicy ??\n (ohEnv.ohStage.stageType === OPEN_HI_STAGE.PROD\n ? RemovalPolicy.RETAIN\n : RemovalPolicy.DESTROY);\n Object.assign(props, { removalPolicy });\n\n // Description to use for the stack and all resources within it.\n // Includes service ID, branch name, and hash for easy identification.\n const description = `OpenHi Service: ${id} [${branchName}] - ${branchHash}`;\n\n // Call the super constructor of Stack.\n // This initializes the AWS CDK Stack with:\n // - Scope: the OpenHI environment\n // - ID: unique stack name including branch hash\n // - Props: stack properties including description and removal policy\n super(ohEnv, [branchHash, id, account, region].join(\"-\"), {\n ...props,\n description,\n });\n\n // Store the service ID for use in deployment context and other operations.\n this.serviceId = id;\n\n // Set the removal policy for this stack based on the deployment target role.\n this.removalPolicy = removalPolicy;\n\n /**\n * Explicit config or use the environment config as a backup,\n */\n this.config = props.config ?? ohEnv.props.config;\n\n // Initialize deployment context properties directly on the service\n this.deploymentTargetRole = ohEnv.deploymentTargetRole;\n this.repoName = repoName;\n this.appName = appName;\n this.defaultReleaseBranch = defaultReleaseBranch;\n this.branchName = branchName;\n this.environmentHash = environmentHash;\n this.branchHash = branchHash;\n this.stackHash = stackHash;\n\n // Standard tagging across all resources in the stack.\n // Use id (the service type string passed to super) since abstract serviceType cannot be accessed in constructor.\n Tags.of(this).add(`${appName}:repo-name`, repoName.slice(0, 255));\n Tags.of(this).add(`${appName}:branch-name`, branchName.slice(0, 255));\n Tags.of(this).add(`${appName}:service-type`, id.slice(0, 255));\n Tags.of(this).add(\n `${appName}:stage-type`,\n ohEnv.ohStage.stageType.slice(0, 255),\n );\n }\n\n /**\n * DNS prefix for this branche's child zone.\n */\n public get childZonePrefix(): string {\n return paramCase(this.branchName).slice(0, 200);\n }\n}\n","import {\n Certificate,\n CertificateProps,\n} from \"aws-cdk-lib/aws-certificatemanager\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/acm/root-wildcard-certificate.md\n */\n\nexport class RootWildcardCertificate extends Certificate {\n /**\n * Used when storing the Certificate ARN in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"ROOT_WILDCARD_CERT_ARN\";\n\n /**\n * Using a special name here since this will be shared and used among many\n * stacks and services. Use with OpenHiGlobalService.rootWildcardCertificateFromConstruct.\n */\n public static ssmParameterName(): string {\n return (\n \"/\" +\n [\"GLOBAL\", RootWildcardCertificate.SSM_PARAM_NAME].join(\"/\").toUpperCase()\n );\n }\n\n constructor(scope: Construct, props: CertificateProps) {\n super(scope, \"root-wildcard-certificate\", { ...props });\n\n /**\n * Generate the SSM Parameter used to store this Certificate's ARN.\n */\n new StringParameter(this, \"wildcard-cert-param\", {\n parameterName: RootWildcardCertificate.ssmParameterName(),\n stringValue: this.certificateArn,\n });\n }\n}\n","import { HttpApi, HttpApiProps } from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app/open-hi-service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/api-gateway/root-http-api.md\n */\n\nexport class RootHttpApi extends HttpApi {\n /**\n * Used when storing the API ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"ROOT_HTTP_API\";\n\n constructor(scope: Construct, props: HttpApiProps = {}) {\n const stack = OpenHiService.of(scope) as OpenHiService;\n\n const origins = props.corsPreflight?.allowOrigins;\n if (origins?.length) {\n const withTrailingSlash = origins.filter((o) => o.endsWith(\"/\"));\n if (withTrailingSlash.length > 0) {\n throw new Error(\n `CORS allowOrigins must not include a trailing slash. The browser Origin header is scheme + host + port only (no path), so API Gateway will not match origins like \"https://example.com/\" and CORS can fail. Invalid: ${withTrailingSlash.join(\", \")}. Use e.g. \"https://example.com\" instead.`,\n );\n }\n }\n\n super(scope, \"http-api\", {\n /**\n * User provided props\n */\n ...props,\n\n /**\n * Required\n */\n apiName: [\"root\", \"http\", \"api\", stack.branchHash].join(\"-\"),\n });\n }\n}\n","import {\n Definition,\n GraphqlApi,\n GraphqlApiProps,\n IGraphqlApi,\n} from \"aws-cdk-lib/aws-appsync\";\nimport { CodeFirstSchema, GraphqlType, ObjectType } from \"awscdk-appsync-utils\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/app-sync/root-graphql-api.md\n */\n\nexport interface RootGraphqlApiProps extends GraphqlApiProps {}\n\nexport class RootGraphqlApi extends GraphqlApi {\n /**\n * Used when storing the GraphQl API ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"ROOT_GRAPHQL_API\";\n\n public static fromConstruct(scope: Construct): IGraphqlApi {\n const graphqlApiId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: RootGraphqlApi.SSM_PARAM_NAME,\n serviceType: \"graphql-api\",\n });\n\n return GraphqlApi.fromGraphqlApiAttributes(scope, \"root-graphql-api\", {\n graphqlApiId,\n });\n }\n\n constructor(scope: Construct, props?: Omit<RootGraphqlApiProps, \"name\">) {\n const stack = OpenHiService.of(scope) as OpenHiService;\n\n const schema = new CodeFirstSchema();\n schema.addType(\n new ObjectType(\"Query\", {\n definition: { HelloWorld: GraphqlType.string() },\n }),\n );\n\n super(scope, \"root-graphql-api\", {\n /**\n * Defaults\n */\n queryDepthLimit: 2,\n resolverCountLimit: 50,\n definition: Definition.fromSchema(schema),\n\n /**\n * Overrideable props\n */\n ...props,\n\n /**\n * Required\n */\n name: [\"root\", \"graphql\", \"api\", stack.branchHash].join(\"-\"),\n });\n\n /**\n * Generate the SSM Parameter used to store this GraphQL API's ID.\n */\n new DiscoverableStringParameter(this, \"graphql-api-param\", {\n ssmParamName: RootGraphqlApi.SSM_PARAM_NAME,\n serviceType: \"graphql-api\",\n stringValue: this.apiId,\n });\n }\n}\n","import { Tags } from \"aws-cdk-lib\";\nimport {\n StringParameter,\n type StringParameterProps,\n} from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/ssm/discoverable-string-parameter.md\n */\n\n/*******************************************************************************\n *\n * DiscoverableStringParameterProps: props for creating or looking up SSM\n * parameters. Includes StringParameterProps (minus parameterName) plus\n * name-building fields used by buildParameterName.\n *\n ******************************************************************************/\n\nexport interface DiscoverableStringParameterProps extends Omit<\n StringParameterProps,\n \"parameterName\"\n> {\n /**\n * SSM param name used to build the SSM parameter name via buildParameterName\n * and stored as a tag on the parameter for discoverability.\n */\n readonly ssmParamName: string;\n\n /**\n * The environment hash the parameter belongs to.\n * @default - the current stack's environment hash\n */\n readonly branchHash?: string;\n\n /**\n * The service type the parameter belongs to.\n * @default - the current stack's service type\n */\n readonly serviceType?: string;\n\n /**\n * The AWS account the parameter belongs to.\n * @default - the current stack's account\n */\n readonly account?: string;\n\n /**\n * The AWS region the parameter belongs to.\n * @default - the current stack's region\n */\n readonly region?: string;\n}\n\n/**\n * Props for buildParameterName and valueForLookupName.\n * Includes ssmParamName (required) and optional overrides (branchHash, serviceType, account, region).\n */\nexport type BuildParameterNameProps = Pick<\n DiscoverableStringParameterProps,\n \"ssmParamName\" | \"branchHash\" | \"serviceType\" | \"account\" | \"region\"\n>;\n\n/**\n * Discoverable SSM string parameter construct. Extends CDK StringParameter:\n * builds parameterName from the given name via buildParameterName and tags\n * the parameter with the name constant.\n */\nexport class DiscoverableStringParameter extends StringParameter {\n /**\n * Version of the parameter name format / discoverability schema.\n * Bump when buildParameterName or tagging semantics change.\n * Also used to drive replacement of parameters during CloudFormation deploys.\n */\n public static readonly version = \"v1\";\n\n /**\n * Build a param name based on predictable attributes found in services and\n * constructs. Used for storage and retrieval of SSM values across services.\n */\n public static buildParameterName(\n scope: Construct,\n props: BuildParameterNameProps,\n ): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return (\n \"/\" +\n [\n DiscoverableStringParameter.version,\n props.branchHash ?? stack.branchHash,\n props.serviceType ?? stack.serviceType,\n props.account ?? stack.account,\n props.region ?? stack.region,\n props.ssmParamName,\n ]\n .join(\"/\")\n .toUpperCase()\n );\n }\n\n /**\n * Read the string value of an SSM parameter created with DiscoverableStringParameter,\n * using props that include ssmParamName and optional overrides (e.g. serviceType).\n */\n public static valueForLookupName(\n scope: Construct,\n props: BuildParameterNameProps,\n ): string {\n const paramName = DiscoverableStringParameter.buildParameterName(\n scope,\n props,\n );\n return StringParameter.valueForStringParameter(scope, paramName);\n }\n\n constructor(\n scope: Construct,\n id: string,\n props: DiscoverableStringParameterProps,\n ) {\n const { ssmParamName, branchHash, serviceType, account, region, ...rest } =\n props;\n\n const parameterName = DiscoverableStringParameter.buildParameterName(\n scope,\n props,\n );\n\n super(scope, id + \"-\" + DiscoverableStringParameter.version, {\n ...rest,\n parameterName,\n });\n\n const { appName } = OpenHiService.of(scope) as OpenHiService;\n Tags.of(this).add(`${appName}:param-name`, ssmParamName);\n }\n}\n","import {\n UserPool,\n UserPoolProps,\n VerificationEmailStyle,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app/open-hi-service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool.md\n */\n\nexport class CognitoUserPool extends UserPool {\n /**\n * Used when storing the User Pool ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL\";\n\n constructor(scope: Construct, props: UserPoolProps = {}) {\n const service = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, \"user-pool\", {\n /**\n * Defaults\n */\n selfSignUpEnabled: true,\n signInAliases: {\n email: true,\n },\n userVerification: {\n emailSubject: \"Verify your email!\",\n emailBody: \"Your verification code is {####}.\",\n emailStyle: VerificationEmailStyle.CODE,\n },\n removalPolicy: props.removalPolicy ?? service.removalPolicy,\n\n /**\n * Over-rideable props\n */\n ...props,\n\n /**\n * Required\n */\n userPoolName: [\"cognito\", \"user\", \"pool\", service.branchHash].join(\"-\"),\n });\n }\n}\n","import { UserPoolClient, UserPoolClientProps } from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool-client.md\n */\n\nexport class CognitoUserPoolClient extends UserPoolClient {\n /**\n * Used when storing the User Pool Client ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL_CLIENT\";\n\n constructor(scope: Construct, props: UserPoolClientProps) {\n super(scope, \"user-pool-client\", {\n /**\n * Defaults\n */\n generateSecret: false,\n oAuth: {\n flows: {\n authorizationCodeGrant: true,\n implicitCodeGrant: true,\n },\n callbackUrls: [`https://localhost:3000/oauth/callback`],\n },\n\n /**\n * Overrideable props\n */\n ...props,\n });\n }\n}\n","import { UserPoolDomain, UserPoolDomainProps } from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool-domain.md\n */\n\nexport class CognitoUserPoolDomain extends UserPoolDomain {\n /**\n * Used when storing the User Pool Domain in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL_DOMAIN\";\n\n constructor(scope: Construct, props: UserPoolDomainProps) {\n /**\n * This supports both custom and native Cognito domains, but we need to\n * name them uniquely so that swap outs work and don't cause conflicts\n * when cloudformation does it's deploy.\n */\n const id = props.cognitoDomain?.domainPrefix\n ? \"cognito-domain\"\n : \"custom-domain\";\n\n super(scope, id, {\n ...props,\n });\n }\n}\n","import { Key, KeyProps } from \"aws-cdk-lib/aws-kms\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app/open-hi-service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool-kms-key.md\n */\n\nexport class CognitoUserPoolKmsKey extends Key {\n /**\n * Used when storing the KMS Key in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL_KMS_KEY\";\n\n constructor(scope: Construct, props: KeyProps = {}) {\n const service = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, \"kms-key\", {\n ...props,\n // alias: [\"alias\", \"cognito\", service.branchHash].join(\"/\"),\n description: `KMS Key for Cognito User Pool - ${service.branchHash}`,\n removalPolicy: props.removalPolicy ?? service.removalPolicy,\n });\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { NodejsFunction } from \"aws-cdk-lib/aws-lambda-nodejs\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/pre-token-generation-lambda.md\n */\n\nconst HANDLER_NAME = \"pre-token-generation.handler.js\";\n\n/**\n * Resolve Lambda entry so it works when running from src/ (tests) or from lib/ (built).\n */\nfunction resolveHandlerEntry(dirname: string): string {\n const sameDir = path.join(dirname, HANDLER_NAME);\n if (fs.existsSync(sameDir)) {\n return sameDir;\n }\n\n const fromLib = path.join(dirname, \"..\", \"..\", \"..\", \"lib\", HANDLER_NAME);\n return fromLib;\n}\n\n/**\n * Lambda used as Cognito Pre Token Generation trigger.\n */\nexport class PreTokenGenerationLambda extends Construct {\n public readonly lambda: NodejsFunction;\n\n constructor(scope: Construct) {\n super(scope, \"pre-token-generation-lambda\");\n\n this.lambda = new NodejsFunction(this, \"handler\", {\n entry: resolveHandlerEntry(__dirname),\n runtime: Runtime.NODEJS_LATEST,\n memorySize: 1024,\n });\n }\n}\n","import { RemovalPolicy } from \"aws-cdk-lib\";\nimport {\n AttributeType,\n BillingMode,\n ProjectionType,\n Table,\n TableProps,\n} from \"aws-cdk-lib/aws-dynamodb\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/dynamodb/dynamo-db-data-store.md\n */\n\n/**\n * DynamoDB table name for the data store. Used for cross-stack reference and\n * deterministic naming per branch. The table backs multiple use cases (e.g.\n * CRM, CMS, ERP, EHR).\n */\nexport function getDynamoDbDataStoreTableName(scope: Construct): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return `data-store-${stack.branchHash}`;\n}\n\nexport interface DynamoDbDataStoreProps extends Omit<\n TableProps,\n \"tableName\" | \"removalPolicy\"\n> {\n /**\n * Optional removal policy override. If not set, uses the service's default\n * removal policy (RETAIN for prod, DESTROY otherwise).\n */\n readonly removalPolicy?: RemovalPolicy;\n}\n\n/**\n * DynamoDB table implementing the single-table design for app data (e.g. FHIR\n * resources, CRM, CMS, ERP, EHR).\n *\n * @see {@link https://github.com/codedrifters/openhi/blob/main/sites/www-docs/content/architecture/dynamodb-single-table-design.md | DynamoDB Single-Table Design}\n *\n * Primary key: PK (String), SK (String).\n * GSIs: GSI1 (reverse reference), GSI2 (identifier lookup), GSI3 (facility ops), GSI4 (resource type list).\n */\nexport class DynamoDbDataStore extends Table {\n constructor(\n scope: Construct,\n id: string,\n props: DynamoDbDataStoreProps = {},\n ) {\n const service = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, id, {\n ...props,\n tableName: getDynamoDbDataStoreTableName(scope),\n partitionKey: {\n name: \"PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"SK\",\n type: AttributeType.STRING,\n },\n billingMode: BillingMode.PAY_PER_REQUEST,\n removalPolicy: props.removalPolicy ?? service.removalPolicy,\n });\n\n // GSI1 — Reverse Reference Index: \"what references X?\"\n this.addGlobalSecondaryIndex({\n indexName: \"GSI1\",\n partitionKey: {\n name: \"GSI1PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI1SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.INCLUDE,\n nonKeyAttributes: [\"srcType\", \"srcId\", \"path\", \"srcPk\", \"srcSk\", \"ts\"],\n });\n\n // GSI2 — Identifier Lookup Index: MRN, NPI, member ID, etc.\n this.addGlobalSecondaryIndex({\n indexName: \"GSI2\",\n partitionKey: {\n name: \"GSI2PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI2SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.INCLUDE,\n nonKeyAttributes: [\"resourcePk\", \"resourceSk\", \"display\", \"status\"],\n });\n\n // GSI3 — Facility Ops Index: worklists, rosters, schedules\n this.addGlobalSecondaryIndex({\n indexName: \"GSI3\",\n partitionKey: {\n name: \"GSI3PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI3SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.INCLUDE,\n nonKeyAttributes: [\"resourcePk\", \"resourceSk\"],\n });\n\n // GSI4 — Resource Type Index: list all resources of a type in workspace (no scan)\n this.addGlobalSecondaryIndex({\n indexName: \"GSI4\",\n partitionKey: {\n name: \"GSI4PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI4SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.ALL,\n });\n }\n}\n","import { EventBus, EventBusProps } from \"aws-cdk-lib/aws-events\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/event-bridge/data-event-bus.md\n */\n\nexport class DataEventBus extends EventBus {\n /*****************************************************************************\n *\n * Return a name for this EventBus based on the stack environment hash. This\n * name is common across all stacks since it's using the environment hash in\n * it's name.\n *\n ****************************************************************************/\n\n public static getEventBusName(scope: Construct): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return `data${stack.branchHash}`;\n }\n\n constructor(scope: Construct, props?: EventBusProps) {\n super(scope, \"data-event-bus\", {\n ...props,\n eventBusName: DataEventBus.getEventBusName(scope),\n });\n }\n}\n","import { EventBus, EventBusProps } from \"aws-cdk-lib/aws-events\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/event-bridge/ops-event-bus.md\n */\n\nexport class OpsEventBus extends EventBus {\n /*****************************************************************************\n *\n * Return a name for this EventBus based on the stack environment hash. This\n * name is common across all stacks since it's using the environment hash in\n * it's name.\n *\n ****************************************************************************/\n\n public static getEventBusName(scope: Construct): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return `ops${stack.branchHash}`;\n }\n\n constructor(scope: Construct, props?: EventBusProps) {\n super(scope, \"ops-event-bus\", {\n ...props,\n eventBusName: OpsEventBus.getEventBusName(scope),\n });\n }\n}\n","import { Duration } from \"aws-cdk-lib\";\nimport {\n HostedZone,\n HostedZoneProps,\n IHostedZone,\n NsRecord,\n} from \"aws-cdk-lib/aws-route53\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/route-53/child-hosted-zone.md\n */\n\nexport interface ChildHostedZoneProps extends HostedZoneProps {\n /**\n * The root zone we will attach this sub-zone to.\n */\n readonly parentHostedZone: IHostedZone;\n}\n\nexport class ChildHostedZone extends HostedZone {\n /**\n * Used when storing the child zone ID in SSM. Use {@link OpenHiGlobalService.childHostedZoneFromConstruct} to look up.\n */\n public static readonly SSM_PARAM_NAME = \"CHILDHOSTEDZONE\";\n\n constructor(scope: Construct, id: string, props: ChildHostedZoneProps) {\n super(scope, id, { ...props });\n\n /**\n * Chain the child zone to the parent zone using NS record.\n */\n new NsRecord(this, \"child-ns-record\", {\n zone: props.parentHostedZone,\n recordName: this.zoneName,\n values: this.hostedZoneNameServers || [],\n ttl: Duration.minutes(5),\n });\n }\n}\n","import { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/route-53/root-hosted-zone.md\n */\n\n/**\n * Placeholder for root hosted zone. Use {@link OpenHiGlobalService.rootHostedZoneFromConstruct}\n * to obtain an IHostedZone from attributes (e.g. from config). The root zone is always\n * created manually and imported via config.\n */\nexport class RootHostedZone extends Construct {}\n","import {\n IUserPool,\n IUserPoolClient,\n IUserPoolDomain,\n LambdaVersion,\n UserPool,\n UserPoolClient,\n UserPoolDomain,\n UserPoolOperation,\n UserPoolProps,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { IKey, Key } from \"aws-cdk-lib/aws-kms\";\nimport { IFunction } from \"aws-cdk-lib/aws-lambda\";\nimport { Construct } from \"constructs\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport { CognitoUserPool } from \"../components/cognito/cognito-user-pool\";\nimport { CognitoUserPoolClient } from \"../components/cognito/cognito-user-pool-client\";\nimport { CognitoUserPoolDomain } from \"../components/cognito/cognito-user-pool-domain\";\nimport { CognitoUserPoolKmsKey } from \"../components/cognito/cognito-user-pool-kms-key\";\nimport { PreTokenGenerationLambda } from \"../components/cognito/pre-token-generation-lambda\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-auth-service.md\n */\n\nexport interface OpenHiAuthServiceProps extends OpenHiServiceProps {\n /**\n * Optional props for the Cognito User Pool.\n */\n readonly userPoolProps?: UserPoolProps;\n}\n\n/**\n * OpenHI Auth Service stack.\n *\n * @remarks\n * The Auth service manages authentication infrastructure including:\n * - Cognito User Pool for user management and authentication\n * - User Pool Client for application integration\n * - User Pool Domain for hosting the Cognito hosted UI\n * - KMS Key for Cognito User Pool encryption\n *\n * Resources are created in protected methods; subclasses may override to customize.\n * Other stacks obtain auth by calling **OpenHiAuthService.userPoolFromConstruct(scope)**,\n * **OpenHiAuthService.userPoolClientFromConstruct(scope)**,\n * **OpenHiAuthService.userPoolDomainFromConstruct(scope)**,\n * and **OpenHiAuthService.userPoolKmsKeyFromConstruct(scope)** for each resource needed.\n *\n * Only one instance of the auth service should exist per environment.\n *\n * @public\n */\nexport class OpenHiAuthService extends OpenHiService {\n static readonly SERVICE_TYPE = \"auth\";\n\n /**\n * Returns an IUserPool by looking up the Auth stack's User Pool ID from SSM.\n */\n static userPoolFromConstruct(scope: Construct): IUserPool {\n const userPoolId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CognitoUserPool.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n });\n return UserPool.fromUserPoolId(scope, \"user-pool\", userPoolId);\n }\n\n /**\n * Returns an IUserPoolClient by looking up the Auth stack's User Pool Client ID from SSM.\n */\n static userPoolClientFromConstruct(scope: Construct): IUserPoolClient {\n const userPoolClientId = DiscoverableStringParameter.valueForLookupName(\n scope,\n {\n ssmParamName: CognitoUserPoolClient.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n },\n );\n return UserPoolClient.fromUserPoolClientId(\n scope,\n \"user-pool-client\",\n userPoolClientId,\n );\n }\n\n /**\n * Returns an IUserPoolDomain by looking up the Auth stack's User Pool Domain from SSM.\n */\n static userPoolDomainFromConstruct(scope: Construct): IUserPoolDomain {\n const domainName = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CognitoUserPoolDomain.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n });\n return UserPoolDomain.fromDomainName(scope, \"user-pool-domain\", domainName);\n }\n\n /**\n * Returns an IKey (KMS) by looking up the Auth stack's User Pool KMS Key ARN from SSM.\n */\n static userPoolKmsKeyFromConstruct(scope: Construct): IKey {\n const keyArn = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CognitoUserPoolKmsKey.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n });\n return Key.fromKeyArn(scope, \"kms-key\", keyArn);\n }\n\n get serviceType(): string {\n return OpenHiAuthService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options (e.g. userPoolProps). */\n public override props: OpenHiAuthServiceProps;\n\n public readonly userPoolKmsKey: IKey;\n public readonly preTokenGenerationLambda: IFunction;\n public readonly userPool: IUserPool;\n public readonly userPoolClient: IUserPoolClient;\n public readonly userPoolDomain: IUserPoolDomain;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiAuthServiceProps = {}) {\n super(ohEnv, OpenHiAuthService.SERVICE_TYPE, props);\n this.props = props;\n\n this.userPoolKmsKey = this.createUserPoolKmsKey();\n this.preTokenGenerationLambda = this.createPreTokenGenerationLambda();\n this.userPool = this.createUserPool();\n this.userPoolClient = this.createUserPoolClient();\n this.userPoolDomain = this.createUserPoolDomain();\n }\n\n /**\n * Creates the KMS key for the Cognito User Pool and exports its ARN to SSM.\n * Look up via {@link OpenHiAuthService.userPoolKmsKeyFromConstruct}.\n * Override to customize.\n */\n protected createUserPoolKmsKey(): IKey {\n const key = new CognitoUserPoolKmsKey(this);\n new DiscoverableStringParameter(this, \"kms-key-param\", {\n ssmParamName: CognitoUserPoolKmsKey.SSM_PARAM_NAME,\n stringValue: key.keyArn,\n description:\n \"KMS key ARN for Cognito User Pool (e.g. custom sender); cross-stack reference\",\n });\n return key;\n }\n\n /**\n * Creates the Pre Token Generation Lambda (Cognito trigger). Phase 2 will add\n * openhi_* claims to the access token only; trigger version V2_0 may be required.\n */\n protected createPreTokenGenerationLambda(): IFunction {\n const construct = new PreTokenGenerationLambda(this);\n return construct.lambda;\n }\n\n /**\n * Creates the Cognito User Pool and exports its ID to SSM.\n * Look up via {@link OpenHiAuthService.userPoolFromConstruct}.\n * Override to customize.\n */\n protected createUserPool(): IUserPool {\n const userPool = new CognitoUserPool(this, {\n ...this.props.userPoolProps,\n customSenderKmsKey: this.userPoolKmsKey,\n });\n // Access-token-only claims require Pre Token Generation V2_0.\n userPool.addTrigger(\n UserPoolOperation.PRE_TOKEN_GENERATION_CONFIG,\n this.preTokenGenerationLambda,\n LambdaVersion.V2_0,\n );\n new DiscoverableStringParameter(this, \"user-pool-param\", {\n ssmParamName: CognitoUserPool.SSM_PARAM_NAME,\n stringValue: userPool.userPoolId,\n description:\n \"Cognito User Pool ID for this Auth stack; cross-stack reference\",\n });\n return userPool;\n }\n\n /**\n * Creates the User Pool Client and exports its ID to SSM (AUTH service type).\n * Look up via {@link OpenHiAuthService.userPoolClientFromConstruct}.\n * Override to customize.\n */\n protected createUserPoolClient(): IUserPoolClient {\n const client = new CognitoUserPoolClient(this, {\n userPool: this.userPool,\n });\n new DiscoverableStringParameter(this, \"user-pool-client-param\", {\n ssmParamName: CognitoUserPoolClient.SSM_PARAM_NAME,\n stringValue: client.userPoolClientId,\n description:\n \"Cognito User Pool Client ID for this Auth stack; cross-stack reference\",\n });\n return client;\n }\n\n /**\n * Creates the User Pool Domain (Cognito hosted UI) and exports domain name to SSM.\n * Look up via {@link OpenHiAuthService.userPoolDomainFromConstruct}.\n * Override to customize.\n */\n protected createUserPoolDomain(): IUserPoolDomain {\n const domain = new CognitoUserPoolDomain(this, {\n userPool: this.userPool,\n cognitoDomain: {\n domainPrefix: `auth-${this.branchHash}`,\n },\n });\n new DiscoverableStringParameter(this, \"user-pool-domain-param\", {\n ssmParamName: CognitoUserPoolDomain.SSM_PARAM_NAME,\n stringValue: domain.domainName,\n description:\n \"Cognito User Pool Domain (hosted UI) for this Auth stack; cross-stack reference\",\n });\n return domain;\n }\n}\n","import {\n Certificate,\n CertificateValidation,\n ICertificate,\n} from \"aws-cdk-lib/aws-certificatemanager\";\nimport {\n HostedZone,\n HostedZoneAttributes,\n IHostedZone,\n} from \"aws-cdk-lib/aws-route53\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport {\n OpenHiService,\n OpenHiServiceProps,\n OpenHiServiceType,\n} from \"../app/open-hi-service\";\nimport { RootWildcardCertificate } from \"../components/acm/root-wildcard-certificate\";\nimport { ChildHostedZone } from \"../components/route-53/child-hosted-zone\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-global-service.md\n */\n\nexport interface OpenHiGlobalServiceProps extends OpenHiServiceProps {}\n\n/**\n * Global Infrastructure stack: owns global DNS and certificates.\n * Resources (root zone, optional child zone, wildcard cert) are created\n * in protected methods; subclasses may override to customize.\n */\nexport class OpenHiGlobalService extends OpenHiService {\n static readonly SERVICE_TYPE = \"global\";\n\n /**\n * Returns an IHostedZone from the given attributes (no SSM). Use when the zone is imported from config.\n */\n static rootHostedZoneFromConstruct(\n scope: Construct,\n props: HostedZoneAttributes,\n ): IHostedZone {\n return HostedZone.fromHostedZoneAttributes(scope, \"root-zone\", props);\n }\n\n /**\n * Returns an ICertificate by looking up the Global stack's wildcard cert ARN from SSM.\n */\n static rootWildcardCertificateFromConstruct(scope: Construct): ICertificate {\n const certificateArn = StringParameter.valueForStringParameter(\n scope,\n RootWildcardCertificate.ssmParameterName(),\n );\n return Certificate.fromCertificateArn(\n scope,\n \"wildcard-certificate\",\n certificateArn,\n );\n }\n\n /**\n * Returns an IHostedZone by looking up the child hosted zone ID from SSM. Defaults to GLOBAL service type.\n */\n static childHostedZoneFromConstruct(\n scope: Construct,\n props: { zoneName: string; serviceType?: OpenHiServiceType },\n ): IHostedZone {\n const hostedZoneId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: ChildHostedZone.SSM_PARAM_NAME,\n serviceType: props.serviceType ?? OpenHiGlobalService.SERVICE_TYPE,\n });\n return HostedZone.fromHostedZoneAttributes(scope, \"child-zone\", {\n hostedZoneId,\n zoneName: props.zoneName,\n });\n }\n\n get serviceType(): string {\n return OpenHiGlobalService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options. */\n public override props: OpenHiGlobalServiceProps;\n\n public readonly rootHostedZone: IHostedZone;\n public readonly childHostedZone?: IHostedZone;\n public readonly rootWildcardCertificate: ICertificate;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiGlobalServiceProps = {}) {\n super(ohEnv, OpenHiGlobalService.SERVICE_TYPE, props);\n this.props = props;\n\n this.validateConfig(props);\n\n this.rootHostedZone = this.createRootHostedZone();\n this.childHostedZone = this.createChildHostedZone();\n this.rootWildcardCertificate = this.createRootWildcardCertificate();\n }\n\n /**\n * Validates that config required for the Global stack is present.\n */\n protected validateConfig(props: OpenHiGlobalServiceProps): void {\n const { config } = props;\n if (!config) {\n throw new Error(\"Config is required\");\n }\n if (!config.zoneName) {\n throw new Error(\"Zone name is required to import the root zone\");\n }\n if (!config.hostedZoneId) {\n throw new Error(\"Hosted zone ID is required to import the root zone\");\n }\n }\n\n /**\n * Creates the root hosted zone (imported via attributes from config).\n * Override to customize or create the zone.\n */\n protected createRootHostedZone(): IHostedZone {\n return OpenHiGlobalService.rootHostedZoneFromConstruct(this, {\n zoneName: this.config.zoneName!,\n hostedZoneId: this.config.hostedZoneId!,\n });\n }\n\n /**\n * Creates the optional child hosted zone (e.g. branch subdomain).\n * Override to create a child zone when config provides childHostedZoneAttributes.\n * If you create a ChildHostedZone, also create a DiscoverableStringParameter\n * with ChildHostedZone.SSM_PARAM_NAME and the zone's hostedZoneId.\n */\n protected createChildHostedZone(): IHostedZone | undefined {\n return undefined;\n }\n\n /**\n * Creates the root wildcard certificate. On main branch, creates a new cert\n * with DNS validation; otherwise imports from SSM.\n * Override to customize certificate creation.\n */\n protected createRootWildcardCertificate(): ICertificate {\n if (this.branchName === \"main\") {\n return new RootWildcardCertificate(this, {\n domainName: `*.${this.rootHostedZone.zoneName}`,\n subjectAlternativeNames: [this.rootHostedZone.zoneName],\n validation: CertificateValidation.fromDns(this.rootHostedZone),\n });\n }\n return OpenHiGlobalService.rootWildcardCertificateFromConstruct(this);\n }\n}\n","import {\n CorsHttpMethod,\n DomainName,\n HttpApi,\n HttpMethod,\n HttpNoneAuthorizer,\n HttpRoute,\n HttpRouteKey,\n IHttpApi,\n} from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { HttpUserPoolAuthorizer } from \"aws-cdk-lib/aws-apigatewayv2-authorizers\";\nimport { HttpLambdaIntegration } from \"aws-cdk-lib/aws-apigatewayv2-integrations\";\nimport { ICertificate } from \"aws-cdk-lib/aws-certificatemanager\";\nimport { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport {\n ARecord,\n HostedZone,\n IHostedZone,\n RecordTarget,\n} from \"aws-cdk-lib/aws-route53\";\nimport { ApiGatewayv2DomainProperties } from \"aws-cdk-lib/aws-route53-targets\";\nimport { Duration } from \"aws-cdk-lib/core\";\nimport { Construct } from \"constructs\";\nimport { OpenHiAuthService } from \"./open-hi-auth-service\";\nimport { OpenHiDataService } from \"./open-hi-data-service\";\nimport { OpenHiGlobalService } from \"./open-hi-global-service\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport { RootHttpApi } from \"../components/api-gateway/root-http-api\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\nimport { RestApiLambda } from \"../data/lambda/rest-api-lambda\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-rest-api-service.md\n */\n\n/**\n * CORS configuration for the REST API HTTP API (API Gateway v2).\n * When origins are set, API Gateway sends CORS headers; backend CORS headers are ignored for browser requests.\n */\nexport interface RestApiCorsOptions {\n /** Allowed origins (e.g. https://app.example.com, http://localhost:3000). Required when enabling CORS. */\n readonly allowOrigins: string[];\n /** Allowed HTTP methods. Defaults to GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS. */\n readonly allowMethods?: CorsHttpMethod[];\n /** Allowed request headers. Defaults to Content-Type, Authorization. */\n readonly allowHeaders?: string[];\n /** Whether to allow credentials (cookies, auth headers). Default true. */\n readonly allowCredentials?: boolean;\n /** How long preflight results can be cached. Default 1 day. */\n readonly maxAge?: Duration;\n}\n\nexport interface OpenHiRestApiServiceProps extends OpenHiServiceProps {\n /**\n * Optional CORS configuration for the root HTTP API.\n * When set, API Gateway will send CORS headers for the given origins.\n * When omitted, no CORS is configured at the gateway (Express CORS in the Lambda still applies for direct or non-browser use).\n */\n readonly cors?: RestApiCorsOptions;\n}\n\n/**\n * SSM parameter name suffix for the REST API base URL.\n * Full parameter name is built via buildParameterName with serviceType REST_API.\n */\nexport const REST_API_BASE_URL_SSM_NAME = \"REST_API_BASE_URL\";\n\n/**\n * REST API service stack: HTTP API, custom domain, and Lambda; exports base URL via SSM.\n * Resources are created in protected methods; subclasses may override to customize.\n */\nexport class OpenHiRestApiService extends OpenHiService {\n static readonly SERVICE_TYPE = \"rest-api\";\n\n /**\n * Returns an IHttpApi by looking up the REST API stack's HTTP API ID from SSM.\n */\n static rootHttpApiFromConstruct(scope: Construct): IHttpApi {\n const httpApiId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: RootHttpApi.SSM_PARAM_NAME,\n serviceType: OpenHiRestApiService.SERVICE_TYPE,\n });\n return HttpApi.fromHttpApiAttributes(scope, \"http-api\", { httpApiId });\n }\n\n /**\n * Returns the REST API base URL (e.g. https://api.example.com) by looking it up from SSM.\n * Use in other stacks for E2E, scripts, or config.\n */\n static restApiBaseUrlFromConstruct(scope: Construct): string {\n return DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: REST_API_BASE_URL_SSM_NAME,\n serviceType: OpenHiRestApiService.SERVICE_TYPE,\n });\n }\n\n get serviceType(): string {\n return OpenHiRestApiService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options (e.g. cors). */\n public override props: OpenHiRestApiServiceProps;\n\n public readonly rootHttpApi: RootHttpApi;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiRestApiServiceProps = {}) {\n super(ohEnv, OpenHiRestApiService.SERVICE_TYPE, props);\n this.props = props;\n\n this.validateConfig(props);\n\n const hostedZone = this.createHostedZone();\n const certificate = this.createCertificate();\n const apiDomainName = this.createApiDomainNameString(hostedZone);\n this.createRestApiBaseUrlParameter(apiDomainName);\n const domainName = this.createDomainName(hostedZone, certificate);\n this.rootHttpApi = this.createRootHttpApi(domainName);\n this.createRestApiLambdaAndRoutes(hostedZone, domainName);\n }\n\n /**\n * Validates that config required for the REST API stack is present.\n */\n protected validateConfig(props: OpenHiRestApiServiceProps): void {\n const { config } = props;\n if (!config) {\n throw new Error(\"Config is required\");\n }\n if (!config.hostedZoneId) {\n throw new Error(\"Hosted zone ID is required\");\n }\n if (!config.zoneName) {\n throw new Error(\"Zone name is required\");\n }\n }\n\n /**\n * Creates the hosted zone reference (imported from config).\n * Override to customize.\n */\n protected createHostedZone(): IHostedZone {\n const { config } = this.props;\n return HostedZone.fromHostedZoneAttributes(this, \"root-zone\", {\n hostedZoneId: config!.hostedZoneId!,\n zoneName: config!.zoneName!,\n });\n }\n\n /**\n * Creates the wildcard certificate (imported from Global stack via SSM).\n * Override to customize.\n */\n protected createCertificate() {\n return OpenHiGlobalService.rootWildcardCertificateFromConstruct(this);\n }\n\n /**\n * Returns the API domain name string (e.g. api.example.com or api-{prefix}.example.com).\n * Override to customize.\n */\n protected createApiDomainNameString(hostedZone: IHostedZone): string {\n const apiPrefix =\n this.branchName === \"main\" ? `api` : `api-${this.childZonePrefix}`;\n return [apiPrefix, hostedZone.zoneName].join(\".\");\n }\n\n /**\n * Creates the SSM parameter for the REST API base URL.\n * Look up via {@link OpenHiRestApiService.restApiBaseUrlFromConstruct}.\n * Override to customize.\n */\n protected createRestApiBaseUrlParameter(apiDomainName: string): void {\n const restApiBaseUrl = `https://${apiDomainName}`;\n new DiscoverableStringParameter(this, \"rest-api-base-url-param\", {\n ssmParamName: REST_API_BASE_URL_SSM_NAME,\n stringValue: restApiBaseUrl,\n description: \"REST API base URL for this deployment (E2E, scripts)\",\n });\n }\n\n /**\n * Creates the API Gateway custom domain name resource.\n * Override to customize.\n */\n protected createDomainName(\n _hostedZone: IHostedZone,\n certificate: ICertificate,\n ): DomainName {\n const apiDomainName = this.createApiDomainNameString(_hostedZone);\n return new DomainName(this, \"domain\", {\n domainName: apiDomainName,\n certificate,\n });\n }\n\n /**\n * Creates the Lambda integration, HTTP routes, and API DNS record.\n * Override to customize. Uses {@link rootHttpApi} set by the constructor.\n */\n protected createRestApiLambdaAndRoutes(\n hostedZone: IHostedZone,\n domainName: DomainName,\n ): void {\n const dataStoreTable =\n OpenHiDataService.dynamoDbDataStoreFromConstruct(this);\n const { lambda } = new RestApiLambda(this, {\n dynamoTableName: dataStoreTable.tableName,\n branchTagValue: this.branchName,\n httpApiTagValue: RootHttpApi.SSM_PARAM_NAME,\n });\n const dynamoActions = [\n \"dynamodb:GetItem\",\n \"dynamodb:Query\",\n \"dynamodb:BatchGetItem\",\n \"dynamodb:ConditionCheckItem\",\n \"dynamodb:DescribeTable\",\n \"dynamodb:BatchWriteItem\",\n \"dynamodb:PutItem\",\n \"dynamodb:UpdateItem\",\n \"dynamodb:DeleteItem\",\n ] as const;\n dataStoreTable.grant(lambda, ...dynamoActions);\n // Query (and other operations) on GSIs require the index resource ARN\n lambda.addToRolePolicy(\n new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [...dynamoActions],\n resources: [`${dataStoreTable.tableArn}/index/*`],\n }),\n );\n // Temporary: broad SSM read for dynamic config (test only)\n lambda.addToRolePolicy(\n new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\n \"ssm:GetParameter\",\n \"ssm:GetParameters\",\n \"ssm:DescribeParameters\",\n ],\n resources: [\"*\"],\n }),\n );\n const integration = new HttpLambdaIntegration(\"lambda-integration\", lambda);\n const noAuth = new HttpNoneAuthorizer();\n // OPTIONS routes without authorizer so CORS preflight succeeds (browsers do not send auth on preflight).\n new HttpRoute(this, \"options-route-root\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/\", HttpMethod.OPTIONS),\n integration,\n authorizer: noAuth,\n });\n new HttpRoute(this, \"options-route-proxy\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/{proxy+}\", HttpMethod.OPTIONS),\n integration,\n authorizer: noAuth,\n });\n new HttpRoute(this, \"proxy-route-root\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/\", HttpMethod.ANY),\n integration,\n });\n new HttpRoute(this, \"proxy-route\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/{proxy+}\", HttpMethod.ANY),\n integration,\n });\n const apiPrefix =\n this.branchName === \"main\" ? `api` : `api-${this.childZonePrefix}`;\n new ARecord(this, \"api-a-record\", {\n zone: hostedZone,\n recordName: apiPrefix,\n target: RecordTarget.fromAlias(\n new ApiGatewayv2DomainProperties(\n domainName.regionalDomainName,\n domainName.regionalHostedZoneId,\n ),\n ),\n });\n }\n\n /**\n * Creates the Root HTTP API with default domain mapping, Cognito JWT authorizer, and exports API ID to SSM.\n * Look up via {@link OpenHiRestApiService.rootHttpApiFromConstruct}.\n * Override to customize.\n */\n protected createRootHttpApi(domainName: DomainName): RootHttpApi {\n const userPool = OpenHiAuthService.userPoolFromConstruct(this);\n const userPoolClient = OpenHiAuthService.userPoolClientFromConstruct(this);\n const cognitoAuthorizer = new HttpUserPoolAuthorizer(\n \"cognito-authorizer\",\n userPool,\n { userPoolClients: [userPoolClient] },\n );\n const cors = this.props.cors;\n const corsPreflight =\n cors && cors.allowOrigins.length > 0\n ? {\n allowOrigins: cors.allowOrigins,\n allowMethods: cors.allowMethods ?? [\n CorsHttpMethod.GET,\n CorsHttpMethod.HEAD,\n CorsHttpMethod.POST,\n CorsHttpMethod.PUT,\n CorsHttpMethod.PATCH,\n CorsHttpMethod.DELETE,\n CorsHttpMethod.OPTIONS,\n ],\n allowHeaders: cors.allowHeaders ?? [\n \"Content-Type\",\n \"Authorization\",\n ],\n allowCredentials: cors.allowCredentials ?? true,\n maxAge: cors.maxAge ?? Duration.days(1),\n }\n : undefined;\n const rootHttpApi = new RootHttpApi(this, {\n defaultDomainMapping: {\n domainName,\n mappingKey: undefined,\n },\n defaultAuthorizer: cognitoAuthorizer,\n ...(corsPreflight && { corsPreflight }),\n });\n new DiscoverableStringParameter(this, \"http-api-url-param\", {\n ssmParamName: RootHttpApi.SSM_PARAM_NAME,\n stringValue: rootHttpApi.httpApiId,\n description:\n \"API Gateway HTTP API ID for this REST API stack (cross-stack reference)\",\n });\n return rootHttpApi;\n }\n}\n","import { ITable, Table } from \"aws-cdk-lib/aws-dynamodb\";\nimport { EventBus, IEventBus } from \"aws-cdk-lib/aws-events\";\nimport { Construct } from \"constructs\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport {\n DynamoDbDataStore,\n getDynamoDbDataStoreTableName,\n} from \"../components/dynamodb/dynamo-db-data-store\";\nimport { DataEventBus } from \"../components/event-bridge/data-event-bus\";\nimport { OpsEventBus } from \"../components/event-bridge/ops-event-bus\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-data-service.md\n */\n\nexport interface OpenHiDataServiceProps extends OpenHiServiceProps {}\n\n/**\n * Data storage service stack: centralizes DynamoDB, S3, EventBridge event buses,\n * and other persistence resources for OpenHI. Creates the single-table data store\n * (CRM, CMS, ERP, EHR) and the data/ops event buses in protected methods;\n * subclasses may override to customize.\n */\nexport class OpenHiDataService extends OpenHiService {\n static readonly SERVICE_TYPE = \"data\";\n\n /**\n * Returns the data event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.\n */\n static dataEventBusFromConstruct(scope: Construct): IEventBus {\n return EventBus.fromEventBusName(\n scope,\n \"data-event-bus\",\n DataEventBus.getEventBusName(scope),\n );\n }\n\n /**\n * Returns the ops event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.\n */\n static opsEventBusFromConstruct(scope: Construct): IEventBus {\n return EventBus.fromEventBusName(\n scope,\n \"ops-event-bus\",\n OpsEventBus.getEventBusName(scope),\n );\n }\n\n /**\n * Returns the data store table by name. Use from other stacks (e.g. REST API Lambda) to obtain an ITable reference.\n */\n static dynamoDbDataStoreFromConstruct(\n scope: Construct,\n id = \"dynamo-db-data-store\",\n ): ITable {\n return Table.fromTableName(scope, id, getDynamoDbDataStoreTableName(scope));\n }\n\n get serviceType(): string {\n return OpenHiDataService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options. */\n public override props: OpenHiDataServiceProps;\n\n /**\n * Event bus for data-related events (ingestion, transformation, storage).\n * Other stacks obtain it via {@link OpenHiDataService.dataEventBusFromConstruct}.\n */\n public readonly dataEventBus: IEventBus;\n\n /**\n * Event bus for operational events (monitoring, alerting, system health).\n * Other stacks obtain it via {@link OpenHiDataService.opsEventBusFromConstruct}.\n */\n public readonly opsEventBus: IEventBus;\n\n /**\n * The single-table DynamoDB data store. Use {@link OpenHiDataService.dynamoDbDataStoreFromConstruct}\n * from other stacks to obtain an ITable reference by name.\n */\n public readonly dataStore: ITable;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiDataServiceProps = {}) {\n super(ohEnv, OpenHiDataService.SERVICE_TYPE, props);\n this.props = props;\n\n this.dataEventBus = this.createDataEventBus();\n this.opsEventBus = this.createOpsEventBus();\n this.dataStore = this.createDataStore();\n }\n\n /**\n * Creates the data event bus.\n * Override to customize.\n */\n protected createDataEventBus(): IEventBus {\n return new DataEventBus(this);\n }\n\n /**\n * Creates the ops event bus.\n * Override to customize.\n */\n protected createOpsEventBus(): IEventBus {\n return new OpsEventBus(this);\n }\n\n /**\n * Creates the single-table DynamoDB data store.\n * Override to customize.\n */\n protected createDataStore(): ITable {\n return new DynamoDbDataStore(this, \"dynamo-db-data-store\");\n }\n}\n","import path from \"path\";\nimport { Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { NodejsFunction } from \"aws-cdk-lib/aws-lambda-nodejs\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/data/lambda/rest-api-lambda.md\n */\n\nexport interface RestApiLambdaProps {\n /**\n * DynamoDB table name for the data store. The Lambda receives it as the\n * environment variable DYNAMO_TABLE_NAME at runtime.\n */\n readonly dynamoTableName: string;\n\n /**\n * Branch name from the service. Passed as BRANCH_TAG_VALUE at runtime.\n */\n readonly branchTagValue: string;\n\n /**\n * SSM parameter name for the HTTP API (e.g. RootHttpApi.SSM_PARAM_NAME).\n * Passed as HTTP_API_TAG_VALUE at runtime.\n */\n readonly httpApiTagValue: string;\n}\n\nexport class RestApiLambda extends Construct {\n public readonly lambda: NodejsFunction;\n\n constructor(scope: Construct, props: RestApiLambdaProps) {\n super(scope, \"rest-api-lambda\");\n\n /**\n * Create a Lambda function\n */\n this.lambda = new NodejsFunction(this, \"handler\", {\n entry: path.join(__dirname, \"rest-api-lambda.handler.js\"),\n runtime: Runtime.NODEJS_LATEST,\n memorySize: 1024,\n environment: {\n DYNAMO_TABLE_NAME: props.dynamoTableName,\n BRANCH_TAG_VALUE: props.branchTagValue,\n HTTP_API_TAG_VALUE: props.httpApiTagValue,\n },\n });\n }\n}\n","import {\n AuthorizationType,\n IGraphqlApi,\n UserPoolDefaultAction,\n} from \"aws-cdk-lib/aws-appsync\";\nimport { Construct } from \"constructs\";\nimport { OpenHiAuthService } from \"./open-hi-auth-service\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport { RootGraphqlApi } from \"../components/app-sync/root-graphql-api\";\n\nexport interface OpenHiGraphqlServiceProps extends OpenHiServiceProps {}\n\n/**\n * GraphQL API service stack: creates the AppSync API via {@link RootGraphqlApi}\n * and exports its ID via SSM. Look up from other stacks via\n * {@link OpenHiGraphqlService.graphqlApiFromConstruct}.\n */\nexport class OpenHiGraphqlService extends OpenHiService {\n static readonly SERVICE_TYPE = \"graphql-api\";\n\n /**\n * Returns the GraphQL API by looking up the GraphQL stack's API ID from SSM.\n * Use from other stacks to obtain an IGraphqlApi reference.\n */\n static graphqlApiFromConstruct(scope: Construct): IGraphqlApi {\n return RootGraphqlApi.fromConstruct(scope);\n }\n\n get serviceType(): string {\n return OpenHiGraphqlService.SERVICE_TYPE;\n }\n\n /* Override so this.props is typed with this service's options */\n public override props: OpenHiGraphqlServiceProps;\n\n public readonly rootGraphqlApi: RootGraphqlApi;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiGraphqlServiceProps = {}) {\n super(ohEnv, OpenHiGraphqlService.SERVICE_TYPE, props);\n this.props = props;\n this.rootGraphqlApi = this.createRootGraphqlApi();\n }\n\n /** Creates the root GraphQL API with Cognito user pool. */\n protected createRootGraphqlApi(): RootGraphqlApi {\n const userPool = OpenHiAuthService.userPoolFromConstruct(this);\n return new RootGraphqlApi(this, {\n authorizationConfig: {\n defaultAuthorization: {\n authorizationType: AuthorizationType.USER_POOL,\n userPoolConfig: {\n userPool,\n defaultAction: UserPoolDefaultAction.ALLOW,\n },\n },\n },\n });\n }\n}\n"],"mappings":"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","names":["import_config","Stage","Stage","import_config","Tags","StringParameter","StringParameter","Tags","EventBus","EventBus","Construct","UserPool","UserPoolClient","UserPoolDomain","Key","UserPool","UserPoolClient","UserPoolDomain","Key","Certificate","HostedZone","StringParameter","HostedZone","StringParameter","Certificate","HttpApi","HostedZone","Duration","Table","EventBus","EventBus","Table","path","Runtime","NodejsFunction","Construct","HttpApi","HostedZone","Duration"]}
|
|
1
|
+
{"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../src/app/open-hi-app.ts","../src/app/open-hi-environment.ts","../src/app/open-hi-stage.ts","../src/app/open-hi-service.ts","../src/components/acm/root-wildcard-certificate.ts","../src/components/api-gateway/root-http-api.ts","../src/components/app-sync/root-graphql-api.ts","../src/components/ssm/discoverable-string-parameter.ts","../src/components/cognito/cognito-user-pool.ts","../src/components/cognito/cognito-user-pool-client.ts","../src/components/cognito/cognito-user-pool-domain.ts","../src/components/cognito/cognito-user-pool-kms-key.ts","../src/components/cognito/pre-token-generation-lambda.ts","../src/components/dynamodb/dynamo-db-data-store.ts","../src/components/event-bridge/data-event-bus.ts","../src/components/event-bridge/ops-event-bus.ts","../src/components/route-53/child-hosted-zone.ts","../src/components/route-53/root-hosted-zone.ts","../src/services/open-hi-auth-service.ts","../src/services/open-hi-global-service.ts","../src/services/open-hi-rest-api-service.ts","../src/services/open-hi-data-service.ts","../src/data/lambda/rest-api-lambda.ts","../src/services/open-hi-graphql-service.ts"],"sourcesContent":["/*******************************************************************************\n *\n * OpenHi Config\n *\n * These types are kept in their own package to prevent dependency conflicts and\n * conditions between @openhi/constructs and @openhi/platform..\n *\n ******************************************************************************/\n\n/**\n * Stage Types\n *\n * What stage of deployment is this? Dev, staging, or prod?\n */\nexport const OPEN_HI_STAGE = {\n /**\n * Development environment, typically used for testing and development.\n */\n DEV: \"dev\",\n /**\n * Staging environment, used for pre-production testing.\n */\n STAGE: \"stage\",\n /**\n * Production environment, used for live deployments.\n */\n PROD: \"prod\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiStageType =\n (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n\n/**\n * Deployment Target Role\n *\n * Is this (account, region) the primary or a secondary deployment target for the stage?\n * Works for both multi-region (different regions) and cellular (same region, different accounts).\n */\nexport const OPEN_HI_DEPLOYMENT_TARGET_ROLE = {\n /**\n * The primary deployment target for this stage (main account/region).\n * For example, the base DynamoDB region for global tables.\n */\n PRIMARY: \"primary\",\n\n /**\n * A secondary deployment target for this stage (additional account/region).\n * For example, a replica region for a global DynamoDB table, or another cell in the same region.\n */\n SECONDARY: \"secondary\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiDeploymentTargetRoleType =\n (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\nexport interface OpenHiEnvironmentConfig {\n account: string;\n region: string;\n /**\n * Route53 zone containing DNS for this service.\n */\n hostedZoneId?: string;\n zoneName?: string;\n}\n\n/**\n * Represents the configuration for OpenHi services across different stages and\n * deployment targets.\n */\nexport interface OpenHiConfig {\n versions?: {\n cdk?: {\n cdkLibVersion?: string;\n cdkCliVersion?: string;\n };\n };\n deploymentTargets?: {\n [OPEN_HI_STAGE.DEV]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.STAGE]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.PROD]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n };\n}\n","export * from \"./open-hi-config\";\n","import {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OPEN_HI_STAGE,\n OpenHiConfig,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { App, AppProps } from \"aws-cdk-lib\";\nimport { IConstruct } from \"constructs\";\nimport { OpenHiEnvironment } from \"./open-hi-environment\";\nimport { OpenHiStage } from \"./open-hi-stage\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-app.md\n */\n\n/**\n * Symbol used for runtime type checking to identify OpenHiApp instances.\n *\n * @internal\n */\nconst OPEN_HI_APP_SYMBOL = Symbol.for(\"@openhi/constructs/core.OpenHiApp\");\n\n/**\n * Properties for creating an OpenHiApp instance.\n */\nexport interface OpenHiAppProps extends AppProps {\n /**\n * Optional name for the application.\n * ```\n */\n readonly appName?: string;\n\n /**\n * The OpenHi configuration object that defines stages, environments, and\n * their associated AWS account and region settings.\n */\n readonly config: OpenHiConfig;\n}\n\n/**\n * Root application construct for OpenHi CDK applications.\n */\nexport class OpenHiApp extends App {\n /**\n * Finds the OpenHiApp instance that contains the given construct in its\n * construct tree.\n */\n public static of(construct: IConstruct): OpenHiApp | undefined {\n return construct.node.scopes.reverse().find(OpenHiApp.isOpenHiApp);\n }\n\n /**\n * Type guard that checks if a value is an OpenHiApp instance.\n */\n public static isOpenHiApp(this: void, x: any): x is OpenHiApp {\n return x !== null && typeof x === \"object\" && OPEN_HI_APP_SYMBOL in x;\n }\n\n /**\n * Name for the application.\n */\n readonly appName: string;\n\n /**\n * The OpenHi configuration object for this application.\n */\n readonly config: OpenHiConfig;\n\n /**\n * Creates a new OpenHiApp instance.\n */\n constructor(props: OpenHiAppProps) {\n super(props);\n\n // Set runtime symbol for type checking\n Object.defineProperty(this, OPEN_HI_APP_SYMBOL, { value: true });\n\n // Store app name, defaulting to \"openhi\" if not provided\n this.appName = props.appName ?? \"openhi\";\n\n // Store configuration for use by child constructs\n this.config = props.config;\n\n // Create stages and environments based on configuration\n // Iterate through all possible stage types (dev, stage, prod)\n Object.values(OPEN_HI_STAGE).forEach((stageType) => {\n // Only create a stage if it's configured in the config\n if (this.config.deploymentTargets?.[stageType]) {\n const stage = new OpenHiStage(this, { stageType });\n\n // Create primary deployment target if configured\n // Each stage can have at most one primary deployment target\n if (\n this.config.deploymentTargets?.[stageType]?.[\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY\n ]\n ) {\n const envConfig =\n this.config.deploymentTargets[stageType][\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY\n ]!;\n new OpenHiEnvironment(stage, {\n deploymentTargetRole: OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,\n config: envConfig,\n env: { account: envConfig.account, region: envConfig.region },\n });\n }\n\n // Create secondary deployment targets if configured\n // Each stage can have zero or more secondary deployment targets\n if (\n this.config.deploymentTargets?.[stageType]?.[\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY\n ]\n ) {\n this.config.deploymentTargets[stageType][\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY\n ]!.forEach((envConfig: OpenHiEnvironmentConfig) => {\n new OpenHiEnvironment(stage, {\n deploymentTargetRole: OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,\n config: envConfig,\n env: { account: envConfig.account, region: envConfig.region },\n });\n });\n }\n }\n });\n }\n\n /*****************************************************************************\n *\n * Stages\n *\n ****************************************************************************/\n\n /**\n * Gets all OpenHiStage instances that are direct children of this app.\n\n */\n public get stages(): Array<OpenHiStage> {\n return this.node.children.filter(OpenHiStage.isOpenHiStage);\n }\n\n /**\n * Gets the development stage, if it exists.\n */\n public get devStage(): OpenHiStage | undefined {\n return this.stages.find((stage) => stage.stageType === OPEN_HI_STAGE.DEV);\n }\n\n /**\n * Gets the staging stage, if it exists.\n */\n public get stageStage(): OpenHiStage | undefined {\n return this.stages.find((stage) => stage.stageType === OPEN_HI_STAGE.STAGE);\n }\n\n /**\n * Gets the production stage, if it exists.\n */\n public get prodStage(): OpenHiStage | undefined {\n return this.stages.find((stage) => stage.stageType === OPEN_HI_STAGE.PROD);\n }\n\n /*****************************************************************************\n *\n * Environments\n *\n ****************************************************************************/\n\n /**\n * Gets all OpenHiEnvironment instances across all stages in this app.\n */\n public get environments(): Array<OpenHiEnvironment> {\n return this.stages.flatMap((stage) => stage.environments);\n }\n\n /**\n * Gets all primary environments across all stages in this app.\n */\n public get primaryEnvironments(): Array<OpenHiEnvironment> {\n return this.environments.filter(\n (env) => env.deploymentTargetRole === \"primary\",\n );\n }\n\n /**\n * Gets all secondary environments across all stages in this app.\n */\n public get secondaryEnvironments(): Array<OpenHiEnvironment> {\n return this.environments.filter(\n (env) => env.deploymentTargetRole === \"secondary\",\n );\n }\n}\n","import {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { Stage, StageProps } from \"aws-cdk-lib\";\nimport { IConstruct } from \"constructs\";\nimport { OpenHiStage } from \"./open-hi-stage\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-environment.md\n */\n\n/**\n * Symbol used to identify OpenHiEnvironment instances at runtime.\n */\nconst OPEN_HI_ENVIRONMENT_SYMBOL = Symbol.for(\n \"@openhi/constructs/core.OpenHiEnvironment\",\n);\n\n/**\n * Properties for creating an OpenHiEnvironment.\n */\nexport interface OpenHiEnvironmentProps extends StageProps {\n /**\n * The deployment target role for this (account, region).\n */\n readonly deploymentTargetRole: (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\n /**\n * Configuration for this specific environment.\n */\n readonly config: OpenHiEnvironmentConfig;\n}\n\n/**\n * Represents an OpenHi environment within an AWS CDK stage.\n */\nexport class OpenHiEnvironment extends Stage {\n /**\n * Finds the OpenHiEnvironment that contains the given construct.\n * ```\n */\n public static of(construct: IConstruct): OpenHiEnvironment | undefined {\n return construct.node.scopes\n .reverse()\n .find(OpenHiEnvironment.isOpenHiEnvironment);\n }\n\n /**\n * Type guard to check if a value is an OpenHiEnvironment instance.\n */\n public static isOpenHiEnvironment(\n this: void,\n x: any,\n ): x is OpenHiEnvironment {\n return (\n x !== null && typeof x === \"object\" && OPEN_HI_ENVIRONMENT_SYMBOL in x\n );\n }\n\n /**\n * Configuration for this specific environment.\n */\n readonly config: OpenHiEnvironmentConfig;\n\n /**\n * The deployment target role for this (account, region).\n */\n public readonly deploymentTargetRole: (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\n /**\n * Creates a new OpenHiEnvironment.\n */\n constructor(\n /**\n * The OpenHiStage that contains this environment.\n */\n public ohStage: OpenHiStage,\n /**\n * Properties for creating the environment.\n */\n public props: OpenHiEnvironmentProps,\n ) {\n // Copy account and region from config into env, if provided.\n // This allows all resources in this environment to default to the correct\n // account and region without having to specify it on each stack or resource.\n if (props.config.account && props.config.region) {\n props = {\n ...props,\n env: {\n account: props.config.account,\n region: props.config.region,\n },\n };\n }\n\n // Determine the stage name:\n // - Primary environments use the environment type as the name\n // - Secondary deployment targets use \"{deploymentTargetRole}-{index}\" format\n const stageName =\n props.deploymentTargetRole === OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY\n ? props.deploymentTargetRole\n : [props.deploymentTargetRole, ohStage.environments.length].join(\"-\");\n\n super(ohStage, stageName, {\n env: props.env ?? ohStage.props.env,\n ...props,\n });\n\n // Mark this instance as an OpenHiEnvironment for runtime type checking\n Object.defineProperty(this, OPEN_HI_ENVIRONMENT_SYMBOL, { value: true });\n\n this.deploymentTargetRole = props.deploymentTargetRole;\n this.config = props.config;\n }\n}\n","import { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Stage, StageProps } from \"aws-cdk-lib\";\nimport { IConstruct } from \"constructs\";\nimport { OpenHiApp } from \"./open-hi-app\";\nimport { OpenHiEnvironment } from \"./open-hi-environment\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-stage.md\n */\n\n/**\n * Symbol used to identify OpenHiStage instances at runtime.\n *\n * @internal\n */\nconst OPEN_HI_STAGE_SYMBOL = Symbol.for(\"@openhi/constructs/core.OpenHiStage\");\n\n/**\n * Properties for creating an OpenHiStage instance.\n */\nexport interface OpenHiStageProps extends StageProps {\n /**\n * The type of the OpenHi stage.\n */\n readonly stageType: (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n}\n\n/**\n * Represents a deployment stage in the OpenHi infrastructure hierarchy.\n */\nexport class OpenHiStage extends Stage {\n /**\n * Finds the OpenHiStage that contains the given construct.\n */\n public static of(construct: IConstruct): OpenHiStage | undefined {\n return construct.node.scopes.reverse().find(OpenHiStage.isOpenHiStage);\n }\n\n /**\n * Type guard to check if a value is an OpenHiStage instance.\n */\n public static isOpenHiStage(this: void, x: any): x is OpenHiStage {\n return x !== null && typeof x === \"object\" && OPEN_HI_STAGE_SYMBOL in x;\n }\n\n /**\n * The type of this OpenHi stage.\n */\n public readonly stageType: (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n\n /**\n * Creates a new OpenHiStage instance.\n */\n constructor(\n /**\n * The OpenHiApp that this stage belongs to.\n *\n * @public\n */\n public ohApp: OpenHiApp,\n\n /**\n * Properties for configuring the stage.\n *\n * @public\n */\n public props: OpenHiStageProps,\n ) {\n super(ohApp, props.stageType, props);\n\n Object.defineProperty(this, OPEN_HI_STAGE_SYMBOL, { value: true });\n\n this.stageType = props.stageType;\n }\n\n /**\n * Gets all OpenHiEnvironment instances contained within this stage.\n */\n public get environments(): Array<OpenHiEnvironment> {\n return this.node.children.filter(OpenHiEnvironment.isOpenHiEnvironment);\n }\n\n /**\n * Gets the primary OpenHiEnvironment for this stage, if one exists.\n */\n public get primaryEnvironment(): OpenHiEnvironment | undefined {\n return this.environments.find(\n (env) => env.deploymentTargetRole === \"primary\",\n );\n }\n\n /**\n * Gets all secondary OpenHiEnvironment instances for this stage.\n */\n public get secondaryEnvironments(): Array<OpenHiEnvironment> {\n return this.environments.filter(\n (env) => env.deploymentTargetRole === \"secondary\",\n );\n }\n}\n","import {\n findGitBranch,\n findGitRepoName,\n hashString,\n} from \"@codedrifters/utils\";\nimport { OPEN_HI_STAGE, OpenHiEnvironmentConfig } from \"@openhi/config\";\nimport { RemovalPolicy, Stack, StackProps, Tags } from \"aws-cdk-lib\";\nimport { paramCase } from \"change-case\";\nimport { OpenHiEnvironment } from \"./open-hi-environment\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/app/open-hi-service.md\n */\n\n/**\n * Known OpenHI service type strings. Each service class defines its own\n * static SERVICE_TYPE (e.g. OpenHiAuthService.SERVICE_TYPE === \"auth\").\n *\n * @public\n */\nexport type OpenHiServiceType =\n | \"auth\"\n | \"rest-api\"\n | \"data\"\n | \"global\"\n | \"graphql-api\";\n\n/**\n * Properties for creating an {@link OpenHiService} stack.\n *\n * @public\n */\nexport interface OpenHiServiceProps extends StackProps {\n /**\n * Optional branch name override.\n */\n readonly branchName?: string;\n\n /**\n * Optional repository name override.\n */\n readonly repoName?: string;\n\n /**\n * Optional application name override.\n */\n readonly appName?: string;\n\n /**\n * Default release branch name.\n */\n readonly defaultReleaseBranch?: string;\n\n /**\n * The removal policy for persistent stack resources.\n */\n readonly removalPolicy?: RemovalPolicy;\n\n /**\n * Environment configuration for this service.\n */\n readonly config?: OpenHiEnvironmentConfig;\n\n /**\n * A constant that identifies the service type.\n */\n readonly serviceType?: OpenHiServiceType;\n}\n\n/**\n * Represents an OpenHI service stack within the OpenHI platform.\n * Subclasses must override {@link serviceType} to return their static SERVICE_TYPE.\n */\nexport abstract class OpenHiService extends Stack {\n /**\n * The service/stack ID that was passed to the constructor.\n */\n public readonly serviceId: string;\n\n /**\n * The deployment target role identifier.\n */\n public readonly deploymentTargetRole: string;\n\n /**\n * Repository name used in resource tagging.\n */\n public readonly repoName: string;\n\n /**\n * Application name identifier.\n */\n public readonly appName: string;\n\n /**\n * Default release branch name.\n */\n public readonly defaultReleaseBranch: string;\n\n /**\n * Branch name used when calculating resource names and hashes.\n */\n public readonly branchName: string;\n\n /**\n * Short hash unique to the deployment target (app name, deployment target role, account, region).\n */\n public readonly environmentHash: string;\n\n /**\n * Short hash unique to the environment and branch combination.\n */\n public readonly branchHash: string;\n\n /**\n * Short hash unique to the specific stack/service.\n */\n public readonly stackHash: string;\n\n /**\n * The removal policy for persistent stack resources.\n */\n public readonly removalPolicy: RemovalPolicy;\n\n /**\n * Environment configuration for this service.\n * This is either the value passed in or the default config\n */\n public readonly config: OpenHiEnvironmentConfig;\n\n /**\n * Service type identifier. Override in subclasses to return the class's static SERVICE_TYPE.\n * Used for parameter names, tags, and service discovery.\n */\n abstract get serviceType(): OpenHiServiceType | string;\n\n /**\n * Creates a new OpenHI service stack.\n *\n * @param ohEnv - The OpenHI environment (stage) this service belongs to\n * @param id - Unique identifier for this service stack (e.g., \"user-service\")\n * @param props - Optional properties for configuring the service\n *\n * @throws {Error} If account and region are not defined in props or environment\n *\n */\n constructor(\n public ohEnv: OpenHiEnvironment,\n id: string,\n public props: OpenHiServiceProps = {},\n ) {\n // Determine the account and region based on environment or user passed props.\n // This must be done before calling super() as it's needed for stack naming.\n const { account, region } = props.env || ohEnv;\n if (!account || !region) {\n throw new Error(\n \"Account and region must be defined in OpenHiServiceProps or OpenHiEnvironment\",\n );\n }\n\n // Get app name from the app in the hierarchy (via environment -> stage -> app)\n const appName = props.appName ?? ohEnv.ohStage.ohApp.appName ?? \"openhi\";\n\n // Initialize deployment context properties\n // Repo name is used in tagging. This tag value is important for tracking\n // when tearing preview stacks back down. If not provided, detect from git.\n const repoName = props.repoName ?? findGitRepoName();\n\n // Default release branch is used when not in dev stage. Defaults to \"main\" if not provided.\n const defaultReleaseBranch = props.defaultReleaseBranch ?? \"main\";\n\n // Branch name is used to calculate hashes and names for resources.\n // Detection logic:\n // - If explicitly provided, use that value\n // - If Jest is running, use \"test-branch\" to avoid snapshot test issues\n // - If GIT_BRANCH_NAME env is set (e.g. by CI), use it\n // - If in dev stage, detect from git using findGitBranch()\n // - Otherwise (stage/prod), default to defaultReleaseBranch\n const branchName =\n props.branchName ??\n (process.env.JEST_WORKER_ID\n ? \"test-branch\"\n : process.env.GIT_BRANCH_NAME?.trim() ||\n (ohEnv.ohStage.stageType === OPEN_HI_STAGE.DEV\n ? findGitBranch()\n : defaultReleaseBranch));\n\n // Compute environment hash: unique to deployment target (app name, role, account, region)\n // Mainly used for DNS names and deployment-target-scoped resources\n const environmentHash = hashString(\n [appName, ohEnv.deploymentTargetRole, account, region].join(\"-\"),\n 6,\n );\n\n // Compute branch hash: unique to deployment target and branch combination\n // Useful for resources shared across stacks within the same branch\n const branchHash = hashString(\n [appName, ohEnv.deploymentTargetRole, account, region, branchName].join(\n \"-\",\n ),\n 6,\n );\n\n // Compute stack hash: unique to the specific stack/service\n // Useful for stack-specific resources like S3 buckets, KMS key aliases\n // This ensures two PR builds or different services don't collide\n const stackHash = hashString(\n [\n appName,\n ohEnv.deploymentTargetRole,\n account,\n region,\n branchName,\n id,\n ].join(\"-\"),\n 6,\n );\n\n // Set the removal policy for this stack based on the deployment target role.\n // Production stages retain resources, others destroy them on stack deletion.\n const removalPolicy =\n props.removalPolicy ??\n (ohEnv.ohStage.stageType === OPEN_HI_STAGE.PROD\n ? RemovalPolicy.RETAIN\n : RemovalPolicy.DESTROY);\n Object.assign(props, { removalPolicy });\n\n // Description to use for the stack and all resources within it.\n // Includes service ID, branch name, and hash for easy identification.\n const description = `OpenHi Service: ${id} [${branchName}] - ${branchHash}`;\n\n // Call the super constructor of Stack.\n // This initializes the AWS CDK Stack with:\n // - Scope: the OpenHI environment\n // - ID: unique stack name including branch hash\n // - Props: stack properties including description and removal policy\n super(ohEnv, [branchHash, id, account, region].join(\"-\"), {\n ...props,\n description,\n });\n\n // Store the service ID for use in deployment context and other operations.\n this.serviceId = id;\n\n // Set the removal policy for this stack based on the deployment target role.\n this.removalPolicy = removalPolicy;\n\n /**\n * Explicit config or use the environment config as a backup,\n */\n this.config = props.config ?? ohEnv.props.config;\n\n // Initialize deployment context properties directly on the service\n this.deploymentTargetRole = ohEnv.deploymentTargetRole;\n this.repoName = repoName;\n this.appName = appName;\n this.defaultReleaseBranch = defaultReleaseBranch;\n this.branchName = branchName;\n this.environmentHash = environmentHash;\n this.branchHash = branchHash;\n this.stackHash = stackHash;\n\n // Standard tagging across all resources in the stack.\n // Use id (the service type string passed to super) since abstract serviceType cannot be accessed in constructor.\n Tags.of(this).add(`${appName}:repo-name`, repoName.slice(0, 255));\n Tags.of(this).add(`${appName}:branch-name`, branchName.slice(0, 255));\n Tags.of(this).add(`${appName}:service-type`, id.slice(0, 255));\n Tags.of(this).add(\n `${appName}:stage-type`,\n ohEnv.ohStage.stageType.slice(0, 255),\n );\n }\n\n /**\n * DNS prefix for this branche's child zone.\n */\n public get childZonePrefix(): string {\n return paramCase(this.branchName).slice(0, 200);\n }\n}\n","import {\n Certificate,\n CertificateProps,\n} from \"aws-cdk-lib/aws-certificatemanager\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/acm/root-wildcard-certificate.md\n */\n\nexport class RootWildcardCertificate extends Certificate {\n /**\n * Used when storing the Certificate ARN in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"ROOT_WILDCARD_CERT_ARN\";\n\n /**\n * Using a special name here since this will be shared and used among many\n * stacks and services. Use with OpenHiGlobalService.rootWildcardCertificateFromConstruct.\n */\n public static ssmParameterName(): string {\n return (\n \"/\" +\n [\"GLOBAL\", RootWildcardCertificate.SSM_PARAM_NAME].join(\"/\").toUpperCase()\n );\n }\n\n constructor(scope: Construct, props: CertificateProps) {\n super(scope, \"root-wildcard-certificate\", { ...props });\n\n /**\n * Generate the SSM Parameter used to store this Certificate's ARN.\n */\n new StringParameter(this, \"wildcard-cert-param\", {\n parameterName: RootWildcardCertificate.ssmParameterName(),\n stringValue: this.certificateArn,\n });\n }\n}\n","import { HttpApi, HttpApiProps } from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app/open-hi-service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/api-gateway/root-http-api.md\n */\n\nexport class RootHttpApi extends HttpApi {\n /**\n * Used when storing the API ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"ROOT_HTTP_API\";\n\n constructor(scope: Construct, props: HttpApiProps = {}) {\n const stack = OpenHiService.of(scope) as OpenHiService;\n\n const origins = props.corsPreflight?.allowOrigins;\n if (origins?.length) {\n const withTrailingSlash = origins.filter((o) => o.endsWith(\"/\"));\n if (withTrailingSlash.length > 0) {\n throw new Error(\n `CORS allowOrigins must not include a trailing slash. The browser Origin header is scheme + host + port only (no path), so API Gateway will not match origins like \"https://example.com/\" and CORS can fail. Invalid: ${withTrailingSlash.join(\", \")}. Use e.g. \"https://example.com\" instead.`,\n );\n }\n }\n\n super(scope, \"http-api\", {\n /**\n * User provided props\n */\n ...props,\n\n /**\n * Required\n */\n apiName: [\"root\", \"http\", \"api\", stack.branchHash].join(\"-\"),\n });\n }\n}\n","import {\n Definition,\n GraphqlApi,\n GraphqlApiProps,\n IGraphqlApi,\n} from \"aws-cdk-lib/aws-appsync\";\nimport { CodeFirstSchema, GraphqlType, ObjectType } from \"awscdk-appsync-utils\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/app-sync/root-graphql-api.md\n */\n\nexport interface RootGraphqlApiProps extends GraphqlApiProps {}\n\nexport class RootGraphqlApi extends GraphqlApi {\n /**\n * Used when storing the GraphQl API ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"ROOT_GRAPHQL_API\";\n\n public static fromConstruct(scope: Construct): IGraphqlApi {\n const graphqlApiId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: RootGraphqlApi.SSM_PARAM_NAME,\n serviceType: \"graphql-api\",\n });\n\n return GraphqlApi.fromGraphqlApiAttributes(scope, \"root-graphql-api\", {\n graphqlApiId,\n });\n }\n\n constructor(scope: Construct, props?: Omit<RootGraphqlApiProps, \"name\">) {\n const stack = OpenHiService.of(scope) as OpenHiService;\n\n const schema = new CodeFirstSchema();\n schema.addType(\n new ObjectType(\"Query\", {\n definition: { HelloWorld: GraphqlType.string() },\n }),\n );\n\n super(scope, \"root-graphql-api\", {\n /**\n * Defaults\n */\n queryDepthLimit: 2,\n resolverCountLimit: 50,\n definition: Definition.fromSchema(schema),\n\n /**\n * Overrideable props\n */\n ...props,\n\n /**\n * Required\n */\n name: [\"root\", \"graphql\", \"api\", stack.branchHash].join(\"-\"),\n });\n\n /**\n * Generate the SSM Parameter used to store this GraphQL API's ID.\n */\n new DiscoverableStringParameter(this, \"graphql-api-param\", {\n ssmParamName: RootGraphqlApi.SSM_PARAM_NAME,\n serviceType: \"graphql-api\",\n stringValue: this.apiId,\n });\n }\n}\n","import { Tags } from \"aws-cdk-lib\";\nimport {\n StringParameter,\n type StringParameterProps,\n} from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/ssm/discoverable-string-parameter.md\n */\n\n/*******************************************************************************\n *\n * DiscoverableStringParameterProps: props for creating or looking up SSM\n * parameters. Includes StringParameterProps (minus parameterName) plus\n * name-building fields used by buildParameterName.\n *\n ******************************************************************************/\n\nexport interface DiscoverableStringParameterProps extends Omit<\n StringParameterProps,\n \"parameterName\"\n> {\n /**\n * SSM param name used to build the SSM parameter name via buildParameterName\n * and stored as a tag on the parameter for discoverability.\n */\n readonly ssmParamName: string;\n\n /**\n * The environment hash the parameter belongs to.\n * @default - the current stack's environment hash\n */\n readonly branchHash?: string;\n\n /**\n * The service type the parameter belongs to.\n * @default - the current stack's service type\n */\n readonly serviceType?: string;\n\n /**\n * The AWS account the parameter belongs to.\n * @default - the current stack's account\n */\n readonly account?: string;\n\n /**\n * The AWS region the parameter belongs to.\n * @default - the current stack's region\n */\n readonly region?: string;\n}\n\n/**\n * Props for buildParameterName and valueForLookupName.\n * Includes ssmParamName (required) and optional overrides (branchHash, serviceType, account, region).\n */\nexport type BuildParameterNameProps = Pick<\n DiscoverableStringParameterProps,\n \"ssmParamName\" | \"branchHash\" | \"serviceType\" | \"account\" | \"region\"\n>;\n\n/**\n * Discoverable SSM string parameter construct. Extends CDK StringParameter:\n * builds parameterName from the given name via buildParameterName and tags\n * the parameter with the name constant.\n */\nexport class DiscoverableStringParameter extends StringParameter {\n /**\n * Version of the parameter name format / discoverability schema.\n * Bump when buildParameterName or tagging semantics change.\n * Also used to drive replacement of parameters during CloudFormation deploys.\n */\n public static readonly version = \"v1\";\n\n /**\n * Build a param name based on predictable attributes found in services and\n * constructs. Used for storage and retrieval of SSM values across services.\n */\n public static buildParameterName(\n scope: Construct,\n props: BuildParameterNameProps,\n ): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return (\n \"/\" +\n [\n DiscoverableStringParameter.version,\n props.branchHash ?? stack.branchHash,\n props.serviceType ?? stack.serviceType,\n props.account ?? stack.account,\n props.region ?? stack.region,\n props.ssmParamName,\n ]\n .join(\"/\")\n .toUpperCase()\n );\n }\n\n /**\n * Read the string value of an SSM parameter created with DiscoverableStringParameter,\n * using props that include ssmParamName and optional overrides (e.g. serviceType).\n */\n public static valueForLookupName(\n scope: Construct,\n props: BuildParameterNameProps,\n ): string {\n const paramName = DiscoverableStringParameter.buildParameterName(\n scope,\n props,\n );\n return StringParameter.valueForStringParameter(scope, paramName);\n }\n\n constructor(\n scope: Construct,\n id: string,\n props: DiscoverableStringParameterProps,\n ) {\n const { ssmParamName, branchHash, serviceType, account, region, ...rest } =\n props;\n\n const parameterName = DiscoverableStringParameter.buildParameterName(\n scope,\n props,\n );\n\n super(scope, id + \"-\" + DiscoverableStringParameter.version, {\n ...rest,\n parameterName,\n });\n\n const { appName } = OpenHiService.of(scope) as OpenHiService;\n Tags.of(this).add(`${appName}:param-name`, ssmParamName);\n }\n}\n","import {\n UserPool,\n UserPoolProps,\n VerificationEmailStyle,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app/open-hi-service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool.md\n */\n\nexport class CognitoUserPool extends UserPool {\n /**\n * Used when storing the User Pool ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL\";\n\n constructor(scope: Construct, props: UserPoolProps = {}) {\n const service = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, \"user-pool\", {\n /**\n * Defaults\n */\n selfSignUpEnabled: true,\n signInAliases: {\n email: true,\n },\n userVerification: {\n emailSubject: \"Verify your email!\",\n emailBody: \"Your verification code is {####}.\",\n emailStyle: VerificationEmailStyle.CODE,\n },\n removalPolicy: props.removalPolicy ?? service.removalPolicy,\n\n /**\n * Over-rideable props\n */\n ...props,\n\n /**\n * Required\n */\n userPoolName: [\"cognito\", \"user\", \"pool\", service.branchHash].join(\"-\"),\n });\n }\n}\n","import { UserPoolClient, UserPoolClientProps } from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool-client.md\n */\n\nexport class CognitoUserPoolClient extends UserPoolClient {\n /**\n * Used when storing the User Pool Client ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL_CLIENT\";\n\n constructor(scope: Construct, props: UserPoolClientProps) {\n super(scope, \"user-pool-client\", {\n /**\n * Defaults\n */\n generateSecret: false,\n oAuth: {\n flows: {\n authorizationCodeGrant: true,\n implicitCodeGrant: true,\n },\n callbackUrls: [`https://localhost:3000/oauth/callback`],\n },\n\n /**\n * Overrideable props\n */\n ...props,\n });\n }\n}\n","import { UserPoolDomain, UserPoolDomainProps } from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool-domain.md\n */\n\nexport class CognitoUserPoolDomain extends UserPoolDomain {\n /**\n * Used when storing the User Pool Domain in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL_DOMAIN\";\n\n constructor(scope: Construct, props: UserPoolDomainProps) {\n /**\n * This supports both custom and native Cognito domains, but we need to\n * name them uniquely so that swap outs work and don't cause conflicts\n * when cloudformation does it's deploy.\n */\n const id = props.cognitoDomain?.domainPrefix\n ? \"cognito-domain\"\n : \"custom-domain\";\n\n super(scope, id, {\n ...props,\n });\n }\n}\n","import { Key, KeyProps } from \"aws-cdk-lib/aws-kms\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app/open-hi-service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/cognito-user-pool-kms-key.md\n */\n\nexport class CognitoUserPoolKmsKey extends Key {\n /**\n * Used when storing the KMS Key in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"COGNITO_USER_POOL_KMS_KEY\";\n\n constructor(scope: Construct, props: KeyProps = {}) {\n const service = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, \"kms-key\", {\n ...props,\n // alias: [\"alias\", \"cognito\", service.branchHash].join(\"/\"),\n description: `KMS Key for Cognito User Pool - ${service.branchHash}`,\n removalPolicy: props.removalPolicy ?? service.removalPolicy,\n });\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { NodejsFunction } from \"aws-cdk-lib/aws-lambda-nodejs\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/cognito/pre-token-generation-lambda.md\n */\n\nconst HANDLER_NAME = \"pre-token-generation.handler.js\";\n\n/**\n * Resolve Lambda entry so it works when running from src/ (tests) or from lib/ (built).\n */\nfunction resolveHandlerEntry(dirname: string): string {\n const sameDir = path.join(dirname, HANDLER_NAME);\n if (fs.existsSync(sameDir)) {\n return sameDir;\n }\n\n const fromLib = path.join(dirname, \"..\", \"..\", \"..\", \"lib\", HANDLER_NAME);\n return fromLib;\n}\n\n/**\n * Lambda used as Cognito Pre Token Generation trigger.\n */\nexport class PreTokenGenerationLambda extends Construct {\n public readonly lambda: NodejsFunction;\n\n constructor(scope: Construct) {\n super(scope, \"pre-token-generation-lambda\");\n\n this.lambda = new NodejsFunction(this, \"handler\", {\n entry: resolveHandlerEntry(__dirname),\n runtime: Runtime.NODEJS_LATEST,\n memorySize: 1024,\n });\n }\n}\n","import { RemovalPolicy } from \"aws-cdk-lib\";\nimport {\n AttributeType,\n BillingMode,\n ProjectionType,\n Table,\n TableProps,\n} from \"aws-cdk-lib/aws-dynamodb\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/dynamodb/dynamo-db-data-store.md\n */\n\n/**\n * DynamoDB table name for the data store. Used for cross-stack reference and\n * deterministic naming per branch. The table backs multiple use cases (e.g.\n * CRM, CMS, ERP, EHR).\n */\nexport function getDynamoDbDataStoreTableName(scope: Construct): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return `data-store-${stack.branchHash}`;\n}\n\nexport interface DynamoDbDataStoreProps extends Omit<\n TableProps,\n \"tableName\" | \"removalPolicy\"\n> {\n /**\n * Optional removal policy override. If not set, uses the service's default\n * removal policy (RETAIN for prod, DESTROY otherwise).\n */\n readonly removalPolicy?: RemovalPolicy;\n}\n\n/**\n * DynamoDB table implementing the single-table design for app data (e.g. FHIR\n * resources, CRM, CMS, ERP, EHR).\n *\n * @see {@link https://github.com/codedrifters/openhi/blob/main/sites/www-docs/content/architecture/dynamodb-single-table-design.md | DynamoDB Single-Table Design}\n *\n * Primary key: PK (String), SK (String).\n * GSIs: GSI1 (reverse reference), GSI2 (identifier lookup), GSI3 (facility ops), GSI4 (resource type list).\n */\nexport class DynamoDbDataStore extends Table {\n constructor(\n scope: Construct,\n id: string,\n props: DynamoDbDataStoreProps = {},\n ) {\n const service = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, id, {\n ...props,\n tableName: getDynamoDbDataStoreTableName(scope),\n partitionKey: {\n name: \"PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"SK\",\n type: AttributeType.STRING,\n },\n billingMode: BillingMode.PAY_PER_REQUEST,\n removalPolicy: props.removalPolicy ?? service.removalPolicy,\n });\n\n // GSI1 — Reverse Reference Index: \"what references X?\"\n this.addGlobalSecondaryIndex({\n indexName: \"GSI1\",\n partitionKey: {\n name: \"GSI1PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI1SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.INCLUDE,\n nonKeyAttributes: [\"srcType\", \"srcId\", \"path\", \"srcPk\", \"srcSk\", \"ts\"],\n });\n\n // GSI2 — Identifier Lookup Index: MRN, NPI, member ID, etc.\n this.addGlobalSecondaryIndex({\n indexName: \"GSI2\",\n partitionKey: {\n name: \"GSI2PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI2SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.INCLUDE,\n nonKeyAttributes: [\"resourcePk\", \"resourceSk\", \"display\", \"status\"],\n });\n\n // GSI3 — Facility Ops Index: worklists, rosters, schedules\n this.addGlobalSecondaryIndex({\n indexName: \"GSI3\",\n partitionKey: {\n name: \"GSI3PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI3SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.INCLUDE,\n nonKeyAttributes: [\"resourcePk\", \"resourceSk\"],\n });\n\n // GSI4 — Resource Type Index: list all resources of a type in workspace (no scan)\n this.addGlobalSecondaryIndex({\n indexName: \"GSI4\",\n partitionKey: {\n name: \"GSI4PK\",\n type: AttributeType.STRING,\n },\n sortKey: {\n name: \"GSI4SK\",\n type: AttributeType.STRING,\n },\n projectionType: ProjectionType.ALL,\n });\n }\n}\n","import { EventBus, EventBusProps } from \"aws-cdk-lib/aws-events\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/event-bridge/data-event-bus.md\n */\n\nexport class DataEventBus extends EventBus {\n /*****************************************************************************\n *\n * Return a name for this EventBus based on the stack environment hash. This\n * name is common across all stacks since it's using the environment hash in\n * it's name.\n *\n ****************************************************************************/\n\n public static getEventBusName(scope: Construct): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return `data${stack.branchHash}`;\n }\n\n constructor(scope: Construct, props?: EventBusProps) {\n super(scope, \"data-event-bus\", {\n ...props,\n eventBusName: DataEventBus.getEventBusName(scope),\n });\n }\n}\n","import { EventBus, EventBusProps } from \"aws-cdk-lib/aws-events\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/event-bridge/ops-event-bus.md\n */\n\nexport class OpsEventBus extends EventBus {\n /*****************************************************************************\n *\n * Return a name for this EventBus based on the stack environment hash. This\n * name is common across all stacks since it's using the environment hash in\n * it's name.\n *\n ****************************************************************************/\n\n public static getEventBusName(scope: Construct): string {\n const stack = OpenHiService.of(scope) as OpenHiService;\n return `ops${stack.branchHash}`;\n }\n\n constructor(scope: Construct, props?: EventBusProps) {\n super(scope, \"ops-event-bus\", {\n ...props,\n eventBusName: OpsEventBus.getEventBusName(scope),\n });\n }\n}\n","import { Duration } from \"aws-cdk-lib\";\nimport {\n HostedZone,\n HostedZoneProps,\n IHostedZone,\n NsRecord,\n} from \"aws-cdk-lib/aws-route53\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/route-53/child-hosted-zone.md\n */\n\nexport interface ChildHostedZoneProps extends HostedZoneProps {\n /**\n * The root zone we will attach this sub-zone to.\n */\n readonly parentHostedZone: IHostedZone;\n}\n\nexport class ChildHostedZone extends HostedZone {\n /**\n * Used when storing the child zone ID in SSM. Use {@link OpenHiGlobalService.childHostedZoneFromConstruct} to look up.\n */\n public static readonly SSM_PARAM_NAME = \"CHILDHOSTEDZONE\";\n\n constructor(scope: Construct, id: string, props: ChildHostedZoneProps) {\n super(scope, id, { ...props });\n\n /**\n * Chain the child zone to the parent zone using NS record.\n */\n new NsRecord(this, \"child-ns-record\", {\n zone: props.parentHostedZone,\n recordName: this.zoneName,\n values: this.hostedZoneNameServers || [],\n ttl: Duration.minutes(5),\n });\n }\n}\n","import { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/components/route-53/root-hosted-zone.md\n */\n\n/**\n * Placeholder for root hosted zone. Use {@link OpenHiGlobalService.rootHostedZoneFromConstruct}\n * to obtain an IHostedZone from attributes (e.g. from config). The root zone is always\n * created manually and imported via config.\n */\nexport class RootHostedZone extends Construct {}\n","import {\n IUserPool,\n IUserPoolClient,\n IUserPoolDomain,\n LambdaVersion,\n UserPool,\n UserPoolClient,\n UserPoolDomain,\n UserPoolOperation,\n UserPoolProps,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { IKey, Key } from \"aws-cdk-lib/aws-kms\";\nimport { IFunction } from \"aws-cdk-lib/aws-lambda\";\nimport { Construct } from \"constructs\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport { CognitoUserPool } from \"../components/cognito/cognito-user-pool\";\nimport { CognitoUserPoolClient } from \"../components/cognito/cognito-user-pool-client\";\nimport { CognitoUserPoolDomain } from \"../components/cognito/cognito-user-pool-domain\";\nimport { CognitoUserPoolKmsKey } from \"../components/cognito/cognito-user-pool-kms-key\";\nimport { PreTokenGenerationLambda } from \"../components/cognito/pre-token-generation-lambda\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-auth-service.md\n */\n\nexport interface OpenHiAuthServiceProps extends OpenHiServiceProps {\n /**\n * Optional props for the Cognito User Pool.\n */\n readonly userPoolProps?: UserPoolProps;\n}\n\n/**\n * OpenHI Auth Service stack.\n *\n * @remarks\n * The Auth service manages authentication infrastructure including:\n * - Cognito User Pool for user management and authentication\n * - User Pool Client for application integration\n * - User Pool Domain for hosting the Cognito hosted UI\n * - KMS Key for Cognito User Pool encryption\n *\n * Resources are created in protected methods; subclasses may override to customize.\n * Other stacks obtain auth by calling **OpenHiAuthService.userPoolFromConstruct(scope)**,\n * **OpenHiAuthService.userPoolClientFromConstruct(scope)**,\n * **OpenHiAuthService.userPoolDomainFromConstruct(scope)**,\n * and **OpenHiAuthService.userPoolKmsKeyFromConstruct(scope)** for each resource needed.\n *\n * Only one instance of the auth service should exist per environment.\n *\n * @public\n */\nexport class OpenHiAuthService extends OpenHiService {\n static readonly SERVICE_TYPE = \"auth\";\n\n /**\n * Returns an IUserPool by looking up the Auth stack's User Pool ID from SSM.\n */\n static userPoolFromConstruct(scope: Construct): IUserPool {\n const userPoolId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CognitoUserPool.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n });\n return UserPool.fromUserPoolId(scope, \"user-pool\", userPoolId);\n }\n\n /**\n * Returns an IUserPoolClient by looking up the Auth stack's User Pool Client ID from SSM.\n */\n static userPoolClientFromConstruct(scope: Construct): IUserPoolClient {\n const userPoolClientId = DiscoverableStringParameter.valueForLookupName(\n scope,\n {\n ssmParamName: CognitoUserPoolClient.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n },\n );\n return UserPoolClient.fromUserPoolClientId(\n scope,\n \"user-pool-client\",\n userPoolClientId,\n );\n }\n\n /**\n * Returns an IUserPoolDomain by looking up the Auth stack's User Pool Domain from SSM.\n */\n static userPoolDomainFromConstruct(scope: Construct): IUserPoolDomain {\n const domainName = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CognitoUserPoolDomain.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n });\n return UserPoolDomain.fromDomainName(scope, \"user-pool-domain\", domainName);\n }\n\n /**\n * Returns an IKey (KMS) by looking up the Auth stack's User Pool KMS Key ARN from SSM.\n */\n static userPoolKmsKeyFromConstruct(scope: Construct): IKey {\n const keyArn = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CognitoUserPoolKmsKey.SSM_PARAM_NAME,\n serviceType: OpenHiAuthService.SERVICE_TYPE,\n });\n return Key.fromKeyArn(scope, \"kms-key\", keyArn);\n }\n\n get serviceType(): string {\n return OpenHiAuthService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options (e.g. userPoolProps). */\n public override props: OpenHiAuthServiceProps;\n\n public readonly userPoolKmsKey: IKey;\n public readonly preTokenGenerationLambda: IFunction;\n public readonly userPool: IUserPool;\n public readonly userPoolClient: IUserPoolClient;\n public readonly userPoolDomain: IUserPoolDomain;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiAuthServiceProps = {}) {\n super(ohEnv, OpenHiAuthService.SERVICE_TYPE, props);\n this.props = props;\n\n this.userPoolKmsKey = this.createUserPoolKmsKey();\n this.preTokenGenerationLambda = this.createPreTokenGenerationLambda();\n this.userPool = this.createUserPool();\n this.userPoolClient = this.createUserPoolClient();\n this.userPoolDomain = this.createUserPoolDomain();\n }\n\n /**\n * Creates the KMS key for the Cognito User Pool and exports its ARN to SSM.\n * Look up via {@link OpenHiAuthService.userPoolKmsKeyFromConstruct}.\n * Override to customize.\n */\n protected createUserPoolKmsKey(): IKey {\n const key = new CognitoUserPoolKmsKey(this);\n new DiscoverableStringParameter(this, \"kms-key-param\", {\n ssmParamName: CognitoUserPoolKmsKey.SSM_PARAM_NAME,\n stringValue: key.keyArn,\n description:\n \"KMS key ARN for Cognito User Pool (e.g. custom sender); cross-stack reference\",\n });\n return key;\n }\n\n /**\n * Creates the Pre Token Generation Lambda (Cognito trigger). Phase 2 will add\n * openhi_* claims to the access token only; trigger version V2_0 may be required.\n */\n protected createPreTokenGenerationLambda(): IFunction {\n const construct = new PreTokenGenerationLambda(this);\n return construct.lambda;\n }\n\n /**\n * Creates the Cognito User Pool and exports its ID to SSM.\n * Look up via {@link OpenHiAuthService.userPoolFromConstruct}.\n * Override to customize.\n */\n protected createUserPool(): IUserPool {\n const userPool = new CognitoUserPool(this, {\n ...this.props.userPoolProps,\n customSenderKmsKey: this.userPoolKmsKey,\n });\n // Access-token-only claims require Pre Token Generation V2_0.\n userPool.addTrigger(\n UserPoolOperation.PRE_TOKEN_GENERATION_CONFIG,\n this.preTokenGenerationLambda,\n LambdaVersion.V2_0,\n );\n new DiscoverableStringParameter(this, \"user-pool-param\", {\n ssmParamName: CognitoUserPool.SSM_PARAM_NAME,\n stringValue: userPool.userPoolId,\n description:\n \"Cognito User Pool ID for this Auth stack; cross-stack reference\",\n });\n return userPool;\n }\n\n /**\n * Creates the User Pool Client and exports its ID to SSM (AUTH service type).\n * Look up via {@link OpenHiAuthService.userPoolClientFromConstruct}.\n * Override to customize.\n */\n protected createUserPoolClient(): IUserPoolClient {\n const client = new CognitoUserPoolClient(this, {\n userPool: this.userPool,\n });\n new DiscoverableStringParameter(this, \"user-pool-client-param\", {\n ssmParamName: CognitoUserPoolClient.SSM_PARAM_NAME,\n stringValue: client.userPoolClientId,\n description:\n \"Cognito User Pool Client ID for this Auth stack; cross-stack reference\",\n });\n return client;\n }\n\n /**\n * Creates the User Pool Domain (Cognito hosted UI) and exports domain name to SSM.\n * Look up via {@link OpenHiAuthService.userPoolDomainFromConstruct}.\n * Override to customize.\n */\n protected createUserPoolDomain(): IUserPoolDomain {\n const domain = new CognitoUserPoolDomain(this, {\n userPool: this.userPool,\n cognitoDomain: {\n domainPrefix: `auth-${this.branchHash}`,\n },\n });\n new DiscoverableStringParameter(this, \"user-pool-domain-param\", {\n ssmParamName: CognitoUserPoolDomain.SSM_PARAM_NAME,\n stringValue: domain.domainName,\n description:\n \"Cognito User Pool Domain (hosted UI) for this Auth stack; cross-stack reference\",\n });\n return domain;\n }\n}\n","import {\n Certificate,\n CertificateValidation,\n ICertificate,\n} from \"aws-cdk-lib/aws-certificatemanager\";\nimport {\n HostedZone,\n HostedZoneAttributes,\n IHostedZone,\n} from \"aws-cdk-lib/aws-route53\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport {\n OpenHiService,\n OpenHiServiceProps,\n OpenHiServiceType,\n} from \"../app/open-hi-service\";\nimport { RootWildcardCertificate } from \"../components/acm/root-wildcard-certificate\";\nimport { ChildHostedZone } from \"../components/route-53/child-hosted-zone\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-global-service.md\n */\n\nexport interface OpenHiGlobalServiceProps extends OpenHiServiceProps {}\n\n/**\n * Global Infrastructure stack: owns global DNS and certificates.\n * Resources (root zone, optional child zone, wildcard cert) are created\n * in protected methods; subclasses may override to customize.\n */\nexport class OpenHiGlobalService extends OpenHiService {\n static readonly SERVICE_TYPE = \"global\";\n\n /**\n * Returns an IHostedZone from the given attributes (no SSM). Use when the zone is imported from config.\n */\n static rootHostedZoneFromConstruct(\n scope: Construct,\n props: HostedZoneAttributes,\n ): IHostedZone {\n return HostedZone.fromHostedZoneAttributes(scope, \"root-zone\", props);\n }\n\n /**\n * Returns an ICertificate by looking up the Global stack's wildcard cert ARN from SSM.\n */\n static rootWildcardCertificateFromConstruct(scope: Construct): ICertificate {\n const certificateArn = StringParameter.valueForStringParameter(\n scope,\n RootWildcardCertificate.ssmParameterName(),\n );\n return Certificate.fromCertificateArn(\n scope,\n \"wildcard-certificate\",\n certificateArn,\n );\n }\n\n /**\n * Returns an IHostedZone by looking up the child hosted zone ID from SSM. Defaults to GLOBAL service type.\n */\n static childHostedZoneFromConstruct(\n scope: Construct,\n props: { zoneName: string; serviceType?: OpenHiServiceType },\n ): IHostedZone {\n const hostedZoneId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: ChildHostedZone.SSM_PARAM_NAME,\n serviceType: props.serviceType ?? OpenHiGlobalService.SERVICE_TYPE,\n });\n return HostedZone.fromHostedZoneAttributes(scope, \"child-zone\", {\n hostedZoneId,\n zoneName: props.zoneName,\n });\n }\n\n get serviceType(): string {\n return OpenHiGlobalService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options. */\n public override props: OpenHiGlobalServiceProps;\n\n public readonly rootHostedZone: IHostedZone;\n public readonly childHostedZone?: IHostedZone;\n public readonly rootWildcardCertificate: ICertificate;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiGlobalServiceProps = {}) {\n super(ohEnv, OpenHiGlobalService.SERVICE_TYPE, props);\n this.props = props;\n\n this.validateConfig(props);\n\n this.rootHostedZone = this.createRootHostedZone();\n this.childHostedZone = this.createChildHostedZone();\n this.rootWildcardCertificate = this.createRootWildcardCertificate();\n }\n\n /**\n * Validates that config required for the Global stack is present.\n */\n protected validateConfig(props: OpenHiGlobalServiceProps): void {\n const { config } = props;\n if (!config) {\n throw new Error(\"Config is required\");\n }\n if (!config.zoneName) {\n throw new Error(\"Zone name is required to import the root zone\");\n }\n if (!config.hostedZoneId) {\n throw new Error(\"Hosted zone ID is required to import the root zone\");\n }\n }\n\n /**\n * Creates the root hosted zone (imported via attributes from config).\n * Override to customize or create the zone.\n */\n protected createRootHostedZone(): IHostedZone {\n return OpenHiGlobalService.rootHostedZoneFromConstruct(this, {\n zoneName: this.config.zoneName!,\n hostedZoneId: this.config.hostedZoneId!,\n });\n }\n\n /**\n * Creates the optional child hosted zone (e.g. branch subdomain).\n * Override to create a child zone when config provides childHostedZoneAttributes.\n * If you create a ChildHostedZone, also create a DiscoverableStringParameter\n * with ChildHostedZone.SSM_PARAM_NAME and the zone's hostedZoneId.\n */\n protected createChildHostedZone(): IHostedZone | undefined {\n return undefined;\n }\n\n /**\n * Creates the root wildcard certificate. On main branch, creates a new cert\n * with DNS validation; otherwise imports from SSM.\n * Override to customize certificate creation.\n */\n protected createRootWildcardCertificate(): ICertificate {\n if (this.branchName === \"main\") {\n return new RootWildcardCertificate(this, {\n domainName: `*.${this.rootHostedZone.zoneName}`,\n subjectAlternativeNames: [this.rootHostedZone.zoneName],\n validation: CertificateValidation.fromDns(this.rootHostedZone),\n });\n }\n return OpenHiGlobalService.rootWildcardCertificateFromConstruct(this);\n }\n}\n","import {\n CorsHttpMethod,\n DomainName,\n HttpApi,\n HttpMethod,\n HttpNoneAuthorizer,\n HttpRoute,\n HttpRouteKey,\n IHttpApi,\n} from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { HttpUserPoolAuthorizer } from \"aws-cdk-lib/aws-apigatewayv2-authorizers\";\nimport { HttpLambdaIntegration } from \"aws-cdk-lib/aws-apigatewayv2-integrations\";\nimport { ICertificate } from \"aws-cdk-lib/aws-certificatemanager\";\nimport { Effect, PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport {\n ARecord,\n HostedZone,\n IHostedZone,\n RecordTarget,\n} from \"aws-cdk-lib/aws-route53\";\nimport { ApiGatewayv2DomainProperties } from \"aws-cdk-lib/aws-route53-targets\";\nimport { Duration } from \"aws-cdk-lib/core\";\nimport { Construct } from \"constructs\";\nimport { OpenHiAuthService } from \"./open-hi-auth-service\";\nimport { OpenHiDataService } from \"./open-hi-data-service\";\nimport { OpenHiGlobalService } from \"./open-hi-global-service\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport { RootHttpApi } from \"../components/api-gateway/root-http-api\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\nimport { RestApiLambda } from \"../data/lambda/rest-api-lambda\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-rest-api-service.md\n */\n\n/**\n * CORS configuration for the REST API HTTP API (API Gateway v2).\n * When origins are set, API Gateway sends CORS headers; backend CORS headers are ignored for browser requests.\n */\nexport interface RestApiCorsOptions {\n /** Allowed origins (e.g. https://app.example.com, http://localhost:3000). Required when enabling CORS. */\n readonly allowOrigins: string[];\n /** Allowed HTTP methods. Defaults to GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS. */\n readonly allowMethods?: CorsHttpMethod[];\n /** Allowed request headers. Defaults to Content-Type, Authorization. */\n readonly allowHeaders?: string[];\n /** Whether to allow credentials (cookies, auth headers). Default true. */\n readonly allowCredentials?: boolean;\n /** How long preflight results can be cached. Default 1 day. */\n readonly maxAge?: Duration;\n}\n\nexport interface OpenHiRestApiServiceProps extends OpenHiServiceProps {\n /**\n * Optional CORS configuration for the root HTTP API.\n * When set, API Gateway will send CORS headers for the given origins.\n * When omitted, no CORS is configured at the gateway (Express CORS in the Lambda still applies for direct or non-browser use).\n */\n readonly cors?: RestApiCorsOptions;\n}\n\n/**\n * SSM parameter name suffix for the REST API base URL.\n * Full parameter name is built via buildParameterName with serviceType REST_API.\n */\nexport const REST_API_BASE_URL_SSM_NAME = \"REST_API_BASE_URL\";\n\n/**\n * REST API service stack: HTTP API, custom domain, and Lambda; exports base URL via SSM.\n * Resources are created in protected methods; subclasses may override to customize.\n */\nexport class OpenHiRestApiService extends OpenHiService {\n static readonly SERVICE_TYPE = \"rest-api\";\n\n /**\n * Returns an IHttpApi by looking up the REST API stack's HTTP API ID from SSM.\n */\n static rootHttpApiFromConstruct(scope: Construct): IHttpApi {\n const httpApiId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: RootHttpApi.SSM_PARAM_NAME,\n serviceType: OpenHiRestApiService.SERVICE_TYPE,\n });\n return HttpApi.fromHttpApiAttributes(scope, \"http-api\", { httpApiId });\n }\n\n /**\n * Returns the REST API base URL (e.g. https://api.example.com) by looking it up from SSM.\n * Use in other stacks for E2E, scripts, or config.\n */\n static restApiBaseUrlFromConstruct(scope: Construct): string {\n return DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: REST_API_BASE_URL_SSM_NAME,\n serviceType: OpenHiRestApiService.SERVICE_TYPE,\n });\n }\n\n get serviceType(): string {\n return OpenHiRestApiService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options (e.g. cors). */\n public override props: OpenHiRestApiServiceProps;\n\n public readonly rootHttpApi: RootHttpApi;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiRestApiServiceProps = {}) {\n super(ohEnv, OpenHiRestApiService.SERVICE_TYPE, props);\n this.props = props;\n\n this.validateConfig(props);\n\n const hostedZone = this.createHostedZone();\n const certificate = this.createCertificate();\n const apiDomainName = this.createApiDomainNameString(hostedZone);\n this.createRestApiBaseUrlParameter(apiDomainName);\n const domainName = this.createDomainName(hostedZone, certificate);\n this.rootHttpApi = this.createRootHttpApi(domainName);\n this.createRestApiLambdaAndRoutes(hostedZone, domainName);\n }\n\n /**\n * Validates that config required for the REST API stack is present.\n */\n protected validateConfig(props: OpenHiRestApiServiceProps): void {\n const { config } = props;\n if (!config) {\n throw new Error(\"Config is required\");\n }\n if (!config.hostedZoneId) {\n throw new Error(\"Hosted zone ID is required\");\n }\n if (!config.zoneName) {\n throw new Error(\"Zone name is required\");\n }\n }\n\n /**\n * Creates the hosted zone reference (imported from config).\n * Override to customize.\n */\n protected createHostedZone(): IHostedZone {\n const { config } = this.props;\n return HostedZone.fromHostedZoneAttributes(this, \"root-zone\", {\n hostedZoneId: config!.hostedZoneId!,\n zoneName: config!.zoneName!,\n });\n }\n\n /**\n * Creates the wildcard certificate (imported from Global stack via SSM).\n * Override to customize.\n */\n protected createCertificate() {\n return OpenHiGlobalService.rootWildcardCertificateFromConstruct(this);\n }\n\n /**\n * Returns the API domain name string (e.g. api.example.com or api-{prefix}.example.com).\n * Override to customize.\n */\n protected createApiDomainNameString(hostedZone: IHostedZone): string {\n const apiPrefix =\n this.branchName === \"main\" ? `api` : `api-${this.childZonePrefix}`;\n return [apiPrefix, hostedZone.zoneName].join(\".\");\n }\n\n /**\n * Creates the SSM parameter for the REST API base URL.\n * Look up via {@link OpenHiRestApiService.restApiBaseUrlFromConstruct}.\n * Override to customize.\n */\n protected createRestApiBaseUrlParameter(apiDomainName: string): void {\n const restApiBaseUrl = `https://${apiDomainName}`;\n new DiscoverableStringParameter(this, \"rest-api-base-url-param\", {\n ssmParamName: REST_API_BASE_URL_SSM_NAME,\n stringValue: restApiBaseUrl,\n description: \"REST API base URL for this deployment (E2E, scripts)\",\n });\n }\n\n /**\n * Creates the API Gateway custom domain name resource.\n * Override to customize.\n */\n protected createDomainName(\n _hostedZone: IHostedZone,\n certificate: ICertificate,\n ): DomainName {\n const apiDomainName = this.createApiDomainNameString(_hostedZone);\n return new DomainName(this, \"domain\", {\n domainName: apiDomainName,\n certificate,\n });\n }\n\n /**\n * Creates the Lambda integration, HTTP routes, and API DNS record.\n * Override to customize. Uses {@link rootHttpApi} set by the constructor.\n */\n protected createRestApiLambdaAndRoutes(\n hostedZone: IHostedZone,\n domainName: DomainName,\n ): void {\n const dataStoreTable =\n OpenHiDataService.dynamoDbDataStoreFromConstruct(this);\n const { lambda } = new RestApiLambda(this, {\n dynamoTableName: dataStoreTable.tableName,\n branchTagValue: this.branchName,\n httpApiTagValue: RootHttpApi.SSM_PARAM_NAME,\n });\n const dynamoActions = [\n \"dynamodb:GetItem\",\n \"dynamodb:Query\",\n \"dynamodb:BatchGetItem\",\n \"dynamodb:ConditionCheckItem\",\n \"dynamodb:DescribeTable\",\n \"dynamodb:BatchWriteItem\",\n \"dynamodb:PutItem\",\n \"dynamodb:UpdateItem\",\n \"dynamodb:DeleteItem\",\n ] as const;\n dataStoreTable.grant(lambda, ...dynamoActions);\n // Query (and other operations) on GSIs require the index resource ARN\n lambda.addToRolePolicy(\n new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [...dynamoActions],\n resources: [`${dataStoreTable.tableArn}/index/*`],\n }),\n );\n // Temporary: broad SSM read for dynamic config (test only)\n lambda.addToRolePolicy(\n new PolicyStatement({\n effect: Effect.ALLOW,\n actions: [\n \"ssm:GetParameter\",\n \"ssm:GetParameters\",\n \"ssm:DescribeParameters\",\n ],\n resources: [\"*\"],\n }),\n );\n const integration = new HttpLambdaIntegration(\"lambda-integration\", lambda);\n const noAuth = new HttpNoneAuthorizer();\n // OPTIONS routes without authorizer so CORS preflight succeeds (browsers do not send auth on preflight).\n new HttpRoute(this, \"options-route-root\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/\", HttpMethod.OPTIONS),\n integration,\n authorizer: noAuth,\n });\n new HttpRoute(this, \"options-route-proxy\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/{proxy+}\", HttpMethod.OPTIONS),\n integration,\n authorizer: noAuth,\n });\n new HttpRoute(this, \"proxy-route-root\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/\", HttpMethod.ANY),\n integration,\n });\n new HttpRoute(this, \"proxy-route\", {\n httpApi: this.rootHttpApi,\n routeKey: HttpRouteKey.with(\"/{proxy+}\", HttpMethod.ANY),\n integration,\n });\n const apiPrefix =\n this.branchName === \"main\" ? `api` : `api-${this.childZonePrefix}`;\n new ARecord(this, \"api-a-record\", {\n zone: hostedZone,\n recordName: apiPrefix,\n target: RecordTarget.fromAlias(\n new ApiGatewayv2DomainProperties(\n domainName.regionalDomainName,\n domainName.regionalHostedZoneId,\n ),\n ),\n });\n }\n\n /**\n * Creates the Root HTTP API with default domain mapping, Cognito JWT authorizer, and exports API ID to SSM.\n * Look up via {@link OpenHiRestApiService.rootHttpApiFromConstruct}.\n * Override to customize.\n */\n protected createRootHttpApi(domainName: DomainName): RootHttpApi {\n const userPool = OpenHiAuthService.userPoolFromConstruct(this);\n const userPoolClient = OpenHiAuthService.userPoolClientFromConstruct(this);\n const cognitoAuthorizer = new HttpUserPoolAuthorizer(\n \"cognito-authorizer\",\n userPool,\n { userPoolClients: [userPoolClient] },\n );\n const cors = this.props.cors;\n const corsPreflight =\n cors && cors.allowOrigins.length > 0\n ? {\n allowOrigins: cors.allowOrigins,\n allowMethods: cors.allowMethods ?? [\n CorsHttpMethod.GET,\n CorsHttpMethod.HEAD,\n CorsHttpMethod.POST,\n CorsHttpMethod.PUT,\n CorsHttpMethod.PATCH,\n CorsHttpMethod.DELETE,\n CorsHttpMethod.OPTIONS,\n ],\n allowHeaders: cors.allowHeaders ?? [\n \"Content-Type\",\n \"Authorization\",\n ],\n allowCredentials: cors.allowCredentials ?? true,\n maxAge: cors.maxAge ?? Duration.days(1),\n }\n : undefined;\n const rootHttpApi = new RootHttpApi(this, {\n defaultDomainMapping: {\n domainName,\n mappingKey: undefined,\n },\n defaultAuthorizer: cognitoAuthorizer,\n ...(corsPreflight && { corsPreflight }),\n });\n new DiscoverableStringParameter(this, \"http-api-url-param\", {\n ssmParamName: RootHttpApi.SSM_PARAM_NAME,\n stringValue: rootHttpApi.httpApiId,\n description:\n \"API Gateway HTTP API ID for this REST API stack (cross-stack reference)\",\n });\n return rootHttpApi;\n }\n}\n","import { ITable, Table } from \"aws-cdk-lib/aws-dynamodb\";\nimport { EventBus, IEventBus } from \"aws-cdk-lib/aws-events\";\nimport { Construct } from \"constructs\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport {\n DynamoDbDataStore,\n getDynamoDbDataStoreTableName,\n} from \"../components/dynamodb/dynamo-db-data-store\";\nimport { DataEventBus } from \"../components/event-bridge/data-event-bus\";\nimport { OpsEventBus } from \"../components/event-bridge/ops-event-bus\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-data-service.md\n */\n\nexport interface OpenHiDataServiceProps extends OpenHiServiceProps {}\n\n/**\n * Data storage service stack: centralizes DynamoDB, S3, EventBridge event buses,\n * and other persistence resources for OpenHI. Creates the single-table data store\n * (CRM, CMS, ERP, EHR) and the data/ops event buses in protected methods;\n * subclasses may override to customize.\n */\nexport class OpenHiDataService extends OpenHiService {\n static readonly SERVICE_TYPE = \"data\";\n\n /**\n * Returns the data event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.\n */\n static dataEventBusFromConstruct(scope: Construct): IEventBus {\n return EventBus.fromEventBusName(\n scope,\n \"data-event-bus\",\n DataEventBus.getEventBusName(scope),\n );\n }\n\n /**\n * Returns the ops event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.\n */\n static opsEventBusFromConstruct(scope: Construct): IEventBus {\n return EventBus.fromEventBusName(\n scope,\n \"ops-event-bus\",\n OpsEventBus.getEventBusName(scope),\n );\n }\n\n /**\n * Returns the data store table by name. Use from other stacks (e.g. REST API Lambda) to obtain an ITable reference.\n */\n static dynamoDbDataStoreFromConstruct(\n scope: Construct,\n id = \"dynamo-db-data-store\",\n ): ITable {\n return Table.fromTableName(scope, id, getDynamoDbDataStoreTableName(scope));\n }\n\n get serviceType(): string {\n return OpenHiDataService.SERVICE_TYPE;\n }\n\n /** Override so this.props is typed with this service's options. */\n public override props: OpenHiDataServiceProps;\n\n /**\n * Event bus for data-related events (ingestion, transformation, storage).\n * Other stacks obtain it via {@link OpenHiDataService.dataEventBusFromConstruct}.\n */\n public readonly dataEventBus: IEventBus;\n\n /**\n * Event bus for operational events (monitoring, alerting, system health).\n * Other stacks obtain it via {@link OpenHiDataService.opsEventBusFromConstruct}.\n */\n public readonly opsEventBus: IEventBus;\n\n /**\n * The single-table DynamoDB data store. Use {@link OpenHiDataService.dynamoDbDataStoreFromConstruct}\n * from other stacks to obtain an ITable reference by name.\n */\n public readonly dataStore: ITable;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiDataServiceProps = {}) {\n super(ohEnv, OpenHiDataService.SERVICE_TYPE, props);\n this.props = props;\n\n this.dataEventBus = this.createDataEventBus();\n this.opsEventBus = this.createOpsEventBus();\n this.dataStore = this.createDataStore();\n }\n\n /**\n * Creates the data event bus.\n * Override to customize.\n */\n protected createDataEventBus(): IEventBus {\n return new DataEventBus(this);\n }\n\n /**\n * Creates the ops event bus.\n * Override to customize.\n */\n protected createOpsEventBus(): IEventBus {\n return new OpsEventBus(this);\n }\n\n /**\n * Creates the single-table DynamoDB data store.\n * Override to customize.\n */\n protected createDataStore(): ITable {\n return new DynamoDbDataStore(this, \"dynamo-db-data-store\");\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { NodejsFunction } from \"aws-cdk-lib/aws-lambda-nodejs\";\nimport { Construct } from \"constructs\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/constructs/data/lambda/rest-api-lambda.md\n */\n\nconst HANDLER_NAME = \"rest-api-lambda.handler.js\";\n\n/**\n * Resolve Lambda entry so it works when running from src/ (tests) or from lib/ (built).\n */\nfunction resolveHandlerEntry(dirname: string): string {\n const sameDir = path.join(dirname, HANDLER_NAME);\n if (fs.existsSync(sameDir)) {\n return sameDir;\n }\n\n const fromLib = path.join(dirname, \"..\", \"..\", \"..\", \"lib\", HANDLER_NAME);\n return fromLib;\n}\n\nexport interface RestApiLambdaProps {\n /**\n * DynamoDB table name for the data store. The Lambda receives it as the\n * environment variable DYNAMO_TABLE_NAME at runtime.\n */\n readonly dynamoTableName: string;\n\n /**\n * Branch name from the service. Passed as BRANCH_TAG_VALUE at runtime.\n */\n readonly branchTagValue: string;\n\n /**\n * SSM parameter name for the HTTP API (e.g. RootHttpApi.SSM_PARAM_NAME).\n * Passed as HTTP_API_TAG_VALUE at runtime.\n */\n readonly httpApiTagValue: string;\n}\n\nexport class RestApiLambda extends Construct {\n public readonly lambda: NodejsFunction;\n\n constructor(scope: Construct, props: RestApiLambdaProps) {\n super(scope, \"rest-api-lambda\");\n\n /**\n * Create a Lambda function\n */\n this.lambda = new NodejsFunction(this, \"handler\", {\n entry: resolveHandlerEntry(__dirname),\n runtime: Runtime.NODEJS_LATEST,\n memorySize: 1024,\n environment: {\n DYNAMO_TABLE_NAME: props.dynamoTableName,\n BRANCH_TAG_VALUE: props.branchTagValue,\n HTTP_API_TAG_VALUE: props.httpApiTagValue,\n },\n });\n }\n}\n","import {\n AuthorizationType,\n IGraphqlApi,\n UserPoolDefaultAction,\n} from \"aws-cdk-lib/aws-appsync\";\nimport { Construct } from \"constructs\";\nimport { OpenHiAuthService } from \"./open-hi-auth-service\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport { OpenHiService, OpenHiServiceProps } from \"../app/open-hi-service\";\nimport { RootGraphqlApi } from \"../components/app-sync/root-graphql-api\";\n\nexport interface OpenHiGraphqlServiceProps extends OpenHiServiceProps {}\n\n/**\n * GraphQL API service stack: creates the AppSync API via {@link RootGraphqlApi}\n * and exports its ID via SSM. Look up from other stacks via\n * {@link OpenHiGraphqlService.graphqlApiFromConstruct}.\n */\nexport class OpenHiGraphqlService extends OpenHiService {\n static readonly SERVICE_TYPE = \"graphql-api\";\n\n /**\n * Returns the GraphQL API by looking up the GraphQL stack's API ID from SSM.\n * Use from other stacks to obtain an IGraphqlApi reference.\n */\n static graphqlApiFromConstruct(scope: Construct): IGraphqlApi {\n return RootGraphqlApi.fromConstruct(scope);\n }\n\n get serviceType(): string {\n return OpenHiGraphqlService.SERVICE_TYPE;\n }\n\n /* Override so this.props is typed with this service's options */\n public override props: OpenHiGraphqlServiceProps;\n\n public readonly rootGraphqlApi: RootGraphqlApi;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiGraphqlServiceProps = {}) {\n super(ohEnv, OpenHiGraphqlService.SERVICE_TYPE, props);\n this.props = props;\n this.rootGraphqlApi = this.createRootGraphqlApi();\n }\n\n /** Creates the root GraphQL API with Cognito user pool. */\n protected createRootGraphqlApi(): RootGraphqlApi {\n const userPool = OpenHiAuthService.userPoolFromConstruct(this);\n return new RootGraphqlApi(this, {\n authorizationConfig: {\n defaultAuthorization: {\n authorizationType: AuthorizationType.USER_POOL,\n userPoolConfig: {\n userPool,\n defaultAction: UserPoolDefaultAction.ALLOW,\n },\n },\n },\n });\n }\n}\n"],"mappings":"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","names":["import_config","Stage","Stage","import_config","Tags","StringParameter","StringParameter","Tags","EventBus","EventBus","Construct","UserPool","UserPoolClient","UserPoolDomain","Key","UserPool","UserPoolClient","UserPoolDomain","Key","Certificate","HostedZone","StringParameter","HostedZone","StringParameter","Certificate","HttpApi","HostedZone","Duration","Table","EventBus","EventBus","Table","fs","path","Runtime","NodejsFunction","Construct","HANDLER_NAME","resolveHandlerEntry","HttpApi","HostedZone","Duration"]}
|
|
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(rest_api_lambda_handler_exports);
|
|
|
36
36
|
var import_serverless_express2 = __toESM(require("@codegenie/serverless-express"));
|
|
37
37
|
|
|
38
38
|
// src/data/rest-api/rest-api.ts
|
|
39
|
-
var
|
|
39
|
+
var import_node_path2 = __toESM(require("path"));
|
|
40
40
|
var import_cors = __toESM(require("cors"));
|
|
41
41
|
var import_express3 = __toESM(require("express"));
|
|
42
42
|
|
|
@@ -1180,7 +1180,7 @@ router2.delete("/:key", deleteConfiguration);
|
|
|
1180
1180
|
// src/data/rest-api/rest-api.ts
|
|
1181
1181
|
var app = (0, import_express3.default)();
|
|
1182
1182
|
app.set("view engine", "ejs");
|
|
1183
|
-
app.set("views",
|
|
1183
|
+
app.set("views", import_node_path2.default.join(__dirname, "views"));
|
|
1184
1184
|
app.use((0, import_cors.default)());
|
|
1185
1185
|
app.use(import_express3.default.json());
|
|
1186
1186
|
app.use(import_express3.default.urlencoded({ extended: true }));
|