@openhi/platform 0.0.42 → 0.0.44

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.js CHANGED
@@ -477,11 +477,7 @@ var OpenHiService = class {
477
477
  tasks: ["post-compile"]
478
478
  });
479
479
  if (this.options.type === OPEN_HI_SERVICE_TYPE.WEBSITE) {
480
- const turbo = import_configulator.TurboRepo.of(this.project);
481
- const postCompileEnv = turbo?.postCompileTask?.env;
482
- if (postCompileEnv && !postCompileEnv.includes("OPENHI_PR_NUMBER")) {
483
- postCompileEnv.push("OPENHI_PR_NUMBER");
484
- }
480
+ this.project.addDeps("@codedrifters/admin-console@workspace:*");
485
481
  }
486
482
  new GenerateTemplates(this);
487
483
  [import_config2.OPEN_HI_STAGE.DEV, import_config2.OPEN_HI_STAGE.STAGE, import_config2.OPEN_HI_STAGE.PROD].forEach(
@@ -760,10 +756,6 @@ var BuildDevelopmentWorkflow = class extends import_projen5.Component {
760
756
  types: ["opened", "synchronize", "reopened"]
761
757
  }
762
758
  });
763
- ghWorkflow.file?.addOverride(
764
- "env.OPENHI_PR_NUMBER",
765
- "${{ github.event.pull_request.number || '' }}"
766
- );
767
759
  websiteDeploy.awsDeploymentTargets.forEach((target) => {
768
760
  const jobId = [
769
761
  target.awsStageType,
@@ -802,10 +794,6 @@ var BuildStageWorkflow = class extends import_projen6.Component {
802
794
  }
803
795
  }
804
796
  });
