ronantakizawa/codereview-bench huggingface dataset:
Repository: supabase/supabase
File: packages/common/telemetry-constants.ts (TypeScript)

Code before:
  | BranchCloseMergeRequestButtonClickedEvent
  | BranchMergeSubmittedEvent
  | BranchMergeSucceededEvent
  | BranchMergeFailedEvent
  | BranchUpdatedEvent
  | BranchReviewWithAssistantClickedEvent
  | DpaPdfOpenedEvent
  | HomeGettingStartedWorkflowClickedEvent
  | HomeGettingStartedStepClickedEvent
  | HomeGettingStartedClosedEvent
  | HomeSectionRowsMovedEvent
  | HomeActivityStatClickedEvent
  | HomeAdvisorAskAssistantClickedEvent
  | HomeAdvisorIssueCardClickedEvent
  | HomeAdvisorFixIssueClickedEvent
  | HomeProjectUsageServiceClickedEvent
  | HomeProjectUsageChartClickedEvent
  | HomeCustomReportBlockAddedEvent
  | HomeCustomReportBlockRemovedEvent
  | DpaRequestButtonClickedEvent
  | DocumentViewButtonClickedEvent
  | HipaaRequestButtonClickedEvent
  | TableCreatedEvent
  | TableDataAddedEvent
  | TableRLSEnabledEvent
  | AuthUsersSearchedEvent


Review comment (security):
```suggestion
  | AuthUsersSearchSubmittedEvent
```

Code after:
  | ForeignDataWrapperCreatedEvent
  | StorageBucketCreatedEvent
  | BranchCreateButtonClickedEvent
  | BranchDeleteButtonClickedEvent
  | BranchCreateMergeRequestButtonClickedEvent
  | BranchCloseMergeRequestButtonClickedEvent
  | BranchMergeSubmittedEvent
  | BranchMergeSucceededEvent
  | BranchMergeFailedEvent
  | BranchUpdatedEvent
  | BranchReviewWithAssistantClickedEvent
  | DpaPdfOpenedEvent
  | HomeGettingStartedWorkflowClickedEvent
  | HomeGettingStartedStepClickedEvent
  | HomeGettingStartedClosedEvent
  | HomeSectionRowsMovedEvent
  | HomeActivityStatClickedEvent
  | HomeAdvisorAskAssistantClickedEvent
  | HomeAdvisorIssueCardClickedEvent
  | HomeAdvisorFixIssueClickedEvent
  | HomeProjectUsageServiceClickedEvent
  | HomeProjectUsageChartClickedEvent
  | HomeCustomReportBlockAddedEvent
  | HomeCustomReportBlockRemovedEvent
  | DpaRequestButtonClickedEvent
  | DocumentViewButtonClickedEvent
  | HipaaRequestButtonClickedEvent
  | TableCreatedEvent
  | TableDataAddedEvent
  | TableRLSEnabledEvent
  | AuthUsersSearchSubmittedEvent
Repository: supabase/supabase
File: apps/studio/components/interfaces/Settings/API/ServiceList.tsx (TypeScript)

Code before:
                <Alert_Shadcn_ variant="destructive">
                  <AlertCircle size={16} />
                  <AlertTitle_Shadcn_>Failed to retrieve project URL</AlertTitle_Shadcn_>
                </Alert_Shadcn_>
              ) : (
                <FormLayout
                  layout="horizontal"
                  label={
                    isCustomDomainActive ? (
                      <div className="flex items-center space-x-2">
                        <p>URL</p>
                        <Badge>Custom domain active</Badge>
                      </div>
                    ) : (
                      'URL'
                    )
                  }
                  description={
                    loadBalancerSelected
                      ? 'RESTful endpoint for querying and managing your databases through your load balancer'
                      : replicaSelected
                        ? 'RESTful endpoint for querying your read replica'
                        : 'RESTful endpoint for querying and managing your database'
                  }
                >
                  <Input copy readOnly className="input-mono" value={endpoint} />
                </FormLayout>
              )}
            </CardContent>
          </Card>

          <PostgrestConfig />
        </>
      )}
    </ScaffoldSection>
  )
}


