-            
-              
+      
+        
+          
+          
+            
+              
The project "{project?.name}" is currently paused
+              
+                {isLoading && 
}
 
-              
-                
-                  
-                    The project "{project?.name ?? ''}" is currently paused.
-                  
-                  
+                {isPauseStatusSuccess && !isRestoreDisabled ? (
+                  isFreePlan ? (
+                    <>
+                      
+                        All data, including backups and storage objects, remains safe. You can
+                        resume this project from the dashboard within{' '}
+                        
+                          
+                            
+                              {finalDaysRemainingBeforeRestoreDisabled} day
+                              {finalDaysRemainingBeforeRestoreDisabled > 1 ? 's' : ''}
+                            {' '}
+                          
+                          
+                            Free projects cannot be restored through the dashboard if they are
+                            paused for more than {pauseStatus.max_days_till_restore_disabled} days
+                          
+                        {' '}
+                        (until{' '}
+                        
+                        ). After that, this project will not be resumable, but data will still be
+                        available for download.
+                      
+                      
+                        {enableProBenefitWording === 'variant-a'
+                          ? 'Upgrade to Pro to prevent pauses and unlock features like branching, compute upgrades, and daily backups.'
+                          : 'To prevent future pauses, consider upgrading to Pro.'}
+                      
+                    >
+                  ) : (
+                    
+                      Your project data is safe but inaccessible while paused. Once resumed, usage
+                      will be billed by compute size and hours active.
+                    
+                  )
+                ) : !isLoading ? (
+                  
                     All of your project's data is still intact, but your project is inaccessible
                     while paused.{' '}
                     {product !== undefined ? (
                       <>
-                        Restore this project to access the{' '}
-                        {product} page
+                        Resume this project to access the{' '}
+                        {product} page.
                       >
-                    ) : (
-                      'Restore this project and get back to building!'
-                    )}
+                    ) : !isRestoreDisabled ? (
+                      'Resume this project and get back to building!'
+                    ) : null}
                   
-                
-
-                {isLoading && 
}
-                {isError && (
-                  
-                )}
-                {isSuccess && (
-                  <>
-                    {isRestoreDisabled ? (
-                      
-                    ) : isFreePlan ? (
-                      <>
-                        
-                          {enableProBenefitWording === 'variant-a'
-                            ? 'Upgrade to Pro plan to prevent future pauses and use Pro features like branching, compute upgrades, and daily backups.'
-                            : 'To prevent future pauses, consider upgrading to Pro.'}
-                        
-                        
-                          
-                            Project can be restored through the dashboard within the next{' '}
-                            {finalDaysRemainingBeforeRestoreDisabled} day
-                            {finalDaysRemainingBeforeRestoreDisabled > 1 ? 's' : ''}
-                          
-                          
-                            Free projects cannot be restored through the dashboard if they are
-                            paused for more than{' '}
-                            
-                              {pauseStatus?.max_days_till_restore_disabled} days
-                            
-                            . The latest that your project can be restored is by{' '}
-                            
-                              {dayjs()
-                                .utc()
-                                .add(pauseStatus.remaining_days_till_restore_disabled ?? 0, 'day')
-                                .format('DD MMM YYYY')}
-                            
-                            . However, your database backup and Storage objects will still be
-                            available for download thereafter.
-                          
-                          
-                            }>
-                              
-                                More information
-                              
-                            
-                          
-                        
-                      >
-                    ) : (
-                      
-                    )}
-                  >
-                )}
+                ) : null}
               
-
-              {isSuccess && !isRestoreDisabled && (
-                
-                  
-                    Restore project
-                  
-                  {isFreePlan ? (
-                    
-                  ) : (
-                    
-                  )}
-                
-              )}
             
-        
+        
+
+        {isError && (
+          
+        )}
+
+        {isPauseStatusSuccess && !isRestoreDisabled && (
+          
+            
+              Resume project
+            
+
+            {isFreePlan ? (
+              
+            ) : (
+              
+            )}
+          
+        )}
 
-      
}
+      
+
+      
 setShowConfirmRestore(false)}
