graduate auto-RLS project creation experiment (test variant wins) (#43499)

## Problem

The `projectCreationEnableRlsEventTrigger` A/B experiment tested showing
an opt-in "Enable automatic RLS" checkbox in the project creation flow,
which sets up a Postgres event trigger to auto-enable RLS on every new
table in the public schema. The test variant passed with a +3.3pp lift.

## Changes

- `SecurityOptions.tsx` — removed PostHog flag check, checkbox is now
always rendered
- `pages/new/[slug].tsx` — removed experiment flag reads, exposure
tracking (`useTrackExperimentExposure`), and the conditional
`rlsOptionVariant` telemetry property

The underlying feature logic (`enableRlsEventTrigger` form field,
`AUTO_ENABLE_RLS_EVENT_TRIGGER_SQL`, submission handling) is unchanged —
we're just removing the scaffolding that was gating it.

## Testing

Verified `pnpm typecheck` passes clean. The "Enable automatic RLS"
checkbox now shows unconditionally in the Security Options section of
project creation.

GROWTH-653
This commit is contained in:
Sean Oliver authored and GitHub committed 2026-03-09 09:22:23 -07:00
1 parent 18bee64d98
commit 96f776fc63
2 files changed
+27 -51

No files matched your search

@@ -1,5 +1,4 @@
import Panel from 'components/ui/Panel'
import { usePHFlag } from 'hooks/ui/useFlag'
import Link from 'next/link'
import { UseFormReturn } from 'react-hook-form'
import {
@@ -22,10 +21,6 @@ interface SecurityOptionsProps {
}
export const SecurityOptions = ({ form, layout = 'horizontal' }: SecurityOptionsProps) => {
const rlsExperimentVariant = usePHFlag<'control' | 'test' | false | undefined>(
'projectCreationEnableRlsEventTrigger'
)
const shouldShowEnableRlsEventTrigger = rlsExperimentVariant === 'test'
const dataApi = useWatch_Shadcn_({ control: form.control, name: 'dataApi' })
return (
@@ -65,32 +60,30 @@ export const SecurityOptions = ({ form, layout = 'horizontal' }: SecurityOptions
)}
/>
{shouldShowEnableRlsEventTrigger && (
<FormField_Shadcn_
name="enableRlsEventTrigger"
control={form.control}
render={({ field }) => (
<FormItem_Shadcn_ className="flex items-start gap-3">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
checked={field.value}
disabled={field.disabled}
onCheckedChange={(value) => field.onChange(value === true)}
/>
</FormControl_Shadcn_>
<div className="space-y-1">
<FormLabel_Shadcn_ className="text-sm text-foreground">
Enable automatic RLS
</FormLabel_Shadcn_>
<FormDescription_Shadcn_ className="text-foreground-lighter">
Create an event trigger that automatically enables Row Level Security on all
new tables in the public schema.
</FormDescription_Shadcn_>
</div>
</FormItem_Shadcn_>
)}
/>
)}
<FormField_Shadcn_
name="enableRlsEventTrigger"
control={form.control}
render={({ field }) => (
<FormItem_Shadcn_ className="flex items-start gap-3">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
checked={field.value}
disabled={field.disabled}
onCheckedChange={(value) => field.onChange(value === true)}
/>
</FormControl_Shadcn_>
<div className="space-y-1">
<FormLabel_Shadcn_ className="text-sm text-foreground">
Enable automatic RLS
</FormLabel_Shadcn_>
<FormDescription_Shadcn_ className="text-foreground-lighter">
Create an event trigger that automatically enables Row Level Security on all new
tables in the public schema.
</FormDescription_Shadcn_>
</div>
</FormItem_Shadcn_>
)}
/>
{!dataApi && (
<Admonition
+3 -20
View File
@@ -11,8 +11,8 @@ import { DisabledWarningDueToIncident } from 'components/interfaces/ProjectCreat
import { FreeProjectLimitWarning } from 'components/interfaces/ProjectCreation/FreeProjectLimitWarning'
import { OrganizationSelector } from 'components/interfaces/ProjectCreation/OrganizationSelector'
import {
PostgresVersionSelector,
extractPostgresVersionDetails,
PostgresVersionSelector,
} from 'components/interfaces/ProjectCreation/PostgresVersionSelector'
import { sizes } from 'components/interfaces/ProjectCreation/ProjectCreation.constants'
import { FormSchema } from 'components/interfaces/ProjectCreation/ProjectCreation.schema'
@@ -44,7 +44,6 @@ import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage'
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
import { useTrackExperimentExposure } from 'hooks/misc/useTrackExperimentExposure'
import { withAuth } from 'hooks/misc/withAuth'
import { usePHFlag } from 'hooks/ui/useFlag'
import { DOCS_URL, PROJECT_STATUS, PROVIDERS, useDefaultProvider } from 'lib/constants'
@@ -57,9 +56,9 @@ import { useForm } from 'react-hook-form'
import { AWS_REGIONS, type CloudProvider } from 'shared-data'
import { toast } from 'sonner'
import type { NextPageWithLayout } from 'types'
import { Button, FormField_Shadcn_, Form_Shadcn_, useWatch_Shadcn_ } from 'ui'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
import { Button, Form_Shadcn_, FormField_Shadcn_, useWatch_Shadcn_ } from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
import { z } from 'zod'
const sizesWithNoCostConfirmationRequired: DesiredInstanceSize[] = ['micro', 'small']
@@ -72,10 +71,6 @@ const Wizard: NextPageWithLayout = () => {
const { profile } = useProfile()
const { data: currentOrg } = useSelectedOrganizationQuery()
const rlsExperimentVariant = usePHFlag<'control' | 'test' | false | undefined>(
'projectCreationEnableRlsEventTrigger'
)
const shouldShowEnableRlsEventTrigger = rlsExperimentVariant === 'test'
const isFreePlan = currentOrg?.plan?.id === 'free'
const canChooseInstanceSize = !isFreePlan
@@ -250,9 +245,6 @@ const Wizard: NextPageWithLayout = () => {
{
instanceSize: form.getValues('instanceSize'),
enableRlsEventTrigger: form.getValues('enableRlsEventTrigger'),
...((rlsExperimentVariant === 'control' || rlsExperimentVariant === 'test') && {
rlsOptionVariant: rlsExperimentVariant,
}),
dataApiEnabled: form.getValues('dataApi'),
useOrioleDb: form.getValues('useOrioleDb'),
},
@@ -389,15 +381,6 @@ const Wizard: NextPageWithLayout = () => {
}
}, [instanceSize, watchedInstanceSize, form])
// Track exposure to RLS option experiment (only when explicitly assigned to a variant)
const shouldTrackRlsExposure =
!!currentOrg?.slug && (rlsExperimentVariant === 'control' || rlsExperimentVariant === 'test')
useTrackExperimentExposure(
'project_creation_rls_option',
shouldTrackRlsExposure ? rlsExperimentVariant : undefined
)
return (
<Form_Shadcn_ {...form}>
<form onSubmit={form.handleSubmit(onSubmitWithComputeCostsConfirmation)}>