Review comment (suggestion):
I assume the `disabled` prop was passed here (and elsewhere) to achieve the _look_ of a disabled input.

I’ve instead added `read-only` specific styles to the Input component’s definition. This is important for ergonomics. I want to be able to select text of a read-only input. Disabled inputs make that (appear) harder.

Code after:
                <Alert_Shadcn_ variant="destructive">
                  <AlertCircle size={16} />
                  <AlertTitle_Shadcn_>Failed to retrieve project URL</AlertTitle_Shadcn_>
                </Alert_Shadcn_>
              ) : (
                <FormLayout
                  layout="horizontal"
                  label={
                    isCustomDomainActive ? (
                      <div className="flex items-center space-x-2">
                        <p>URL</p>
                        <Badge>Custom domain active</Badge>
                      </div>
                    ) : (
                      'URL'
                    )
                  }
                  description={
                    loadBalancerSelected
                      ? 'RESTful endpoint for querying and managing your databases through your load balancer'
                      : replicaSelected
                        ? 'RESTful endpoint for querying your read replica'
                        : 'RESTful endpoint for querying and managing your database'
                  }
                >
                  <Input copy readOnly className="font-mono" value={endpoint} />
                </FormLayout>
              )}
            </CardContent>
          </Card>

          <PostgrestConfig />
        </>
      )}
    </ScaffoldSection>
  )
}
Repository: supabase/supabase
File: packages/eslint-config-supabase/next.js (JavaScript)

Code before:
const { defineConfig } = require('eslint/config')
const js = require('@eslint/js')
const { FlatCompat } = require('@eslint/eslintrc')
const prettierConfig = require('eslint-config-prettier/flat')
const { default: turboConfig } = require('eslint-config-turbo/flat')
const { fixupPluginRules } = require('@eslint/compat')
const tanstackQuery = require('@tanstack/eslint-plugin-query')

const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all,
})

const eslintConfig = {
  name: '@tanstack/query',
  plugins: { '@tanstack/query': fixupPluginRules(tanstackQuery) },
  rules: {
    '@tanstack/query/exhaustive-deps': 'warn',
    '@tanstack/query/no-deprecated-options': 'warn',
    '@tanstack/query/prefer-query-object-syntax': 'warn',
    '@tanstack/query/stable-query-client': 'warn',
  },
}

