mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Clean up auto region selection experiment (#51121)
## Context Just cleans up the experiment that was introduced [here](https://github.com/supabase/supabase/issues/50851) - can clean up feature flag in ConfigCat thereafter too <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Project Creation** * Removed the “Best available” region option. Choose a specific region or smart group when creating a project; the selected region name appears in the selector. * Recommended badges remain visible on recommended regions. * **Telemetry** * Project creation events no longer include details about the removed region option or the initial region recommendation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
1 parent
39e13d3181
commit
94b8b06eb2
7 files changed
+16
-239
No files matched your search
@@ -11,7 +11,6 @@ import {
|
||||
getAvailableRegions,
|
||||
getHighAvailabilityRegionCode,
|
||||
resolveDefaultDbRegion,
|
||||
resolveSelectedRegionOptionType,
|
||||
} from './ProjectCreation.utils'
|
||||
|
||||
describe('resolveDefaultDbRegion', () => {
|
||||
@@ -70,55 +69,6 @@ describe('resolveDefaultDbRegion', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('resolveSelectedRegionOptionType', () => {
|
||||
const smartGroupRegions = [{ name: 'Americas' }, { name: 'APAC' }]
|
||||
const specificRegions = [{ name: 'ap-southeast-1' }, { name: 'us-east-1' }]
|
||||
|
||||
it('returns general when the "Best available region" shortcut was used', () => {
|
||||
expect(
|
||||
resolveSelectedRegionOptionType({
|
||||
isBestAvailableSelected: true,
|
||||
dbRegion: 'ap-southeast-1',
|
||||
smartGroupRegions,
|
||||
specificRegions,
|
||||
})
|
||||
).toBe('general')
|
||||
})
|
||||
|
||||
it('returns general when the region was picked from the smart group list', () => {
|
||||
expect(
|
||||
resolveSelectedRegionOptionType({
|
||||
isBestAvailableSelected: false,
|
||||
dbRegion: 'Americas',
|
||||
smartGroupRegions,
|
||||
specificRegions,
|
||||
})
|
||||
).toBe('general')
|
||||
})
|
||||
|
||||
it('returns specific when the region was picked from the specific regions list', () => {
|
||||
expect(
|
||||
resolveSelectedRegionOptionType({
|
||||
isBestAvailableSelected: false,
|
||||
dbRegion: 'ap-southeast-1',
|
||||
smartGroupRegions,
|
||||
specificRegions,
|
||||
})
|
||||
).toBe('specific')
|
||||
})
|
||||
|
||||
it('returns undefined when the region matches neither list', () => {
|
||||
expect(
|
||||
resolveSelectedRegionOptionType({
|
||||
isBestAvailableSelected: false,
|
||||
dbRegion: undefined,
|
||||
smartGroupRegions,
|
||||
specificRegions,
|
||||
})
|
||||
).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAvailableRegions', () => {
|
||||
it.each(['local', 'staging', 'prod'])('returns all AWS regions for AWS on %s', (environment) => {
|
||||
expect(getAvailableRegions('AWS', environment)).toEqual(AWS_REGIONS)
|
||||
|
||||
@@ -68,26 +68,6 @@ export function resolveDefaultDbRegion({
|
||||
: fixedDefaultRegion
|
||||
}
|
||||
|
||||
type ResolveSelectedRegionOptionTypeArgs = {
|
||||
isBestAvailableSelected: boolean
|
||||
dbRegion: string | undefined
|
||||
smartGroupRegions: Array<{ name: string }>
|
||||
specificRegions: Array<{ name: string }>
|
||||
}
|
||||
|
||||
export function resolveSelectedRegionOptionType({
|
||||
isBestAvailableSelected,
|
||||
dbRegion,
|
||||
smartGroupRegions,
|
||||
specificRegions,
|
||||
}: ResolveSelectedRegionOptionTypeArgs): 'general' | 'specific' | undefined {
|
||||
// The "Best available region" shortcut always resolves to a smart-group recommendation
|
||||
if (isBestAvailableSelected) return 'general'
|
||||
if (smartGroupRegions.some((region) => region.name === dbRegion)) return 'general'
|
||||
if (specificRegions.some((region) => region.name === dbRegion)) return 'specific'
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* When launching new projects, they only get assigned a compute size once successfully launched,
|
||||
* this might assume wrong compute size, but only for projects being rapidly launched after one another on non-default compute sizes.
|
||||
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
instanceLabel,
|
||||
monthlyInstancePrice,
|
||||
resolveDefaultDbRegion,
|
||||
resolveSelectedRegionOptionType,
|
||||
smartRegionToExactRegion,
|
||||
} from './ProjectCreation.utils'
|
||||
import { ProjectCreationFooter } from './ProjectCreationFooter'
|
||||
@@ -143,18 +142,6 @@ export const ProjectCreationForm = ({
|
||||
useFlag('newProjectInternalOnlyConfiguration') && !isVercelIntegrationFlow
|
||||
const { getRegionRestriction } = useRegionRestriction()
|
||||
|
||||
// [Joshen] Temp experiment - to clean up once completed
|
||||
const showBestAvailableRegionFeature = useIsFeatureEnabled(
|
||||
'project_creation:show_best_available_region'
|
||||
)
|
||||
const showBestAvailableRegionFlag = useFlag('showBestAvailableRegion')
|
||||
const showBestAvailableRegionOption =
|
||||
showBestAvailableRegionFeature && showBestAvailableRegionFlag && isFreePlan
|
||||
const [isBestAvailableSelected, setIsBestAvailableSelected] = useState(false)
|
||||
|
||||
const shouldTrackRegionRecommendation = isFreePlan && showBestAvailableRegionFeature
|
||||
const initialRecommendedRegionRef = useRef<string | undefined>(undefined)
|
||||
|
||||
// Read the raw flag for telemetry — coerce-undefined-to-false would record false for
|
||||
// users whose flags haven't loaded yet. The raw value preserves undefined (omitted from
|
||||
// PostHog) so we only record an actual value (boolean true/false, or a variant string
|
||||
@@ -309,16 +296,6 @@ export const ProjectCreationForm = ({
|
||||
? availableRegionsData?.recommendations.smartGroup.name
|
||||
: ''
|
||||
|
||||
if (
|
||||
initialRecommendedRegionRef.current === undefined &&
|
||||
flagsLoaded &&
|
||||
shouldTrackRegionRecommendation
|
||||
) {
|
||||
initialRecommendedRegionRef.current = showBestAvailableRegionOption
|
||||
? 'best_available'
|
||||
: recommendedSmartRegion || undefined
|
||||
}
|
||||
|
||||
const fixedDefaultRegion = PROVIDERS[selectedCloudProvider].default_region.displayName
|
||||
const regionError = smartRegionEnabled ? availableRegionsError : defaultRegionError
|
||||
const defaultRegion = resolveDefaultDbRegion({
|
||||
@@ -371,15 +348,6 @@ export const ProjectCreationForm = ({
|
||||
} = useProjectCreateMutation({
|
||||
onSuccess: (res) => {
|
||||
setProjectCreationError(undefined)
|
||||
const { smartGroup = [], specific = [] } = availableRegionsData?.all ?? {}
|
||||
const submittedDbRegion = form.getValues('dbRegion')
|
||||
const selectedRegionOption = isBestAvailableSelected ? 'best_available' : submittedDbRegion
|
||||
const selectedRegionOptionType = resolveSelectedRegionOptionType({
|
||||
isBestAvailableSelected,
|
||||
dbRegion: submittedDbRegion,
|
||||
smartGroupRegions: smartGroup,
|
||||
specificRegions: specific,
|
||||
})
|
||||
track(
|
||||
'project_creation_simple_version_submitted',
|
||||
{
|
||||
@@ -392,11 +360,6 @@ export const ProjectCreationForm = ({
|
||||
...(dataApiRevokeOnCreateDefaultFlag !== undefined && {
|
||||
dataApiRevokeOnCreateDefaultEnabled: dataApiRevokeOnCreateDefaultFlag,
|
||||
}),
|
||||
...(shouldTrackRegionRecommendation && {
|
||||
selectedRegionOption,
|
||||
selectedRegionOptionType,
|
||||
initialRecommendedRegion: initialRecommendedRegionRef.current,
|
||||
}),
|
||||
},
|
||||
{
|
||||
project: res.ref,
|
||||
@@ -818,9 +781,6 @@ export const ProjectCreationForm = ({
|
||||
form={form}
|
||||
hasSelectedOrganization={hasSelectedOrganization}
|
||||
instanceSize={instanceSize as DesiredInstanceSize}
|
||||
showBestAvailableRegionOption={showBestAvailableRegionOption}
|
||||
isBestAvailableSelected={isBestAvailableSelected}
|
||||
onBestAvailableSelectedChange={setIsBestAvailableSelected}
|
||||
/>
|
||||
|
||||
{isVercelIntegrationFlow && !!externalId && <DataSeeding form={form} />}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useFeatureFlags, useFlag, useParams } from 'common'
|
||||
import { Loader2, ThumbsUp } from 'lucide-react'
|
||||
import { Loader2 } from 'lucide-react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { UseFormReturn } from 'react-hook-form'
|
||||
import type { CloudProvider } from 'shared-data'
|
||||
@@ -51,9 +51,6 @@ interface RegionSelectorProps {
|
||||
hasSelectedOrganization: boolean
|
||||
instanceSize?: DesiredInstanceSize
|
||||
layout?: 'vertical' | 'horizontal'
|
||||
showBestAvailableRegionOption: boolean
|
||||
isBestAvailableSelected: boolean
|
||||
onBestAvailableSelectedChange: (value: boolean) => void
|
||||
}
|
||||
|
||||
// [Joshen] Let's use a library to maintain the flag SVGs in the future
|
||||
@@ -70,20 +67,11 @@ const getDisplayNameForSmartRegion = (name: string): string => {
|
||||
|
||||
const isLocal = process.env.NEXT_PUBLIC_ENVIRONMENT === 'local'
|
||||
|
||||
const BestAvailableRegionIcon = () => (
|
||||
<div className="w-5 border border-brand-500 h-4.5 rounded-[3px] bg-brand-300 flex items-center justify-center">
|
||||
<ThumbsUp size={10} className="text-brand" />
|
||||
</div>
|
||||
)
|
||||
|
||||
export const RegionSelector = ({
|
||||
form,
|
||||
hasSelectedOrganization,
|
||||
instanceSize,
|
||||
layout = 'horizontal',
|
||||
showBestAvailableRegionOption,
|
||||
isBestAvailableSelected,
|
||||
onBestAvailableSelectedChange,
|
||||
}: RegionSelectorProps) => {
|
||||
const { slug } = useParams()
|
||||
const cloudProvider = form.getValues('cloudProvider') as CloudProvider
|
||||
@@ -127,32 +115,6 @@ export const RegionSelector = ({
|
||||
const recommendedSmartRegions = new Set(
|
||||
[availableRegionsData?.recommendations.smartGroup.code].filter(Boolean)
|
||||
)
|
||||
const recommendedSmartRegion = smartRegions.find(
|
||||
(x) => x.code === recommendedSmartRegions.values().next().value
|
||||
)
|
||||
|
||||
const isBestAvailableOptionShown = showBestAvailableRegionOption && !!recommendedSmartRegion
|
||||
const isBestAvailableActive = isBestAvailableSelected && isBestAvailableOptionShown
|
||||
|
||||
// Defaults free orgs to the "Best available region" shortcut once the recommendation loads,
|
||||
// unless the user has already interacted with the region field themselves.
|
||||
const hasUserSelectedRegionRef = useRef(false)
|
||||
useEffect(() => {
|
||||
if (hasUserSelectedRegionRef.current) return
|
||||
if (isBestAvailableOptionShown) {
|
||||
onBestAvailableSelectedChange(true)
|
||||
}
|
||||
}, [isBestAvailableOptionShown, onBestAvailableSelectedChange])
|
||||
|
||||
// Keeps dbRegion following the recommendation while "Best available" is active, so a
|
||||
// recommendation change (e.g. after a refetch) doesn't leave the form submitting a stale
|
||||
// region behind a label that still reads "Auto".
|
||||
useEffect(() => {
|
||||
if (!isBestAvailableSelected || !recommendedSmartRegion) return
|
||||
if (dbRegion !== recommendedSmartRegion.name) {
|
||||
form.setValue('dbRegion', recommendedSmartRegion.name)
|
||||
}
|
||||
}, [isBestAvailableSelected, recommendedSmartRegion, dbRegion, form])
|
||||
|
||||
const recommendedSpecificRegions = new Set(
|
||||
availableRegionsData?.recommendations.specific.map((region) => region.code)
|
||||
@@ -234,11 +196,7 @@ export const RegionSelector = ({
|
||||
selectedRestriction !== undefined
|
||||
? getRegionRestrictionCopy(selectedRestriction)
|
||||
: undefined
|
||||
const triggerLabel = isLoading
|
||||
? 'Loading available regions...'
|
||||
: isBestAvailableActive
|
||||
? 'Auto'
|
||||
: selectedRegionLabel
|
||||
const triggerLabel = isLoading ? 'Loading available regions...' : selectedRegionLabel
|
||||
|
||||
const affectingIncidents = incidents.filter((incident) => {
|
||||
const affectedRegions = incident.cache?.affected_regions ?? []
|
||||
@@ -280,18 +238,10 @@ export const RegionSelector = ({
|
||||
>
|
||||
<FormControl>
|
||||
<Select
|
||||
value={isBestAvailableActive ? 'best_available' : dbRegion}
|
||||
value={dbRegion}
|
||||
onValueChange={(value) => {
|
||||
if (value === '') return
|
||||
hasUserSelectedRegionRef.current = true
|
||||
if (value === 'best_available') {
|
||||
if (!recommendedSmartRegion) return
|
||||
onBestAvailableSelectedChange(true)
|
||||
field.onChange(recommendedSmartRegion.name)
|
||||
} else {
|
||||
onBestAvailableSelectedChange(false)
|
||||
field.onChange(value)
|
||||
}
|
||||
field.onChange(value)
|
||||
}}
|
||||
disabled={isLoading}
|
||||
>
|
||||
@@ -310,12 +260,8 @@ export const RegionSelector = ({
|
||||
{dbRegion !== undefined && (
|
||||
<div className="flex items-center gap-x-3">
|
||||
{isLoading && <Loader2 size={14} className="animate-spin" />}
|
||||
{isBestAvailableActive ? (
|
||||
<BestAvailableRegionIcon />
|
||||
) : (
|
||||
selectedRegion?.code && (
|
||||
<RegionFlag className="w-5" region={selectedRegion.code} />
|
||||
)
|
||||
{selectedRegion?.code && (
|
||||
<RegionFlag className="w-5" region={selectedRegion.code} />
|
||||
)}
|
||||
<span className="text-foreground">{triggerLabel}</span>
|
||||
</div>
|
||||
@@ -323,28 +269,6 @@ export const RegionSelector = ({
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{isBestAvailableOptionShown && (
|
||||
<>
|
||||
<SelectGroup>
|
||||
<SelectLabel>Recommendation</SelectLabel>
|
||||
<SelectItem
|
||||
value="best_available"
|
||||
className="w-full [&>:nth-child(2)]:w-full"
|
||||
>
|
||||
<div className="flex flex-row items-center justify-between w-full">
|
||||
<div className="flex items-center gap-x-3">
|
||||
<BestAvailableRegionIcon />
|
||||
<span className="text-foreground">Auto</span>
|
||||
</div>
|
||||
<Badge variant="success" className="mr-1">
|
||||
Recommended
|
||||
</Badge>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
<SelectSeparator />
|
||||
</>
|
||||
)}
|
||||
{smartRegionEnabled && !highAvailability && (
|
||||
<>
|
||||
<SelectGroup>
|
||||
@@ -365,12 +289,11 @@ export const RegionSelector = ({
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{!isBestAvailableOptionShown &&
|
||||
recommendedSmartRegions.has(value.code) && (
|
||||
<Badge variant="success" className="mr-1">
|
||||
Recommended
|
||||
</Badge>
|
||||
)}
|
||||
{recommendedSmartRegions.has(value.code) && (
|
||||
<Badge variant="success" className="mr-1">
|
||||
Recommended
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</SelectItem>
|
||||
@@ -410,12 +333,11 @@ export const RegionSelector = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!isBestAvailableOptionShown &&
|
||||
recommendedSpecificRegions.has(value.code) && (
|
||||
<Badge variant="success" className="mr-1">
|
||||
Recommended
|
||||
</Badge>
|
||||
)}
|
||||
{recommendedSpecificRegions.has(value.code) && (
|
||||
<Badge variant="success" className="mr-1">
|
||||
Recommended
|
||||
</Badge>
|
||||
)}
|
||||
|
||||
{restrictionCopy !== undefined && (
|
||||
<Tooltip>
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
|
||||
"project_creation:show_advanced_config": true,
|
||||
"project_creation:show_high_availability": true,
|
||||
"project_creation:show_best_available_region": true,
|
||||
|
||||
"project_homepage:show_instance_size": true,
|
||||
"project_homepage:show_examples": true,
|
||||
|
||||
@@ -358,10 +358,6 @@
|
||||
"type": "boolean",
|
||||
"description": "Show the high availability toggle in the project creation flow"
|
||||
},
|
||||
"project_creation:show_best_available_region": {
|
||||
"type": "boolean",
|
||||
"description": "Show the best available region option in the project creation region selector"
|
||||
},
|
||||
|
||||
"project_homepage:show_instance_size": {
|
||||
"type": "boolean",
|
||||
|
||||
@@ -449,36 +449,6 @@ export interface ProjectCreationSimpleVersionSubmittedEvent {
|
||||
* omitted = PostHog flags had not loaded at the time of project creation
|
||||
*/
|
||||
dataApiRevokeOnCreateDefaultEnabled?: boolean | string
|
||||
/**
|
||||
* Which region option was submitted. Only present for the region-recommendation experiment's
|
||||
* eligible cohort (free plan + `project_creation:show_best_available_region` feature enabled —
|
||||
* see `shouldTrackRegionRecommendation` in ProjectCreationForm.tsx). This is cohort-level
|
||||
* eligibility, not "the option was shown" — it's present for both the PostHog flag's control
|
||||
* and test arms so the two can be compared; omitted entirely outside the cohort (e.g. paid
|
||||
* plans, or providers like AWS_NIMBUS where the feature is disabled).
|
||||
* 'best_available' = the "Best available region" shortcut was used
|
||||
* otherwise = the name of the region that was directly selected (e.g. 'Americas', 'ap-southeast-1')
|
||||
*/
|
||||
selectedRegionOption?: string
|
||||
/**
|
||||
* Which region list `selectedRegionOption` came from. Only present alongside `selectedRegionOption`.
|
||||
* 'general' = picked from the "General regions" (smart group) list, or the "Best available
|
||||
* region" shortcut was used (it always resolves to a general/smart region)
|
||||
* 'specific' = picked from the "Specific regions" list
|
||||
*/
|
||||
selectedRegionOptionType?: 'general' | 'specific'
|
||||
/**
|
||||
* The region that was recommended/defaulted to on initial render, before any user
|
||||
* interaction. Present under the same cohort gate as `selectedRegionOption`. Frozen the
|
||||
* first time it's known, so a later refetch (e.g. switching cloud provider or instance size)
|
||||
* doesn't overwrite what was actually shown to the user initially.
|
||||
* 'best_available' = the user was in the PostHog flag's test arm, so the form defaulted to
|
||||
* the "Best available region" shortcut
|
||||
* otherwise = the name of the smart-group region recommended by the `available-regions`
|
||||
* endpoint (e.g. 'Americas'), for users in the flag's control arm
|
||||
* undefined = no recommendation had loaded yet at submission time
|
||||
*/
|
||||
initialRecommendedRegion?: string
|
||||
}
|
||||
groups: TelemetryGroups
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user