import * as cdk from 'aws-cdk-lib'; // Multi-environment configuration (PR2). Resolved from CDK context: `-c env=staging`, // default `prod`. Only non-prod environments take a stack-name suffix. // // prod now targets the dedicated seahaven-prod workload account (011934824531); the mgmt // account (328440206208) is FROZEN for new workloads. The prior proposal-system footprint // was fully torn down 2026-07-14, so THIS first prod deploy is the last safe window to // rename construct IDs / stack names. After prod go-live, renaming a deployed stack (or a // stateful construct ID) triggers replace-and-delete, which would destroy the Aurora cluster. // // STAGING is intentionally NOT deployable: it still points at the frozen mgmt account, and // resolveConfig() hard-throws on `env=staging` until it is retargeted to seahaven-dev // (710827005802). See the guard in resolveConfig below. export type EnvName = 'prod' | 'staging'; export interface EnvConfig { readonly envName: EnvName; readonly env: cdk.Environment; /** Suffix for stack names + construct IDs. '' for prod so deployed stacks are untouched. */ readonly stackSuffix: string; /** S3 bucket CORS allowed origins. */ readonly s3CorsOrigins: string[]; /** API Gateway CORS allowed origins. */ readonly apiCorsOrigins: string[]; /** Cognito web-client callback / logout URLs. */ readonly webCallbackUrls: string[]; readonly webLogoutUrls: string[]; /** Cognito hosted-UI domain prefix (must be globally unique). */ readonly cognitoDomainPrefix: string; /** Email subscribed to the CloudWatch alarm SNS topic. */ readonly alarmsEmail: string; /** Retain stateful resources (RDS, buckets) on stack deletion. */ readonly retainData: boolean; } // seahaven-prod workload account (org prod OU). mgmt 328440206208 is frozen for workloads. const PROD_ACCOUNT = '011934824531'; // Frozen mgmt account — staging still references it and must NOT be deployed there. const MGMT_ACCOUNT_FROZEN = '328440206208'; const REGION = 'us-east-1'; const PROD: EnvConfig = { envName: 'prod', env: { account: PROD_ACCOUNT, region: REGION }, stackSuffix: '', s3CorsOrigins: ['https://proposals.seahaven.com', 'http://localhost:5173'], apiCorsOrigins: [ 'https://proposals.seahaven.com', 'https://d2yevct5e5uuz5.cloudfront.net', 'http://localhost:5173', ], webCallbackUrls: [ 'https://proposals.seahaven.com/callback', 'http://localhost:5173/callback', ], webLogoutUrls: ['https://proposals.seahaven.com', 'http://localhost:5173'], cognitoDomainPrefix: 'proposal-system-seahaven', alarmsEmail: 'adam@seahavenind.com', retainData: true, }; // Staging: ⚠️ STILL points at the FROZEN mgmt account (MGMT_ACCOUNT_FROZEN). It is NOT // deployable — resolveConfig() throws on env=staging. Retarget to seahaven-dev // (710827005802) in a dedicated follow-up before ever enabling staging deploys. // Suffixed stacks, CloudFront default URL + localhost, data not retained. const STAGING: EnvConfig = { envName: 'staging', env: { account: MGMT_ACCOUNT_FROZEN, region: REGION }, stackSuffix: '-staging', s3CorsOrigins: ['http://localhost:5173'], apiCorsOrigins: ['http://localhost:5173'], webCallbackUrls: ['http://localhost:5173/callback'], webLogoutUrls: ['http://localhost:5173'], cognitoDomainPrefix: 'proposal-system-seahaven-staging', alarmsEmail: 'adam@seahavenind.com', retainData: false, }; const CONFIGS: Record = { prod: PROD, staging: STAGING }; export function resolveConfig(app: cdk.App): EnvConfig { const name = (app.node.tryGetContext('env') as EnvName | undefined) ?? 'prod'; const config = CONFIGS[name]; if (!config) { throw new Error(`Unknown env '${name}'. Use -c env=prod (default) or -c env=staging.`); } // Hard guard: staging still targets the frozen mgmt account (328440206208). Block any // synth/deploy under env=staging until it is retargeted to seahaven-dev (710827005802), // so an accidental `-c env=staging` deploy can never land in the frozen mgmt account. if (name === 'staging') { throw new Error( 'env=staging is disabled: it targets the FROZEN mgmt account (328440206208). ' + 'Retarget STAGING to seahaven-dev (710827005802) in config.ts before using it.', ); } return config; }