module.exports = defineConfig([
  // Global ignore for the .next folder
  { ignores: ['.next', 'public'] },
  turboConfig,
  prettierConfig,
  eslintConfig,
  {
    extends: compat.extends('next/core-web-vitals'),
    linterOptions: {
      reportUnusedDisableDirectives: 'warn',
    },
    rules: {
      '@next/next/no-html-link-for-pages': 'off',
      'react/jsx-key': 'off',
    },

Review comment (suggestion):
```suggestion
const tanstackQueryConfig = {
```

they're all eslint configs 😄 

Code after:
const { defineConfig } = require('eslint/config')
const js = require('@eslint/js')
const { FlatCompat } = require('@eslint/eslintrc')
const prettierConfig = require('eslint-config-prettier/flat')
const { default: turboConfig } = require('eslint-config-turbo/flat')
const { fixupPluginRules } = require('@eslint/compat')
const tanstackQuery = require('@tanstack/eslint-plugin-query')

const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all,
})

// Tanstack Query config is meant for the old non-flat esling configs. This adapts it to work with flat configs. v5 of
// the plugin supports flat configs natively.
const tanstackQueryConfig = {
  name: '@tanstack/query',
  plugins: { '@tanstack/query': fixupPluginRules(tanstackQuery) },
  rules: {
    '@tanstack/query/exhaustive-deps': 'warn',
    '@tanstack/query/no-deprecated-options': 'warn',
    '@tanstack/query/prefer-query-object-syntax': 'warn',
    '@tanstack/query/stable-query-client': 'warn',
  },
}

module.exports = defineConfig([
  // Global ignore for the .next folder
  { ignores: ['.next', 'public'] },
  turboConfig,
  prettierConfig,
  tanstackQueryConfig,
  {
    extends: compat.extends('next/core-web-vitals'),
    linterOptions: {
      reportUnusedDisableDirectives: 'warn',
    },
    rules: {
      '@next/next/no-html-link-for-pages': 'off',
Repository: supabase/supabase
File: apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx (TypeScript)

Code before:
import { LOCAL_STORAGE_KEYS } from 'common'

export const FEATURE_PREVIEWS = [
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS,
    name: 'Security notification templates',
    discussionsUrl: undefined,
    isNew: true,
    isPlatformOnly: false,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_NEW_STORAGE_UI,
    name: 'New Storage interface',
    discussionsUrl: undefined,
    isNew: true,
    isPlatformOnly: false,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS,
    name: 'New Logs interface',
    discussionsUrl: 'https://github.com/orgs/supabase/discussions/37234',
    isNew: true,
    isPlatformOnly: true,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0,
    name: 'Branching via dashboard',
    discussionsUrl: 'https://github.com/orgs/supabase/discussions/branching-2-0',
    isNew: true,
    isPlatformOnly: true,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES,
    name: 'Disable Advisor rules',

Review comment (suggestion):
Should `isPlatformOnly` be `true`? My understanding of `platform` is that it means the “Supabase-hosted version” of Studio. Does that mean these email templates only apply when that’s the case?

CC @issuedat 

Code after:
import { LOCAL_STORAGE_KEYS } from 'common'

export const FEATURE_PREVIEWS = [
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS,
    name: 'Security notification templates',
    discussionsUrl: undefined,
    isNew: true,
    isPlatformOnly: true,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_NEW_STORAGE_UI,
    name: 'New Storage interface',
    discussionsUrl: undefined,
    isNew: true,
    isPlatformOnly: false,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS,
    name: 'New Logs interface',
    discussionsUrl: 'https://github.com/orgs/supabase/discussions/37234',
    isNew: true,
    isPlatformOnly: true,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0,
    name: 'Branching via dashboard',
    discussionsUrl: 'https://github.com/orgs/supabase/discussions/branching-2-0',
    isNew: true,
    isPlatformOnly: true,
  },
  {
    key: LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES,
    name: 'Disable Advisor rules',
Repository: supabase/supabase
File: apps/studio/lib/telemetry/track.ts (TypeScript)

Code before:
 * track('help_button_clicked')
 */
export const useTrack = () => {
  const { data: project } = useSelectedProjectQuery()
  const { data: org } = useSelectedOrganizationQuery()
  const { mutate: sendEvent } = useSendEventMutation()

  const track = useCallback(
    <A extends keyof EventMap>(
      action: A,
      ...args: HasProperties<A> extends true
        ? [properties: PropertiesForAction<A>, groupOverrides?: Partial<TelemetryGroups>]
        : [properties?: undefined, groupOverrides?: Partial<TelemetryGroups>]
    ) => {
      const [properties, groupOverrides] = args

      const groups = {
        ...(project?.ref && { project: project.ref }),
        ...(org?.slug && { organization: org.slug }),
        ...groupOverrides,
      }

      const event = {
        action,
        ...(properties && { properties }),
        ...(Object.keys(groups).length > 0 && { groups }),
      } as EventMap[A]

      sendEvent(event)
    },
    [project?.ref, org?.slug, sendEvent]
  )

  return track
}


Review comment (suggestion):
Pretty sure this keys check is not needed you can achieve the same using the following: 
```suggestion
        ...(groups && { groups }),
```

Code after:
 * const track = useTrack()
 * track('table_created', { method: 'sql_editor', schema_name: 'public' })
 * track('help_button_clicked')
 */
export const useTrack = () => {
  const { data: project } = useSelectedProjectQuery()
  const { data: org } = useSelectedOrganizationQuery()
  const router = useRouter()

  const track = useCallback(
    <A extends keyof EventMap>(
      action: A,
      ...args: HasProperties<A> extends true
        ? [properties: PropertiesForAction<A>, groupOverrides?: Partial<TelemetryGroups>]
        : [properties?: undefined, groupOverrides?: Partial<TelemetryGroups>]
    ) => {
      const [properties, groupOverrides] = args

      const groups = {
        ...(project?.ref && { project: project.ref }),
        ...(org?.slug && { organization: org.slug }),
        ...groupOverrides,
      }

      const event = {
        action,
        ...(properties && { properties }),
        ...(groups && { groups }),
      } as EventMap[A]

      sendTelemetryEvent(API_URL, event, router.pathname)
    },
    [project?.ref, org?.slug, router.pathname]
  )

  return track
}
Repository: supabase/supabase
File: apps/studio/lib/telemetry/track.ts (TypeScript)

Code before:
 *
 * @example
 * const track = useTrack()
 * track('table_created', { method: 'sql_editor', schema_name: 'public' })
 * track('help_button_clicked')
 */
export const useTrack = () => {
  const { data: project } = useSelectedProjectQuery()
  const { data: org } = useSelectedOrganizationQuery()
  const { mutate: sendEvent } = useSendEventMutation()

  const track = useCallback(
    <A extends keyof EventMap>(
      action: A,
      ...args: HasProperties<A> extends true
        ? [properties: PropertiesForAction<A>, groupOverrides?: Partial<TelemetryGroups>]
        : [properties?: undefined, groupOverrides?: Partial<TelemetryGroups>]
    ) => {
      const [properties, groupOverrides] = args

      const groups = {
        ...(project?.ref && { project: project.ref }),
        ...(org?.slug && { organization: org.slug }),
        ...groupOverrides,
      }

      const event = {
        action,
        ...(properties && { properties }),
        ...(Object.keys(groups).length > 0 && { groups }),
      } as EventMap[A]

      sendEvent(event)
    },
    [project?.ref, org?.slug, sendEvent]
  )

  return track
}


Review comment (suggestion):
In a lot of places, the send event actually default the values to `Unknown`. To keep the parity we should do the same in this wrapper right? Example files:
- supabase/apps/studio/components/layouts/ProjectLayout/LayoutHeader/MergeRequestButton.tsx
- /supabase/apps/studio/components/interfaces/TableGridEditor/GridHeaderActions.tsx

Its in a bunch of other places, we do go that route the object spread becomes simple:

 
```suggestion
        { project: project.ref ?? 'Unknown',   organization: org.slug ?? 'Unknown', ...groupOverrides }
```

Code after:
/**
 * Hook for type-safe telemetry event tracking with automatic project/org context injection.
 *
 * @example
 * const track = useTrack()
 * track('table_created', { method: 'sql_editor', schema_name: 'public' })
 * track('help_button_clicked')
 */
export const useTrack = () => {
  const { data: project } = useSelectedProjectQuery()
  const { data: org } = useSelectedOrganizationQuery()
  const router = useRouter()

  const track = useCallback(
    <A extends keyof EventMap>(
      action: A,
      ...args: HasProperties<A> extends true
        ? [properties: PropertiesForAction<A>, groupOverrides?: Partial<TelemetryGroups>]
        : [properties?: undefined, groupOverrides?: Partial<TelemetryGroups>]
    ) => {
      const [properties, groupOverrides] = args

      const groups = {
        ...(project?.ref && { project: project.ref }),
        ...(org?.slug && { organization: org.slug }),
        ...groupOverrides,
      }

      const event = {
        action,
        ...(properties && { properties }),
        ...(groups && { groups }),
      } as EventMap[A]

      sendTelemetryEvent(API_URL, event, router.pathname)
    },
    [project?.ref, org?.slug, router.pathname]
  )

  return track
}
Repository: supabase/supabase
File: apps/studio/components/interfaces/Storage/VectorBuckets/VectorBucketDetails.tsx (TypeScript)

Code before:
import {
  Button,
  Card,
  CardContent,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { TimestampInfo } from 'ui-patterns/TimestampInfo'
import { BUCKET_TYPES } from '../Storage.constants'
import { CreateVectorIndexSheet } from './CreateVectorIndexSheet'

// Mock data for development - remove when backend is ready
const MOCK_VECTOR_INDEXES = [
  {
    indexName: 'documents_index',
    creationTime: '1704067200', // Jan 1, 2024
  },
  {
    indexName: 'embeddings_index',
    creationTime: '1704153600', // Jan 2, 2024
  },
  {
    indexName: 'search_index',
    creationTime: '1704240000', // Jan 3, 2024
  },
]

const MOCK_VECTOR_INDEXES_EMPTY = []

interface VectorBucketDetailsProps {
  bucket: { vectorBucketName: string; creationTime: string }
}

export const VectorBucketDetails = ({ bucket }: VectorBucketDetailsProps) => {
  const { ref: projectRef } = useParams()

  // Use the correct query for bucket contents
  const { data, isLoading, error } = useVectorBucketsIndexesQuery({
    projectRef,
    vectorBucketName: bucket.vectorBucketName,
  })


Review comment (suggestion):
Reintroduced these. Sorry. Figured they are helpful to show in the table because they are required options upon table creation.

Code after:
import {
  Button,
  Card,
  CardContent,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { BUCKET_TYPES } from '../Storage.constants'
import { CreateVectorTableSheet } from './CreateVectorTableSheet'

// Mock data for development - remove when backend is ready
const MOCK_VECTOR_INDEXES = [
  {
    indexName: 'documents_index',
    creationTime: '1704067200', // Jan 1, 2024
    dimension: 1536,
    distanceMetric: 'cosine',
  },
  {
    indexName: 'embeddings_index',
    creationTime: '1704153600', // Jan 2, 2024
    dimension: 1536,
    distanceMetric: 'cosine',
  },
  {
    indexName: 'search_index',
    creationTime: '1704240000', // Jan 3, 2024
    dimension: 1536,
    distanceMetric: 'cosine',
  },
]

const MOCK_VECTOR_INDEXES_EMPTY = []

interface VectorBucketDetailsProps {
  bucket: { vectorBucketName: string; creationTime: string }
}

export const VectorBucketDetails = ({ bucket }: VectorBucketDetailsProps) => {
  const { ref: projectRef } = useParams()

  // Use the correct query for bucket contents
Repository: supabase/supabase
File: apps/studio/components/ui/ErrorBoundary/InsertBeforeRemoveChildErrorHandler.tsx (TypeScript)

Code before:
                ? 'https://github.com/facebook/react/issues/17256'
                : isInsertBeforeError
                  ? 'https://github.com/facebook/react/issues/24865'
                  : '/'
            }
          >
            More information
          </a>
        </Button>
        <Button type="outline" onClick={() => router.reload()}>
          Refresh page
        </Button>
      </div>
      <SupportLink
        className="text-center text-xs text-foreground-lighter hover:text-foreground-light transition"
        queryParams={{
          category: SupportCategories.DASHBOARD_BUG,
          subject: `Client error: Failed to execute '${isRemoveChildError ? 'removeChild' : 'insertBefore'}' on 'Node'`,
          sid: sentryIssueId,
          error: urlMessage,
        }}
      >
        Still stuck?
      </SupportLink>
    </>
  )
}


Review comment (suggestion):
I thought we agreed to remove the ability to not create a support ticket on this? Might be mistake on it

Code after:
            href={
              isRemoveChildError
                ? 'https://github.com/facebook/react/issues/17256'
                : isInsertBeforeError
                  ? 'https://github.com/facebook/react/issues/24865'
                  : '/'
            }
          >
            More information
          </a>
        </Button>
        <Button type="outline" onClick={() => router.reload()}>
          Refresh page
        </Button>
      </div>
      <SupportLink
        className="text-center text-xs text-foreground-lighter hover:text-foreground-light transition"
        queryParams={{
          category: SupportCategories.DASHBOARD_BUG,
          subject: `Client error: Failed to execute '${isRemoveChildError ? 'removeChild' : 'insertBefore'}' on 'Node'`,
          sid: sentryIssueId,
          error: urlMessage,
        }}
      >
        Still stuck?
      </SupportLink>
    </>
  )
}
Repository: supabase/supabase
File: apps/studio/components/interfaces/Auth/Policies/PoliciesDataContext.tsx (TypeScript)

Code before:
import type { PostgresPolicy } from '@supabase/postgres-meta'
import type { PropsWithChildren } from 'react'
import { createContext, useCallback, useContext, useMemo } from 'react'

import type { ResponseError } from 'types'

type TableKey = `${string}.${string}`

interface PoliciesDataContextValue {
  getPoliciesForTable: (schema: string, table: string) => PostgresPolicy[]
  isPoliciesLoading: boolean
  isPoliciesError: boolean
  policiesError?: ResponseError | Error
  exposedSchemas: Set<string>
}

const PoliciesDataContext = createContext<PoliciesDataContextValue | null>(null)

export const usePoliciesData = () => {
  const context = useContext(PoliciesDataContext)
  if (!context) throw new Error('usePoliciesData must be used within PoliciesDataProvider')
  return context
}

interface PoliciesDataProviderProps {
  policies: PostgresPolicy[]
  isPoliciesLoading: boolean
  isPoliciesError: boolean
  policiesError?: ResponseError | Error
  exposedSchemas: string[]
}

export const PoliciesDataProvider = ({
  children,
  policies,
  isPoliciesLoading,
  isPoliciesError,
  policiesError,
  exposedSchemas,
}: PropsWithChildren<PoliciesDataProviderProps>) => {

Review comment (suggestion):
nit: Some places we use types and other places we use interfaces? Thoughts on just standardizing this to types? 


```suggestion
type PoliciesDataContextValue = {
  getPoliciesForTable: (schema: string, table: string) => PostgresPolicy[]
  isPoliciesLoading: boolean
  isPoliciesError: boolean
  policiesError?: ResponseError | Error
  exposedSchemas: Set<string>
}
```

Code after:
import type { PostgresPolicy } from '@supabase/postgres-meta'
import type { PropsWithChildren } from 'react'
import { createContext, useCallback, useContext, useMemo } from 'react'

import type { ResponseError } from 'types'

type TableKey = `${string}.${string}`

type PoliciesDataContextValue = {
  getPoliciesForTable: (schema: string, table: string) => PostgresPolicy[]
  isPoliciesLoading: boolean
  isPoliciesError: boolean
  policiesError?: ResponseError | Error
  exposedSchemas: Set<string>
}

const PoliciesDataContext = createContext<PoliciesDataContextValue | null>(null)

export const usePoliciesData = () => {
  const context = useContext(PoliciesDataContext)
  if (!context) throw new Error('usePoliciesData must be used within PoliciesDataProvider')
  return context
}

type PoliciesDataProviderProps = {
  policies: PostgresPolicy[]
  isPoliciesLoading: boolean
  isPoliciesError: boolean
  policiesError?: ResponseError | Error
  exposedSchemas: string[]
}

export const PoliciesDataProvider = ({
  children,
  policies,
  isPoliciesLoading,
  isPoliciesError,
  policiesError,
  exposedSchemas,
}: PropsWithChildren<PoliciesDataProviderProps>) => {