@openhi/constructs 0.0.1 → 0.0.2
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.d.mts +335 -211
- package/lib/index.d.ts +337 -213
- package/lib/index.js +636 -451
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +652 -469
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../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/ssm/discoverable-string-parameter.ts","../src/services/open-hi-core-service.ts","../src/components/auth.ts","../src/components/cognito/core-user-pool.ts","../src/components/cognito/core-user-pool-client.ts","../src/components/cognito/core-user-pool-domain.ts","../src/components/cognito/core-user-pool-kms-key.ts","../src/services/open-hi-auth-service.ts","../src/components/global.ts","../src/components/acm/root-wildcard-certificate.ts","../src/components/route-53/child-hosted-zone.ts","../src/components/route-53/root-hosted-zone.ts","../src/services/open-hi-global-service.ts","../src/services/open-hi-rest-api-service.ts","../src/components/api-gateway/core-http-api.ts","../src/components/dynamodb/dynamo-db-data-store.ts","../src/data/lambda/rest-api-lambda.ts","../src/services/open-hi-data-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","/** @openhi/constructs — root barrel exports. */\nexport * from \"./app\";\nexport * from \"./components\";\nexport * from \"./services\";\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 * 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 * 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 * 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\";\nimport { CoreProps } from \"../components/core\";\n\n/**\n * Service type identifiers for OpenHI services.\n *\n * @remarks\n * These constants define the different types of services that can be deployed\n * within the OpenHI platform. Each service type represents a distinct domain\n * or functional area with its own data model, API endpoints, and business logic.\n *\n * Service types are used for:\n * - Resource naming and tagging\n * - Service discovery and routing\n * - Deployment context calculations\n * - Cross-service communication patterns\n *\n * @public\n */\nexport const OPEN_HI_SERVICE_TYPE = {\n /**\n * Authentication service.\n * *\n * Only one instance of the auth service should exist per environment.\n */\n AUTH: \"auth\",\n\n /**\n * Root shared core services.\n *\n * Only one instance of the core service should exist per environment.\n */\n CORE: \"core\",\n\n /**\n * Rest API service.\n */\n REST_API: \"rest-api\",\n\n /**\n * Global Infrastructure stack (Route53, ACM).\n */\n GLOBAL: \"global\",\n\n /**\n * Data service (DynamoDB, S3, persistence).\n */\n DATA: \"data\",\n} as const;\n\n/**\n * Type representing valid OpenHI service type values. This is a union of the\n * values from {@link OPEN_HI_SERVICE_TYPE}.\n *\n * @public\n */\nexport type OpenHiServiceType =\n (typeof OPEN_HI_SERVICE_TYPE)[keyof typeof OPEN_HI_SERVICE_TYPE];\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 * Optional props for the core construct.\n */\n readonly coreProps?: CoreProps;\n}\n\n/**\n * Represents an OpenHI service stack within the OpenHI platform.\n */\nexport 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 * A constant that identifies the service type.\n */\n public readonly serviceType:\n | (typeof OPEN_HI_SERVICE_TYPE)[keyof typeof OPEN_HI_SERVICE_TYPE]\n | string;\n\n /**\n * Core construct containing shared infrastructure.\n */\n // public core: Core;\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 // Root DNS information, if provided in configs.\n // This is used for configuring API Gateway custom domains.\n const hostedZoneId = ohEnv.props.config.hostedZoneId;\n const zoneName = ohEnv.props.config.zoneName;\n\n if (hostedZoneId && zoneName) {\n props = {\n ...props,\n coreProps: {\n ...props.coreProps,\n },\n };\n }\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 // Set the service type for this stack.\n // Used when assembling parameter names, tags, and for service discovery.\n // Defaults to the construct ID if not explicitly provided.\n this.serviceType = props.serviceType ?? id;\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 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(\n `${appName}:service-type`,\n this.serviceType.slice(0, 255),\n );\n Tags.of(this).add(\n `${appName}:stage-type`,\n ohEnv.ohStage.stageType.slice(0, 255),\n );\n\n // Create the Core construct that contains core resources used across all services.\n // Most services will get an imported/shared instance.\n // Only the actual Core Service creates the concrete instance.\n // this.core = this.createCore(props);\n }\n\n /**\n * Creates or returns the core construct for shared infrastructure.\n */\n /*\n protected createCore(props: OpenHiServiceProps = {}): Core {\n if (!this.core) {\n return new Core(this, props.coreProps);\n }\n return this.core;\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 { 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 *\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 * 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 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, {\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 { Code, Function, Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { OpenHiEnvironment } from \"../app\";\nimport {\n OPEN_HI_SERVICE_TYPE,\n OpenHiService,\n OpenHiServiceProps,\n} from \"../app/open-hi-service\";\n\nexport interface OpenHiCoreServiceProps extends OpenHiServiceProps {}\n\nexport class OpenHiCoreService extends OpenHiService {\n /*****************************************************************************\n *\n * PROPS\n *\n * Final props calculated from inputs combined with default values.\n *\n ****************************************************************************/\n\n public readonly props: OpenHiCoreServiceProps;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiCoreServiceProps = {}) {\n /**\n * Force concrete version of all core resources to be created in this\n * service. In all other stacks, imported versions will be used.\n */\n props = {\n ...props,\n };\n\n super(ohEnv, OPEN_HI_SERVICE_TYPE.CORE, props);\n\n /**\n * Store the props in case they are needed later. Mostly this is just a\n * resource of what was passed in, combined with any custom or default\n * settings, if any.\n */\n this.props = props;\n\n // A Lambda to integrate\n new Function(this, \"test-fn\", {\n runtime: Runtime.NODEJS_LATEST,\n handler: \"index.handler\",\n code: Code.fromInline(\n 'exports.handler = async () => { return {statusCode:200, body:\"ok\"} }',\n ),\n });\n\n // Create a Lambda integration\n // const integration = new HttpLambdaIntegration(\"test-integration\", fn);\n\n // new HttpRoute(this, \"test-route\", {\n // httpApi: this.core.httpApi,\n // routeKey: HttpRouteKey.with(`/hello-world`, HttpMethod.GET),\n // integration,\n // });\n }\n}\n","import {\n IUserPool,\n IUserPoolClient,\n IUserPoolDomain,\n UserPoolProps,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { IKey } from \"aws-cdk-lib/aws-kms\";\nimport { Construct } from \"constructs\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"../app/open-hi-service\";\nimport { CoreUserPool } from \"./cognito/core-user-pool\";\nimport { CoreUserPoolClient } from \"./cognito/core-user-pool-client\";\nimport { CoreUserPoolDomain } from \"./cognito/core-user-pool-domain\";\nimport { CoreUserPoolKmsKey } from \"./cognito/core-user-pool-kms-key\";\n\nexport interface AuthProps {\n /**\n * Optional props for creating the user pool.\n */\n readonly userPoolProps?: UserPoolProps;\n}\n\n/**\n * Auth construct that manages Cognito authentication resources.\n *\n * @remarks\n * The Auth construct provides 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 * When created in the Auth service (`serviceType === OPEN_HI_SERVICE_TYPE.AUTH`),\n * it creates concrete resources. Otherwise, it imports existing resources\n * from SSM Parameter Store.\n *\n * Use {@link Auth.fromConstruct} to obtain an Auth instance (with resources\n * imported from AUTH SSM parameters) when not in the Auth service, e.g. from\n * the Core construct.\n *\n * @public\n */\nexport class Auth extends Construct {\n /**\n * Returns an Auth instance that uses resources imported from AUTH SSM\n * parameters. Use this when creating Core or other stacks that consume\n * auth resources; the Auth stack must be deployed first.\n *\n * @param scope - Construct scope (e.g. Core); must be in a stack that has\n * access to the same account/region as the deployed Auth stack.\n */\n public static fromConstruct(scope: Construct): Auth {\n return new Auth(scope, {});\n }\n\n /**\n * Is this construct being created in the auth service or elsewhere?\n */\n public readonly isAuthService: boolean;\n\n /**\n * KMS Key used to encrypt the Cognito User Pool. We need a custom key so that\n * we can decrypt tokens when sending emails using something other than SES.\n */\n public readonly userPoolKmsKey: IKey;\n\n /**\n * Cognito User Pool for user management and authentication.\n */\n public readonly userPool: IUserPool;\n\n /**\n * Cognito User Pool Client for application integration with the User Pool.\n */\n public readonly userPoolClient: IUserPoolClient;\n\n /**\n * Cognito User Pool Domain for hosting the Cognito hosted UI.\n */\n public readonly userPoolDomain: IUserPoolDomain;\n\n constructor(scope: Construct, props: AuthProps = {}) {\n super(scope, \"auth\");\n\n /**\n * Reference to parent stack this belongs to.\n */\n const service = OpenHiService.of(this) as OpenHiService;\n\n /**\n * Determine if we are in the auth service or not.\n */\n this.isAuthService = service.serviceType === OPEN_HI_SERVICE_TYPE.AUTH;\n\n /**\n * Auth Support\n */\n this.userPoolKmsKey = this.createUserPoolKmsKey();\n this.userPool = this.createUserPool({\n ...props.userPoolProps,\n customSenderKmsKey: this.userPoolKmsKey,\n });\n this.userPoolClient = this.createUserPoolClient({\n userPool: this.userPool,\n });\n this.userPoolDomain = this.createUserPoolDomain({\n userPool: this.userPool,\n });\n }\n\n /*****************************************************************************\n *\n * Auth Support\n *\n ****************************************************************************/\n\n protected createUserPoolKmsKey(): IKey {\n return this.isAuthService\n ? new CoreUserPoolKmsKey(this)\n : CoreUserPoolKmsKey.fromConstruct(this);\n }\n\n protected createUserPool(props?: UserPoolProps): IUserPool {\n return this.isAuthService\n ? new CoreUserPool(this, props)\n : CoreUserPool.fromConstruct(this);\n }\n\n protected createUserPoolClient(props: {\n userPool: IUserPool;\n }): IUserPoolClient {\n return this.isAuthService\n ? new CoreUserPoolClient(this, { userPool: props.userPool })\n : CoreUserPoolClient.fromConstruct(this);\n }\n\n protected createUserPoolDomain(props: {\n userPool: IUserPool;\n }): IUserPoolDomain {\n const service = OpenHiService.of(this) as OpenHiService;\n return this.isAuthService\n ? new CoreUserPoolDomain(this, {\n userPool: props.userPool,\n cognitoDomain: {\n domainPrefix: `auth-${service.branchHash}`,\n },\n })\n : CoreUserPoolDomain.fromConstruct(this);\n }\n}\n","import {\n IUserPool,\n UserPool,\n UserPoolProps,\n VerificationEmailStyle,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"../../app/open-hi-service\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\nexport class CoreUserPool extends UserPool {\n /**\n * Used when storing the User Pool ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"CORE_USER_POOL\";\n\n public static fromConstruct(scope: Construct): IUserPool {\n const userPoolId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CoreUserPool.SSM_PARAM_NAME,\n serviceType: OPEN_HI_SERVICE_TYPE.AUTH,\n });\n\n return UserPool.fromUserPoolId(scope, \"user-pool\", userPoolId);\n }\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: [\"core\", \"user\", \"pool\", service.branchHash].join(\"-\"),\n });\n\n /**\n * Generate the SSM Parameter used to store this User Pool's ID.\n */\n new DiscoverableStringParameter(this, \"user-pool-param\", {\n ssmParamName: CoreUserPool.SSM_PARAM_NAME,\n stringValue: this.userPoolId,\n });\n }\n}\n","import {\n IUserPoolClient,\n UserPoolClient,\n UserPoolClientProps,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\nimport { OPEN_HI_SERVICE_TYPE } from \"../../app/open-hi-service\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\nexport class CoreUserPoolClient extends UserPoolClient {\n /**\n * Used when storing the User Pool Client ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"CORE_USER_POOL_CLIENT\";\n\n public static fromConstruct(scope: Construct): IUserPoolClient {\n const userPoolClientId = DiscoverableStringParameter.valueForLookupName(\n scope,\n {\n ssmParamName: CoreUserPoolClient.SSM_PARAM_NAME,\n serviceType: OPEN_HI_SERVICE_TYPE.AUTH,\n },\n );\n\n return UserPoolClient.fromUserPoolClientId(\n scope,\n \"user-pool-client\",\n userPoolClientId,\n );\n }\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 * Generate the SSM Parameter used to store this User Pool's ID.\n */\n new DiscoverableStringParameter(this, \"user-pool-client-param\", {\n ssmParamName: CoreUserPoolClient.SSM_PARAM_NAME,\n stringValue: this.userPoolClientId,\n });\n }\n}\n","import {\n IUserPoolDomain,\n UserPoolDomain,\n UserPoolDomainProps,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { Construct } from \"constructs\";\nimport { OPEN_HI_SERVICE_TYPE } from \"../../app/open-hi-service\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\nexport class CoreUserPoolDomain extends UserPoolDomain {\n /**\n * Used when storing the User Pool Domain in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"CORE_USER_POOL_DOMAIN\";\n\n public static fromConstruct(scope: Construct): IUserPoolDomain {\n const userPoolDomain = DiscoverableStringParameter.valueForLookupName(\n scope,\n {\n ssmParamName: CoreUserPoolDomain.SSM_PARAM_NAME,\n serviceType: OPEN_HI_SERVICE_TYPE.AUTH,\n },\n );\n\n return UserPoolDomain.fromDomainName(\n scope,\n \"user-pool-domain\",\n userPoolDomain,\n );\n }\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 * Generate the SSM Parameter used to store this User Pool's Domain.\n */\n new DiscoverableStringParameter(this, \"user-pool-domain-param\", {\n ssmParamName: CoreUserPoolDomain.SSM_PARAM_NAME,\n stringValue: this.domainName,\n });\n }\n}\n","import { IKey, Key, KeyProps } from \"aws-cdk-lib/aws-kms\";\nimport { Construct } from \"constructs\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"../../app/open-hi-service\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\nexport class CoreUserPoolKmsKey extends Key {\n /**\n * Used when storing the KMS Key in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"CORE_USER_POOL_KMS_KEY\";\n\n public static fromConstruct(scope: Construct): IKey {\n const keyArn = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CoreUserPoolKmsKey.SSM_PARAM_NAME,\n serviceType: OPEN_HI_SERVICE_TYPE.AUTH,\n });\n\n return Key.fromKeyArn(scope, \"kms-key\", keyArn);\n }\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 * Generate the SSM Parameter used to store this KMS Key.\n */\n new DiscoverableStringParameter(this, \"kms-key-param\", {\n ssmParamName: CoreUserPoolKmsKey.SSM_PARAM_NAME,\n stringValue: this.keyArn,\n });\n }\n}\n","import { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport {\n OPEN_HI_SERVICE_TYPE,\n OpenHiService,\n OpenHiServiceProps,\n} from \"../app/open-hi-service\";\nimport { Auth, AuthProps } from \"../components/auth\";\n\nexport interface OpenHiAuthServiceProps extends OpenHiServiceProps {\n /**\n * Optional props for the auth construct.\n */\n readonly authProps?: AuthProps;\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 * Only one instance of the auth service should exist per environment.\n *\n * @public\n */\nexport class OpenHiAuthService extends OpenHiService {\n /**\n * Auth construct containing authentication resources.\n */\n public readonly auth: Auth;\n\n constructor(\n ohEnv: OpenHiEnvironment,\n public props: OpenHiAuthServiceProps = {},\n ) {\n super(ohEnv, OPEN_HI_SERVICE_TYPE.AUTH, props);\n\n /**\n * Create the Auth construct that manages authentication resources.\n */\n this.auth = new Auth(this, props.authProps);\n }\n}\n","import {\n CertificateValidation,\n ICertificate,\n} from \"aws-cdk-lib/aws-certificatemanager\";\nimport { HostedZoneAttributes, IHostedZone } from \"aws-cdk-lib/aws-route53\";\nimport { Construct } from \"constructs\";\nimport { SetOptional } from \"type-fest\";\nimport { OpenHiService } from \"../app\";\nimport { RootWildcardCertificate } from \"./acm/root-wildcard-certificate\";\nimport { ChildHostedZone } from \"./route-53/child-hosted-zone\";\nimport { RootHostedZone } from \"./route-53/root-hosted-zone\";\n\nexport interface GlobalProps {\n /**\n * Root zone configuration attributes. Zone name is required, hosted zone ID\n * is optional.\n */\n readonly rootHostedZoneAttributes: HostedZoneAttributes;\n\n /**\n * Child zone configuration attributes. Zone name is required, hosted zone ID\n * is optional.\n */\n readonly childHostedZoneAttributes?: SetOptional<\n HostedZoneAttributes,\n \"hostedZoneId\"\n >;\n}\n\n/**\n * Global construct: owns global infrastructure (e.g. DNS and certificate resources).\n\n */\nexport class Global extends Construct {\n /**\n * Root hosted zone when config provides zoneName.\n */\n public readonly rootHostedZone: IHostedZone;\n\n /**\n * Child hosted zone when root zone exists.\n */\n public readonly childHostedZone?: IHostedZone;\n\n /**\n * Root wildcard certificate.\n */\n public readonly rootWildcardCertificate: ICertificate;\n\n constructor(\n scope: Construct,\n id: string,\n public props: GlobalProps,\n ) {\n super(scope, id);\n\n /**\n * Deconstruct props into individual variables.\n */\n const { rootHostedZoneAttributes, childHostedZoneAttributes } = props;\n\n const service = OpenHiService.of(this) as OpenHiService;\n\n /***************************************************************************\n *\n * Root Zone\n *\n * This always is configured manually. Never created by CDK.\n *\n **************************************************************************/\n\n this.rootHostedZone = RootHostedZone.fromConstruct(\n this,\n rootHostedZoneAttributes,\n );\n\n /***************************************************************************\n *\n * Child Zone\n *\n **************************************************************************/\n\n if (childHostedZoneAttributes) {\n this.childHostedZone = new ChildHostedZone(this, \"child-zone\", {\n parentHostedZone: this.rootHostedZone,\n zoneName: childHostedZoneAttributes.zoneName,\n });\n }\n\n /***************************************************************************\n *\n * Root WildCard Certificate\n *\n * Crated in main, used in all other environments via SSM import.\n *\n **************************************************************************/\n\n if (service.branchName === \"main\") {\n this.rootWildcardCertificate = new RootWildcardCertificate(this, {\n domainName: `*.${this.rootHostedZone.zoneName}`,\n subjectAlternativeNames: [this.rootHostedZone.zoneName],\n validation: CertificateValidation.fromDns(this.rootHostedZone),\n });\n } else {\n this.rootWildcardCertificate =\n RootWildcardCertificate.fromConstruct(this);\n }\n }\n}\n","import {\n Certificate,\n CertificateProps,\n ICertificate,\n} from \"aws-cdk-lib/aws-certificatemanager\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { Construct } from \"constructs\";\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.\n */\n public static ssmParameterName(): string {\n return (\n \"/\" +\n [\"GLOBAL\", RootWildcardCertificate.SSM_PARAM_NAME].join(\"/\").toUpperCase()\n );\n }\n\n public static fromConstruct(scope: Construct): ICertificate {\n const certificateArn = StringParameter.valueForStringParameter(\n scope,\n RootWildcardCertificate.ssmParameterName(),\n );\n\n return Certificate.fromCertificateArn(\n scope,\n \"wildcard-certificate\",\n certificateArn,\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 { 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\";\nimport {\n OPEN_HI_SERVICE_TYPE,\n OpenHiServiceType,\n} from \"../../app/open-hi-service\";\nimport { DiscoverableStringParameter } from \"../ssm\";\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 API ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"CHILDHOSTEDZONE\";\n\n public static fromConstruct(\n scope: Construct,\n props: { zoneName: string; serviceType?: OpenHiServiceType },\n ): IHostedZone {\n /**\n * Assume it was created in the global stack if no service type was submitted\n */\n const hostedZoneId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: ChildHostedZone.SSM_PARAM_NAME,\n serviceType: props.serviceType ?? OPEN_HI_SERVICE_TYPE.GLOBAL,\n });\n\n return HostedZone.fromHostedZoneAttributes(scope, \"child-zone\", {\n hostedZoneId,\n zoneName: props.zoneName,\n });\n }\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 * Generate the SSM Parameter used to store this zone's ID.\n */\n new DiscoverableStringParameter(this, \"child-zone-param\", {\n ssmParamName: ChildHostedZone.SSM_PARAM_NAME,\n stringValue: this.hostedZoneId,\n description: \"Route53 child hosted zone ID.\",\n });\n }\n}\n","import {\n HostedZone,\n HostedZoneAttributes,\n IHostedZone,\n} from \"aws-cdk-lib/aws-route53\";\nimport { Construct } from \"constructs\";\n\n/**\n * This will always return a root hosted zone based on attributes. It will\n * never create the root zone since the root zone should always be created\n * manually.\n */\nexport class RootHostedZone extends Construct {\n public static fromConstruct(\n scope: Construct,\n props: HostedZoneAttributes,\n ): IHostedZone {\n return HostedZone.fromHostedZoneAttributes(scope, \"root-zone\", {\n hostedZoneId: props.hostedZoneId,\n zoneName: props.zoneName,\n });\n }\n}\n","import { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport {\n OPEN_HI_SERVICE_TYPE,\n OpenHiService,\n OpenHiServiceProps,\n} from \"../app/open-hi-service\";\nimport { Global } from \"../components/global\";\n\nexport interface OpenHiGlobalServiceProps extends OpenHiServiceProps {}\n\n/**\n * Global Infrastructure stack: owns global DNS and certificates\n */\nexport class OpenHiGlobalService extends OpenHiService {\n /**\n * Global construct.\n */\n public readonly global: Global;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiGlobalServiceProps = {}) {\n super(ohEnv, OPEN_HI_SERVICE_TYPE.GLOBAL, props);\n\n /**\n * Unpack some incoming props. Don't pass config into constructs,\n * deconstruct what you need and pass those values into the construct.\n */\n const { config } = props;\n\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 * Create a global construct containing root and child zones\n */\n this.global = new Global(this, \"global\", {\n rootHostedZoneAttributes: {\n zoneName: config.zoneName,\n hostedZoneId: config.hostedZoneId,\n },\n /*\n childHostedZoneAttributes: {\n zoneName: `${this.childZonePrefix}.${config.zoneName}`,\n hostedZoneId: config.hostedZoneId,\n },\n */\n });\n }\n}\n","import {\n DomainName,\n HttpMethod,\n HttpRoute,\n HttpRouteKey,\n} from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { HttpLambdaIntegration } from \"aws-cdk-lib/aws-apigatewayv2-integrations\";\nimport { ARecord, HostedZone, RecordTarget } from \"aws-cdk-lib/aws-route53\";\nimport { ApiGatewayv2DomainProperties } from \"aws-cdk-lib/aws-route53-targets\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport {\n OPEN_HI_SERVICE_TYPE,\n OpenHiService,\n OpenHiServiceProps,\n} from \"../app/open-hi-service\";\nimport { RootWildcardCertificate } from \"../components/acm/root-wildcard-certificate\";\nimport { CoreHttpApi } from \"../components/api-gateway/core-http-api\";\nimport { DynamoDbDataStore } from \"../components/dynamodb/dynamo-db-data-store\";\nimport { DiscoverableStringParameter } from \"../components/ssm\";\nimport { RestApiLambda } from \"../data/lambda/rest-api-lambda\";\n\nexport interface OpenHiRestApiServiceProps extends OpenHiServiceProps {}\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 */\nexport class OpenHiRestApiService extends OpenHiService {\n public readonly coreHttpApi: CoreHttpApi;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiRestApiServiceProps = {}) {\n super(ohEnv, OPEN_HI_SERVICE_TYPE.REST_API, props);\n\n /**\n * Unpack some incoming props. Don't pass config into constructs,\n * deconstruct what you need and pass those values into the construct.\n */\n const { config } = props;\n\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 * DNS for the API Endpoint\n *\n **************************************************************************/\n\n const hostedZone = HostedZone.fromHostedZoneAttributes(this, \"root-zone\", {\n hostedZoneId: config.hostedZoneId,\n zoneName: config.zoneName,\n });\n\n const certificate = RootWildcardCertificate.fromConstruct(this);\n\n const apiPrefix =\n this.branchName === \"main\" ? `api` : `api-${this.childZonePrefix}`;\n const apiDomainName = [apiPrefix, hostedZone.zoneName].join(\".\");\n const restApiBaseUrl = `https://${apiDomainName}`;\n\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 const domainName = new DomainName(this, \"domain\", {\n domainName: apiDomainName,\n certificate,\n });\n\n /***************************************************************************\n *\n * Core Data API Definition\n *\n **************************************************************************/\n\n this.coreHttpApi = new CoreHttpApi(this, {\n defaultDomainMapping: {\n domainName,\n mappingKey: undefined, // serve at root of domain\n },\n });\n\n /**\n * Create a Lambda function\n */\n const dataStoreTable = DynamoDbDataStore.fromConstruct(this);\n const { lambda } = new RestApiLambda(this, {\n dynamoTableName: dataStoreTable.tableName,\n });\n // Explicit DynamoDB actions only; Scan is intentionally omitted to enforce query-only access.\n dataStoreTable.grant(\n lambda,\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 );\n\n /**\n * Integrate Lambda with HTTP API\n */\n const integration = new HttpLambdaIntegration(\"lambda-integration\", lambda);\n\n /**\n * Proxy all requests to the Lambda (root and all paths)\n */\n new HttpRoute(this, \"proxy-route-root\", {\n httpApi: this.coreHttpApi,\n routeKey: HttpRouteKey.with(\"/\", HttpMethod.ANY),\n integration,\n });\n new HttpRoute(this, \"proxy-route\", {\n httpApi: this.coreHttpApi,\n routeKey: HttpRouteKey.with(\"/{proxy+}\", HttpMethod.ANY),\n integration,\n });\n\n // Point DNS at the API Gateway custom domain\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","import { HttpApi, HttpApiProps, IHttpApi } from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { Construct } from \"constructs\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"../../app/open-hi-service\";\nimport { DiscoverableStringParameter } from \"../ssm\";\n\nexport class CoreHttpApi extends HttpApi {\n /**\n * Used when storing the API ID in SSM.\n */\n public static readonly SSM_PARAM_NAME = \"CORE_HTTP_API\";\n\n public static fromConstruct(scope: Construct): IHttpApi {\n const httpApiId = DiscoverableStringParameter.valueForLookupName(scope, {\n ssmParamName: CoreHttpApi.SSM_PARAM_NAME,\n serviceType: OPEN_HI_SERVICE_TYPE.REST_API,\n });\n\n return HttpApi.fromHttpApiAttributes(scope, \"http-api\", {\n httpApiId,\n });\n }\n\n constructor(scope: Construct, props: HttpApiProps = {}) {\n const stack = OpenHiService.of(scope) as OpenHiService;\n\n super(scope, \"http-api\", {\n /**\n * User provided props\n */\n ...props,\n\n /**\n * Required\n */\n apiName: [\"core\", \"http\", \"api\", stack.branchHash].join(\"-\"),\n });\n\n /**\n * Generate the SSM Parameter used to store this API's ID.\n */\n new DiscoverableStringParameter(this, \"http-api-url-param\", {\n ssmParamName: CoreHttpApi.SSM_PARAM_NAME,\n serviceType: OPEN_HI_SERVICE_TYPE.REST_API,\n stringValue: this.httpApiId,\n });\n }\n}\n","import { RemovalPolicy } from \"aws-cdk-lib\";\nimport {\n AttributeType,\n BillingMode,\n ITable,\n ProjectionType,\n Table,\n TableProps,\n} from \"aws-cdk-lib/aws-dynamodb\";\nimport { Construct } from \"constructs\";\nimport { OpenHiService } from \"../../app\";\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 /**\n * Import the data store table by name for use in another stack (e.g. data\n * service or Lambda). Uses the same naming as {@link getDynamoDbDataStoreTableName}.\n */\n public static fromConstruct(\n scope: Construct,\n id = \"dynamo-db-data-store\",\n ): ITable {\n return Table.fromTableName(scope, id, getDynamoDbDataStoreTableName(scope));\n }\n\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 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\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\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 environment: {\n DYNAMO_TABLE_NAME: props.dynamoTableName,\n },\n });\n }\n}\n","import { ITable } from \"aws-cdk-lib/aws-dynamodb\";\nimport { OpenHiEnvironment } from \"../app/open-hi-environment\";\nimport {\n OPEN_HI_SERVICE_TYPE,\n OpenHiService,\n OpenHiServiceProps,\n} from \"../app/open-hi-service\";\nimport { DynamoDbDataStore } from \"../components/dynamodb/dynamo-db-data-store\";\n\nexport interface OpenHiDataServiceProps extends OpenHiServiceProps {}\n\n/**\n * Data storage service stack: centralizes DynamoDB, S3, and other persistence\n * resources for OpenHI. Creates the single-table data store (CRM, CMS, ERP,\n * EHR); add buckets or other resources as needed.\n */\nexport class OpenHiDataService extends OpenHiService {\n /**\n * The single-table DynamoDB data store. Use {@link DynamoDbDataStore.fromConstruct}\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, OPEN_HI_SERVICE_TYPE.DATA, props);\n\n this.dataStore = new DynamoDbDataStore(this, \"dynamo-db-data-store\");\n }\n}\n"],"mappings":"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","names":["exports","exports","import_config","import_aws_cdk_lib","import_aws_cdk_lib","import_config","import_aws_cdk_lib","import_aws_cdk_lib","import_aws_cognito","import_aws_cognito","import_aws_certificatemanager","import_constructs","import_aws_ssm","import_aws_cdk_lib","import_aws_route53","import_constructs","import_aws_apigatewayv2","import_aws_route53","import_aws_lambda","import_constructs","path"]}
|
|
1
|
+
{"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../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/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"],"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","/** @openhi/constructs — root barrel exports. */\nexport * from \"./app\";\nexport * from \"./components\";\nexport * from \"./services\";\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 * 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 * 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 * 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 * 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\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\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 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\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 *\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\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\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\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\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 { 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 * 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\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\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\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 * 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 UserPool,\n UserPoolClient,\n UserPoolDomain,\n UserPoolProps,\n} from \"aws-cdk-lib/aws-cognito\";\nimport { IKey, Key } from \"aws-cdk-lib/aws-kms\";\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 { DiscoverableStringParameter } from \"../components/ssm\";\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 public readonly userPoolKmsKey: IKey;\n public readonly userPool: IUserPool;\n public readonly userPoolClient: IUserPoolClient;\n public readonly userPoolDomain: IUserPoolDomain;\n\n constructor(\n ohEnv: OpenHiEnvironment,\n public props: OpenHiAuthServiceProps = {},\n ) {\n super(ohEnv, OpenHiAuthService.SERVICE_TYPE, props);\n\n this.userPoolKmsKey = this.createUserPoolKmsKey();\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 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 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\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 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\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 DomainName,\n HttpApi,\n HttpMethod,\n HttpRoute,\n HttpRouteKey,\n IHttpApi,\n} from \"aws-cdk-lib/aws-apigatewayv2\";\nimport { HttpLambdaIntegration } from \"aws-cdk-lib/aws-apigatewayv2-integrations\";\nimport { ICertificate } from \"aws-cdk-lib/aws-certificatemanager\";\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 { Construct } from \"constructs\";\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\nexport interface OpenHiRestApiServiceProps extends OpenHiServiceProps {}\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 public readonly rootHttpApi: RootHttpApi;\n\n constructor(ohEnv: OpenHiEnvironment, props: OpenHiRestApiServiceProps = {}) {\n super(ohEnv, OpenHiRestApiService.SERVICE_TYPE, 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 });\n dataStoreTable.grant(\n lambda,\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 );\n const integration = new HttpLambdaIntegration(\"lambda-integration\", lambda);\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 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 rootHttpApi = new RootHttpApi(this, {\n defaultDomainMapping: {\n domainName,\n mappingKey: undefined,\n },\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\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 /**\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\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\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\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 environment: {\n DYNAMO_TABLE_NAME: props.dynamoTableName,\n },\n });\n }\n}\n"],"mappings":"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","names":["exports","exports","import_config","import_aws_cdk_lib","import_aws_cdk_lib","import_config","import_aws_cdk_lib","import_aws_cdk_lib","import_aws_ssm","import_aws_cognito","import_aws_cognito","import_aws_events","import_aws_cdk_lib","import_aws_cognito","import_aws_kms","import_aws_certificatemanager","import_aws_route53","import_aws_ssm","import_aws_apigatewayv2","import_aws_route53","import_aws_dynamodb","import_aws_events","import_constructs","path"]}
|