Files
supabase/apps/studio/data/reports/database-charts.test.ts
Alaister Young 23949ae633 [MUL-1364] fix(studio): use multipooler copy for dedicated pooler chart on HA (#49525)
The "Dedicated Pooler Client Connections" chart on the Database
observability page labels its series `pgbouncer` and links to PgBouncer
limits docs. High Availability projects run Multigres, whose dedicated
pooler is multipooler, so that copy was misleading. This swaps the copy
for HA projects and drops the docs link until multipooler docs exist
(per the ticket, disabling the link for now is fine).

**Changed:**
- HA projects: legend label `pgbouncer` → `multipooler`, series tooltip
→ "Multipooler connections"
- HA projects: the info icon shows a "docs coming soon" tooltip instead
of linking to the compute-and-disk limits docs
- Non-HA projects are unchanged

**Added:**
- Unit test for `getReportAttributesV2` covering both the PgBouncer and
multipooler branches

Out of scope (flagging for follow-up): the "Max pooler connections"
reference line still uses the PgBouncer value on HA projects, and the
Supavisor chart still renders for HA projects.

Addresses
https://linear.app/supabase/issue/MUL-1364/database-dashboard-update-dedicated-poolers-copy

## To test

- On a High Availability project, open Observability → Database and find
"Dedicated Pooler Client Connections"
- Legend and hover tooltip should say `multipooler`; the info icon
should show a tooltip ending in "(docs coming soon)" with no link
- On a non-HA project, the chart should be unchanged: `pgbouncer` legend
and the info icon links to the compute-and-disk docs

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- High Availability projects now display dedicated connection pooler
charts with multipooler-specific labels and guidance.
- Standard projects continue to show PgBouncer information and
documentation links.
- High Availability charts include a tooltip indicating that
documentation is coming soon.

- **Tests**
- Added coverage to verify the correct chart labels, tooltips, and
documentation behavior for both project types.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-08-25 08:38:41 +00:00

97 lines
3.5 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { getReportAttributesV2 } from './database-charts'
import { Project } from '@/data/projects/project-detail-query'
const PROJECT: Project = {
cloud_provider: 'AWS',
connectionString: 'postgresql://postgres:password@db.project-ref.supabase.co:5432/postgres',
db_host: 'db.project-ref.supabase.co',
dbVersion: 'supabase-postgres-15.1.0',
high_availability: false,
id: 1,
infra_compute_size: 'micro',
inserted_at: '2026-01-01T00:00:00.000Z',
integration_source: null,
is_branch_enabled: false,
is_physical_backups_enabled: false,
name: 'Production',
organization_id: 1,
ref: 'project-ref',
region: 'us-east-1',
restUrl: 'https://project-ref.supabase.co',
status: 'ACTIVE_HEALTHY',
subscription_id: 'subscription-1',
updated_at: '2026-01-01T00:00:00.000Z',
}
const ENTITLED_FEATURES = ['database']
const buildProject = (overrides: Partial<Project> = {}): Project => ({ ...PROJECT, ...overrides })
const getDedicatedPoolerChart = (project: Project) => {
const chart = getReportAttributesV2(ENTITLED_FEATURES, project).find(
(attribute) => attribute.id === 'pgbouncer-connections'
)
if (!chart) throw new Error('Expected the dedicated pooler chart to exist')
return chart
}
const getClientConnectionsAttribute = (chart: ReturnType<typeof getDedicatedPoolerChart>) => {
const attribute = chart.attributes?.find(
(attr) => attr !== false && attr.attribute === 'client_connections_pgbouncer'
)
if (!attribute) throw new Error('Expected the client connections attribute to exist')
return attribute
}
const getBurstBalanceChart = (project: Project, showDiskIOBurstBalanceChart = true) =>
getReportAttributesV2(
ENTITLED_FEATURES,
project,
undefined,
undefined,
undefined,
false,
showDiskIOBurstBalanceChart
).find((chart) => chart.id === 'disk-io-burst-balance')
describe('getReportAttributesV2 dedicated pooler chart', () => {
it('uses PgBouncer copy and links to the docs for standard projects', () => {
const chart = getDedicatedPoolerChart(buildProject())
const attribute = getClientConnectionsAttribute(chart)
expect(chart.titleTooltip).toBeUndefined()
expect(chart.docsUrl).toContain('/guides/platform/compute-and-disk#limits-and-constraints')
expect(attribute).toMatchObject({ label: 'pgbouncer', tooltip: 'PgBouncer connections' })
})
it('uses multipooler copy and drops the docs link for High Availability projects', () => {
const chart = getDedicatedPoolerChart(buildProject({ high_availability: true }))
const attribute = getClientConnectionsAttribute(chart)
expect(chart.docsUrl).toBeUndefined()
expect(chart.titleTooltip).toContain('multipooler')
expect(chart.titleTooltip).toContain('docs coming soon')
expect(attribute).toMatchObject({ label: 'multipooler', tooltip: 'Multipooler connections' })
})
})
describe('getReportAttributesV2 disk-io-burst-balance chart', () => {
it('shows the chart for burstable non high availability projects', () => {
expect(getBurstBalanceChart(buildProject())?.hide).toBe(false)
})
it('hides the chart for high availability projects', () => {
expect(getBurstBalanceChart(buildProject({ high_availability: true }))?.hide).toBe(true)
})
it('hides the chart when the feature flag is off', () => {
expect(getBurstBalanceChart(buildProject(), false)?.hide).toBe(true)
})
it('hides the chart for non burstable compute sizes', () => {
expect(getBurstBalanceChart(buildProject({ infra_compute_size: '16xlarge' }))?.hide).toBe(true)
})
})