Files
supabase/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.constants.ts
Stephen MorganandJoshen Lim 9dc5c0faf3 feat: privatelink read replica (#48642)
Frontend changes for new privatelink functionality.
The updates to the API are already live, but will be putting the UI
changes behind a feature flag while we do some full end to end testing.

Changes to Integration page:
<img width="744" height="456" alt="image"
src="https://github.com/user-attachments/assets/02026083-4b61-4f36-927b-1bac42cb73e2"
/>

Changes to create associations page:
<img width="859" height="411" alt="image"
src="https://github.com/user-attachments/assets/303b4ec5-3b5a-4eaf-8d22-45e1e63a0705"
/>

Fixes SEC-919

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

- **New Features**
- AWS PrivateLink connections can target the primary database or a read
replica.
- Connection lists and confirmation dialogs now identify the selected
database clearly.
- Replica details include improved status information and a “Manage
replica” link.

- **Bug Fixes**
- Replica removal errors now provide clearer guidance and link to
integration settings when PrivateLink issues occur.

- **Updates**
- Infrastructure diagrams focus on visualization, with replica
management actions moved to dedicated management views.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-04 20:47:48 +12:00

111 lines
3.6 KiB
TypeScript

import { ReadReplicaSetupError, ReadReplicaSetupProgress } from '@supabase/shared-types/out/events'
import type { AWS_REGIONS_KEYS } from 'shared-data'
import { AWS_REGIONS } from 'shared-data'
export interface Region {
key: AWS_REGIONS_KEYS
name: string
region: string
coordinates: [number, number]
}
export type NodeData = {
id: string
provider: string
region: Region
computeSize?: string
status: string
inserted_at: string
}
export type PrimaryNodeData = NodeData & {
numReplicas: number
numRegions: number
hasLoadBalancer: boolean
}
export type LoadBalancerData = NodeData & {
numDatabases: number
}
export type ReplicaNodeData = NodeData & {
onSelectRestartReplica: () => void
onSelectResizeReplica: () => void
onSelectDropReplica: () => void
}
export type EdgeData = {
status: string
identifier: string
connectionString: string | null | undefined
}
// ReactFlow is scaling everything by the factor of 2
export const NODE_WIDTH = 660
export const NODE_SEP = 20
// The region wrapper is a static, non-measured sibling node with a fixed size.
export const REGION_NODE_HEIGHT = 162
// First-paint fallback heights for the dagre layout, only used before React
// Flow has measured the real nodes. Subsequent layouts use node.measured.height.
export const NODE_HEIGHT_FALLBACKS: Record<string, number> = {
LOAD_BALANCER: 64,
PRIMARY: 140,
READ_REPLICA: 140,
REGION: REGION_NODE_HEIGHT,
}
// [Joshen] Coordinates from https://github.com/tobilg/aws-edge-locations/blob/main/data/aws-edge-locations.json
// In the format of [lon, lat]
export const AWS_REGIONS_COORDINATES: { [key: string]: [number, number] } = {
SOUTHEAST_ASIA: [103.8, 1.37],
NORTHEAST_ASIA: [139.42, 35.41],
NORTHEAST_ASIA_2: [126.98, 37.56],
CENTRAL_CANADA: [-73.6, 45.5],
WEST_US: [-121.96, 37.35],
WEST_US_2: [-122.67, 45.51],
EAST_US: [-78.45, 38.13],
WEST_EU: [-8, 53],
WEST_EU_2: [-0.1, 51],
CENTRAL_EU: [8, 50],
SOUTH_ASIA: [72.88, 19.08],
OCEANIA: [151.2, -33.86],
SOUTH_AMERICA: [-46.38, -23.34],
CENTRAL_EU_2: [8.54, 47.45],
EAST_US_2: [-83, 39.96],
NORTH_EU: [17.91, 59.65],
WEST_EU_3: [2.35, 48.86],
}
// [Joshen] Just to make sure that we just depend on AWS_REGIONS to determine available
export const AVAILABLE_REPLICA_REGIONS: Region[] = Object.keys(AWS_REGIONS)
.map((key) => {
return {
key: key as AWS_REGIONS_KEYS,
name: AWS_REGIONS?.[key as AWS_REGIONS_KEYS].displayName,
region: AWS_REGIONS?.[key as AWS_REGIONS_KEYS].code,
coordinates: AWS_REGIONS_COORDINATES[key],
}
})
.filter((x) => x.coordinates !== undefined)
// [Joshen] Just a more user friendly language, so that all the verbs are progressive
export const INIT_PROGRESS = {
[ReadReplicaSetupProgress.Requested]: 'Requesting replica instance',
[ReadReplicaSetupProgress.Started]: 'Launching replica instance',
[ReadReplicaSetupProgress.LaunchedReadReplicaInstance]: 'Initiating replica setup',
[ReadReplicaSetupProgress.InitiatedReadReplicaSetup]: 'Downloading base backup',
[ReadReplicaSetupProgress.DownloadedBaseBackup]: 'Replaying WAL archives',
[ReadReplicaSetupProgress.ReplayedWalArchives]: 'Completing set up',
[ReadReplicaSetupProgress.CompletedReadReplicaSetup]: 'Completed',
}
export const ERROR_STATES = {
[ReadReplicaSetupError.ReadReplicaInstanceLaunchFailed]: 'Failed to launch replica',
[ReadReplicaSetupError.InitiateReadReplicaSetupFailed]: 'Failed to initiate replica',
[ReadReplicaSetupError.DownloadBaseBackupFailed]: 'Failed to download backup',
[ReadReplicaSetupError.ReplayWalArchivesFailed]: 'Failed to replay WAL archives',
[ReadReplicaSetupError.CompleteReadReplicaSetupFailed]: 'Failed to set up replica',
}