-        header={'Restore this project'}
+        onConfirm={() => form.handleSubmit(onConfirmRestore)()}
+        loading={isRestoring}
+        confirmLabel="Confirm resume"
+        cancelLabel="Cancel"
       >
         
           
         
-      
+      
 
-      
 setShowFreeProjectLimitWarning(false)}
+      
+        
+          
+            
+              Your organization has members who have exceeded their free project limits
+            
+          
+          
+            
+              The following members have reached their maximum limits for the number of active free
+              plan projects within organizations where they are an administrator or owner:
+            
+            
+              {(membersExceededLimit || []).map((member, idx: number) => (
+                - 
+                  {member.username || member.primary_email} (Limit: {member.free_project_limit} free
+                  projects)
+                +              ))}
+
+
+              These members will need to either delete, pause, or upgrade one or more of these
+              projects before you're able to resume this project.
+            
+          
+          
+            
+          
+        
+      
     >
   )
 }
diff --git a/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx b/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx
index 68d6e88b3597b..507121413df39 100644
--- a/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx
+++ b/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx
@@ -1,12 +1,13 @@
-import { AnimatePresence, motion } from 'framer-motion'
 import Head from 'next/head'
 import { useRouter } from 'next/router'
 import { forwardRef, Fragment, PropsWithChildren, ReactNode, useEffect, useState } from 'react'
-import { useParams, useFlag } from 'common'
+
+import { useFlag, useParams } from 'common'
 import { CreateBranchModal } from 'components/interfaces/BranchManagement/CreateBranchModal'
-import ProjectAPIDocs from 'components/interfaces/ProjectAPIDocs/ProjectAPIDocs'
+import { ProjectAPIDocs } from 'components/interfaces/ProjectAPIDocs/ProjectAPIDocs'
 import { Loading } from 'components/ui/Loading'
 import { ResourceExhaustionWarningBanner } from 'components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner'
+import { AnimatePresence, motion } from 'framer-motion'
 import { useCustomContent } from 'hooks/custom-content/useCustomContent'
 import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
 import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
@@ -19,6 +20,8 @@ import MobileSheetNav from 'ui-patterns/MobileSheetNav/MobileSheetNav'
 import { useEditorType } from '../editors/EditorsLayout.hooks'
 import BuildingState from './BuildingState'
 import ConnectingState from './ConnectingState'
+import { LayoutSidebar } from './LayoutSidebar'
+import { LayoutSidebarProvider } from './LayoutSidebar/LayoutSidebarProvider'
 import { LoadingState } from './LoadingState'
 import { ProjectPausedState } from './PausedState/ProjectPausedState'
 import { PauseFailedState } from './PauseFailedState'
@@ -29,8 +32,6 @@ import RestartingState from './RestartingState'
 import { RestoreFailedState } from './RestoreFailedState'
 import RestoringState from './RestoringState'
 import { UpgradingState } from './UpgradingState'
-import { LayoutSidebar } from './LayoutSidebar'
-import { LayoutSidebarProvider } from './LayoutSidebar/LayoutSidebarProvider'
 
 // [Joshen] This is temporary while we unblock users from managing their project
 // if their project is not responding well for any reason. Eventually needs a bit of an overhaul
diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx
index 7cade33d6da85..28dda2cedd8b6 100644
--- a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx
+++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorNav.tsx
@@ -19,8 +19,8 @@ import { Snippet, SnippetFolder, useSQLSnippetFoldersQuery } from 'data/content/
 import { useSqlSnippetsQuery } from 'data/content/sql-snippets-query'
 import { useLocalStorage } from 'hooks/misc/useLocalStorage'
 import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
+import { uuidv4 } from 'lib/helpers'
 import { useProfile } from 'lib/profile'