805
- buildWorkflow.workflow.file?.addOverride(
806
- "env.OPENHI_PR_NUMBER",
807
- "${{ github.event.pull_request.number || '' }}"
808
- );
809
797
  const { awsDeploymentTargets: authTargets } = new import_configulator4.AwsDeployWorkflow(
810
798
  openhi.auth.project,
811
799
  {
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/openhi.ts","../src/service.ts","../src/templates/service-template.ts","../src/templates/src/app.ts","../src/templates/src/app-test.ts","../src/templates/src/config.ts","../src/templates/src/data/models/README.md.ts","../src/templates/src/data/README.md.ts","../src/templates/src/infrastructure/README.md.ts","../src/templates/src/integrations/README.md.ts","../src/templates/src/main.ts","../src/templates/src/README.md.ts","../src/templates/src/workflows/README.md.ts","../src/templates/generate-templates.ts","../src/workflows/aws-teardown-workflow.ts","../src/workflows/build-dev-workflow.ts","../src/workflows/build-stage-workflow.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","/**\n * @see sites/www-docs/content/packages/@openhi/platform/index.md\n */\n/** @openhi/platform — root barrel exports. */\nexport * from \"./openhi\";\nexport * from \"./service\";\n","import {\n MonorepoProject,\n MonorepoProjectOptions,\n} from \"@codedrifters/configulator\";\nimport { OpenHiConfig } from \"@openhi/config\";\nimport { merge } from \"ts-deepmerge\";\nimport { SetOptional } from \"type-fest\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"./service\";\nimport { AwsTeardownWorkflow } from \"./workflows/aws-teardown-workflow\";\nimport { BuildDevelopmentWorkflow } from \"./workflows/build-dev-workflow\";\nimport { BuildStageWorkflow } from \"./workflows/build-stage-workflow\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/openhi.md\n */\n\nexport interface OpenHiOptions {\n /*****************************************************************************\n *\n * Root Project Configuration Options\n *\n * Configuration options for the root monorepo project that contains all\n * OpenHi services and coordinate releases and builds.\n *\n ****************************************************************************/\n\n readonly rootProjectOptions?: SetOptional<MonorepoProjectOptions, \"name\">;\n\n /**\n * Monorepo root project, if using an existing project.\n */\n readonly rootProject?: MonorepoProject;\n\n /*****************************************************************************\n *\n * Service Configuration Options\n *\n * These options are used to configure the various services within the OpenHi\n * framework. Each service can have its own configuration settings, which will\n * be merged with the default configuration.\n *\n ****************************************************************************/\n\n /**\n * Default configuration used in all services with undefined configs.\n */\n readonly defaultConfig?: OpenHiConfig;\n\n /**\n * Global Service Config\n */\n readonly globalServiceConfig?: OpenHiConfig;\n\n /**\n * Auth Service Config\n */\n readonly authServiceConfig?: OpenHiConfig;\n\n /**\n * Rest API Service Config\n */\n readonly restApiServiceConfig?: OpenHiConfig;\n\n /**\n * Data Service Config (DynamoDB FHIR store, S3, etc.)\n */\n readonly dataServiceConfig?: OpenHiConfig;\n\n /**\n * GraphQL API Service Config\n */\n readonly graphApiServiceConfig?: OpenHiConfig;\n\n /**\n * Website Service Config (static hosting + content uploader).\n */\n readonly websiteServiceConfig?: OpenHiConfig;\n}\n\nexport class OpenHi {\n /**\n * Final options used to build this instance.\n */\n public options: OpenHiOptions;\n\n /**\n * Monorepo root project, either passed in as an argument or generated in\n * this component\n */\n public readonly rootProject?: MonorepoProject;\n\n /**\n * Test identifier for this instance.\n */\n public readonly id: string;\n\n /**\n * Global service (deployed first; Auth, data service, and other stacks depend on it).\n */\n public readonly global: OpenHiService;\n\n /**\n * Auth service (deployed first; data service, REST API, and data services depend on it).\n */\n public readonly auth: OpenHiService;\n\n /**\n * Rest API service\n */\n public readonly restApi: OpenHiService;\n\n /**\n * Data service (DynamoDB FHIR store, S3, and other persistence).\n */\n public readonly data: OpenHiService;\n\n /**\n * GraphQL API service (AppSync); deploys as sibling to REST API after Data.\n */\n public readonly graphApi: OpenHiService;\n\n /**\n * Website service (static hosting + content uploader); deploys as sibling\n * to the other services after Global.\n */\n public readonly website: OpenHiService;\n\n constructor(options: OpenHiOptions = {}) {\n /***************************************************************************\n *\n * Options\n *\n * Combine input options with defaults.\n *\n **************************************************************************/\n\n this.options = merge({ name: \"openhi\" }, options);\n this.rootProject = this.options.rootProject;\n this.id = this.options.rootProject?.name ?? \"openhi\";\n\n /**\n * In future we would create root project here. For now, require it to be\n * passed in.\n */\n if (!this.rootProject) {\n throw new Error(\n \"OpenHi requires a MonorepoProject to be passed in via the rootProject option\",\n );\n }\n\n const rootProject = this.rootProject;\n\n /***************************************************************************\n *\n * Global Service\n *\n * Global infrastructure (Route53, ACM). Deployed first in primary;\n * Auth, data service, and other stacks depend on it.\n *\n **************************************************************************/\n\n this.global = new OpenHiService(this, \"global\", {\n type: OPEN_HI_SERVICE_TYPE.GLOBAL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.globalServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Auth Service\n *\n * Authentication (Cognito user pool, client, domain, KMS). Deployed first;\n * data service, REST API, and data services consume auth via SSM.\n *\n **************************************************************************/\n\n this.auth = new OpenHiService(this, \"auth\", {\n type: OPEN_HI_SERVICE_TYPE.AUTH,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.authServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Rest API service\n *\n * This contains the REST API for the OpenHi platform.\n *\n **************************************************************************/\n\n this.restApi = new OpenHiService(this, \"rest-api\", {\n type: OPEN_HI_SERVICE_TYPE.REST_API,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.restApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Data Service\n *\n * Data storage stack (DynamoDB FHIR store, S3, etc.). Deployed so that\n * REST API and other services can reference the table via cross-stack.\n *\n **************************************************************************/\n\n this.data = new OpenHiService(this, \"data\", {\n type: OPEN_HI_SERVICE_TYPE.DATA_SERVICE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.dataServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * GraphQL API service\n *\n * AppSync API; deploys as sibling to REST API after Data.\n *\n **************************************************************************/\n\n this.graphApi = new OpenHiService(this, \"graphql\", {\n type: OPEN_HI_SERVICE_TYPE.GRAPHQL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.graphApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Website service\n *\n * Static hosting (CloudFront + S3 + Lambda@Edge) and content uploader;\n * deploys as a sibling to the other services after Global.\n *\n **************************************************************************/\n\n this.website = new OpenHiService(this, \"website\", {\n type: OPEN_HI_SERVICE_TYPE.WEBSITE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.websiteServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Integrations\n *\n * Various purpose specific integrations.\n *\n **************************************************************************/\n\n /***************************************************************************\n *\n * Workflows\n *\n * Workflows for each environment.\n *\n **************************************************************************/\n\n new BuildDevelopmentWorkflow(rootProject, { openhi: this });\n new BuildStageWorkflow(rootProject, { openhi: this });\n\n new AwsTeardownWorkflow(rootProject, { openhi: this });\n }\n}\n","import { sep } from \"path\";\nimport {\n AwsDeploymentTarget,\n TurboRepo,\n VERSION,\n} from \"@codedrifters/configulator\";\nimport {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OPEN_HI_STAGE,\n OpenHiConfig,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { paramCase, pascalCase } from \"change-case\";\nimport { awscdk } from \"projen\";\nimport { NodePackageManager, Transform } from \"projen/lib/javascript\";\nimport { ValueOf } from \"type-fest\";\nimport { OpenHi } from \"./openhi\";\nimport { GenerateTemplates } from \"./templates/generate-templates\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/service.md\n */\n\nexport const OPEN_HI_SERVICE_TYPE = {\n AUTH: \"auth\",\n DATA_SERVICE: \"data\",\n GLOBAL: \"global\",\n GRAPHQL: \"graphql\",\n INTEGRATION: \"integration\",\n REST_API: \"rest-api\",\n WEBSITE: \"website\",\n} as const;\n\nexport interface OpenHiServiceOptions {\n /**\n * Configuration for this service.\n *\n * @default uses the global default config.\n */\n readonly config: OpenHiConfig;\n\n /**\n * What type of service is this?\n */\n readonly type: ValueOf<typeof OPEN_HI_SERVICE_TYPE>;\n}\n\nexport class OpenHiService {\n public readonly project: awscdk.AwsCdkTypeScriptApp;\n\n constructor(\n public openHi: OpenHi,\n public id: string,\n public options: OpenHiServiceOptions,\n ) {\n /**\n * Build the construct name we expect to use in this service.\n */\n\n /***************************************************************************\n *\n * Projen based CDK build\n *\n **************************************************************************/\n\n this.project = new awscdk.AwsCdkTypeScriptApp({\n /**\n * Top level project config options\n */\n defaultReleaseBranch: \"main\",\n name: this.serviceName,\n outdir: this.outDir,\n parent: this.openHi.rootProject,\n cdkVersion:\n this.options?.config?.versions?.cdk?.cdkLibVersion ??\n VERSION.AWS_CDK_LIB_VERSION,\n cdkCliVersion:\n this.options?.config?.versions?.cdk?.cdkCliVersion ??\n VERSION.AWS_CDK_CLI_VERSION,\n\n /**\n * Packaging options\n *\n * TODO: Figure out license for monorepo vs per package?\n */\n licensed: false,\n\n /**\n * Node configs\n */\n packageManager: NodePackageManager.PNPM,\n\n /**\n * Turn on prettier formatting\n */\n prettier: true,\n\n /**\n * Don't generate sample code.\n */\n sampleCode: false,\n\n /**\n * Make sure jest config is stored outside of package.json and use SWC\n * for faster tests.\n */\n jestOptions: {\n configFilePath: \"jest.config.json\",\n jestConfig: {\n transform: {\n [\"^.+\\\\.[t]sx?$\"]: new Transform(\"@swc/jest\"),\n },\n },\n },\n\n /**\n * SWC for faster testing\n */\n devDeps: [\"@swc/jest\", \"@swc/core\"],\n\n /**\n * Don't package test files.\n */\n npmIgnoreOptions: {\n ignorePatterns: [\"*.spec.*\", \"*.test.*\"],\n },\n });\n\n /**\n * We're using SWC now, remove ts-jest which is included by default.\n */\n this.project.deps.removeDependency(\"ts-jest\");\n\n /***************************************************************************\n *\n * Workspace Dependencies\n *\n * - Constructs are used to build out the AWS CDK environments.\n *\n **************************************************************************/\n\n this.project.addDeps(\n \"@openhi/config@workspace:*\",\n \"@openhi/constructs@workspace:*\",\n );\n\n /***************************************************************************\n *\n * Turbo Configuration\n *\n * - Activate turborepo for the project.\n *\n **************************************************************************/\n\n new TurboRepo(this.project);\n\n TurboRepo.of(this.project)?.activateBranchNameEnvVar({\n tasks: [\"post-compile\"],\n });\n\n /**\n * The website service composes its hostname (and the S3 key prefix\n * the lifecycle rule expires) from the OPENHI_PR_NUMBER env var on\n * non-release-branch synths. Turborepo strips env vars that are\n * not declared on the task, so the value reaches the workflow's\n * `env:` block but never reaches the `cdk synth` subprocess that\n * the post-compile task runs. Add OPENHI_PR_NUMBER to the\n * post-compile task env so Turborepo passes it through.\n *\n * Scoped to the website project — no other service reads\n * OPENHI_PR_NUMBER, so adding it elsewhere would only cause\n * spurious per-PR cache misses on cdk synth.\n */\n if (this.options.type === OPEN_HI_SERVICE_TYPE.WEBSITE) {\n const turbo = TurboRepo.of(this.project);\n const postCompileEnv = turbo?.postCompileTask?.env;\n if (postCompileEnv && !postCompileEnv.includes(\"OPENHI_PR_NUMBER\")) {\n postCompileEnv.push(\"OPENHI_PR_NUMBER\");\n }\n }\n\n /***************************************************************************\n *\n * Define some basic Service Structure\n *\n **************************************************************************/\n\n new GenerateTemplates(this);\n\n /***************************************************************************\n *\n * Deployment Targets\n *\n **************************************************************************/\n\n [OPEN_HI_STAGE.DEV, OPEN_HI_STAGE.STAGE, OPEN_HI_STAGE.PROD].forEach(\n (stage) => {\n const targets = this.options?.config?.deploymentTargets?.[stage];\n if (targets?.primary) {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,\n targets.primary,\n );\n }\n targets?.secondary?.forEach((env) => {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,\n env,\n );\n });\n },\n );\n }\n\n private addDeploymentTarget = (\n awsStageType: ValueOf<typeof OPEN_HI_STAGE>,\n awsEnvironmentType: ValueOf<typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE>,\n envConfig: OpenHiEnvironmentConfig,\n ) => {\n new AwsDeploymentTarget(this.project, {\n account: envConfig.account,\n region: envConfig.region,\n awsStageType,\n awsEnvironmentType,\n localDeployment: true,\n localDeploymentConfig: {\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n roleName: \"poweruseraccess\",\n },\n ciDeployment: true,\n ciDeploymentConfig: {\n roleArn: `arn:aws:iam::${envConfig.account}:role/GitHubOpenHiDeployer`,\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n },\n\n branches:\n awsStageType === OPEN_HI_STAGE.DEV\n ? [\n {\n branch: \"feat/*\",\n description: [\n \"Feature branches for OpenHI (short form).\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"feature/*\",\n description: [\n \"Feature branches for OpenHI.\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"fix/*\",\n description: [\n \"Fix branches for OpenHI.\",\n \"This branch pattern is used when a developer is working on a fix on the project.\",\n ],\n },\n ]\n : [\n {\n branch: \"main\",\n description: [\n \"Main branch for OpenHI.\",\n \"This branch is used for the main branch.\",\n ],\n },\n ],\n });\n };\n\n get constructName(): string {\n return pascalCase([\"open\", \"hi\", this.id, \"service\"].join(\"-\"));\n }\n\n get outDir() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(sep);\n }\n\n get serviceName() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(\"-\");\n }\n}\n","import { existsSync, unlinkSync } from \"node:fs\";\nimport { sep } from \"node:path\";\nimport { SampleFile } from \"projen\";\nimport { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/service-template.md\n */\n\nexport interface ServiceTemplateOptions {\n /**\n * The content of the sample file, as an array.\n */\n readonly contents: Array<string>;\n\n /**\n * The relative file path from the project root.\n */\n readonly filePath: string;\n\n /**\n * Overwrite this template file to it's original state?\n *\n * @default false\n */\n readonly overwrite?: boolean;\n}\n\nexport class ServiceTemplate {\n /**\n * The file being generated.\n */\n public file?: SampleFile;\n\n /**\n * Absolute Filepath, including the project path.\n */\n public fullFilePath: string;\n\n constructor(\n public service: OpenHiService,\n public options: ServiceTemplateOptions,\n ) {\n /**\n * Determine the full file path for this file.\n */\n this.fullFilePath = [\n this.service.project.outdir,\n this.options.filePath,\n ].join(sep);\n\n /**\n * Build the template file.\n */\n this.createTemplate();\n }\n\n protected createTemplate() {\n if (this.options.overwrite) {\n this.overwriteTemplate();\n }\n\n this.file = new SampleFile(this.service.project, this.options.filePath, {\n contents: this.options.contents.join(\"\\n\"),\n });\n }\n\n public overwriteTemplate() {\n /**\n * Delete file, if it exists.\n */\n if (existsSync(this.fullFilePath)) {\n unlinkSync(this.fullFilePath);\n }\n this.file = undefined;\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app.md\n */\n\nexport class SrcApp extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.ts\",\n contents: [\n `import { OpenHiApp, ${service.constructName} } from \"@openhi/constructs\";`,\n `import { CONFIG } from \"./config\";`,\n ``,\n `const app = new OpenHiApp({ config: CONFIG });`,\n ``,\n `const stacks = app.environments.map((e) => {`,\n ` return new ${service.constructName}(e, { config: e.config });`,\n `});`,\n ``,\n `export { app, stacks };`,\n ``,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app-test.md\n */\n\nexport class SrcAppTest extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.test.ts\",\n contents: [\n `import { Template } from \"aws-cdk-lib/assertions\";`,\n `import { Code, type CodeConfig } from \"aws-cdk-lib/aws-lambda\";`,\n `import { stacks } from \"./app\"`,\n ``,\n `/** Replace volatile CDK asset S3 keys/buckets with static values for snapshot stability. */`,\n `function normalizeTemplateForSnapshot(template: Record<string, unknown>): Record<string, unknown> {`,\n ` const staticBucket = \"mock-assets-bucket\";`,\n ` const staticKey = \"mock-asset-key.zip\";`,\n ` const json = JSON.stringify(template);`,\n ` const normalized = json`,\n ` .replace(/\"S3Key\":\\\\s*\"[^\"]+\\\\.zip\"/g, \\`\"S3Key\": \"\\${staticKey}\"\\`)`,\n ` .replace(/\"S3Bucket\":\\\\s*\"[^\"]+\"/g, \\`\"S3Bucket\": \"\\${staticBucket}\"\\`);`,\n ` return JSON.parse(normalized) as Record<string, unknown>;`,\n `}`,\n ``,\n `let fromAssetMock: jest.SpyInstance;`,\n ``,\n `beforeAll(() => {`,\n ` fromAssetMock = jest.spyOn(Code, \"fromAsset\").mockReturnValue({`,\n ` isInline: false,`,\n ` bind: (): CodeConfig => ({`,\n ` s3Location: {`,\n ` bucketName: \"mock-assets-bucket\",`,\n ` objectKey: \"mock-asset-key.zip\",`,\n ` },`,\n ` }),`,\n ` bindToResource: () => {`,\n ` return;`,\n ` },`,\n ` } as any);`,\n `});`,\n ``,\n `afterAll(() => {`,\n ` fromAssetMock?.mockRestore();`,\n `});`,\n ``,\n `describe(\"Smoke Test\", () => {`,\n ` it(\"should match previous snapshots\", () => {`,\n ` stacks.forEach((s) => {`,\n ` const template = Template.fromStack(s).toJSON();`,\n ` expect(normalizeTemplateForSnapshot(template)).toMatchSnapshot();`,\n ` });`,\n ` });`,\n `});`,\n ``,\n ],\n });\n }\n}\n","import { SourceCode } from \"projen\";\nimport { OpenHiService } from \"../../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/config.md\n */\n\nexport class SrcConfig extends SourceCode {\n constructor(service: OpenHiService) {\n super(service.project, \"src/config.ts\");\n\n /**\n * Imports\n */\n this.line(`import { OpenHiConfig } from \"@openhi/config\";`);\n this.line(\"\");\n\n /**\n * Write the config content\n */\n const start = \"export const CONFIG: OpenHiConfig = \";\n const mid = JSON.stringify(service.options?.config, null, 2);\n const end = \" as const;\";\n this.line(`${start}${mid}${end}`);\n }\n}\n","import { OpenHiService } from \"../../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/models/readme.md\n */\n\nexport class DataModelsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/models/README.md\",\n contents: [\n `# ${service.serviceName}: Data Models`,\n ``,\n `This directory contains data model definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/readme.md\n */\n\nexport class DataReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/README.md\",\n contents: [\n `# ${service.serviceName}: Data`,\n ``,\n `This directory contains data models and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/infrastructure/readme.md\n */\n\nexport class InfrastructureReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/infrastructure/README.md\",\n contents: [\n `# ${service.serviceName}: Infrastructure`,\n ``,\n `This directory contains infrastructure definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/integrations/readme.md\n */\n\nexport class IntegrationsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/integrations/README.md\",\n contents: [\n `# ${service.serviceName}: Integrations`,\n ``,\n `This directory contains integration definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/main.md\n */\n\nexport class SrcMain extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/main.ts\",\n contents: [`import { app } from \"./app\";`, ``, `app.synth();`, ``],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/readme.md\n */\n\nexport class SrcReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/README.md\",\n contents: [\n `# ${service.serviceName}: Service Overview`,\n ``,\n `This directory contains the main entry point for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/workflows/readme.md\n */\n\nexport class WorkflowsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/workflows/README.md\",\n contents: [\n `# ${service.serviceName}: Workflows`,\n ``,\n `This directory contains workflow definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../service\";\nimport { SrcApp } from \"./src/app\";\nimport { SrcAppTest } from \"./src/app-test\";\nimport { SrcConfig } from \"./src/config\";\nimport { DataModelsReadMe } from \"./src/data/models/README.md\";\nimport { DataReadMe } from \"./src/data/README.md\";\nimport { InfrastructureReadMe } from \"./src/infrastructure/README.md\";\nimport { IntegrationsReadMe } from \"./src/integrations/README.md\";\nimport { SrcMain } from \"./src/main\";\nimport { SrcReadMe } from \"./src/README.md\";\nimport { WorkflowsReadMe } from \"./src/workflows/README.md\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/generate-templates.md\n */\n\nexport class GenerateTemplates {\n constructor(private service: OpenHiService) {\n /**\n * Root src templates\n */\n new SrcApp(this.service);\n new SrcAppTest(this.service);\n new SrcConfig(this.service);\n new SrcMain(this.service);\n new SrcReadMe(this.service);\n\n /**\n * Data\n */\n new DataReadMe(this.service);\n new DataModelsReadMe(this.service);\n\n /**\n * Infrastructure\n */\n new InfrastructureReadMe(this.service);\n\n /**\n * Integrations\n */\n new IntegrationsReadMe(this.service);\n\n /**\n * Workflows\n */\n new WorkflowsReadMe(this.service);\n }\n}\n","import {\n AwsDeploymentConfig,\n MonorepoProject,\n} from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { GitHub, GithubWorkflow } from \"projen/lib/github\";\nimport { JobPermission } from \"projen/lib/github/workflows-model\";\nimport { OpenHi } from \"../openhi\";\nimport type { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/aws-teardown-workflow.md\n */\n\nexport interface AwsTeardownWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class AwsTeardownWorkflow extends Component {\n constructor(\n public rootProject: MonorepoProject,\n options: AwsTeardownWorkflowOptions,\n ) {\n super(rootProject);\n\n const { openhi } = options;\n\n /***************************************************************************\n *\n * Root project check\n *\n * Detect the root project and ensure it's of type MonorepoProject.\n *\n **************************************************************************/\n\n if (!(rootProject instanceof MonorepoProject)) {\n throw new Error(\n \"AwsTeardownWorkflow requires the root project to be a MonorepoProject\",\n );\n }\n\n //this.rootProject = project.root;\n\n /***************************************************************************\n *\n * GitHub Check\n *\n * Make sure github config is active in the project. This is to ensure all\n * workflows will be output properly during synth.\n *\n **************************************************************************/\n\n const github = GitHub.of(this.rootProject);\n\n if (!github) {\n throw new Error(\n \"AwsTeardownWorkflow requires a GitHub component in the root project\",\n );\n }\n\n /***************************************************************************\n *\n * Workflow Destroy Targets\n *\n * Find all the CI targets for the Global project in the DEV stage\n * only. One job per (account, region) teardowns all orphan stacks (Auth,\n * Core, data) in that account/region.\n *\n **************************************************************************/\n\n const devTargetsFor = (service: OpenHiService) =>\n AwsDeploymentConfig.of(service.project)?.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === OPEN_HI_STAGE.DEV && target.ciDeployment,\n ) ?? [];\n const awsDestructionTargets = devTargetsFor(openhi.global);\n\n /***************************************************************************\n *\n * Create Workflow\n *\n * Make a new workflow for AWS stack teardown. This runs each night and is\n * also triggered each time a branch is deleted.\n *\n **************************************************************************/\n\n const workflow = new GithubWorkflow(github, \"teardown-dev\");\n workflow.on({\n workflowDispatch: {},\n schedule: [\n {\n cron: \"32 6 * * *\", // Every Sunday at 6:32 AM UTC\n },\n ],\n delete: {\n branches: [\"feature/*\", \"feat/*\", \"fix/*\"],\n },\n /* for debugging \n push: {\n branches: [\"feature/*\"],\n },\n */\n });\n\n awsDestructionTargets.forEach((target) => {\n const {\n awsStageType,\n awsEnvironmentType,\n account,\n region,\n ciDeploymentConfig,\n } = target;\n const { roleArn } = ciDeploymentConfig ?? {};\n\n workflow.addJob(`teardown-${account}-${region}`.toLowerCase(), {\n name: `Teardown Stacks in ${target.account}/${target.region}`,\n //if: \"github.event.ref_type == 'branch'\",\n runsOn: [\"ubuntu-latest\"],\n permissions: {\n contents: JobPermission.READ,\n idToken: JobPermission.WRITE,\n },\n env: {\n REPO: \"${{ github.repository }}\",\n REGIONS: [region].join(\" \"),\n },\n steps: [\n /**\n * Configure AWS creds.\n */\n {\n name: `AWS Creds ${awsStageType}/${awsEnvironmentType}/${account}/${region}`,\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n \"role-to-assume\": roleArn,\n \"aws-region\": region,\n \"role-duration-seconds\": 900, // 15 minutes\n },\n },\n\n /**\n * Fetch all branch names in the repo\n */\n {\n name: \"Fetch All Branches\",\n id: \"fetch_branches\",\n uses: \"actions/github-script@v7\",\n with: {\n script: [\n \"const all = await github.paginate(github.rest.repos.listBranches, {\",\n \" owner: context.repo.owner,\",\n \" repo: context.repo.repo,\",\n \" per_page: 100\",\n \"});\",\n \"const names = all.map(b => b.name);\",\n \"console.log(`Found branches: ${names}`);\",\n 'core.setOutput(\"json\", JSON.stringify(names));',\n ].join(\"\\n\"),\n },\n },\n\n /**\n * Save branches to a file\n */\n {\n name: \"Save Branches to File\",\n run: [\n 'echo \"Saving branches to file\"',\n \"echo '${{ steps.fetch_branches.outputs.json }}' | jq -r '.[]' | sort -u > branches.txt\",\n 'echo \"Branches:\"',\n \"cat branches.txt\",\n ].join(\"\\n\"),\n },\n\n /**\n * Find all stacks tagged with a stage of dev. for this repo. return\n * tag and resource arn.\n */\n {\n name: \"Find Stacks by Tag\",\n id: \"find_stacks\",\n run: [\n \"set -euo pipefail\",\n \": > candidates.txt # columns: arn region branchTag\",\n\n \"# Build tag filters\",\n 'TAG_FILTERS=( \"Key=openhi:repo-name,Values=$REPO\" )',\n `TAG_FILTERS+=( \"Key=openhi:stage-type,Values=${OPEN_HI_STAGE.DEV}\" )`,\n\n \"for r in $REGIONS; do\",\n ` echo \"Scanning region: $r\"`,\n \" aws resourcegroupstaggingapi get-resources \\\\\",\n ' --region \"$r\" \\\\',\n ' --resource-type-filters \"cloudformation:stack\" \\\\',\n ' --tag-filters \"${TAG_FILTERS[@]}\" \\\\',\n ` | jq -r --arg r \"$r\" '`,\n \" .ResourceTagMappingList[]\",\n \" | . as $res\",\n ' | ($res.Tags[] | select(.Key==\"openhi:branch-name\") | .Value) as $branch',\n ' | [$res.ResourceARN, $r, ($branch // \"\")]',\n \" | @tsv\",\n \" ' >> candidates.txt\",\n \"done\",\n\n \"echo 'Tagged stacks:'\",\n `(echo -e \"ARN\\\\tREGION\\\\tBRANCH\"; cat candidates.txt) | column -t -s $'\\\\t'`,\n ].join(\"\\n\"),\n },\n\n /**\n * Determine which stacks are orphans that no longer have a matching branch.\n * Save those to a file for the next step.\n */\n {\n name: \"Determine Orphan Stacks (No Matching Branch)\",\n run: [\n \"set -euo pipefail\",\n \": > orphans.txt # arn region branch\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n ' if [ -z \"$branch\" ]; then',\n \" # If no Branch tag, treat as not-a-preview; skip (or flip to delete if you want)\",\n \" continue\",\n \" fi\",\n ' if ! grep -Fxq \"$branch\" branches.txt; then',\n ' echo -e \"$arn\\\\t$region\\\\t$branch\" >> orphans.txt',\n \" fi\",\n \"done < candidates.txt\",\n \"\",\n \"if [ -s orphans.txt ]; then\",\n ' echo \"Orphan stacks (no matching branch):\"',\n \" (echo -e \\\"ARN\\\\tREGION\\\\tBRANCH\\\"; cat orphans.txt) | column -t -s $'\\\\t'\",\n \"else\",\n ' echo \"No orphan stacks found.\"',\n \"fi\",\n ].join(\"\\n\"),\n },\n\n /**\n * Delete orphan stacks.\n */\n {\n name: \"Delete Orphan Stacks\",\n if: \"hashFiles('orphans.txt') != ''\",\n run: [\n \"set -euo pipefail\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n \" stack_name=$(cut -d'/' -f2 <<<\\\"$arn\\\")\",\n ' echo \"Deleting $stack_name (branch=$branch) in $region\"',\n ' aws cloudformation delete-stack --region \"$region\" --stack-name \"$stack_name\" || true',\n \"done < orphans.txt\",\n ].join(\"\\n\"),\n },\n ],\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * Job-level `if:` condition that restricts the per-PR website deploy to\n * pull-request events plus manual dispatch. Push events to feat/fix/feature\n * branches no longer trigger a website deploy because the OPENHI_PR_NUMBER\n * env var is only resolvable when a PR exists.\n */\nconst PR_GATED_WEBSITE_JOB_IF =\n \"${{ !needs.build.outputs.self_mutation_happened && \" +\n \"(github.event_name == 'pull_request' || \" +\n \"github.event_name == 'workflow_dispatch') }}\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-dev-workflow.md\n */\n\nexport interface BuildDevelopmentWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildDevelopmentWorkflow extends Component {\n constructor(\n parent: MonorepoProject,\n options: BuildDevelopmentWorkflowOptions,\n ) {\n super(parent, \"dev-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets } = new AwsDeployWorkflow(\n openhi.global.project,\n {\n buildWorkflow: parent.buildWorkflow,\n },\n );\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n *\n * Deploy the Rest API service after Data (and Global).\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n *\n * Deploy the GraphQL API service after Data (sibling to REST API).\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n const websiteDeploy = new AwsDeployWorkflow(openhi.website.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n\n /**\n * Per-PR preview wiring for the website deploy:\n *\n * 1. Trigger the build workflow on PR events so feature-branch deploys\n * have a PR number to address themselves with\n * (`admin-pr-<N>.<zone>`).\n * 2. Inject `OPENHI_PR_NUMBER` at the workflow env level so\n * `OpenHiWebsiteService` resolves it via the same fallback path it\n * uses for the `prNumber` prop.\n * 3. Gate every `*-deploy-openhi-website-*` job to `pull_request` +\n * `workflow_dispatch` only — push-to-branch no longer triggers a\n * website deploy (a website deploy requires a PR for its hostname).\n * Other services' deploy jobs are unchanged.\n */\n const buildWorkflow = parent.buildWorkflow;\n if (!buildWorkflow) {\n throw new Error(\"BuildDevelopmentWorkflow requires a buildWorkflow\");\n }\n const ghWorkflow = buildWorkflow.workflow;\n ghWorkflow.on({\n pullRequest: {\n types: [\"opened\", \"synchronize\", \"reopened\"],\n },\n });\n ghWorkflow.file?.addOverride(\n \"env.OPENHI_PR_NUMBER\",\n \"${{ github.event.pull_request.number || '' }}\",\n );\n websiteDeploy.awsDeploymentTargets.forEach((target) => {\n const jobId = [\n target.awsStageType,\n target.deploymentTargetRole,\n \"deploy\",\n target.project.name,\n target.account,\n target.region,\n ].join(\"-\");\n const job = ghWorkflow.getJob(jobId);\n ghWorkflow.updateJob(jobId, {\n ...job,\n if: PR_GATED_WEBSITE_JOB_IF,\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-stage-workflow.md\n */\n\nexport interface BuildStageWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildStageWorkflow extends Component {\n constructor(parent: MonorepoProject, options: BuildStageWorkflowOptions) {\n super(parent, \"stage-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets, buildWorkflow } =\n new AwsDeployWorkflow(openhi.global.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflowOptions: {\n name: \"deploy-stage\",\n workflowTriggers: {\n push: {\n branches: [\"main\"],\n },\n workflowDispatch: {},\n },\n },\n });\n\n // Inject OPENHI_PR_NUMBER at the workflow env level so it propagates\n // to every job (including the website deploy job). Release-branch\n // deploys ignore this value (no PR exists on a main push); the env is\n // included so OpenHiWebsiteService resolves consistently across\n // workflows. See BuildDevelopmentWorkflow for the PR-event wiring on\n // the dev side.\n buildWorkflow.workflow.file?.addOverride(\n \"env.OPENHI_PR_NUMBER\",\n \"${{ github.event.pull_request.number || '' }}\",\n );\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n * Auth creates the stage build workflow; data service and REST API services add to it.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n new AwsDeployWorkflow(openhi.website.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n }\n}\n"],"mappings":"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","names":["exports","exports","import_config","import_projen","import_projen","import_configulator","import_config","import_projen","import_configulator","import_projen","import_configulator","import_config","import_projen"]}
1
+ {"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../src/index.ts","../src/openhi.ts","../src/service.ts","../src/templates/service-template.ts","../src/templates/src/app.ts","../src/templates/src/app-test.ts","../src/templates/src/config.ts","../src/templates/src/data/models/README.md.ts","../src/templates/src/data/README.md.ts","../src/templates/src/infrastructure/README.md.ts","../src/templates/src/integrations/README.md.ts","../src/templates/src/main.ts","../src/templates/src/README.md.ts","../src/templates/src/workflows/README.md.ts","../src/templates/generate-templates.ts","../src/workflows/aws-teardown-workflow.ts","../src/workflows/build-dev-workflow.ts","../src/workflows/build-stage-workflow.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","/**\n * @see sites/www-docs/content/packages/@openhi/platform/index.md\n */\n/** @openhi/platform — root barrel exports. */\nexport * from \"./openhi\";\nexport * from \"./service\";\n","import {\n MonorepoProject,\n MonorepoProjectOptions,\n} from \"@codedrifters/configulator\";\nimport { OpenHiConfig } from \"@openhi/config\";\nimport { merge } from \"ts-deepmerge\";\nimport { SetOptional } from \"type-fest\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"./service\";\nimport { AwsTeardownWorkflow } from \"./workflows/aws-teardown-workflow\";\nimport { BuildDevelopmentWorkflow } from \"./workflows/build-dev-workflow\";\nimport { BuildStageWorkflow } from \"./workflows/build-stage-workflow\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/openhi.md\n */\n\nexport interface OpenHiOptions {\n /*****************************************************************************\n *\n * Root Project Configuration Options\n *\n * Configuration options for the root monorepo project that contains all\n * OpenHi services and coordinate releases and builds.\n *\n ****************************************************************************/\n\n readonly rootProjectOptions?: SetOptional<MonorepoProjectOptions, \"name\">;\n\n /**\n * Monorepo root project, if using an existing project.\n */\n readonly rootProject?: MonorepoProject;\n\n /*****************************************************************************\n *\n * Service Configuration Options\n *\n * These options are used to configure the various services within the OpenHi\n * framework. Each service can have its own configuration settings, which will\n * be merged with the default configuration.\n *\n ****************************************************************************/\n\n /**\n * Default configuration used in all services with undefined configs.\n */\n readonly defaultConfig?: OpenHiConfig;\n\n /**\n * Global Service Config\n */\n readonly globalServiceConfig?: OpenHiConfig;\n\n /**\n * Auth Service Config\n */\n readonly authServiceConfig?: OpenHiConfig;\n\n /**\n * Rest API Service Config\n */\n readonly restApiServiceConfig?: OpenHiConfig;\n\n /**\n * Data Service Config (DynamoDB FHIR store, S3, etc.)\n */\n readonly dataServiceConfig?: OpenHiConfig;\n\n /**\n * GraphQL API Service Config\n */\n readonly graphApiServiceConfig?: OpenHiConfig;\n\n /**\n * Website Service Config (static hosting + content uploader).\n */\n readonly websiteServiceConfig?: OpenHiConfig;\n}\n\nexport class OpenHi {\n /**\n * Final options used to build this instance.\n */\n public options: OpenHiOptions;\n\n /**\n * Monorepo root project, either passed in as an argument or generated in\n * this component\n */\n public readonly rootProject?: MonorepoProject;\n\n /**\n * Test identifier for this instance.\n */\n public readonly id: string;\n\n /**\n * Global service (deployed first; Auth, data service, and other stacks depend on it).\n */\n public readonly global: OpenHiService;\n\n /**\n * Auth service (deployed first; data service, REST API, and data services depend on it).\n */\n public readonly auth: OpenHiService;\n\n /**\n * Rest API service\n */\n public readonly restApi: OpenHiService;\n\n /**\n * Data service (DynamoDB FHIR store, S3, and other persistence).\n */\n public readonly data: OpenHiService;\n\n /**\n * GraphQL API service (AppSync); deploys as sibling to REST API after Data.\n */\n public readonly graphApi: OpenHiService;\n\n /**\n * Website service (static hosting + content uploader); deploys as sibling\n * to the other services after Global.\n */\n public readonly website: OpenHiService;\n\n constructor(options: OpenHiOptions = {}) {\n /***************************************************************************\n *\n * Options\n *\n * Combine input options with defaults.\n *\n **************************************************************************/\n\n this.options = merge({ name: \"openhi\" }, options);\n this.rootProject = this.options.rootProject;\n this.id = this.options.rootProject?.name ?? \"openhi\";\n\n /**\n * In future we would create root project here. For now, require it to be\n * passed in.\n */\n if (!this.rootProject) {\n throw new Error(\n \"OpenHi requires a MonorepoProject to be passed in via the rootProject option\",\n );\n }\n\n const rootProject = this.rootProject;\n\n /***************************************************************************\n *\n * Global Service\n *\n * Global infrastructure (Route53, ACM). Deployed first in primary;\n * Auth, data service, and other stacks depend on it.\n *\n **************************************************************************/\n\n this.global = new OpenHiService(this, \"global\", {\n type: OPEN_HI_SERVICE_TYPE.GLOBAL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.globalServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Auth Service\n *\n * Authentication (Cognito user pool, client, domain, KMS). Deployed first;\n * data service, REST API, and data services consume auth via SSM.\n *\n **************************************************************************/\n\n this.auth = new OpenHiService(this, \"auth\", {\n type: OPEN_HI_SERVICE_TYPE.AUTH,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.authServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Rest API service\n *\n * This contains the REST API for the OpenHi platform.\n *\n **************************************************************************/\n\n this.restApi = new OpenHiService(this, \"rest-api\", {\n type: OPEN_HI_SERVICE_TYPE.REST_API,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.restApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Data Service\n *\n * Data storage stack (DynamoDB FHIR store, S3, etc.). Deployed so that\n * REST API and other services can reference the table via cross-stack.\n *\n **************************************************************************/\n\n this.data = new OpenHiService(this, \"data\", {\n type: OPEN_HI_SERVICE_TYPE.DATA_SERVICE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.dataServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * GraphQL API service\n *\n * AppSync API; deploys as sibling to REST API after Data.\n *\n **************************************************************************/\n\n this.graphApi = new OpenHiService(this, \"graphql\", {\n type: OPEN_HI_SERVICE_TYPE.GRAPHQL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.graphApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Website service\n *\n * Static hosting (CloudFront + S3 + Lambda@Edge) and content uploader;\n * deploys as a sibling to the other services after Global.\n *\n **************************************************************************/\n\n this.website = new OpenHiService(this, \"website\", {\n type: OPEN_HI_SERVICE_TYPE.WEBSITE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.websiteServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Integrations\n *\n * Various purpose specific integrations.\n *\n **************************************************************************/\n\n /***************************************************************************\n *\n * Workflows\n *\n * Workflows for each environment.\n *\n **************************************************************************/\n\n new BuildDevelopmentWorkflow(rootProject, { openhi: this });\n new BuildStageWorkflow(rootProject, { openhi: this });\n\n new AwsTeardownWorkflow(rootProject, { openhi: this });\n }\n}\n","import { sep } from \"path\";\nimport {\n AwsDeploymentTarget,\n TurboRepo,\n VERSION,\n} from \"@codedrifters/configulator\";\nimport {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OPEN_HI_STAGE,\n OpenHiConfig,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { paramCase, pascalCase } from \"change-case\";\nimport { awscdk } from \"projen\";\nimport { NodePackageManager, Transform } from \"projen/lib/javascript\";\nimport { ValueOf } from \"type-fest\";\nimport { OpenHi } from \"./openhi\";\nimport { GenerateTemplates } from \"./templates/generate-templates\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/service.md\n */\n\nexport const OPEN_HI_SERVICE_TYPE = {\n AUTH: \"auth\",\n DATA_SERVICE: \"data\",\n GLOBAL: \"global\",\n GRAPHQL: \"graphql\",\n INTEGRATION: \"integration\",\n REST_API: \"rest-api\",\n WEBSITE: \"website\",\n} as const;\n\nexport interface OpenHiServiceOptions {\n /**\n * Configuration for this service.\n *\n * @default uses the global default config.\n */\n readonly config: OpenHiConfig;\n\n /**\n * What type of service is this?\n */\n readonly type: ValueOf<typeof OPEN_HI_SERVICE_TYPE>;\n}\n\nexport class OpenHiService {\n public readonly project: awscdk.AwsCdkTypeScriptApp;\n\n constructor(\n public openHi: OpenHi,\n public id: string,\n public options: OpenHiServiceOptions,\n ) {\n /**\n * Build the construct name we expect to use in this service.\n */\n\n /***************************************************************************\n *\n * Projen based CDK build\n *\n **************************************************************************/\n\n this.project = new awscdk.AwsCdkTypeScriptApp({\n /**\n * Top level project config options\n */\n defaultReleaseBranch: \"main\",\n name: this.serviceName,\n outdir: this.outDir,\n parent: this.openHi.rootProject,\n cdkVersion:\n this.options?.config?.versions?.cdk?.cdkLibVersion ??\n VERSION.AWS_CDK_LIB_VERSION,\n cdkCliVersion:\n this.options?.config?.versions?.cdk?.cdkCliVersion ??\n VERSION.AWS_CDK_CLI_VERSION,\n\n /**\n * Packaging options\n *\n * TODO: Figure out license for monorepo vs per package?\n */\n licensed: false,\n\n /**\n * Node configs\n */\n packageManager: NodePackageManager.PNPM,\n\n /**\n * Turn on prettier formatting\n */\n prettier: true,\n\n /**\n * Don't generate sample code.\n */\n sampleCode: false,\n\n /**\n * Make sure jest config is stored outside of package.json and use SWC\n * for faster tests.\n */\n jestOptions: {\n configFilePath: \"jest.config.json\",\n jestConfig: {\n transform: {\n [\"^.+\\\\.[t]sx?$\"]: new Transform(\"@swc/jest\"),\n },\n },\n },\n\n /**\n * SWC for faster testing\n */\n devDeps: [\"@swc/jest\", \"@swc/core\"],\n\n /**\n * Don't package test files.\n */\n npmIgnoreOptions: {\n ignorePatterns: [\"*.spec.*\", \"*.test.*\"],\n },\n });\n\n /**\n * We're using SWC now, remove ts-jest which is included by default.\n */\n this.project.deps.removeDependency(\"ts-jest\");\n\n /***************************************************************************\n *\n * Workspace Dependencies\n *\n * - Constructs are used to build out the AWS CDK environments.\n *\n **************************************************************************/\n\n this.project.addDeps(\n \"@openhi/config@workspace:*\",\n \"@openhi/constructs@workspace:*\",\n );\n\n /***************************************************************************\n *\n * Turbo Configuration\n *\n * - Activate turborepo for the project.\n *\n **************************************************************************/\n\n new TurboRepo(this.project);\n\n TurboRepo.of(this.project)?.activateBranchNameEnvVar({\n tasks: [\"post-compile\"],\n });\n\n /**\n * The website's CDK app uploads the admin-console SPA build (the\n * `dist/` directory the Vite build emits) to S3 in place of the\n * hand-written `content/` placeholder. Declaring the workspace\n * dep here both makes the package resolvable at synth time (via\n * `require.resolve(\"@codedrifters/admin-console/package.json\")`\n * in `openhi/website/src/app.ts`) and threads\n * `@codedrifters/admin-console#turbo:build` into the website's\n * `post-compile.dependsOn` so turbo builds the SPA before the\n * website synth runs.\n */\n if (this.options.type === OPEN_HI_SERVICE_TYPE.WEBSITE) {\n this.project.addDeps(\"@codedrifters/admin-console@workspace:*\");\n }\n\n /***************************************************************************\n *\n * Define some basic Service Structure\n *\n **************************************************************************/\n\n new GenerateTemplates(this);\n\n /***************************************************************************\n *\n * Deployment Targets\n *\n **************************************************************************/\n\n [OPEN_HI_STAGE.DEV, OPEN_HI_STAGE.STAGE, OPEN_HI_STAGE.PROD].forEach(\n (stage) => {\n const targets = this.options?.config?.deploymentTargets?.[stage];\n if (targets?.primary) {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,\n targets.primary,\n );\n }\n targets?.secondary?.forEach((env) => {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,\n env,\n );\n });\n },\n );\n }\n\n private addDeploymentTarget = (\n awsStageType: ValueOf<typeof OPEN_HI_STAGE>,\n awsEnvironmentType: ValueOf<typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE>,\n envConfig: OpenHiEnvironmentConfig,\n ) => {\n new AwsDeploymentTarget(this.project, {\n account: envConfig.account,\n region: envConfig.region,\n awsStageType,\n awsEnvironmentType,\n localDeployment: true,\n localDeploymentConfig: {\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n roleName: \"poweruseraccess\",\n },\n ciDeployment: true,\n ciDeploymentConfig: {\n roleArn: `arn:aws:iam::${envConfig.account}:role/GitHubOpenHiDeployer`,\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n },\n\n branches:\n awsStageType === OPEN_HI_STAGE.DEV\n ? [\n {\n branch: \"feat/*\",\n description: [\n \"Feature branches for OpenHI (short form).\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"feature/*\",\n description: [\n \"Feature branches for OpenHI.\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"fix/*\",\n description: [\n \"Fix branches for OpenHI.\",\n \"This branch pattern is used when a developer is working on a fix on the project.\",\n ],\n },\n ]\n : [\n {\n branch: \"main\",\n description: [\n \"Main branch for OpenHI.\",\n \"This branch is used for the main branch.\",\n ],\n },\n ],\n });\n };\n\n get constructName(): string {\n return pascalCase([\"open\", \"hi\", this.id, \"service\"].join(\"-\"));\n }\n\n get outDir() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(sep);\n }\n\n get serviceName() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(\"-\");\n }\n}\n","import { existsSync, unlinkSync } from \"node:fs\";\nimport { sep } from \"node:path\";\nimport { SampleFile } from \"projen\";\nimport { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/service-template.md\n */\n\nexport interface ServiceTemplateOptions {\n /**\n * The content of the sample file, as an array.\n */\n readonly contents: Array<string>;\n\n /**\n * The relative file path from the project root.\n */\n readonly filePath: string;\n\n /**\n * Overwrite this template file to it's original state?\n *\n * @default false\n */\n readonly overwrite?: boolean;\n}\n\nexport class ServiceTemplate {\n /**\n * The file being generated.\n */\n public file?: SampleFile;\n\n /**\n * Absolute Filepath, including the project path.\n */\n public fullFilePath: string;\n\n constructor(\n public service: OpenHiService,\n public options: ServiceTemplateOptions,\n ) {\n /**\n * Determine the full file path for this file.\n */\n this.fullFilePath = [\n this.service.project.outdir,\n this.options.filePath,\n ].join(sep);\n\n /**\n * Build the template file.\n */\n this.createTemplate();\n }\n\n protected createTemplate() {\n if (this.options.overwrite) {\n this.overwriteTemplate();\n }\n\n this.file = new SampleFile(this.service.project, this.options.filePath, {\n contents: this.options.contents.join(\"\\n\"),\n });\n }\n\n public overwriteTemplate() {\n /**\n * Delete file, if it exists.\n */\n if (existsSync(this.fullFilePath)) {\n unlinkSync(this.fullFilePath);\n }\n this.file = undefined;\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app.md\n */\n\nexport class SrcApp extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.ts\",\n contents: [\n `import { OpenHiApp, ${service.constructName} } from \"@openhi/constructs\";`,\n `import { CONFIG } from \"./config\";`,\n ``,\n `const app = new OpenHiApp({ config: CONFIG });`,\n ``,\n `const stacks = app.environments.map((e) => {`,\n ` return new ${service.constructName}(e, { config: e.config });`,\n `});`,\n ``,\n `export { app, stacks };`,\n ``,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app-test.md\n */\n\nexport class SrcAppTest extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.test.ts\",\n contents: [\n `import { Template } from \"aws-cdk-lib/assertions\";`,\n `import { Code, type CodeConfig } from \"aws-cdk-lib/aws-lambda\";`,\n `import { stacks } from \"./app\"`,\n ``,\n `/** Replace volatile CDK asset S3 keys/buckets with static values for snapshot stability. */`,\n `function normalizeTemplateForSnapshot(template: Record<string, unknown>): Record<string, unknown> {`,\n ` const staticBucket = \"mock-assets-bucket\";`,\n ` const staticKey = \"mock-asset-key.zip\";`,\n ` const json = JSON.stringify(template);`,\n ` const normalized = json`,\n ` .replace(/\"S3Key\":\\\\s*\"[^\"]+\\\\.zip\"/g, \\`\"S3Key\": \"\\${staticKey}\"\\`)`,\n ` .replace(/\"S3Bucket\":\\\\s*\"[^\"]+\"/g, \\`\"S3Bucket\": \"\\${staticBucket}\"\\`);`,\n ` return JSON.parse(normalized) as Record<string, unknown>;`,\n `}`,\n ``,\n `let fromAssetMock: jest.SpyInstance;`,\n ``,\n `beforeAll(() => {`,\n ` fromAssetMock = jest.spyOn(Code, \"fromAsset\").mockReturnValue({`,\n ` isInline: false,`,\n ` bind: (): CodeConfig => ({`,\n ` s3Location: {`,\n ` bucketName: \"mock-assets-bucket\",`,\n ` objectKey: \"mock-asset-key.zip\",`,\n ` },`,\n ` }),`,\n ` bindToResource: () => {`,\n ` return;`,\n ` },`,\n ` } as any);`,\n `});`,\n ``,\n `afterAll(() => {`,\n ` fromAssetMock?.mockRestore();`,\n `});`,\n ``,\n `describe(\"Smoke Test\", () => {`,\n ` it(\"should match previous snapshots\", () => {`,\n ` stacks.forEach((s) => {`,\n ` const template = Template.fromStack(s).toJSON();`,\n ` expect(normalizeTemplateForSnapshot(template)).toMatchSnapshot();`,\n ` });`,\n ` });`,\n `});`,\n ``,\n ],\n });\n }\n}\n","import { SourceCode } from \"projen\";\nimport { OpenHiService } from \"../../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/config.md\n */\n\nexport class SrcConfig extends SourceCode {\n constructor(service: OpenHiService) {\n super(service.project, \"src/config.ts\");\n\n /**\n * Imports\n */\n this.line(`import { OpenHiConfig } from \"@openhi/config\";`);\n this.line(\"\");\n\n /**\n * Write the config content\n */\n const start = \"export const CONFIG: OpenHiConfig = \";\n const mid = JSON.stringify(service.options?.config, null, 2);\n const end = \" as const;\";\n this.line(`${start}${mid}${end}`);\n }\n}\n","import { OpenHiService } from \"../../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/models/readme.md\n */\n\nexport class DataModelsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/models/README.md\",\n contents: [\n `# ${service.serviceName}: Data Models`,\n ``,\n `This directory contains data model definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/readme.md\n */\n\nexport class DataReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/README.md\",\n contents: [\n `# ${service.serviceName}: Data`,\n ``,\n `This directory contains data models and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/infrastructure/readme.md\n */\n\nexport class InfrastructureReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/infrastructure/README.md\",\n contents: [\n `# ${service.serviceName}: Infrastructure`,\n ``,\n `This directory contains infrastructure definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/integrations/readme.md\n */\n\nexport class IntegrationsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/integrations/README.md\",\n contents: [\n `# ${service.serviceName}: Integrations`,\n ``,\n `This directory contains integration definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/main.md\n */\n\nexport class SrcMain extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/main.ts\",\n contents: [`import { app } from \"./app\";`, ``, `app.synth();`, ``],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/readme.md\n */\n\nexport class SrcReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/README.md\",\n contents: [\n `# ${service.serviceName}: Service Overview`,\n ``,\n `This directory contains the main entry point for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/workflows/readme.md\n */\n\nexport class WorkflowsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/workflows/README.md\",\n contents: [\n `# ${service.serviceName}: Workflows`,\n ``,\n `This directory contains workflow definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../service\";\nimport { SrcApp } from \"./src/app\";\nimport { SrcAppTest } from \"./src/app-test\";\nimport { SrcConfig } from \"./src/config\";\nimport { DataModelsReadMe } from \"./src/data/models/README.md\";\nimport { DataReadMe } from \"./src/data/README.md\";\nimport { InfrastructureReadMe } from \"./src/infrastructure/README.md\";\nimport { IntegrationsReadMe } from \"./src/integrations/README.md\";\nimport { SrcMain } from \"./src/main\";\nimport { SrcReadMe } from \"./src/README.md\";\nimport { WorkflowsReadMe } from \"./src/workflows/README.md\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/generate-templates.md\n */\n\nexport class GenerateTemplates {\n constructor(private service: OpenHiService) {\n /**\n * Root src templates\n */\n new SrcApp(this.service);\n new SrcAppTest(this.service);\n new SrcConfig(this.service);\n new SrcMain(this.service);\n new SrcReadMe(this.service);\n\n /**\n * Data\n */\n new DataReadMe(this.service);\n new DataModelsReadMe(this.service);\n\n /**\n * Infrastructure\n */\n new InfrastructureReadMe(this.service);\n\n /**\n * Integrations\n */\n new IntegrationsReadMe(this.service);\n\n /**\n * Workflows\n */\n new WorkflowsReadMe(this.service);\n }\n}\n","import {\n AwsDeploymentConfig,\n MonorepoProject,\n} from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { GitHub, GithubWorkflow } from \"projen/lib/github\";\nimport { JobPermission } from \"projen/lib/github/workflows-model\";\nimport { OpenHi } from \"../openhi\";\nimport type { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/aws-teardown-workflow.md\n */\n\nexport interface AwsTeardownWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class AwsTeardownWorkflow extends Component {\n constructor(\n public rootProject: MonorepoProject,\n options: AwsTeardownWorkflowOptions,\n ) {\n super(rootProject);\n\n const { openhi } = options;\n\n /***************************************************************************\n *\n * Root project check\n *\n * Detect the root project and ensure it's of type MonorepoProject.\n *\n **************************************************************************/\n\n if (!(rootProject instanceof MonorepoProject)) {\n throw new Error(\n \"AwsTeardownWorkflow requires the root project to be a MonorepoProject\",\n );\n }\n\n //this.rootProject = project.root;\n\n /***************************************************************************\n *\n * GitHub Check\n *\n * Make sure github config is active in the project. This is to ensure all\n * workflows will be output properly during synth.\n *\n **************************************************************************/\n\n const github = GitHub.of(this.rootProject);\n\n if (!github) {\n throw new Error(\n \"AwsTeardownWorkflow requires a GitHub component in the root project\",\n );\n }\n\n /***************************************************************************\n *\n * Workflow Destroy Targets\n *\n * Find all the CI targets for the Global project in the DEV stage\n * only. One job per (account, region) teardowns all orphan stacks (Auth,\n * Core, data) in that account/region.\n *\n **************************************************************************/\n\n const devTargetsFor = (service: OpenHiService) =>\n AwsDeploymentConfig.of(service.project)?.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === OPEN_HI_STAGE.DEV && target.ciDeployment,\n ) ?? [];\n const awsDestructionTargets = devTargetsFor(openhi.global);\n\n /***************************************************************************\n *\n * Create Workflow\n *\n * Make a new workflow for AWS stack teardown. This runs each night and is\n * also triggered each time a branch is deleted.\n *\n **************************************************************************/\n\n const workflow = new GithubWorkflow(github, \"teardown-dev\");\n workflow.on({\n workflowDispatch: {},\n schedule: [\n {\n cron: \"32 6 * * *\", // Every Sunday at 6:32 AM UTC\n },\n ],\n delete: {\n branches: [\"feature/*\", \"feat/*\", \"fix/*\"],\n },\n /* for debugging \n push: {\n branches: [\"feature/*\"],\n },\n */\n });\n\n awsDestructionTargets.forEach((target) => {\n const {\n awsStageType,\n awsEnvironmentType,\n account,\n region,\n ciDeploymentConfig,\n } = target;\n const { roleArn } = ciDeploymentConfig ?? {};\n\n workflow.addJob(`teardown-${account}-${region}`.toLowerCase(), {\n name: `Teardown Stacks in ${target.account}/${target.region}`,\n //if: \"github.event.ref_type == 'branch'\",\n runsOn: [\"ubuntu-latest\"],\n permissions: {\n contents: JobPermission.READ,\n idToken: JobPermission.WRITE,\n },\n env: {\n REPO: \"${{ github.repository }}\",\n REGIONS: [region].join(\" \"),\n },\n steps: [\n /**\n * Configure AWS creds.\n */\n {\n name: `AWS Creds ${awsStageType}/${awsEnvironmentType}/${account}/${region}`,\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n \"role-to-assume\": roleArn,\n \"aws-region\": region,\n \"role-duration-seconds\": 900, // 15 minutes\n },\n },\n\n /**\n * Fetch all branch names in the repo\n */\n {\n name: \"Fetch All Branches\",\n id: \"fetch_branches\",\n uses: \"actions/github-script@v7\",\n with: {\n script: [\n \"const all = await github.paginate(github.rest.repos.listBranches, {\",\n \" owner: context.repo.owner,\",\n \" repo: context.repo.repo,\",\n \" per_page: 100\",\n \"});\",\n \"const names = all.map(b => b.name);\",\n \"console.log(`Found branches: ${names}`);\",\n 'core.setOutput(\"json\", JSON.stringify(names));',\n ].join(\"\\n\"),\n },\n },\n\n /**\n * Save branches to a file\n */\n {\n name: \"Save Branches to File\",\n run: [\n 'echo \"Saving branches to file\"',\n \"echo '${{ steps.fetch_branches.outputs.json }}' | jq -r '.[]' | sort -u > branches.txt\",\n 'echo \"Branches:\"',\n \"cat branches.txt\",\n ].join(\"\\n\"),\n },\n\n /**\n * Find all stacks tagged with a stage of dev. for this repo. return\n * tag and resource arn.\n */\n {\n name: \"Find Stacks by Tag\",\n id: \"find_stacks\",\n run: [\n \"set -euo pipefail\",\n \": > candidates.txt # columns: arn region branchTag\",\n\n \"# Build tag filters\",\n 'TAG_FILTERS=( \"Key=openhi:repo-name,Values=$REPO\" )',\n `TAG_FILTERS+=( \"Key=openhi:stage-type,Values=${OPEN_HI_STAGE.DEV}\" )`,\n\n \"for r in $REGIONS; do\",\n ` echo \"Scanning region: $r\"`,\n \" aws resourcegroupstaggingapi get-resources \\\\\",\n ' --region \"$r\" \\\\',\n ' --resource-type-filters \"cloudformation:stack\" \\\\',\n ' --tag-filters \"${TAG_FILTERS[@]}\" \\\\',\n ` | jq -r --arg r \"$r\" '`,\n \" .ResourceTagMappingList[]\",\n \" | . as $res\",\n ' | ($res.Tags[] | select(.Key==\"openhi:branch-name\") | .Value) as $branch',\n ' | [$res.ResourceARN, $r, ($branch // \"\")]',\n \" | @tsv\",\n \" ' >> candidates.txt\",\n \"done\",\n\n \"echo 'Tagged stacks:'\",\n `(echo -e \"ARN\\\\tREGION\\\\tBRANCH\"; cat candidates.txt) | column -t -s $'\\\\t'`,\n ].join(\"\\n\"),\n },\n\n /**\n * Determine which stacks are orphans that no longer have a matching branch.\n * Save those to a file for the next step.\n */\n {\n name: \"Determine Orphan Stacks (No Matching Branch)\",\n run: [\n \"set -euo pipefail\",\n \": > orphans.txt # arn region branch\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n ' if [ -z \"$branch\" ]; then',\n \" # If no Branch tag, treat as not-a-preview; skip (or flip to delete if you want)\",\n \" continue\",\n \" fi\",\n ' if ! grep -Fxq \"$branch\" branches.txt; then',\n ' echo -e \"$arn\\\\t$region\\\\t$branch\" >> orphans.txt',\n \" fi\",\n \"done < candidates.txt\",\n \"\",\n \"if [ -s orphans.txt ]; then\",\n ' echo \"Orphan stacks (no matching branch):\"',\n \" (echo -e \\\"ARN\\\\tREGION\\\\tBRANCH\\\"; cat orphans.txt) | column -t -s $'\\\\t'\",\n \"else\",\n ' echo \"No orphan stacks found.\"',\n \"fi\",\n ].join(\"\\n\"),\n },\n\n /**\n * Delete orphan stacks.\n */\n {\n name: \"Delete Orphan Stacks\",\n if: \"hashFiles('orphans.txt') != ''\",\n run: [\n \"set -euo pipefail\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n \" stack_name=$(cut -d'/' -f2 <<<\\\"$arn\\\")\",\n ' echo \"Deleting $stack_name (branch=$branch) in $region\"',\n ' aws cloudformation delete-stack --region \"$region\" --stack-name \"$stack_name\" || true',\n \"done < orphans.txt\",\n ].join(\"\\n\"),\n },\n ],\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * Job-level `if:` condition that restricts the per-PR website deploy to\n * pull-request events plus manual dispatch. The website hostname is now\n * derivable from `branchName` alone, so the strict PR gate is no longer\n * required for hostname resolution; the gate is preserved here to avoid\n * spawning per-branch deploys for every push and is revisited under a\n * follow-up issue.\n */\nconst PR_GATED_WEBSITE_JOB_IF =\n \"${{ !needs.build.outputs.self_mutation_happened && \" +\n \"(github.event_name == 'pull_request' || \" +\n \"github.event_name == 'workflow_dispatch') }}\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-dev-workflow.md\n */\n\nexport interface BuildDevelopmentWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildDevelopmentWorkflow extends Component {\n constructor(\n parent: MonorepoProject,\n options: BuildDevelopmentWorkflowOptions,\n ) {\n super(parent, \"dev-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets } = new AwsDeployWorkflow(\n openhi.global.project,\n {\n buildWorkflow: parent.buildWorkflow,\n },\n );\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n *\n * Deploy the Rest API service after Data (and Global).\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n *\n * Deploy the GraphQL API service after Data (sibling to REST API).\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n const websiteDeploy = new AwsDeployWorkflow(openhi.website.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n\n /**\n * Per-PR preview wiring for the website deploy:\n *\n * 1. Trigger the build workflow on PR events so feature-branch deploys\n * run on every push to a PR. The per-PR hostname is derived from\n * `branchName` (e.g. `admin-feat-1093-patient-migration.<zone>`),\n * not a PR number, so no env-var injection is needed.\n * 2. Gate every `*-deploy-openhi-website-*` job to `pull_request` +\n * `workflow_dispatch` only. Other services' deploy jobs are\n * unchanged.\n */\n const buildWorkflow = parent.buildWorkflow;\n if (!buildWorkflow) {\n throw new Error(\"BuildDevelopmentWorkflow requires a buildWorkflow\");\n }\n const ghWorkflow = buildWorkflow.workflow;\n ghWorkflow.on({\n pullRequest: {\n types: [\"opened\", \"synchronize\", \"reopened\"],\n },\n });\n websiteDeploy.awsDeploymentTargets.forEach((target) => {\n const jobId = [\n target.awsStageType,\n target.deploymentTargetRole,\n \"deploy\",\n target.project.name,\n target.account,\n target.region,\n ].join(\"-\");\n const job = ghWorkflow.getJob(jobId);\n ghWorkflow.updateJob(jobId, {\n ...job,\n if: PR_GATED_WEBSITE_JOB_IF,\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-stage-workflow.md\n */\n\nexport interface BuildStageWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildStageWorkflow extends Component {\n constructor(parent: MonorepoProject, options: BuildStageWorkflowOptions) {\n super(parent, \"stage-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets, buildWorkflow } =\n new AwsDeployWorkflow(openhi.global.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflowOptions: {\n name: \"deploy-stage\",\n workflowTriggers: {\n push: {\n branches: [\"main\"],\n },\n workflowDispatch: {},\n },\n },\n });\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n * Auth creates the stage build workflow; data service and REST API services add to it.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n new AwsDeployWorkflow(openhi.website.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n }\n}\n"],"mappings":"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","names":["exports","exports","import_config","import_projen","import_projen","import_configulator","import_config","import_projen","import_configulator","import_projen","import_configulator","import_config","import_projen"]}
package/lib/index.mjs CHANGED
@@ -466,11 +466,7 @@ var OpenHiService = class {
466
466
  tasks: ["post-compile"]
467
467
  });
468
468
  if (this.options.type === OPEN_HI_SERVICE_TYPE.WEBSITE) {
469
- const turbo = TurboRepo.of(this.project);
470
- const postCompileEnv = turbo?.postCompileTask?.env;
471
- if (postCompileEnv && !postCompileEnv.includes("OPENHI_PR_NUMBER")) {
472
- postCompileEnv.push("OPENHI_PR_NUMBER");
473
- }
469
+ this.project.addDeps("@codedrifters/admin-console@workspace:*");
474
470
  }
475
471
  new GenerateTemplates(this);
476
472
  [import_config2.OPEN_HI_STAGE.DEV, import_config2.OPEN_HI_STAGE.STAGE, import_config2.OPEN_HI_STAGE.PROD].forEach(
@@ -752,10 +748,6 @@ var BuildDevelopmentWorkflow = class extends Component2 {
752
748
  types: ["opened", "synchronize", "reopened"]
753
749
  }
754
750
  });
755
- ghWorkflow.file?.addOverride(
756
- "env.OPENHI_PR_NUMBER",
757
- "${{ github.event.pull_request.number || '' }}"
758
- );
759
751
  websiteDeploy.awsDeploymentTargets.forEach((target) => {
760
752
  const jobId = [
761
753
  target.awsStageType,
@@ -794,10 +786,6 @@ var BuildStageWorkflow = class extends Component3 {
794
786
  }
795
787
  }
796
788
  });
797
- buildWorkflow.workflow.file?.addOverride(
798
- "env.OPENHI_PR_NUMBER",
799
- "${{ github.event.pull_request.number || '' }}"
800
- );
801
789
  const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow2(
802
790
  openhi.auth.project,
803
791
  {
package/lib/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../src/openhi.ts","../src/service.ts","../src/templates/service-template.ts","../src/templates/src/app.ts","../src/templates/src/app-test.ts","../src/templates/src/config.ts","../src/templates/src/data/models/README.md.ts","../src/templates/src/data/README.md.ts","../src/templates/src/infrastructure/README.md.ts","../src/templates/src/integrations/README.md.ts","../src/templates/src/main.ts","../src/templates/src/README.md.ts","../src/templates/src/workflows/README.md.ts","../src/templates/generate-templates.ts","../src/workflows/aws-teardown-workflow.ts","../src/workflows/build-dev-workflow.ts","../src/workflows/build-stage-workflow.ts"],"sourcesContent":["/*******************************************************************************\n *\n * OpenHi Config\n *\n * These types are kept in their own package to prevent dependency conflicts and\n * conditions between @openhi/constructs and @openhi/platform..\n *\n ******************************************************************************/\n\n/**\n * Stage Types\n *\n * What stage of deployment is this? Dev, staging, or prod?\n */\nexport const OPEN_HI_STAGE = {\n /**\n * Development environment, typically used for testing and development.\n */\n DEV: \"dev\",\n /**\n * Staging environment, used for pre-production testing.\n */\n STAGE: \"stage\",\n /**\n * Production environment, used for live deployments.\n */\n PROD: \"prod\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiStageType =\n (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n\n/**\n * Deployment Target Role\n *\n * Is this (account, region) the primary or a secondary deployment target for the stage?\n * Works for both multi-region (different regions) and cellular (same region, different accounts).\n */\nexport const OPEN_HI_DEPLOYMENT_TARGET_ROLE = {\n /**\n * The primary deployment target for this stage (main account/region).\n * For example, the base DynamoDB region for global tables.\n */\n PRIMARY: \"primary\",\n\n /**\n * A secondary deployment target for this stage (additional account/region).\n * For example, a replica region for a global DynamoDB table, or another cell in the same region.\n */\n SECONDARY: \"secondary\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiDeploymentTargetRoleType =\n (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\nexport interface OpenHiEnvironmentConfig {\n account: string;\n region: string;\n /**\n * Route53 zone containing DNS for this service.\n */\n hostedZoneId?: string;\n zoneName?: string;\n}\n\n/**\n * Represents the configuration for OpenHi services across different stages and\n * deployment targets.\n */\nexport interface OpenHiConfig {\n versions?: {\n cdk?: {\n cdkLibVersion?: string;\n cdkCliVersion?: string;\n };\n };\n deploymentTargets?: {\n [OPEN_HI_STAGE.DEV]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.STAGE]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.PROD]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n };\n}\n","export * from \"./open-hi-config\";\n","import {\n MonorepoProject,\n MonorepoProjectOptions,\n} from \"@codedrifters/configulator\";\nimport { OpenHiConfig } from \"@openhi/config\";\nimport { merge } from \"ts-deepmerge\";\nimport { SetOptional } from \"type-fest\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"./service\";\nimport { AwsTeardownWorkflow } from \"./workflows/aws-teardown-workflow\";\nimport { BuildDevelopmentWorkflow } from \"./workflows/build-dev-workflow\";\nimport { BuildStageWorkflow } from \"./workflows/build-stage-workflow\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/openhi.md\n */\n\nexport interface OpenHiOptions {\n /*****************************************************************************\n *\n * Root Project Configuration Options\n *\n * Configuration options for the root monorepo project that contains all\n * OpenHi services and coordinate releases and builds.\n *\n ****************************************************************************/\n\n readonly rootProjectOptions?: SetOptional<MonorepoProjectOptions, \"name\">;\n\n /**\n * Monorepo root project, if using an existing project.\n */\n readonly rootProject?: MonorepoProject;\n\n /*****************************************************************************\n *\n * Service Configuration Options\n *\n * These options are used to configure the various services within the OpenHi\n * framework. Each service can have its own configuration settings, which will\n * be merged with the default configuration.\n *\n ****************************************************************************/\n\n /**\n * Default configuration used in all services with undefined configs.\n */\n readonly defaultConfig?: OpenHiConfig;\n\n /**\n * Global Service Config\n */\n readonly globalServiceConfig?: OpenHiConfig;\n\n /**\n * Auth Service Config\n */\n readonly authServiceConfig?: OpenHiConfig;\n\n /**\n * Rest API Service Config\n */\n readonly restApiServiceConfig?: OpenHiConfig;\n\n /**\n * Data Service Config (DynamoDB FHIR store, S3, etc.)\n */\n readonly dataServiceConfig?: OpenHiConfig;\n\n /**\n * GraphQL API Service Config\n */\n readonly graphApiServiceConfig?: OpenHiConfig;\n\n /**\n * Website Service Config (static hosting + content uploader).\n */\n readonly websiteServiceConfig?: OpenHiConfig;\n}\n\nexport class OpenHi {\n /**\n * Final options used to build this instance.\n */\n public options: OpenHiOptions;\n\n /**\n * Monorepo root project, either passed in as an argument or generated in\n * this component\n */\n public readonly rootProject?: MonorepoProject;\n\n /**\n * Test identifier for this instance.\n */\n public readonly id: string;\n\n /**\n * Global service (deployed first; Auth, data service, and other stacks depend on it).\n */\n public readonly global: OpenHiService;\n\n /**\n * Auth service (deployed first; data service, REST API, and data services depend on it).\n */\n public readonly auth: OpenHiService;\n\n /**\n * Rest API service\n */\n public readonly restApi: OpenHiService;\n\n /**\n * Data service (DynamoDB FHIR store, S3, and other persistence).\n */\n public readonly data: OpenHiService;\n\n /**\n * GraphQL API service (AppSync); deploys as sibling to REST API after Data.\n */\n public readonly graphApi: OpenHiService;\n\n /**\n * Website service (static hosting + content uploader); deploys as sibling\n * to the other services after Global.\n */\n public readonly website: OpenHiService;\n\n constructor(options: OpenHiOptions = {}) {\n /***************************************************************************\n *\n * Options\n *\n * Combine input options with defaults.\n *\n **************************************************************************/\n\n this.options = merge({ name: \"openhi\" }, options);\n this.rootProject = this.options.rootProject;\n this.id = this.options.rootProject?.name ?? \"openhi\";\n\n /**\n * In future we would create root project here. For now, require it to be\n * passed in.\n */\n if (!this.rootProject) {\n throw new Error(\n \"OpenHi requires a MonorepoProject to be passed in via the rootProject option\",\n );\n }\n\n const rootProject = this.rootProject;\n\n /***************************************************************************\n *\n * Global Service\n *\n * Global infrastructure (Route53, ACM). Deployed first in primary;\n * Auth, data service, and other stacks depend on it.\n *\n **************************************************************************/\n\n this.global = new OpenHiService(this, \"global\", {\n type: OPEN_HI_SERVICE_TYPE.GLOBAL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.globalServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Auth Service\n *\n * Authentication (Cognito user pool, client, domain, KMS). Deployed first;\n * data service, REST API, and data services consume auth via SSM.\n *\n **************************************************************************/\n\n this.auth = new OpenHiService(this, \"auth\", {\n type: OPEN_HI_SERVICE_TYPE.AUTH,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.authServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Rest API service\n *\n * This contains the REST API for the OpenHi platform.\n *\n **************************************************************************/\n\n this.restApi = new OpenHiService(this, \"rest-api\", {\n type: OPEN_HI_SERVICE_TYPE.REST_API,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.restApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Data Service\n *\n * Data storage stack (DynamoDB FHIR store, S3, etc.). Deployed so that\n * REST API and other services can reference the table via cross-stack.\n *\n **************************************************************************/\n\n this.data = new OpenHiService(this, \"data\", {\n type: OPEN_HI_SERVICE_TYPE.DATA_SERVICE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.dataServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * GraphQL API service\n *\n * AppSync API; deploys as sibling to REST API after Data.\n *\n **************************************************************************/\n\n this.graphApi = new OpenHiService(this, \"graphql\", {\n type: OPEN_HI_SERVICE_TYPE.GRAPHQL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.graphApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Website service\n *\n * Static hosting (CloudFront + S3 + Lambda@Edge) and content uploader;\n * deploys as a sibling to the other services after Global.\n *\n **************************************************************************/\n\n this.website = new OpenHiService(this, \"website\", {\n type: OPEN_HI_SERVICE_TYPE.WEBSITE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.websiteServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Integrations\n *\n * Various purpose specific integrations.\n *\n **************************************************************************/\n\n /***************************************************************************\n *\n * Workflows\n *\n * Workflows for each environment.\n *\n **************************************************************************/\n\n new BuildDevelopmentWorkflow(rootProject, { openhi: this });\n new BuildStageWorkflow(rootProject, { openhi: this });\n\n new AwsTeardownWorkflow(rootProject, { openhi: this });\n }\n}\n","import { sep } from \"path\";\nimport {\n AwsDeploymentTarget,\n TurboRepo,\n VERSION,\n} from \"@codedrifters/configulator\";\nimport {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OPEN_HI_STAGE,\n OpenHiConfig,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { paramCase, pascalCase } from \"change-case\";\nimport { awscdk } from \"projen\";\nimport { NodePackageManager, Transform } from \"projen/lib/javascript\";\nimport { ValueOf } from \"type-fest\";\nimport { OpenHi } from \"./openhi\";\nimport { GenerateTemplates } from \"./templates/generate-templates\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/service.md\n */\n\nexport const OPEN_HI_SERVICE_TYPE = {\n AUTH: \"auth\",\n DATA_SERVICE: \"data\",\n GLOBAL: \"global\",\n GRAPHQL: \"graphql\",\n INTEGRATION: \"integration\",\n REST_API: \"rest-api\",\n WEBSITE: \"website\",\n} as const;\n\nexport interface OpenHiServiceOptions {\n /**\n * Configuration for this service.\n *\n * @default uses the global default config.\n */\n readonly config: OpenHiConfig;\n\n /**\n * What type of service is this?\n */\n readonly type: ValueOf<typeof OPEN_HI_SERVICE_TYPE>;\n}\n\nexport class OpenHiService {\n public readonly project: awscdk.AwsCdkTypeScriptApp;\n\n constructor(\n public openHi: OpenHi,\n public id: string,\n public options: OpenHiServiceOptions,\n ) {\n /**\n * Build the construct name we expect to use in this service.\n */\n\n /***************************************************************************\n *\n * Projen based CDK build\n *\n **************************************************************************/\n\n this.project = new awscdk.AwsCdkTypeScriptApp({\n /**\n * Top level project config options\n */\n defaultReleaseBranch: \"main\",\n name: this.serviceName,\n outdir: this.outDir,\n parent: this.openHi.rootProject,\n cdkVersion:\n this.options?.config?.versions?.cdk?.cdkLibVersion ??\n VERSION.AWS_CDK_LIB_VERSION,\n cdkCliVersion:\n this.options?.config?.versions?.cdk?.cdkCliVersion ??\n VERSION.AWS_CDK_CLI_VERSION,\n\n /**\n * Packaging options\n *\n * TODO: Figure out license for monorepo vs per package?\n */\n licensed: false,\n\n /**\n * Node configs\n */\n packageManager: NodePackageManager.PNPM,\n\n /**\n * Turn on prettier formatting\n */\n prettier: true,\n\n /**\n * Don't generate sample code.\n */\n sampleCode: false,\n\n /**\n * Make sure jest config is stored outside of package.json and use SWC\n * for faster tests.\n */\n jestOptions: {\n configFilePath: \"jest.config.json\",\n jestConfig: {\n transform: {\n [\"^.+\\\\.[t]sx?$\"]: new Transform(\"@swc/jest\"),\n },\n },\n },\n\n /**\n * SWC for faster testing\n */\n devDeps: [\"@swc/jest\", \"@swc/core\"],\n\n /**\n * Don't package test files.\n */\n npmIgnoreOptions: {\n ignorePatterns: [\"*.spec.*\", \"*.test.*\"],\n },\n });\n\n /**\n * We're using SWC now, remove ts-jest which is included by default.\n */\n this.project.deps.removeDependency(\"ts-jest\");\n\n /***************************************************************************\n *\n * Workspace Dependencies\n *\n * - Constructs are used to build out the AWS CDK environments.\n *\n **************************************************************************/\n\n this.project.addDeps(\n \"@openhi/config@workspace:*\",\n \"@openhi/constructs@workspace:*\",\n );\n\n /***************************************************************************\n *\n * Turbo Configuration\n *\n * - Activate turborepo for the project.\n *\n **************************************************************************/\n\n new TurboRepo(this.project);\n\n TurboRepo.of(this.project)?.activateBranchNameEnvVar({\n tasks: [\"post-compile\"],\n });\n\n /**\n * The website service composes its hostname (and the S3 key prefix\n * the lifecycle rule expires) from the OPENHI_PR_NUMBER env var on\n * non-release-branch synths. Turborepo strips env vars that are\n * not declared on the task, so the value reaches the workflow's\n * `env:` block but never reaches the `cdk synth` subprocess that\n * the post-compile task runs. Add OPENHI_PR_NUMBER to the\n * post-compile task env so Turborepo passes it through.\n *\n * Scoped to the website project — no other service reads\n * OPENHI_PR_NUMBER, so adding it elsewhere would only cause\n * spurious per-PR cache misses on cdk synth.\n */\n if (this.options.type === OPEN_HI_SERVICE_TYPE.WEBSITE) {\n const turbo = TurboRepo.of(this.project);\n const postCompileEnv = turbo?.postCompileTask?.env;\n if (postCompileEnv && !postCompileEnv.includes(\"OPENHI_PR_NUMBER\")) {\n postCompileEnv.push(\"OPENHI_PR_NUMBER\");\n }\n }\n\n /***************************************************************************\n *\n * Define some basic Service Structure\n *\n **************************************************************************/\n\n new GenerateTemplates(this);\n\n /***************************************************************************\n *\n * Deployment Targets\n *\n **************************************************************************/\n\n [OPEN_HI_STAGE.DEV, OPEN_HI_STAGE.STAGE, OPEN_HI_STAGE.PROD].forEach(\n (stage) => {\n const targets = this.options?.config?.deploymentTargets?.[stage];\n if (targets?.primary) {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,\n targets.primary,\n );\n }\n targets?.secondary?.forEach((env) => {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,\n env,\n );\n });\n },\n );\n }\n\n private addDeploymentTarget = (\n awsStageType: ValueOf<typeof OPEN_HI_STAGE>,\n awsEnvironmentType: ValueOf<typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE>,\n envConfig: OpenHiEnvironmentConfig,\n ) => {\n new AwsDeploymentTarget(this.project, {\n account: envConfig.account,\n region: envConfig.region,\n awsStageType,\n awsEnvironmentType,\n localDeployment: true,\n localDeploymentConfig: {\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n roleName: \"poweruseraccess\",\n },\n ciDeployment: true,\n ciDeploymentConfig: {\n roleArn: `arn:aws:iam::${envConfig.account}:role/GitHubOpenHiDeployer`,\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n },\n\n branches:\n awsStageType === OPEN_HI_STAGE.DEV\n ? [\n {\n branch: \"feat/*\",\n description: [\n \"Feature branches for OpenHI (short form).\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"feature/*\",\n description: [\n \"Feature branches for OpenHI.\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"fix/*\",\n description: [\n \"Fix branches for OpenHI.\",\n \"This branch pattern is used when a developer is working on a fix on the project.\",\n ],\n },\n ]\n : [\n {\n branch: \"main\",\n description: [\n \"Main branch for OpenHI.\",\n \"This branch is used for the main branch.\",\n ],\n },\n ],\n });\n };\n\n get constructName(): string {\n return pascalCase([\"open\", \"hi\", this.id, \"service\"].join(\"-\"));\n }\n\n get outDir() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(sep);\n }\n\n get serviceName() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(\"-\");\n }\n}\n","import { existsSync, unlinkSync } from \"node:fs\";\nimport { sep } from \"node:path\";\nimport { SampleFile } from \"projen\";\nimport { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/service-template.md\n */\n\nexport interface ServiceTemplateOptions {\n /**\n * The content of the sample file, as an array.\n */\n readonly contents: Array<string>;\n\n /**\n * The relative file path from the project root.\n */\n readonly filePath: string;\n\n /**\n * Overwrite this template file to it's original state?\n *\n * @default false\n */\n readonly overwrite?: boolean;\n}\n\nexport class ServiceTemplate {\n /**\n * The file being generated.\n */\n public file?: SampleFile;\n\n /**\n * Absolute Filepath, including the project path.\n */\n public fullFilePath: string;\n\n constructor(\n public service: OpenHiService,\n public options: ServiceTemplateOptions,\n ) {\n /**\n * Determine the full file path for this file.\n */\n this.fullFilePath = [\n this.service.project.outdir,\n this.options.filePath,\n ].join(sep);\n\n /**\n * Build the template file.\n */\n this.createTemplate();\n }\n\n protected createTemplate() {\n if (this.options.overwrite) {\n this.overwriteTemplate();\n }\n\n this.file = new SampleFile(this.service.project, this.options.filePath, {\n contents: this.options.contents.join(\"\\n\"),\n });\n }\n\n public overwriteTemplate() {\n /**\n * Delete file, if it exists.\n */\n if (existsSync(this.fullFilePath)) {\n unlinkSync(this.fullFilePath);\n }\n this.file = undefined;\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app.md\n */\n\nexport class SrcApp extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.ts\",\n contents: [\n `import { OpenHiApp, ${service.constructName} } from \"@openhi/constructs\";`,\n `import { CONFIG } from \"./config\";`,\n ``,\n `const app = new OpenHiApp({ config: CONFIG });`,\n ``,\n `const stacks = app.environments.map((e) => {`,\n ` return new ${service.constructName}(e, { config: e.config });`,\n `});`,\n ``,\n `export { app, stacks };`,\n ``,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app-test.md\n */\n\nexport class SrcAppTest extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.test.ts\",\n contents: [\n `import { Template } from \"aws-cdk-lib/assertions\";`,\n `import { Code, type CodeConfig } from \"aws-cdk-lib/aws-lambda\";`,\n `import { stacks } from \"./app\"`,\n ``,\n `/** Replace volatile CDK asset S3 keys/buckets with static values for snapshot stability. */`,\n `function normalizeTemplateForSnapshot(template: Record<string, unknown>): Record<string, unknown> {`,\n ` const staticBucket = \"mock-assets-bucket\";`,\n ` const staticKey = \"mock-asset-key.zip\";`,\n ` const json = JSON.stringify(template);`,\n ` const normalized = json`,\n ` .replace(/\"S3Key\":\\\\s*\"[^\"]+\\\\.zip\"/g, \\`\"S3Key\": \"\\${staticKey}\"\\`)`,\n ` .replace(/\"S3Bucket\":\\\\s*\"[^\"]+\"/g, \\`\"S3Bucket\": \"\\${staticBucket}\"\\`);`,\n ` return JSON.parse(normalized) as Record<string, unknown>;`,\n `}`,\n ``,\n `let fromAssetMock: jest.SpyInstance;`,\n ``,\n `beforeAll(() => {`,\n ` fromAssetMock = jest.spyOn(Code, \"fromAsset\").mockReturnValue({`,\n ` isInline: false,`,\n ` bind: (): CodeConfig => ({`,\n ` s3Location: {`,\n ` bucketName: \"mock-assets-bucket\",`,\n ` objectKey: \"mock-asset-key.zip\",`,\n ` },`,\n ` }),`,\n ` bindToResource: () => {`,\n ` return;`,\n ` },`,\n ` } as any);`,\n `});`,\n ``,\n `afterAll(() => {`,\n ` fromAssetMock?.mockRestore();`,\n `});`,\n ``,\n `describe(\"Smoke Test\", () => {`,\n ` it(\"should match previous snapshots\", () => {`,\n ` stacks.forEach((s) => {`,\n ` const template = Template.fromStack(s).toJSON();`,\n ` expect(normalizeTemplateForSnapshot(template)).toMatchSnapshot();`,\n ` });`,\n ` });`,\n `});`,\n ``,\n ],\n });\n }\n}\n","import { SourceCode } from \"projen\";\nimport { OpenHiService } from \"../../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/config.md\n */\n\nexport class SrcConfig extends SourceCode {\n constructor(service: OpenHiService) {\n super(service.project, \"src/config.ts\");\n\n /**\n * Imports\n */\n this.line(`import { OpenHiConfig } from \"@openhi/config\";`);\n this.line(\"\");\n\n /**\n * Write the config content\n */\n const start = \"export const CONFIG: OpenHiConfig = \";\n const mid = JSON.stringify(service.options?.config, null, 2);\n const end = \" as const;\";\n this.line(`${start}${mid}${end}`);\n }\n}\n","import { OpenHiService } from \"../../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/models/readme.md\n */\n\nexport class DataModelsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/models/README.md\",\n contents: [\n `# ${service.serviceName}: Data Models`,\n ``,\n `This directory contains data model definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/readme.md\n */\n\nexport class DataReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/README.md\",\n contents: [\n `# ${service.serviceName}: Data`,\n ``,\n `This directory contains data models and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/infrastructure/readme.md\n */\n\nexport class InfrastructureReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/infrastructure/README.md\",\n contents: [\n `# ${service.serviceName}: Infrastructure`,\n ``,\n `This directory contains infrastructure definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/integrations/readme.md\n */\n\nexport class IntegrationsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/integrations/README.md\",\n contents: [\n `# ${service.serviceName}: Integrations`,\n ``,\n `This directory contains integration definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/main.md\n */\n\nexport class SrcMain extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/main.ts\",\n contents: [`import { app } from \"./app\";`, ``, `app.synth();`, ``],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/readme.md\n */\n\nexport class SrcReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/README.md\",\n contents: [\n `# ${service.serviceName}: Service Overview`,\n ``,\n `This directory contains the main entry point for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/workflows/readme.md\n */\n\nexport class WorkflowsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/workflows/README.md\",\n contents: [\n `# ${service.serviceName}: Workflows`,\n ``,\n `This directory contains workflow definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../service\";\nimport { SrcApp } from \"./src/app\";\nimport { SrcAppTest } from \"./src/app-test\";\nimport { SrcConfig } from \"./src/config\";\nimport { DataModelsReadMe } from \"./src/data/models/README.md\";\nimport { DataReadMe } from \"./src/data/README.md\";\nimport { InfrastructureReadMe } from \"./src/infrastructure/README.md\";\nimport { IntegrationsReadMe } from \"./src/integrations/README.md\";\nimport { SrcMain } from \"./src/main\";\nimport { SrcReadMe } from \"./src/README.md\";\nimport { WorkflowsReadMe } from \"./src/workflows/README.md\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/generate-templates.md\n */\n\nexport class GenerateTemplates {\n constructor(private service: OpenHiService) {\n /**\n * Root src templates\n */\n new SrcApp(this.service);\n new SrcAppTest(this.service);\n new SrcConfig(this.service);\n new SrcMain(this.service);\n new SrcReadMe(this.service);\n\n /**\n * Data\n */\n new DataReadMe(this.service);\n new DataModelsReadMe(this.service);\n\n /**\n * Infrastructure\n */\n new InfrastructureReadMe(this.service);\n\n /**\n * Integrations\n */\n new IntegrationsReadMe(this.service);\n\n /**\n * Workflows\n */\n new WorkflowsReadMe(this.service);\n }\n}\n","import {\n AwsDeploymentConfig,\n MonorepoProject,\n} from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { GitHub, GithubWorkflow } from \"projen/lib/github\";\nimport { JobPermission } from \"projen/lib/github/workflows-model\";\nimport { OpenHi } from \"../openhi\";\nimport type { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/aws-teardown-workflow.md\n */\n\nexport interface AwsTeardownWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class AwsTeardownWorkflow extends Component {\n constructor(\n public rootProject: MonorepoProject,\n options: AwsTeardownWorkflowOptions,\n ) {\n super(rootProject);\n\n const { openhi } = options;\n\n /***************************************************************************\n *\n * Root project check\n *\n * Detect the root project and ensure it's of type MonorepoProject.\n *\n **************************************************************************/\n\n if (!(rootProject instanceof MonorepoProject)) {\n throw new Error(\n \"AwsTeardownWorkflow requires the root project to be a MonorepoProject\",\n );\n }\n\n //this.rootProject = project.root;\n\n /***************************************************************************\n *\n * GitHub Check\n *\n * Make sure github config is active in the project. This is to ensure all\n * workflows will be output properly during synth.\n *\n **************************************************************************/\n\n const github = GitHub.of(this.rootProject);\n\n if (!github) {\n throw new Error(\n \"AwsTeardownWorkflow requires a GitHub component in the root project\",\n );\n }\n\n /***************************************************************************\n *\n * Workflow Destroy Targets\n *\n * Find all the CI targets for the Global project in the DEV stage\n * only. One job per (account, region) teardowns all orphan stacks (Auth,\n * Core, data) in that account/region.\n *\n **************************************************************************/\n\n const devTargetsFor = (service: OpenHiService) =>\n AwsDeploymentConfig.of(service.project)?.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === OPEN_HI_STAGE.DEV && target.ciDeployment,\n ) ?? [];\n const awsDestructionTargets = devTargetsFor(openhi.global);\n\n /***************************************************************************\n *\n * Create Workflow\n *\n * Make a new workflow for AWS stack teardown. This runs each night and is\n * also triggered each time a branch is deleted.\n *\n **************************************************************************/\n\n const workflow = new GithubWorkflow(github, \"teardown-dev\");\n workflow.on({\n workflowDispatch: {},\n schedule: [\n {\n cron: \"32 6 * * *\", // Every Sunday at 6:32 AM UTC\n },\n ],\n delete: {\n branches: [\"feature/*\", \"feat/*\", \"fix/*\"],\n },\n /* for debugging \n push: {\n branches: [\"feature/*\"],\n },\n */\n });\n\n awsDestructionTargets.forEach((target) => {\n const {\n awsStageType,\n awsEnvironmentType,\n account,\n region,\n ciDeploymentConfig,\n } = target;\n const { roleArn } = ciDeploymentConfig ?? {};\n\n workflow.addJob(`teardown-${account}-${region}`.toLowerCase(), {\n name: `Teardown Stacks in ${target.account}/${target.region}`,\n //if: \"github.event.ref_type == 'branch'\",\n runsOn: [\"ubuntu-latest\"],\n permissions: {\n contents: JobPermission.READ,\n idToken: JobPermission.WRITE,\n },\n env: {\n REPO: \"${{ github.repository }}\",\n REGIONS: [region].join(\" \"),\n },\n steps: [\n /**\n * Configure AWS creds.\n */\n {\n name: `AWS Creds ${awsStageType}/${awsEnvironmentType}/${account}/${region}`,\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n \"role-to-assume\": roleArn,\n \"aws-region\": region,\n \"role-duration-seconds\": 900, // 15 minutes\n },\n },\n\n /**\n * Fetch all branch names in the repo\n */\n {\n name: \"Fetch All Branches\",\n id: \"fetch_branches\",\n uses: \"actions/github-script@v7\",\n with: {\n script: [\n \"const all = await github.paginate(github.rest.repos.listBranches, {\",\n \" owner: context.repo.owner,\",\n \" repo: context.repo.repo,\",\n \" per_page: 100\",\n \"});\",\n \"const names = all.map(b => b.name);\",\n \"console.log(`Found branches: ${names}`);\",\n 'core.setOutput(\"json\", JSON.stringify(names));',\n ].join(\"\\n\"),\n },\n },\n\n /**\n * Save branches to a file\n */\n {\n name: \"Save Branches to File\",\n run: [\n 'echo \"Saving branches to file\"',\n \"echo '${{ steps.fetch_branches.outputs.json }}' | jq -r '.[]' | sort -u > branches.txt\",\n 'echo \"Branches:\"',\n \"cat branches.txt\",\n ].join(\"\\n\"),\n },\n\n /**\n * Find all stacks tagged with a stage of dev. for this repo. return\n * tag and resource arn.\n */\n {\n name: \"Find Stacks by Tag\",\n id: \"find_stacks\",\n run: [\n \"set -euo pipefail\",\n \": > candidates.txt # columns: arn region branchTag\",\n\n \"# Build tag filters\",\n 'TAG_FILTERS=( \"Key=openhi:repo-name,Values=$REPO\" )',\n `TAG_FILTERS+=( \"Key=openhi:stage-type,Values=${OPEN_HI_STAGE.DEV}\" )`,\n\n \"for r in $REGIONS; do\",\n ` echo \"Scanning region: $r\"`,\n \" aws resourcegroupstaggingapi get-resources \\\\\",\n ' --region \"$r\" \\\\',\n ' --resource-type-filters \"cloudformation:stack\" \\\\',\n ' --tag-filters \"${TAG_FILTERS[@]}\" \\\\',\n ` | jq -r --arg r \"$r\" '`,\n \" .ResourceTagMappingList[]\",\n \" | . as $res\",\n ' | ($res.Tags[] | select(.Key==\"openhi:branch-name\") | .Value) as $branch',\n ' | [$res.ResourceARN, $r, ($branch // \"\")]',\n \" | @tsv\",\n \" ' >> candidates.txt\",\n \"done\",\n\n \"echo 'Tagged stacks:'\",\n `(echo -e \"ARN\\\\tREGION\\\\tBRANCH\"; cat candidates.txt) | column -t -s $'\\\\t'`,\n ].join(\"\\n\"),\n },\n\n /**\n * Determine which stacks are orphans that no longer have a matching branch.\n * Save those to a file for the next step.\n */\n {\n name: \"Determine Orphan Stacks (No Matching Branch)\",\n run: [\n \"set -euo pipefail\",\n \": > orphans.txt # arn region branch\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n ' if [ -z \"$branch\" ]; then',\n \" # If no Branch tag, treat as not-a-preview; skip (or flip to delete if you want)\",\n \" continue\",\n \" fi\",\n ' if ! grep -Fxq \"$branch\" branches.txt; then',\n ' echo -e \"$arn\\\\t$region\\\\t$branch\" >> orphans.txt',\n \" fi\",\n \"done < candidates.txt\",\n \"\",\n \"if [ -s orphans.txt ]; then\",\n ' echo \"Orphan stacks (no matching branch):\"',\n \" (echo -e \\\"ARN\\\\tREGION\\\\tBRANCH\\\"; cat orphans.txt) | column -t -s $'\\\\t'\",\n \"else\",\n ' echo \"No orphan stacks found.\"',\n \"fi\",\n ].join(\"\\n\"),\n },\n\n /**\n * Delete orphan stacks.\n */\n {\n name: \"Delete Orphan Stacks\",\n if: \"hashFiles('orphans.txt') != ''\",\n run: [\n \"set -euo pipefail\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n \" stack_name=$(cut -d'/' -f2 <<<\\\"$arn\\\")\",\n ' echo \"Deleting $stack_name (branch=$branch) in $region\"',\n ' aws cloudformation delete-stack --region \"$region\" --stack-name \"$stack_name\" || true',\n \"done < orphans.txt\",\n ].join(\"\\n\"),\n },\n ],\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * Job-level `if:` condition that restricts the per-PR website deploy to\n * pull-request events plus manual dispatch. Push events to feat/fix/feature\n * branches no longer trigger a website deploy because the OPENHI_PR_NUMBER\n * env var is only resolvable when a PR exists.\n */\nconst PR_GATED_WEBSITE_JOB_IF =\n \"${{ !needs.build.outputs.self_mutation_happened && \" +\n \"(github.event_name == 'pull_request' || \" +\n \"github.event_name == 'workflow_dispatch') }}\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-dev-workflow.md\n */\n\nexport interface BuildDevelopmentWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildDevelopmentWorkflow extends Component {\n constructor(\n parent: MonorepoProject,\n options: BuildDevelopmentWorkflowOptions,\n ) {\n super(parent, \"dev-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets } = new AwsDeployWorkflow(\n openhi.global.project,\n {\n buildWorkflow: parent.buildWorkflow,\n },\n );\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n *\n * Deploy the Rest API service after Data (and Global).\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n *\n * Deploy the GraphQL API service after Data (sibling to REST API).\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n const websiteDeploy = new AwsDeployWorkflow(openhi.website.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n\n /**\n * Per-PR preview wiring for the website deploy:\n *\n * 1. Trigger the build workflow on PR events so feature-branch deploys\n * have a PR number to address themselves with\n * (`admin-pr-<N>.<zone>`).\n * 2. Inject `OPENHI_PR_NUMBER` at the workflow env level so\n * `OpenHiWebsiteService` resolves it via the same fallback path it\n * uses for the `prNumber` prop.\n * 3. Gate every `*-deploy-openhi-website-*` job to `pull_request` +\n * `workflow_dispatch` only — push-to-branch no longer triggers a\n * website deploy (a website deploy requires a PR for its hostname).\n * Other services' deploy jobs are unchanged.\n */\n const buildWorkflow = parent.buildWorkflow;\n if (!buildWorkflow) {\n throw new Error(\"BuildDevelopmentWorkflow requires a buildWorkflow\");\n }\n const ghWorkflow = buildWorkflow.workflow;\n ghWorkflow.on({\n pullRequest: {\n types: [\"opened\", \"synchronize\", \"reopened\"],\n },\n });\n ghWorkflow.file?.addOverride(\n \"env.OPENHI_PR_NUMBER\",\n \"${{ github.event.pull_request.number || '' }}\",\n );\n websiteDeploy.awsDeploymentTargets.forEach((target) => {\n const jobId = [\n target.awsStageType,\n target.deploymentTargetRole,\n \"deploy\",\n target.project.name,\n target.account,\n target.region,\n ].join(\"-\");\n const job = ghWorkflow.getJob(jobId);\n ghWorkflow.updateJob(jobId, {\n ...job,\n if: PR_GATED_WEBSITE_JOB_IF,\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-stage-workflow.md\n */\n\nexport interface BuildStageWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildStageWorkflow extends Component {\n constructor(parent: MonorepoProject, options: BuildStageWorkflowOptions) {\n super(parent, \"stage-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets, buildWorkflow } =\n new AwsDeployWorkflow(openhi.global.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflowOptions: {\n name: \"deploy-stage\",\n workflowTriggers: {\n push: {\n branches: [\"main\"],\n },\n workflowDispatch: {},\n },\n },\n });\n\n // Inject OPENHI_PR_NUMBER at the workflow env level so it propagates\n // to every job (including the website deploy job). Release-branch\n // deploys ignore this value (no PR exists on a main push); the env is\n // included so OpenHiWebsiteService resolves consistently across\n // workflows. See BuildDevelopmentWorkflow for the PR-event wiring on\n // the dev side.\n buildWorkflow.workflow.file?.addOverride(\n \"env.OPENHI_PR_NUMBER\",\n \"${{ github.event.pull_request.number || '' }}\",\n );\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n * Auth creates the stage build workflow; data service and REST API services add to it.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n new AwsDeployWorkflow(openhi.website.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n }\n}\n"],"mappings":"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","names":["import_config","sep","sep","import_config","Component","import_config","AwsDeployWorkflow","Component"]}
1
+ {"version":3,"sources":["../../config/src/open-hi-config.ts","../../config/src/index.ts","../src/openhi.ts","../src/service.ts","../src/templates/service-template.ts","../src/templates/src/app.ts","../src/templates/src/app-test.ts","../src/templates/src/config.ts","../src/templates/src/data/models/README.md.ts","../src/templates/src/data/README.md.ts","../src/templates/src/infrastructure/README.md.ts","../src/templates/src/integrations/README.md.ts","../src/templates/src/main.ts","../src/templates/src/README.md.ts","../src/templates/src/workflows/README.md.ts","../src/templates/generate-templates.ts","../src/workflows/aws-teardown-workflow.ts","../src/workflows/build-dev-workflow.ts","../src/workflows/build-stage-workflow.ts"],"sourcesContent":["/*******************************************************************************\n *\n * OpenHi Config\n *\n * These types are kept in their own package to prevent dependency conflicts and\n * conditions between @openhi/constructs and @openhi/platform..\n *\n ******************************************************************************/\n\n/**\n * Stage Types\n *\n * What stage of deployment is this? Dev, staging, or prod?\n */\nexport const OPEN_HI_STAGE = {\n /**\n * Development environment, typically used for testing and development.\n */\n DEV: \"dev\",\n /**\n * Staging environment, used for pre-production testing.\n */\n STAGE: \"stage\",\n /**\n * Production environment, used for live deployments.\n */\n PROD: \"prod\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiStageType =\n (typeof OPEN_HI_STAGE)[keyof typeof OPEN_HI_STAGE];\n\n/**\n * Deployment Target Role\n *\n * Is this (account, region) the primary or a secondary deployment target for the stage?\n * Works for both multi-region (different regions) and cellular (same region, different accounts).\n */\nexport const OPEN_HI_DEPLOYMENT_TARGET_ROLE = {\n /**\n * The primary deployment target for this stage (main account/region).\n * For example, the base DynamoDB region for global tables.\n */\n PRIMARY: \"primary\",\n\n /**\n * A secondary deployment target for this stage (additional account/region).\n * For example, a replica region for a global DynamoDB table, or another cell in the same region.\n */\n SECONDARY: \"secondary\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type OpenHiDeploymentTargetRoleType =\n (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];\n\nexport interface OpenHiEnvironmentConfig {\n account: string;\n region: string;\n /**\n * Route53 zone containing DNS for this service.\n */\n hostedZoneId?: string;\n zoneName?: string;\n}\n\n/**\n * Represents the configuration for OpenHi services across different stages and\n * deployment targets.\n */\nexport interface OpenHiConfig {\n versions?: {\n cdk?: {\n cdkLibVersion?: string;\n cdkCliVersion?: string;\n };\n };\n deploymentTargets?: {\n [OPEN_HI_STAGE.DEV]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.STAGE]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n [OPEN_HI_STAGE.PROD]?: {\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]?: OpenHiEnvironmentConfig;\n [OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]?: Array<OpenHiEnvironmentConfig>;\n };\n };\n}\n","export * from \"./open-hi-config\";\n","import {\n MonorepoProject,\n MonorepoProjectOptions,\n} from \"@codedrifters/configulator\";\nimport { OpenHiConfig } from \"@openhi/config\";\nimport { merge } from \"ts-deepmerge\";\nimport { SetOptional } from \"type-fest\";\nimport { OPEN_HI_SERVICE_TYPE, OpenHiService } from \"./service\";\nimport { AwsTeardownWorkflow } from \"./workflows/aws-teardown-workflow\";\nimport { BuildDevelopmentWorkflow } from \"./workflows/build-dev-workflow\";\nimport { BuildStageWorkflow } from \"./workflows/build-stage-workflow\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/openhi.md\n */\n\nexport interface OpenHiOptions {\n /*****************************************************************************\n *\n * Root Project Configuration Options\n *\n * Configuration options for the root monorepo project that contains all\n * OpenHi services and coordinate releases and builds.\n *\n ****************************************************************************/\n\n readonly rootProjectOptions?: SetOptional<MonorepoProjectOptions, \"name\">;\n\n /**\n * Monorepo root project, if using an existing project.\n */\n readonly rootProject?: MonorepoProject;\n\n /*****************************************************************************\n *\n * Service Configuration Options\n *\n * These options are used to configure the various services within the OpenHi\n * framework. Each service can have its own configuration settings, which will\n * be merged with the default configuration.\n *\n ****************************************************************************/\n\n /**\n * Default configuration used in all services with undefined configs.\n */\n readonly defaultConfig?: OpenHiConfig;\n\n /**\n * Global Service Config\n */\n readonly globalServiceConfig?: OpenHiConfig;\n\n /**\n * Auth Service Config\n */\n readonly authServiceConfig?: OpenHiConfig;\n\n /**\n * Rest API Service Config\n */\n readonly restApiServiceConfig?: OpenHiConfig;\n\n /**\n * Data Service Config (DynamoDB FHIR store, S3, etc.)\n */\n readonly dataServiceConfig?: OpenHiConfig;\n\n /**\n * GraphQL API Service Config\n */\n readonly graphApiServiceConfig?: OpenHiConfig;\n\n /**\n * Website Service Config (static hosting + content uploader).\n */\n readonly websiteServiceConfig?: OpenHiConfig;\n}\n\nexport class OpenHi {\n /**\n * Final options used to build this instance.\n */\n public options: OpenHiOptions;\n\n /**\n * Monorepo root project, either passed in as an argument or generated in\n * this component\n */\n public readonly rootProject?: MonorepoProject;\n\n /**\n * Test identifier for this instance.\n */\n public readonly id: string;\n\n /**\n * Global service (deployed first; Auth, data service, and other stacks depend on it).\n */\n public readonly global: OpenHiService;\n\n /**\n * Auth service (deployed first; data service, REST API, and data services depend on it).\n */\n public readonly auth: OpenHiService;\n\n /**\n * Rest API service\n */\n public readonly restApi: OpenHiService;\n\n /**\n * Data service (DynamoDB FHIR store, S3, and other persistence).\n */\n public readonly data: OpenHiService;\n\n /**\n * GraphQL API service (AppSync); deploys as sibling to REST API after Data.\n */\n public readonly graphApi: OpenHiService;\n\n /**\n * Website service (static hosting + content uploader); deploys as sibling\n * to the other services after Global.\n */\n public readonly website: OpenHiService;\n\n constructor(options: OpenHiOptions = {}) {\n /***************************************************************************\n *\n * Options\n *\n * Combine input options with defaults.\n *\n **************************************************************************/\n\n this.options = merge({ name: \"openhi\" }, options);\n this.rootProject = this.options.rootProject;\n this.id = this.options.rootProject?.name ?? \"openhi\";\n\n /**\n * In future we would create root project here. For now, require it to be\n * passed in.\n */\n if (!this.rootProject) {\n throw new Error(\n \"OpenHi requires a MonorepoProject to be passed in via the rootProject option\",\n );\n }\n\n const rootProject = this.rootProject;\n\n /***************************************************************************\n *\n * Global Service\n *\n * Global infrastructure (Route53, ACM). Deployed first in primary;\n * Auth, data service, and other stacks depend on it.\n *\n **************************************************************************/\n\n this.global = new OpenHiService(this, \"global\", {\n type: OPEN_HI_SERVICE_TYPE.GLOBAL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.globalServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Auth Service\n *\n * Authentication (Cognito user pool, client, domain, KMS). Deployed first;\n * data service, REST API, and data services consume auth via SSM.\n *\n **************************************************************************/\n\n this.auth = new OpenHiService(this, \"auth\", {\n type: OPEN_HI_SERVICE_TYPE.AUTH,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.authServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Rest API service\n *\n * This contains the REST API for the OpenHi platform.\n *\n **************************************************************************/\n\n this.restApi = new OpenHiService(this, \"rest-api\", {\n type: OPEN_HI_SERVICE_TYPE.REST_API,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.restApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Data Service\n *\n * Data storage stack (DynamoDB FHIR store, S3, etc.). Deployed so that\n * REST API and other services can reference the table via cross-stack.\n *\n **************************************************************************/\n\n this.data = new OpenHiService(this, \"data\", {\n type: OPEN_HI_SERVICE_TYPE.DATA_SERVICE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.dataServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * GraphQL API service\n *\n * AppSync API; deploys as sibling to REST API after Data.\n *\n **************************************************************************/\n\n this.graphApi = new OpenHiService(this, \"graphql\", {\n type: OPEN_HI_SERVICE_TYPE.GRAPHQL,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.graphApiServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Website service\n *\n * Static hosting (CloudFront + S3 + Lambda@Edge) and content uploader;\n * deploys as a sibling to the other services after Global.\n *\n **************************************************************************/\n\n this.website = new OpenHiService(this, \"website\", {\n type: OPEN_HI_SERVICE_TYPE.WEBSITE,\n config: merge(\n this.options?.defaultConfig ?? {},\n this.options?.websiteServiceConfig ?? {},\n ),\n });\n\n /***************************************************************************\n *\n * Integrations\n *\n * Various purpose specific integrations.\n *\n **************************************************************************/\n\n /***************************************************************************\n *\n * Workflows\n *\n * Workflows for each environment.\n *\n **************************************************************************/\n\n new BuildDevelopmentWorkflow(rootProject, { openhi: this });\n new BuildStageWorkflow(rootProject, { openhi: this });\n\n new AwsTeardownWorkflow(rootProject, { openhi: this });\n }\n}\n","import { sep } from \"path\";\nimport {\n AwsDeploymentTarget,\n TurboRepo,\n VERSION,\n} from \"@codedrifters/configulator\";\nimport {\n OPEN_HI_DEPLOYMENT_TARGET_ROLE,\n OPEN_HI_STAGE,\n OpenHiConfig,\n OpenHiEnvironmentConfig,\n} from \"@openhi/config\";\nimport { paramCase, pascalCase } from \"change-case\";\nimport { awscdk } from \"projen\";\nimport { NodePackageManager, Transform } from \"projen/lib/javascript\";\nimport { ValueOf } from \"type-fest\";\nimport { OpenHi } from \"./openhi\";\nimport { GenerateTemplates } from \"./templates/generate-templates\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/service.md\n */\n\nexport const OPEN_HI_SERVICE_TYPE = {\n AUTH: \"auth\",\n DATA_SERVICE: \"data\",\n GLOBAL: \"global\",\n GRAPHQL: \"graphql\",\n INTEGRATION: \"integration\",\n REST_API: \"rest-api\",\n WEBSITE: \"website\",\n} as const;\n\nexport interface OpenHiServiceOptions {\n /**\n * Configuration for this service.\n *\n * @default uses the global default config.\n */\n readonly config: OpenHiConfig;\n\n /**\n * What type of service is this?\n */\n readonly type: ValueOf<typeof OPEN_HI_SERVICE_TYPE>;\n}\n\nexport class OpenHiService {\n public readonly project: awscdk.AwsCdkTypeScriptApp;\n\n constructor(\n public openHi: OpenHi,\n public id: string,\n public options: OpenHiServiceOptions,\n ) {\n /**\n * Build the construct name we expect to use in this service.\n */\n\n /***************************************************************************\n *\n * Projen based CDK build\n *\n **************************************************************************/\n\n this.project = new awscdk.AwsCdkTypeScriptApp({\n /**\n * Top level project config options\n */\n defaultReleaseBranch: \"main\",\n name: this.serviceName,\n outdir: this.outDir,\n parent: this.openHi.rootProject,\n cdkVersion:\n this.options?.config?.versions?.cdk?.cdkLibVersion ??\n VERSION.AWS_CDK_LIB_VERSION,\n cdkCliVersion:\n this.options?.config?.versions?.cdk?.cdkCliVersion ??\n VERSION.AWS_CDK_CLI_VERSION,\n\n /**\n * Packaging options\n *\n * TODO: Figure out license for monorepo vs per package?\n */\n licensed: false,\n\n /**\n * Node configs\n */\n packageManager: NodePackageManager.PNPM,\n\n /**\n * Turn on prettier formatting\n */\n prettier: true,\n\n /**\n * Don't generate sample code.\n */\n sampleCode: false,\n\n /**\n * Make sure jest config is stored outside of package.json and use SWC\n * for faster tests.\n */\n jestOptions: {\n configFilePath: \"jest.config.json\",\n jestConfig: {\n transform: {\n [\"^.+\\\\.[t]sx?$\"]: new Transform(\"@swc/jest\"),\n },\n },\n },\n\n /**\n * SWC for faster testing\n */\n devDeps: [\"@swc/jest\", \"@swc/core\"],\n\n /**\n * Don't package test files.\n */\n npmIgnoreOptions: {\n ignorePatterns: [\"*.spec.*\", \"*.test.*\"],\n },\n });\n\n /**\n * We're using SWC now, remove ts-jest which is included by default.\n */\n this.project.deps.removeDependency(\"ts-jest\");\n\n /***************************************************************************\n *\n * Workspace Dependencies\n *\n * - Constructs are used to build out the AWS CDK environments.\n *\n **************************************************************************/\n\n this.project.addDeps(\n \"@openhi/config@workspace:*\",\n \"@openhi/constructs@workspace:*\",\n );\n\n /***************************************************************************\n *\n * Turbo Configuration\n *\n * - Activate turborepo for the project.\n *\n **************************************************************************/\n\n new TurboRepo(this.project);\n\n TurboRepo.of(this.project)?.activateBranchNameEnvVar({\n tasks: [\"post-compile\"],\n });\n\n /**\n * The website's CDK app uploads the admin-console SPA build (the\n * `dist/` directory the Vite build emits) to S3 in place of the\n * hand-written `content/` placeholder. Declaring the workspace\n * dep here both makes the package resolvable at synth time (via\n * `require.resolve(\"@codedrifters/admin-console/package.json\")`\n * in `openhi/website/src/app.ts`) and threads\n * `@codedrifters/admin-console#turbo:build` into the website's\n * `post-compile.dependsOn` so turbo builds the SPA before the\n * website synth runs.\n */\n if (this.options.type === OPEN_HI_SERVICE_TYPE.WEBSITE) {\n this.project.addDeps(\"@codedrifters/admin-console@workspace:*\");\n }\n\n /***************************************************************************\n *\n * Define some basic Service Structure\n *\n **************************************************************************/\n\n new GenerateTemplates(this);\n\n /***************************************************************************\n *\n * Deployment Targets\n *\n **************************************************************************/\n\n [OPEN_HI_STAGE.DEV, OPEN_HI_STAGE.STAGE, OPEN_HI_STAGE.PROD].forEach(\n (stage) => {\n const targets = this.options?.config?.deploymentTargets?.[stage];\n if (targets?.primary) {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,\n targets.primary,\n );\n }\n targets?.secondary?.forEach((env) => {\n this.addDeploymentTarget(\n stage,\n OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,\n env,\n );\n });\n },\n );\n }\n\n private addDeploymentTarget = (\n awsStageType: ValueOf<typeof OPEN_HI_STAGE>,\n awsEnvironmentType: ValueOf<typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE>,\n envConfig: OpenHiEnvironmentConfig,\n ) => {\n new AwsDeploymentTarget(this.project, {\n account: envConfig.account,\n region: envConfig.region,\n awsStageType,\n awsEnvironmentType,\n localDeployment: true,\n localDeploymentConfig: {\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n roleName: \"poweruseraccess\",\n },\n ciDeployment: true,\n ciDeploymentConfig: {\n roleArn: `arn:aws:iam::${envConfig.account}:role/GitHubOpenHiDeployer`,\n stackPattern: `${awsStageType}/${awsEnvironmentType}/*-${envConfig.account}-${envConfig.region}`,\n },\n\n branches:\n awsStageType === OPEN_HI_STAGE.DEV\n ? [\n {\n branch: \"feat/*\",\n description: [\n \"Feature branches for OpenHI (short form).\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"feature/*\",\n description: [\n \"Feature branches for OpenHI.\",\n \"These branches are used for developing new features.\",\n ],\n },\n {\n branch: \"fix/*\",\n description: [\n \"Fix branches for OpenHI.\",\n \"This branch pattern is used when a developer is working on a fix on the project.\",\n ],\n },\n ]\n : [\n {\n branch: \"main\",\n description: [\n \"Main branch for OpenHI.\",\n \"This branch is used for the main branch.\",\n ],\n },\n ],\n });\n };\n\n get constructName(): string {\n return pascalCase([\"open\", \"hi\", this.id, \"service\"].join(\"-\"));\n }\n\n get outDir() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(sep);\n }\n\n get serviceName() {\n return [paramCase(this.openHi.id), paramCase(this.id)].join(\"-\");\n }\n}\n","import { existsSync, unlinkSync } from \"node:fs\";\nimport { sep } from \"node:path\";\nimport { SampleFile } from \"projen\";\nimport { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/service-template.md\n */\n\nexport interface ServiceTemplateOptions {\n /**\n * The content of the sample file, as an array.\n */\n readonly contents: Array<string>;\n\n /**\n * The relative file path from the project root.\n */\n readonly filePath: string;\n\n /**\n * Overwrite this template file to it's original state?\n *\n * @default false\n */\n readonly overwrite?: boolean;\n}\n\nexport class ServiceTemplate {\n /**\n * The file being generated.\n */\n public file?: SampleFile;\n\n /**\n * Absolute Filepath, including the project path.\n */\n public fullFilePath: string;\n\n constructor(\n public service: OpenHiService,\n public options: ServiceTemplateOptions,\n ) {\n /**\n * Determine the full file path for this file.\n */\n this.fullFilePath = [\n this.service.project.outdir,\n this.options.filePath,\n ].join(sep);\n\n /**\n * Build the template file.\n */\n this.createTemplate();\n }\n\n protected createTemplate() {\n if (this.options.overwrite) {\n this.overwriteTemplate();\n }\n\n this.file = new SampleFile(this.service.project, this.options.filePath, {\n contents: this.options.contents.join(\"\\n\"),\n });\n }\n\n public overwriteTemplate() {\n /**\n * Delete file, if it exists.\n */\n if (existsSync(this.fullFilePath)) {\n unlinkSync(this.fullFilePath);\n }\n this.file = undefined;\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app.md\n */\n\nexport class SrcApp extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.ts\",\n contents: [\n `import { OpenHiApp, ${service.constructName} } from \"@openhi/constructs\";`,\n `import { CONFIG } from \"./config\";`,\n ``,\n `const app = new OpenHiApp({ config: CONFIG });`,\n ``,\n `const stacks = app.environments.map((e) => {`,\n ` return new ${service.constructName}(e, { config: e.config });`,\n `});`,\n ``,\n `export { app, stacks };`,\n ``,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/app-test.md\n */\n\nexport class SrcAppTest extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/app.test.ts\",\n contents: [\n `import { Template } from \"aws-cdk-lib/assertions\";`,\n `import { Code, type CodeConfig } from \"aws-cdk-lib/aws-lambda\";`,\n `import { stacks } from \"./app\"`,\n ``,\n `/** Replace volatile CDK asset S3 keys/buckets with static values for snapshot stability. */`,\n `function normalizeTemplateForSnapshot(template: Record<string, unknown>): Record<string, unknown> {`,\n ` const staticBucket = \"mock-assets-bucket\";`,\n ` const staticKey = \"mock-asset-key.zip\";`,\n ` const json = JSON.stringify(template);`,\n ` const normalized = json`,\n ` .replace(/\"S3Key\":\\\\s*\"[^\"]+\\\\.zip\"/g, \\`\"S3Key\": \"\\${staticKey}\"\\`)`,\n ` .replace(/\"S3Bucket\":\\\\s*\"[^\"]+\"/g, \\`\"S3Bucket\": \"\\${staticBucket}\"\\`);`,\n ` return JSON.parse(normalized) as Record<string, unknown>;`,\n `}`,\n ``,\n `let fromAssetMock: jest.SpyInstance;`,\n ``,\n `beforeAll(() => {`,\n ` fromAssetMock = jest.spyOn(Code, \"fromAsset\").mockReturnValue({`,\n ` isInline: false,`,\n ` bind: (): CodeConfig => ({`,\n ` s3Location: {`,\n ` bucketName: \"mock-assets-bucket\",`,\n ` objectKey: \"mock-asset-key.zip\",`,\n ` },`,\n ` }),`,\n ` bindToResource: () => {`,\n ` return;`,\n ` },`,\n ` } as any);`,\n `});`,\n ``,\n `afterAll(() => {`,\n ` fromAssetMock?.mockRestore();`,\n `});`,\n ``,\n `describe(\"Smoke Test\", () => {`,\n ` it(\"should match previous snapshots\", () => {`,\n ` stacks.forEach((s) => {`,\n ` const template = Template.fromStack(s).toJSON();`,\n ` expect(normalizeTemplateForSnapshot(template)).toMatchSnapshot();`,\n ` });`,\n ` });`,\n `});`,\n ``,\n ],\n });\n }\n}\n","import { SourceCode } from \"projen\";\nimport { OpenHiService } from \"../../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/config.md\n */\n\nexport class SrcConfig extends SourceCode {\n constructor(service: OpenHiService) {\n super(service.project, \"src/config.ts\");\n\n /**\n * Imports\n */\n this.line(`import { OpenHiConfig } from \"@openhi/config\";`);\n this.line(\"\");\n\n /**\n * Write the config content\n */\n const start = \"export const CONFIG: OpenHiConfig = \";\n const mid = JSON.stringify(service.options?.config, null, 2);\n const end = \" as const;\";\n this.line(`${start}${mid}${end}`);\n }\n}\n","import { OpenHiService } from \"../../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/models/readme.md\n */\n\nexport class DataModelsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/models/README.md\",\n contents: [\n `# ${service.serviceName}: Data Models`,\n ``,\n `This directory contains data model definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/data/readme.md\n */\n\nexport class DataReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/data/README.md\",\n contents: [\n `# ${service.serviceName}: Data`,\n ``,\n `This directory contains data models and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/infrastructure/readme.md\n */\n\nexport class InfrastructureReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/infrastructure/README.md\",\n contents: [\n `# ${service.serviceName}: Infrastructure`,\n ``,\n `This directory contains infrastructure definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/integrations/readme.md\n */\n\nexport class IntegrationsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/integrations/README.md\",\n contents: [\n `# ${service.serviceName}: Integrations`,\n ``,\n `This directory contains integration definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/main.md\n */\n\nexport class SrcMain extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/main.ts\",\n contents: [`import { app } from \"./app\";`, ``, `app.synth();`, ``],\n });\n }\n}\n","import { OpenHiService } from \"../../service\";\nimport { ServiceTemplate, ServiceTemplateOptions } from \"../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/readme.md\n */\n\nexport class SrcReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/README.md\",\n contents: [\n `# ${service.serviceName}: Service Overview`,\n ``,\n `This directory contains the main entry point for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../../../service\";\nimport {\n ServiceTemplate,\n ServiceTemplateOptions,\n} from \"../../service-template\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/src/workflows/readme.md\n */\n\nexport class WorkflowsReadMe extends ServiceTemplate {\n constructor(\n service: OpenHiService,\n options?: Partial<ServiceTemplateOptions>,\n ) {\n super(service, {\n ...options,\n filePath: \"src/workflows/README.md\",\n contents: [\n `# ${service.serviceName}: Workflows`,\n ``,\n `This directory contains workflow definitions and other related files for the ${service.serviceName} service.`,\n ],\n });\n }\n}\n","import { OpenHiService } from \"../service\";\nimport { SrcApp } from \"./src/app\";\nimport { SrcAppTest } from \"./src/app-test\";\nimport { SrcConfig } from \"./src/config\";\nimport { DataModelsReadMe } from \"./src/data/models/README.md\";\nimport { DataReadMe } from \"./src/data/README.md\";\nimport { InfrastructureReadMe } from \"./src/infrastructure/README.md\";\nimport { IntegrationsReadMe } from \"./src/integrations/README.md\";\nimport { SrcMain } from \"./src/main\";\nimport { SrcReadMe } from \"./src/README.md\";\nimport { WorkflowsReadMe } from \"./src/workflows/README.md\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/templates/generate-templates.md\n */\n\nexport class GenerateTemplates {\n constructor(private service: OpenHiService) {\n /**\n * Root src templates\n */\n new SrcApp(this.service);\n new SrcAppTest(this.service);\n new SrcConfig(this.service);\n new SrcMain(this.service);\n new SrcReadMe(this.service);\n\n /**\n * Data\n */\n new DataReadMe(this.service);\n new DataModelsReadMe(this.service);\n\n /**\n * Infrastructure\n */\n new InfrastructureReadMe(this.service);\n\n /**\n * Integrations\n */\n new IntegrationsReadMe(this.service);\n\n /**\n * Workflows\n */\n new WorkflowsReadMe(this.service);\n }\n}\n","import {\n AwsDeploymentConfig,\n MonorepoProject,\n} from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { GitHub, GithubWorkflow } from \"projen/lib/github\";\nimport { JobPermission } from \"projen/lib/github/workflows-model\";\nimport { OpenHi } from \"../openhi\";\nimport type { OpenHiService } from \"../service\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/aws-teardown-workflow.md\n */\n\nexport interface AwsTeardownWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class AwsTeardownWorkflow extends Component {\n constructor(\n public rootProject: MonorepoProject,\n options: AwsTeardownWorkflowOptions,\n ) {\n super(rootProject);\n\n const { openhi } = options;\n\n /***************************************************************************\n *\n * Root project check\n *\n * Detect the root project and ensure it's of type MonorepoProject.\n *\n **************************************************************************/\n\n if (!(rootProject instanceof MonorepoProject)) {\n throw new Error(\n \"AwsTeardownWorkflow requires the root project to be a MonorepoProject\",\n );\n }\n\n //this.rootProject = project.root;\n\n /***************************************************************************\n *\n * GitHub Check\n *\n * Make sure github config is active in the project. This is to ensure all\n * workflows will be output properly during synth.\n *\n **************************************************************************/\n\n const github = GitHub.of(this.rootProject);\n\n if (!github) {\n throw new Error(\n \"AwsTeardownWorkflow requires a GitHub component in the root project\",\n );\n }\n\n /***************************************************************************\n *\n * Workflow Destroy Targets\n *\n * Find all the CI targets for the Global project in the DEV stage\n * only. One job per (account, region) teardowns all orphan stacks (Auth,\n * Core, data) in that account/region.\n *\n **************************************************************************/\n\n const devTargetsFor = (service: OpenHiService) =>\n AwsDeploymentConfig.of(service.project)?.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === OPEN_HI_STAGE.DEV && target.ciDeployment,\n ) ?? [];\n const awsDestructionTargets = devTargetsFor(openhi.global);\n\n /***************************************************************************\n *\n * Create Workflow\n *\n * Make a new workflow for AWS stack teardown. This runs each night and is\n * also triggered each time a branch is deleted.\n *\n **************************************************************************/\n\n const workflow = new GithubWorkflow(github, \"teardown-dev\");\n workflow.on({\n workflowDispatch: {},\n schedule: [\n {\n cron: \"32 6 * * *\", // Every Sunday at 6:32 AM UTC\n },\n ],\n delete: {\n branches: [\"feature/*\", \"feat/*\", \"fix/*\"],\n },\n /* for debugging \n push: {\n branches: [\"feature/*\"],\n },\n */\n });\n\n awsDestructionTargets.forEach((target) => {\n const {\n awsStageType,\n awsEnvironmentType,\n account,\n region,\n ciDeploymentConfig,\n } = target;\n const { roleArn } = ciDeploymentConfig ?? {};\n\n workflow.addJob(`teardown-${account}-${region}`.toLowerCase(), {\n name: `Teardown Stacks in ${target.account}/${target.region}`,\n //if: \"github.event.ref_type == 'branch'\",\n runsOn: [\"ubuntu-latest\"],\n permissions: {\n contents: JobPermission.READ,\n idToken: JobPermission.WRITE,\n },\n env: {\n REPO: \"${{ github.repository }}\",\n REGIONS: [region].join(\" \"),\n },\n steps: [\n /**\n * Configure AWS creds.\n */\n {\n name: `AWS Creds ${awsStageType}/${awsEnvironmentType}/${account}/${region}`,\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n \"role-to-assume\": roleArn,\n \"aws-region\": region,\n \"role-duration-seconds\": 900, // 15 minutes\n },\n },\n\n /**\n * Fetch all branch names in the repo\n */\n {\n name: \"Fetch All Branches\",\n id: \"fetch_branches\",\n uses: \"actions/github-script@v7\",\n with: {\n script: [\n \"const all = await github.paginate(github.rest.repos.listBranches, {\",\n \" owner: context.repo.owner,\",\n \" repo: context.repo.repo,\",\n \" per_page: 100\",\n \"});\",\n \"const names = all.map(b => b.name);\",\n \"console.log(`Found branches: ${names}`);\",\n 'core.setOutput(\"json\", JSON.stringify(names));',\n ].join(\"\\n\"),\n },\n },\n\n /**\n * Save branches to a file\n */\n {\n name: \"Save Branches to File\",\n run: [\n 'echo \"Saving branches to file\"',\n \"echo '${{ steps.fetch_branches.outputs.json }}' | jq -r '.[]' | sort -u > branches.txt\",\n 'echo \"Branches:\"',\n \"cat branches.txt\",\n ].join(\"\\n\"),\n },\n\n /**\n * Find all stacks tagged with a stage of dev. for this repo. return\n * tag and resource arn.\n */\n {\n name: \"Find Stacks by Tag\",\n id: \"find_stacks\",\n run: [\n \"set -euo pipefail\",\n \": > candidates.txt # columns: arn region branchTag\",\n\n \"# Build tag filters\",\n 'TAG_FILTERS=( \"Key=openhi:repo-name,Values=$REPO\" )',\n `TAG_FILTERS+=( \"Key=openhi:stage-type,Values=${OPEN_HI_STAGE.DEV}\" )`,\n\n \"for r in $REGIONS; do\",\n ` echo \"Scanning region: $r\"`,\n \" aws resourcegroupstaggingapi get-resources \\\\\",\n ' --region \"$r\" \\\\',\n ' --resource-type-filters \"cloudformation:stack\" \\\\',\n ' --tag-filters \"${TAG_FILTERS[@]}\" \\\\',\n ` | jq -r --arg r \"$r\" '`,\n \" .ResourceTagMappingList[]\",\n \" | . as $res\",\n ' | ($res.Tags[] | select(.Key==\"openhi:branch-name\") | .Value) as $branch',\n ' | [$res.ResourceARN, $r, ($branch // \"\")]',\n \" | @tsv\",\n \" ' >> candidates.txt\",\n \"done\",\n\n \"echo 'Tagged stacks:'\",\n `(echo -e \"ARN\\\\tREGION\\\\tBRANCH\"; cat candidates.txt) | column -t -s $'\\\\t'`,\n ].join(\"\\n\"),\n },\n\n /**\n * Determine which stacks are orphans that no longer have a matching branch.\n * Save those to a file for the next step.\n */\n {\n name: \"Determine Orphan Stacks (No Matching Branch)\",\n run: [\n \"set -euo pipefail\",\n \": > orphans.txt # arn region branch\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n ' if [ -z \"$branch\" ]; then',\n \" # If no Branch tag, treat as not-a-preview; skip (or flip to delete if you want)\",\n \" continue\",\n \" fi\",\n ' if ! grep -Fxq \"$branch\" branches.txt; then',\n ' echo -e \"$arn\\\\t$region\\\\t$branch\" >> orphans.txt',\n \" fi\",\n \"done < candidates.txt\",\n \"\",\n \"if [ -s orphans.txt ]; then\",\n ' echo \"Orphan stacks (no matching branch):\"',\n \" (echo -e \\\"ARN\\\\tREGION\\\\tBRANCH\\\"; cat orphans.txt) | column -t -s $'\\\\t'\",\n \"else\",\n ' echo \"No orphan stacks found.\"',\n \"fi\",\n ].join(\"\\n\"),\n },\n\n /**\n * Delete orphan stacks.\n */\n {\n name: \"Delete Orphan Stacks\",\n if: \"hashFiles('orphans.txt') != ''\",\n run: [\n \"set -euo pipefail\",\n \"while IFS=$'\\\\t' read -r arn region branch; do\",\n ' [ -z \"$arn\" ] && continue',\n \" stack_name=$(cut -d'/' -f2 <<<\\\"$arn\\\")\",\n ' echo \"Deleting $stack_name (branch=$branch) in $region\"',\n ' aws cloudformation delete-stack --region \"$region\" --stack-name \"$stack_name\" || true',\n \"done < orphans.txt\",\n ].join(\"\\n\"),\n },\n ],\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * Job-level `if:` condition that restricts the per-PR website deploy to\n * pull-request events plus manual dispatch. The website hostname is now\n * derivable from `branchName` alone, so the strict PR gate is no longer\n * required for hostname resolution; the gate is preserved here to avoid\n * spawning per-branch deploys for every push and is revisited under a\n * follow-up issue.\n */\nconst PR_GATED_WEBSITE_JOB_IF =\n \"${{ !needs.build.outputs.self_mutation_happened && \" +\n \"(github.event_name == 'pull_request' || \" +\n \"github.event_name == 'workflow_dispatch') }}\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-dev-workflow.md\n */\n\nexport interface BuildDevelopmentWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildDevelopmentWorkflow extends Component {\n constructor(\n parent: MonorepoProject,\n options: BuildDevelopmentWorkflowOptions,\n ) {\n super(parent, \"dev-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets } = new AwsDeployWorkflow(\n openhi.global.project,\n {\n buildWorkflow: parent.buildWorkflow,\n },\n );\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n *\n * Deploy the Rest API service after Data (and Global).\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n *\n * Deploy the GraphQL API service after Data (sibling to REST API).\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n const websiteDeploy = new AwsDeployWorkflow(openhi.website.project, {\n buildWorkflow: parent.buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n\n /**\n * Per-PR preview wiring for the website deploy:\n *\n * 1. Trigger the build workflow on PR events so feature-branch deploys\n * run on every push to a PR. The per-PR hostname is derived from\n * `branchName` (e.g. `admin-feat-1093-patient-migration.<zone>`),\n * not a PR number, so no env-var injection is needed.\n * 2. Gate every `*-deploy-openhi-website-*` job to `pull_request` +\n * `workflow_dispatch` only. Other services' deploy jobs are\n * unchanged.\n */\n const buildWorkflow = parent.buildWorkflow;\n if (!buildWorkflow) {\n throw new Error(\"BuildDevelopmentWorkflow requires a buildWorkflow\");\n }\n const ghWorkflow = buildWorkflow.workflow;\n ghWorkflow.on({\n pullRequest: {\n types: [\"opened\", \"synchronize\", \"reopened\"],\n },\n });\n websiteDeploy.awsDeploymentTargets.forEach((target) => {\n const jobId = [\n target.awsStageType,\n target.deploymentTargetRole,\n \"deploy\",\n target.project.name,\n target.account,\n target.region,\n ].join(\"-\");\n const job = ghWorkflow.getJob(jobId);\n ghWorkflow.updateJob(jobId, {\n ...job,\n if: PR_GATED_WEBSITE_JOB_IF,\n });\n });\n }\n}\n","import { AwsDeployWorkflow, MonorepoProject } from \"@codedrifters/configulator\";\nimport { OPEN_HI_STAGE } from \"@openhi/config\";\nimport { Component } from \"projen\";\nimport { OpenHi } from \"../openhi\";\n\n/**\n * @see sites/www-docs/content/packages/@openhi/platform/workflows/build-stage-workflow.md\n */\n\nexport interface BuildStageWorkflowOptions {\n /**\n * openhi project\n */\n readonly openhi: OpenHi;\n}\n\nexport class BuildStageWorkflow extends Component {\n constructor(parent: MonorepoProject, options: BuildStageWorkflowOptions) {\n super(parent, \"stage-workflow\");\n\n const { openhi } = options;\n\n /**\n * Global Service Deploy\n *\n * Deploy the Global service first to configure DNS\n */\n const { awsDeploymentTargets: globalTargets, buildWorkflow } =\n new AwsDeployWorkflow(openhi.global.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflowOptions: {\n name: \"deploy-stage\",\n workflowTriggers: {\n push: {\n branches: [\"main\"],\n },\n workflowDispatch: {},\n },\n },\n });\n\n /**\n * Auth Service Deploy\n *\n * Deploy the Auth service first (Cognito); data service and other stacks consume auth via SSM.\n * Auth creates the stage build workflow; data service and REST API services add to it.\n */\n const { awsDeploymentTargets: authTargets } = new AwsDeployWorkflow(\n openhi.auth.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets],\n },\n );\n\n /**\n * Data Service Deploy\n *\n * Deploy the Data service (DynamoDB FHIR store, S3) after Global.\n */\n const { awsDeploymentTargets: dataTargets } = new AwsDeployWorkflow(\n openhi.data.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets],\n },\n );\n\n /**\n * Rest API Service Deploy\n */\n const { awsDeploymentTargets: restApiTargets } = new AwsDeployWorkflow(\n openhi.restApi.project,\n {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n },\n );\n\n /**\n * GraphQL API Service Deploy\n */\n new AwsDeployWorkflow(openhi.graphApi.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...authTargets, ...dataTargets],\n });\n\n /**\n * Website Service Deploy\n *\n * Deploy the Website service after Global and REST API. The website\n * stack's CloudFront distribution fronts the REST API via an\n * `/api/*` behavior whose origin host is resolved at CFN update time\n * from the `REST_API_DOMAIN_NAME` SSM parameter — that parameter is\n * written by the matching branch's rest-api stack, so rest-api must\n * deploy first. The Global dependency holds for the child hosted zone\n * and wildcard certificate. Auth no longer needs to be upstream — the\n * Cognito IDs are exposed via the REST API's runtime-config endpoint\n * at request time, not via CFN dynamic references at update time.\n */\n new AwsDeployWorkflow(openhi.website.project, {\n awsStageType: OPEN_HI_STAGE.STAGE,\n buildWorkflow,\n deployAfterTargets: [...globalTargets, ...restApiTargets],\n });\n }\n}\n"],"mappings":"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","names":["import_config","sep","sep","import_config","Component","import_config","AwsDeployWorkflow","Component"]}
package/package.json CHANGED
@@ -45,7 +45,7 @@
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
- "version": "0.0.42",
48
+ "version": "0.0.44",
49
49
  "types": "lib/index.d.ts",
50
50
  "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm exec projen\".",
51
51
  "scripts": {