useOrgOptedIntoAi.ts84 lines · main
| 1 | import { z } from 'zod' |
| 2 | |
| 3 | import { subscriptionHasHipaaAddon } from '@/components/interfaces/Billing/Subscription/Subscription.utils' |
| 4 | import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' |
| 5 | import { useOrgSubscriptionQuery } from '@/data/subscriptions/org-subscription-query' |
| 6 | import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' |
| 7 | import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' |
| 8 | import { IS_PLATFORM, OPT_IN_TAGS } from '@/lib/constants' |
| 9 | |
| 10 | export const aiOptInLevelSchema = z.enum([ |
| 11 | 'disabled', |
| 12 | 'schema', |
| 13 | 'schema_and_log', |
| 14 | 'schema_and_log_and_data', |
| 15 | ]) |
| 16 | |
| 17 | export type AiOptInLevel = z.infer<typeof aiOptInLevelSchema> |
| 18 | |
| 19 | export const getAiOptInLevel = (tags: string[] | undefined): AiOptInLevel => { |
| 20 | const hasSql = tags?.includes(OPT_IN_TAGS.AI_SQL) |
| 21 | const hasData = tags?.includes(OPT_IN_TAGS.AI_DATA) |
| 22 | const hasLog = tags?.includes(OPT_IN_TAGS.AI_LOG) |
| 23 | |
| 24 | if (hasData) { |
| 25 | return 'schema_and_log_and_data' |
| 26 | } else if (hasLog) { |
| 27 | return 'schema_and_log' |
| 28 | } else if (hasSql) { |
| 29 | return 'schema' |
| 30 | } else { |
| 31 | return 'disabled' |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | /** |
| 36 | * Determines if the organization has opted into *any* level of AI features (schema or schema_and_log or schema_and_log_and_data). |
| 37 | * This is primarily for backward compatibility. |
| 38 | * @returns boolean (true if opted into schema or schema_and_log or schema_and_log_and_data, false otherwise) |
| 39 | */ |
| 40 | export function useOrgOptedIntoAi(): boolean { |
| 41 | const { aiOptInLevel } = useOrgAiOptInLevel() |
| 42 | return !IS_PLATFORM || aiOptInLevel !== 'disabled' |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * Determines the organization's specific AI opt-in level and whether schema metadata should be included. |
| 47 | * @returns Object with aiOptInLevel and includeSchemaMetadata |
| 48 | */ |
| 49 | export function useOrgAiOptInLevel(): { |
| 50 | aiOptInLevel: AiOptInLevel |
| 51 | includeSchemaMetadata: boolean |
| 52 | isHipaaProjectDisallowed: boolean |
| 53 | } { |
| 54 | const { data: selectedProject } = useSelectedProjectQuery() |
| 55 | const { data: selectedOrganization } = useSelectedOrganizationQuery() |
| 56 | |
| 57 | // [Joshen] Default to disabled until migration to clean up existing opt in tags are completed |
| 58 | // Once toggled on, then we can default to their set opt in level and clean up feature flag |
| 59 | const optInTags = selectedOrganization?.opt_in_tags |
| 60 | const level = getAiOptInLevel(optInTags) |
| 61 | const isOptedIntoAI = level !== 'disabled' |
| 62 | |
| 63 | const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: selectedOrganization?.slug }) |
| 64 | const hasHipaaAddon = subscriptionHasHipaaAddon(subscription) |
| 65 | |
| 66 | const { data: projectSettings } = useProjectSettingsV2Query({ projectRef: selectedProject?.ref }) |
| 67 | const isProjectSensitive = !!projectSettings?.is_sensitive |
| 68 | |
| 69 | const preventProjectFromUsingAI = hasHipaaAddon && isProjectSensitive |
| 70 | |
| 71 | // [Joshen] For CLI / self-host, we'd default to 'schema' as opt in level |
| 72 | const aiOptInLevel = !IS_PLATFORM |
| 73 | ? 'schema' |
| 74 | : (isOptedIntoAI && !selectedProject) || (isOptedIntoAI && !preventProjectFromUsingAI) |
| 75 | ? level |
| 76 | : 'disabled' |
| 77 | const includeSchemaMetadata = !IS_PLATFORM || aiOptInLevel !== 'disabled' |
| 78 | |
| 79 | return { |
| 80 | aiOptInLevel, |
| 81 | includeSchemaMetadata, |
| 82 | isHipaaProjectDisallowed: preventProjectFromUsingAI, |
| 83 | } |
| 84 | } |