Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ yarn.lock
# TEMP
tpsGetLock_response.txt
tpsRecordRelease_response.txt

# CLAUDE
.agents/artifacts
1 change: 1 addition & 0 deletions cspell-dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ postpublish
postbump
postrelease
postrun
preassessment
preauth
prerun
preupdate
Expand Down
128 changes: 7 additions & 121 deletions src/commands/data/pg/create.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-await-in-loop */
import {flags as Flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import {color, utils} from '@heroku/heroku-cli-util'
Expand All @@ -11,12 +12,11 @@ import createPool from '../../../lib/data/create-pool.js'
import {parseProvisionOpts} from '../../../lib/data/parse-provision-opts.js'
import PoolConfig from '../../../lib/data/pool-config.js'
import {ExtendedPostgresLevelInfo} from '../../../lib/data/types.js'
import {fetchLevelsAndPricing, renderPricingInfo} from '../../../lib/data/utils.js'
import {fetchLevelsAndPricing} from '../../../lib/data/utils.js'
import notify from '../../../lib/notify.js'

const heredoc = tsheredoc.default

const {prompt, Separator} = inquirer
const {prompt} = inquirer

export default class DataPgCreate extends BaseCommand {
static baseFlags = BaseCommand.baseFlagsWithoutPrompt()
Expand Down Expand Up @@ -201,75 +201,9 @@ export default class DataPgCreate extends BaseCommand {
} while (oneMore)
}

private async highAvailabilityStep(): Promise<string> {
process.stderr.write('The leader pool has high availability enabled and includes a standby instance for redundancy.\n'
+ 'If you disable high availability, you remove the standby and you won\'t have redundancy on your database.\n\n')

const leaderPricing = this.extendedLevelsInfo!.find(level => level.name === this.leaderLevel)?.pricing
const {action} = await this.prompt<{action: string}>({
choices: [
{name: 'Keep high availability (HA)', value: 'keep'},
{
name: 'Remove high availability' + (
renderPricingInfo(leaderPricing) === 'free'
? ''
: ` ${color.info(`-${renderPricingInfo(leaderPricing).replace('~', '')}`)}`
),
value: 'remove',
},
new Separator(),
{name: 'Go back', value: 'back'},
],
message: 'Do you want to keep the high availability standby instance?',
name: 'action',
type: 'list',
})
process.stderr.write('\n')

return action
}

private async leaderConfirmationStep(): Promise<string> {
const leaderLevelInfo = this.extendedLevelsInfo!.find(level => level.name === this.leaderLevel)
const totalPrice = this.highAvailability
? renderPricingInfo(leaderLevelInfo?.pricing, 2)
: renderPricingInfo(leaderLevelInfo?.pricing)
const instancePrice = renderPricingInfo(leaderLevelInfo?.pricing)
process.stderr.write(heredoc`
${`${color.green('✓ Configure Leader Pool')} ${totalPrice}`}
${color.gray(`${this.leaderLevel} ${leaderLevelInfo?.vcpu} ${color.ansis.inverse('vCPU')} `
+ `${leaderLevelInfo?.memory_in_gb} GB ${color.ansis.inverse('MEM')} `
+ instancePrice)}
`)
if (this.highAvailability) {
process.stderr.write(color.gray(` Standby (High Availability) ${instancePrice}\n`))
}

process.stderr.write('\n')

const {action} = await this.prompt<{action: string}>({
choices: [
{name: 'Confirm', value: 'confirm'},
{name: 'Go back', value: 'back'},
],
message: 'Confirm provisioning?',
name: 'action',
type: 'list',
})
process.stderr.write('\n')

return action
}

private async leaderLevelStep(): Promise<void> {
private async leaderPoolConfig(): Promise<void> {
const poolConfig = new PoolConfig(this.extendedLevelsInfo!, this.followerInstanceCount)
const level = await poolConfig.levelStep('Leader')
process.stderr.write('\n')

this.leaderLevel = level
}

private async leaderPoolConfig(): Promise<void> {
process.stderr.write(heredoc`

Create a Heroku Postgres Advanced database
Expand All @@ -282,56 +216,8 @@ export default class DataPgCreate extends BaseCommand {
${color.gray(' Configure Follower Pool(s)')}\n
`)

let configReady = false
let currentStep = 'leaderLevel'

while (!configReady) {
switch (currentStep) {
case 'confirmation': {
switch (await this.leaderConfirmationStep()) {
case 'back': {
currentStep = 'highAvailability'
break
}

case 'confirm': {
configReady = true
break
}
}

break
}

case 'highAvailability': {
switch (await this.highAvailabilityStep()) {
case 'back': {
currentStep = 'leaderLevel'
break
}

case 'keep': {
this.highAvailability = true
currentStep = 'confirmation'
break
}

case 'remove': {
this.highAvailability = false
currentStep = 'confirmation'
break
}
}

break
}

case 'leaderLevel': {
await this.leaderLevelStep()
currentStep = 'highAvailability'
break
}
}
}
const {highAvailability, level} = await poolConfig.leaderInteractiveConfig()
this.leaderLevel = level
this.highAvailability = highAvailability
}
}
Loading
Loading