-import uuidv4 from 'lib/uuid'
 import { useSnippetFolders, useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
 import { createTabId, useTabsStateSnapshot } from 'state/tabs'
 import { TreeView } from 'ui'
diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx
index e22c2d522138b..89e82df6d9269 100644
--- a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx
+++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx
@@ -24,8 +24,8 @@ import { Snippet } from 'data/content/sql-folders-query'
 import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
 import useLatest from 'hooks/misc/useLatest'
 import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
+import { uuidv4 } from 'lib/helpers'
 import { useProfile } from 'lib/profile'
-import uuidv4 from 'lib/uuid'
 import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
 import {
   Button,
diff --git a/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx b/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx
index 10057b9076094..81be39cbbada9 100644
--- a/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx
+++ b/apps/studio/components/layouts/StorageLayout/StorageLayout.tsx
@@ -25,6 +25,8 @@ const StorageLayout = ({ title, children }: StorageLayoutProps) => {
     const { pathname } = router
     const suffix = !!featurePreviewModal ? `?featurePreviewModal=${featurePreviewModal}` : ''
 
+    if (!ref) return
+
     if (isStorageV2) {
       // From old UI to new UI
       if (pathname.endsWith('/storage/settings')) {
@@ -58,7 +60,7 @@ const StorageLayout = ({ title, children }: StorageLayoutProps) => {
       }
     }
     // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [isStorageV2])
+  }, [ref, isStorageV2])
 
   return (
     
>
+
+export const useDeletePublicationMutation = ({
+  onSuccess,
+  onError,
+  ...options
+}: Omit<
+  UseMutationOptions,
+  'mutationFn'
+> = {}) => {
+  const queryClient = useQueryClient()
+
+  return useMutation({
+    mutationFn: (vars) => deletePublication(vars),
+    async onSuccess(data, variables, context) {
+      const { projectRef, sourceId } = variables
+      await queryClient.invalidateQueries(replicationKeys.publications(projectRef, sourceId))
+      await onSuccess?.(data, variables, context)
+    },
+    async onError(data, variables, context) {
+      if (onError === undefined) {
+        toast.error(`Failed to delete publication: ${data.message}`)
+      } else {
+        onError(data, variables, context)
+      }
+    },
+    ...options,
+  })
+}
diff --git a/apps/studio/data/replication/publications-query.ts b/apps/studio/data/replication/publications-query.ts
index 576424cd09aee..8a10561946baf 100644
--- a/apps/studio/data/replication/publications-query.ts
+++ b/apps/studio/data/replication/publications-query.ts
@@ -1,11 +1,15 @@
 import { UseQueryOptions, useQuery } from '@tanstack/react-query'
 
+import { components } from 'api-types'
 import { get, handleError } from 'data/fetchers'
 import { ResponseError } from 'types'
 import { replicationKeys } from './keys'
 
 type ReplicationPublicationsParams = { projectRef?: string; sourceId?: number }
 
+export type ReplicationPublication =
+  components['schemas']['ReplicationPublicationsResponse']['publications'][number]
+
 async function fetchReplicationPublications(
   { projectRef, sourceId }: ReplicationPublicationsParams,
   signal?: AbortSignal
diff --git a/apps/studio/data/storage/analytics-bucket-create-mutation.ts b/apps/studio/data/storage/analytics-bucket-create-mutation.ts
new file mode 100644
index 0000000000000..55d9a081ee3ac
--- /dev/null
+++ b/apps/studio/data/storage/analytics-bucket-create-mutation.ts
@@ -0,0 +1,58 @@
+// @ts-nocheck
+// [Joshen] To remove after infra changes for analytics bucket is in
+import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
+import { toast } from 'sonner'
+
+import { components } from 'api-types'
+import { handleError, post } from 'data/fetchers'
+import type { ResponseError } from 'types'
+import { storageKeys } from './keys'
+
+type AnalyticsBucketCreateVariables = CreateAnalyticsBucketBody & {
+  projectRef: string
+}
+
+type CreateAnalyticsBucketBody = components['schemas']['CreateStorageAnalyticsBucketBody']
+
+async function createAnalyticsBucket({ projectRef, bucketName }: AnalyticsBucketCreateVariables) {
+  if (!projectRef) throw new Error('projectRef is required')
+  if (!bucketName) throw new Error('Bucket name is required')
+
+  const { data, error } = await post('/platform/storage/{ref}/analytics-buckets', {
+    params: { path: { ref: projectRef } },
+    body: { bucketName },
+  })
+
+  if (error) handleError(error)
+  return data
+}
+
+type AnalyticsBucketCreateData = Awaited>
+
+export const useAnalyticsBucketCreateMutation = ({
+  onSuccess,
+  onError,
+  ...options
+}: Omit<
+  UseMutationOptions,
+  'mutationFn'
+> = {}) => {
+  const queryClient = useQueryClient()
+
+  return useMutation({
+    mutationFn: (vars) => createAnalyticsBucket(vars),
+    async onSuccess(data, variables, context) {
+      const { projectRef } = variables
+      await queryClient.invalidateQueries(storageKeys.analyticsBuckets(projectRef))
+      await onSuccess?.(data, variables, context)
+    },
+    async onError(data, variables, context) {
+      if (onError === undefined) {
+        toast.error(`Failed to create analytics bucket: ${data.message}`)
+      } else {
+        onError(data, variables, context)
+      }
+    },
+    ...options,
+  })
+}
diff --git a/apps/studio/data/storage/analytics-bucket-delete-mutation.ts b/apps/studio/data/storage/analytics-bucket-delete-mutation.ts
new file mode 100644
index 0000000000000..d71105d2b78a3
--- /dev/null
+++ b/apps/studio/data/storage/analytics-bucket-delete-mutation.ts
@@ -0,0 +1,61 @@
+// @ts-nocheck
+// [Joshen] To remove after infra changes for analytics bucket is in
+import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
+import { toast } from 'sonner'
+
+import { useIsNewStorageUIEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
+import { del, handleError } from 'data/fetchers'
+import type { ResponseError } from 'types'
+import { storageKeys } from './keys'
+
+type AnalyticsBucketDeleteVariables = {
+  projectRef: string
+  id: string
+}
+
+async function deleteAnalyticsBucket({ projectRef, id }: AnalyticsBucketDeleteVariables) {
+  if (!projectRef) throw new Error('projectRef is required')
+  if (!id) throw new Error('Bucket name is requried')
+
+  const { data, error } = await del('/platform/storage/{ref}/analytics-buckets/{id}', {
+    params: { path: { ref: projectRef, id } },
+  } as any)
+
+  if (error) handleError(error)
+  return data
+}
+
+type AnalyticsBucketDeleteData = Awaited>
+
+export const useAnalyticsBucketDeleteMutation = ({
+  onSuccess,
+  onError,
+  ...options
+}: Omit<
+  UseMutationOptions,
+  'mutationFn'
+> = {}) => {
+  const queryClient = useQueryClient()
+  const isStorageV2 = useIsNewStorageUIEnabled()
+
+  return useMutation({
+    mutationFn: (vars) => deleteAnalyticsBucket(vars),
+    async onSuccess(data, variables, context) {
+      const { projectRef } = variables
+      if (isStorageV2) {
+        await queryClient.invalidateQueries(storageKeys.analyticsBuckets(projectRef))
+      } else {
+        await queryClient.invalidateQueries(storageKeys.buckets(projectRef))
+      }
+      await onSuccess?.(data, variables, context)
+    },
+    async onError(data, variables, context) {
+      if (onError === undefined) {
+        toast.error(`Failed to delete analytics bucket: ${data.message}`)
+      } else {
+        onError(data, variables, context)
+      }
+    },
+    ...options,
+  })
+}
diff --git a/apps/studio/data/storage/analytics-buckets-query.ts b/apps/studio/data/storage/analytics-buckets-query.ts
new file mode 100644
index 0000000000000..03fd2c7e65b6b
--- /dev/null
+++ b/apps/studio/data/storage/analytics-buckets-query.ts
@@ -0,0 +1,66 @@
+// @ts-nocheck
+// [Joshen] To remove after infra changes for analytics bucket is in
+import { useQuery, UseQueryOptions } from '@tanstack/react-query'
+
+import { components } from 'api-types'
+import { get, handleError } from 'data/fetchers'
+import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
+import { PROJECT_STATUS } from 'lib/constants'
+import type { ResponseError } from 'types'
+import { storageKeys } from './keys'
+
+export type AnalyticsBucketsVariables = { projectRef?: string }
+export type AnalyticsBucket = components['schemas']['StorageAnalyticsBucketResponse']
+export type AnalyticsBuckets = components['schemas'][]
+
+export async function getAnalyticsBuckets(
+  { projectRef }: AnalyticsBucketsVariables,
+  signal?: AbortSignal
+) {
+  if (!projectRef) throw new Error('projectRef is required')
+
+  const { data, error } = await get('/platform/storage/{ref}/analytics-buckets', {
+    params: { path: { ref: projectRef } },
+    signal,
+  })
+
+  if (error) handleError(error)
+  return data.data
+}
+
+export type AnalyticsBucketsData = Awaited>
+export type AnalyticsBucketsError = ResponseError
+
+export const useAnalyticsBucketsQuery = (
+  { projectRef }: AnalyticsBucketsVariables,
+  {
+    enabled = true,
+    ...options
+  }: UseQueryOptions = {}
+) => {
+  const { data: project } = useSelectedProjectQuery()
+  const isActive = project?.status === PROJECT_STATUS.ACTIVE_HEALTHY
+
+  return useQuery({
+    queryKey: storageKeys.analyticsBuckets(projectRef),
+    queryFn: ({ signal }) => getAnalyticsBuckets({ projectRef }, signal),
+    enabled: enabled && typeof projectRef !== 'undefined' && isActive,
+    ...options,
+    retry: (failureCount, error) => {
+      if (
+        typeof error === 'object' &&
+        error !== null &&
+        error.message.startsWith('Tenant config') &&
+        error.message.endsWith('not found')
+      ) {
+        return false
+      }
+
+      if (failureCount < 3) {
+        return true
+      }
+
+      return false
+    },
+  })
+}
diff --git a/apps/studio/data/storage/bucket-delete-mutation.ts b/apps/studio/data/storage/bucket-delete-mutation.ts
index 77f2db799110e..7586d1524530b 100644
--- a/apps/studio/data/storage/bucket-delete-mutation.ts
+++ b/apps/studio/data/storage/bucket-delete-mutation.ts
@@ -3,29 +3,26 @@ import { toast } from 'sonner'
 
 import { del, handleError, post } from 'data/fetchers'
 import type { ResponseError } from 'types'
-import { BucketType } from './buckets-query'
 import { storageKeys } from './keys'
 
 type BucketDeleteVariables = {
   projectRef: string
   id: string
-  type: BucketType
 }
 
-async function deleteBucket({ projectRef, id, type }: BucketDeleteVariables) {
+async function deleteBucket({ projectRef, id }: BucketDeleteVariables) {
   if (!projectRef) throw new Error('projectRef is required')
   if (!id) throw new Error('Bucket name is requried')
 
-  if (type !== 'ANALYTICS') {
-    const { error: emptyBucketError } = await post('/platform/storage/{ref}/buckets/{id}/empty', {
-      params: { path: { ref: projectRef, id } },
-    })
-    if (emptyBucketError) handleError(emptyBucketError)
-  }
+  const { error: emptyBucketError } = await post('/platform/storage/{ref}/buckets/{id}/empty', {
+    params: { path: { ref: projectRef, id } },
+  })
+  if (emptyBucketError) handleError(emptyBucketError)
 
   const { data, error: deleteBucketError } = await del('/platform/storage/{ref}/buckets/{id}', {
-    params: { path: { ref: projectRef, id }, query: { type } },
+    params: { path: { ref: projectRef, id } },
   } as any)
+
   if (deleteBucketError) handleError(deleteBucketError)
   return data
 }
diff --git a/apps/studio/data/storage/buckets-query.ts b/apps/studio/data/storage/buckets-query.ts
index 0779e0d9f6369..621e069d9d405 100644
--- a/apps/studio/data/storage/buckets-query.ts
+++ b/apps/studio/data/storage/buckets-query.ts
@@ -44,8 +44,7 @@ export const useBucketsQuery = (
       if (
         typeof error === 'object' &&
         error !== null &&
-        error.message.startsWith('Tenant config') &&
-        error.message.endsWith('not found')
+        error.message.includes('Missing tenant config')
       ) {
         return false
       }
diff --git a/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts b/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts
index 56752fd634651..0b2c08edf9763 100644
--- a/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts
+++ b/apps/studio/data/storage/iceberg-wrapper-create-mutation.ts
@@ -1,7 +1,10 @@
 import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { snakeCase } from 'lodash'
 
 import { WRAPPERS } from 'components/interfaces/Integrations/Wrappers/Wrappers.constants'
+import {
+  getAnalyticsBucketFDWName,
+  getAnalyticsBucketS3KeyName,
+} from 'components/interfaces/Storage/AnalyticsBucketDetails/AnalyticsBucketDetails.utils'
 import {
   getCatalogURI,
   getConnectionURL,
@@ -40,10 +43,10 @@ export const useIcebergWrapperCreateMutation = () => {
   const mutateAsync = async ({ bucketName }: { bucketName: string }) => {
     const createS3KeyData = await createS3AccessKey({
       projectRef: project?.ref,
-      description: `${snakeCase(bucketName)}_keys`,
+      description: getAnalyticsBucketS3KeyName(bucketName),
     })
 
-    const wrapperName = `${snakeCase(bucketName)}_fdw`
+    const wrapperName = getAnalyticsBucketFDWName(bucketName)
 
     const params: FDWCreateVariables = {
       projectRef: project?.ref,
diff --git a/apps/studio/data/storage/keys.ts b/apps/studio/data/storage/keys.ts
index e68911d547c71..5d796b07b0dcc 100644
--- a/apps/studio/data/storage/keys.ts
+++ b/apps/studio/data/storage/keys.ts
@@ -1,5 +1,7 @@
 export const storageKeys = {
   buckets: (projectRef: string | undefined) => ['projects', projectRef, 'buckets'] as const,
+  analyticsBuckets: (projectRef: string | undefined) =>
+    ['projects', projectRef, 'analytics-buckets'] as const,
   archive: (projectRef: string | undefined) => ['projects', projectRef, 'archive'] as const,
   icebergNamespaces: (catalog: string, warehouse: string) =>
     ['catalog', catalog, 'warehouse', warehouse, 'namespaces'] as const,
diff --git a/apps/studio/data/storage/s3-access-key-query.ts b/apps/studio/data/storage/s3-access-key-query.ts
index ffdc0243653d9..61adee253acf4 100644
--- a/apps/studio/data/storage/s3-access-key-query.ts
+++ b/apps/studio/data/storage/s3-access-key-query.ts
@@ -1,12 +1,17 @@
 import { UseQueryOptions, useQuery } from '@tanstack/react-query'
 
+import { components } from 'api-types'
 import { get, handleError } from 'data/fetchers'
+import { IS_PLATFORM } from 'lib/constants'
 import { ResponseError } from 'types'
 import { storageCredentialsKeys } from './s3-access-key-keys'
-import { IS_PLATFORM } from 'lib/constants'
 
 type StorageCredentialsVariables = { projectRef?: string }
 
+export type S3AccessKey = components['schemas']['GetStorageCredentialsResponse']['data'][number] & {
+  access_key: string
+}
+
 async function fetchStorageCredentials(
   { projectRef }: StorageCredentialsVariables,
   signal?: AbortSignal
@@ -19,16 +24,7 @@ async function fetchStorageCredentials(
   })
 
   if (error) handleError(error)
-
-  // Generated types by openapi are wrong so we need to cast it.
-  return data as unknown as {
-    data: {
-      id: string
-      created_at: string
-      access_key: string
-      description: string
-    }[]
-  }
+  return data as { data: S3AccessKey[] }
 }
 
 export type StorageCredentialsData = Awaited>
diff --git a/apps/studio/lib/helpers.test.ts b/apps/studio/lib/helpers.test.ts
index 1c53bda36cdac..7699fdd23108b 100644
--- a/apps/studio/lib/helpers.test.ts
+++ b/apps/studio/lib/helpers.test.ts
@@ -1,4 +1,6 @@
+import { v4 as _uuidV4 } from 'uuid'
 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
+
 import {
   detectBrowser,
   detectOS,
@@ -22,10 +24,23 @@ import {
   timeout,
   tryParseInt,
   tryParseJson,
+  uuidv4,
 } from './helpers'
 
 import { copyToClipboard } from 'ui'
 
+vi.mock('uuid', () => ({
+  v4: vi.fn(() => 'mocked-uuid'),
+}))
+
+describe('uuidv4', () => {
+  it('calls uuid.v4 and returns the result', () => {
+    const result = uuidv4()
+    expect(_uuidV4).toHaveBeenCalled()
+    expect(result).toBe('mocked-uuid')
+  })
+})
+
 describe('tryParseJson', () => {
   it('should return the parsed JSON', () => {
     const result = tryParseJson('{"test": "test"}')
diff --git a/apps/studio/lib/helpers.ts b/apps/studio/lib/helpers.ts
index 7c4d38c1b0b50..a0a21bd26e80b 100644
--- a/apps/studio/lib/helpers.ts
+++ b/apps/studio/lib/helpers.ts
@@ -1,7 +1,12 @@
-export { default as uuidv4 } from './uuid'
 import { UIEvent } from 'react'
+import { v4 as _uuidV4 } from 'uuid'
+
 import type { TablesData } from '../data/tables/tables-query'
 
+export const uuidv4 = () => {
+  return _uuidV4()
+}
+
 export const isAtBottom = ({ currentTarget }: UIEvent): boolean => {
   return currentTarget.scrollTop + 10 >= currentTarget.scrollHeight - currentTarget.clientHeight
 }
diff --git a/apps/studio/lib/uuid.test.ts b/apps/studio/lib/uuid.test.ts
deleted file mode 100644
index 6ceeb8bf49aa7..0000000000000
--- a/apps/studio/lib/uuid.test.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { describe, it, expect, vi } from 'vitest'
-import { v4 as _uuidV4 } from 'uuid'
-import uuidv4 from './uuid'
-
-vi.mock('uuid', () => ({
-  v4: vi.fn(() => 'mocked-uuid'),
-}))
-
-describe('uuidv4', () => {
-  it('calls uuid.v4 and returns the result', () => {
-    const result = uuidv4()
-    expect(_uuidV4).toHaveBeenCalled()
-    expect(result).toBe('mocked-uuid')
-  })
-})
diff --git a/apps/studio/lib/uuid.ts b/apps/studio/lib/uuid.ts
deleted file mode 100644
index c33432b302deb..0000000000000
--- a/apps/studio/lib/uuid.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { v4 as _uuidV4 } from 'uuid'
-
-const uuidv4 = () => {
-  return _uuidV4()
-}
-
-export default uuidv4
diff --git a/apps/studio/pages/project/[ref]/settings/general.tsx b/apps/studio/pages/project/[ref]/settings/general.tsx
index 11943bbd52f38..618016b289f99 100644
--- a/apps/studio/pages/project/[ref]/settings/general.tsx
+++ b/apps/studio/pages/project/[ref]/settings/general.tsx
@@ -1,11 +1,9 @@
 import { subscriptionHasHipaaAddon } from 'components/interfaces/Billing/Subscription/Subscription.utils'
-import {
-  ComplianceConfig,
-  CustomDomainConfig,
-  General,
-  TransferProjectPanel,
-} from 'components/interfaces/Settings/General'
+import { ComplianceConfig } from 'components/interfaces/Settings/General/ComplianceConfig/ProjectComplianceMode'
+import { CustomDomainConfig } from 'components/interfaces/Settings/General/CustomDomainConfig/CustomDomainConfig'
 import { DeleteProjectPanel } from 'components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectPanel'
+import { General } from 'components/interfaces/Settings/General/General'
+import { TransferProjectPanel } from 'components/interfaces/Settings/General/TransferProjectPanel/TransferProjectPanel'
 import DefaultLayout from 'components/layouts/DefaultLayout'
 import SettingsLayout from 'components/layouts/ProjectSettingsLayout/SettingsLayout'
 import { ScaffoldContainer, ScaffoldHeader, ScaffoldTitle } from 'components/layouts/Scaffold'
diff --git a/apps/studio/pages/project/[ref]/storage/analytics/buckets/[bucketId].tsx b/apps/studio/pages/project/[ref]/storage/analytics/buckets/[bucketId].tsx
index 19e8e6768178c..7ea03e11ad711 100644
--- a/apps/studio/pages/project/[ref]/storage/analytics/buckets/[bucketId].tsx
+++ b/apps/studio/pages/project/[ref]/storage/analytics/buckets/[bucketId].tsx
@@ -1,13 +1,17 @@
-import { useParams } from 'common'
+import Link from 'next/link'
 
-import { AnalyticBucketDetails } from 'components/interfaces/Storage/AnalyticBucketDetails'
+import { useParams } from 'common'
+import { AnalyticBucketDetails } from 'components/interfaces/Storage/AnalyticsBucketDetails'
 import StorageBucketsError from 'components/interfaces/Storage/StorageBucketsError'
 import { useSelectedBucket } from 'components/interfaces/Storage/StorageExplorer/useSelectedBucket'
 import DefaultLayout from 'components/layouts/DefaultLayout'
 import StorageLayout from 'components/layouts/StorageLayout/StorageLayout'
+import { AnalyticsBucket } from 'data/storage/analytics-buckets-query'
 import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
 import { useStorageExplorerStateSnapshot } from 'state/storage-explorer'
 import type { NextPageWithLayout } from 'types'
+import { Button } from 'ui'
+import { Admonition } from 'ui-patterns'
 
 const AnalyticsBucketPage: NextPageWithLayout = () => {
   const { bucketId } = useParams()
@@ -16,23 +20,29 @@ const AnalyticsBucketPage: NextPageWithLayout = () => {
   const { bucket, error, isSuccess, isError } = useSelectedBucket()
 
   // [Joshen] Checking against projectRef from storage explorer to check if the store has initialized
+  // We can probably replace this with a better skeleton loader that's more representative of the page layout
   if (!project || !projectRef) return null
 
   return (
-    
+    
       {isError && 
}
 
       {isSuccess ? (
         !bucket ? (
           
-            
Bucket {bucketId} cannot be found
+            
+              
+            
           
-        ) : bucket.type === 'ANALYTICS' ? (
-          
         ) : (
-          
-            
This bucket is not an analytics bucket
-          
+          
         )
       ) : null}
     
diff --git a/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx b/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx
index 241ecb1f31dc9..8965ff4b64e45 100644
--- a/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx
+++ b/apps/studio/pages/project/[ref]/storage/buckets/[bucketId].tsx
@@ -1,11 +1,12 @@
 import { useParams } from 'common'
 
-import { AnalyticBucketDetails } from 'components/interfaces/Storage/AnalyticBucketDetails'
+import { AnalyticBucketDetails } from 'components/interfaces/Storage/AnalyticsBucketDetails'
 import StorageBucketsError from 'components/interfaces/Storage/StorageBucketsError'
 import { StorageExplorer } from 'components/interfaces/Storage/StorageExplorer/StorageExplorer'
 import { useSelectedBucket } from 'components/interfaces/Storage/StorageExplorer/useSelectedBucket'
 import DefaultLayout from 'components/layouts/DefaultLayout'
 import StorageLayout from 'components/layouts/StorageLayout/StorageLayout'
+import { AnalyticsBucket } from 'data/storage/analytics-buckets-query'
 import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
 import { useStorageExplorerStateSnapshot } from 'state/storage-explorer'
 import type { NextPageWithLayout } from 'types'
@@ -29,7 +30,7 @@ const PageLayout: NextPageWithLayout = () => {
             
Bucket {bucketId} cannot be found