mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
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:
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
|
||||
|
||||
@@ -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)}>
|
||||
|
||||
Reference in new issue
Block a user