diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffd68d8b87..2d523dafb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,7 @@ jobs: env: NODE_OPTIONS: '--no-warnings' NEXT_PUBLIC_APP_URL: 'https://www.sim.ai' + DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/simstudio' ENCRYPTION_KEY: '7cf672e460e430c1fba707575c2b0e2ad5a99dddf9b7b7e3b5646e630861db1c' # dummy key for CI only run: bun run test @@ -39,6 +40,7 @@ jobs: env: NODE_OPTIONS: '--no-warnings' NEXT_PUBLIC_APP_URL: 'https://www.sim.ai' + DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/simstudio' STRIPE_SECRET_KEY: 'dummy_key_for_ci_only' STRIPE_WEBHOOK_SECRET: 'dummy_secret_for_ci_only' RESEND_API_KEY: 'dummy_key_for_ci_only' @@ -71,7 +73,7 @@ jobs: run: bun install - name: Apply migrations - working-directory: ./apps/sim + working-directory: ./packages/db env: DATABASE_URL: ${{ github.ref == 'refs/heads/main' && secrets.DATABASE_URL || secrets.STAGING_DATABASE_URL }} - run: bunx drizzle-kit migrate + run: bunx drizzle-kit migrate --config=./drizzle.config.ts diff --git a/README.md b/README.md index c702f2633f..bc3e04a090 100644 --- a/README.md +++ b/README.md @@ -125,10 +125,11 @@ Update your `.env` file with the database URL: DATABASE_URL="postgresql://postgres:your_password@localhost:5432/simstudio" ``` -4. Set up the database: +4. Set up the database (from packages/db): ```bash -bunx drizzle-kit migrate +cd packages/db +bunx drizzle-kit migrate --config=./drizzle.config.ts ``` 5. Start the development servers: diff --git a/apps/docs/content/docs/en/tools/sharepoint.mdx b/apps/docs/content/docs/en/tools/sharepoint.mdx index 9b42322def..b32b84a326 100644 --- a/apps/docs/content/docs/en/tools/sharepoint.mdx +++ b/apps/docs/content/docs/en/tools/sharepoint.mdx @@ -1,6 +1,6 @@ --- title: Sharepoint -description: Read and create pages +description: Work with pages and lists --- import { BlockInfoCard } from "@/components/ui/block-info-card" @@ -61,7 +61,7 @@ In Sim, the SharePoint integration empowers your agents to create and access Sha ## Usage Instructions -Integrate Sharepoint into the workflow. Can read and create pages, and list sites. Requires OAuth. +Integrate SharePoint into the workflow. Read/create pages, list sites, and work with lists (read, create, update items). Requires OAuth. @@ -124,6 +124,65 @@ List details of all SharePoint sites | --------- | ---- | ----------- | | `site` | object | Information about the current SharePoint site | +### `sharepoint_create_list` + +Create a new list in a SharePoint site + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `siteId` | string | No | The ID of the SharePoint site \(internal use\) | +| `siteSelector` | string | No | Select the SharePoint site | +| `listDisplayName` | string | Yes | Display name of the list to create | +| `listDescription` | string | No | Description of the list | +| `listTemplate` | string | No | List template name \(e.g., 'genericList'\) | +| `pageContent` | string | No | Optional JSON of columns. Either a top-level array of column definitions or an object with \{ columns: \[...\] \}. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `list` | object | Created SharePoint list information | + +### `sharepoint_get_list` + +Get metadata (and optionally columns/items) for a SharePoint list + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `siteSelector` | string | No | Select the SharePoint site | +| `siteId` | string | No | The ID of the SharePoint site \(internal use\) | +| `listId` | string | No | The ID of the list to retrieve | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `list` | object | Information about the SharePoint list | + +### `sharepoint_update_list` + +Update the properties (fields) on a SharePoint list item + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `siteSelector` | string | No | Select the SharePoint site | +| `siteId` | string | No | The ID of the SharePoint site \(internal use\) | +| `listId` | string | No | The ID of the list containing the item | +| `itemId` | string | Yes | The ID of the list item to update | +| `listItemFields` | object | Yes | Field values to update on the list item | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `item` | object | Updated SharePoint list item | + ## Notes diff --git a/apps/sim/app/(auth)/components/oauth-provider-checker.tsx b/apps/sim/app/(auth)/components/oauth-provider-checker.tsx index 8aff925c33..43766112bb 100644 --- a/apps/sim/app/(auth)/components/oauth-provider-checker.tsx +++ b/apps/sim/app/(auth)/components/oauth-provider-checker.tsx @@ -4,19 +4,9 @@ import { env } from '@/lib/env' import { isProd } from '@/lib/environment' export async function getOAuthProviderStatus() { - const githubAvailable = !!( - env.GITHUB_CLIENT_ID && - env.GITHUB_CLIENT_SECRET && - env.GITHUB_CLIENT_ID !== 'placeholder' && - env.GITHUB_CLIENT_SECRET !== 'placeholder' - ) + const githubAvailable = !!(env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET) - const googleAvailable = !!( - env.GOOGLE_CLIENT_ID && - env.GOOGLE_CLIENT_SECRET && - env.GOOGLE_CLIENT_ID !== 'placeholder' && - env.GOOGLE_CLIENT_SECRET !== 'placeholder' - ) + const googleAvailable = !!(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) return { githubAvailable, googleAvailable, isProduction: isProd } } diff --git a/apps/sim/app/(auth)/components/social-login-buttons.tsx b/apps/sim/app/(auth)/components/social-login-buttons.tsx index 4cb19691f2..7c76325b6f 100644 --- a/apps/sim/app/(auth)/components/social-login-buttons.tsx +++ b/apps/sim/app/(auth)/components/social-login-buttons.tsx @@ -37,12 +37,6 @@ export function SocialLoginButtons({ setIsGithubLoading(true) try { await client.signIn.social({ provider: 'github', callbackURL }) - - // Mark that the user has previously logged in - if (typeof window !== 'undefined') { - localStorage.setItem('has_logged_in_before', 'true') - document.cookie = 'has_logged_in_before=true; path=/; max-age=31536000; SameSite=Lax' // 1 year expiry - } } catch (err: any) { let errorMessage = 'Failed to sign in with GitHub' @@ -66,13 +60,6 @@ export function SocialLoginButtons({ setIsGoogleLoading(true) try { await client.signIn.social({ provider: 'google', callbackURL }) - - // Mark that the user has previously logged in - if (typeof window !== 'undefined') { - localStorage.setItem('has_logged_in_before', 'true') - // Also set a cookie to enable middleware to check login status - document.cookie = 'has_logged_in_before=true; path=/; max-age=31536000; SameSite=Lax' // 1 year expiry - } } catch (err: any) { let errorMessage = 'Failed to sign in with Google' diff --git a/apps/sim/app/(auth)/login/login-form.tsx b/apps/sim/app/(auth)/login/login-form.tsx index f48b599bab..d30b03b634 100644 --- a/apps/sim/app/(auth)/login/login-form.tsx +++ b/apps/sim/app/(auth)/login/login-form.tsx @@ -74,12 +74,12 @@ const validatePassword = (passwordValue: string): string[] => { if (!PASSWORD_VALIDATIONS.required.test(passwordValue)) { errors.push(PASSWORD_VALIDATIONS.required.message) - return errors // Return early for required field + return errors } if (!PASSWORD_VALIDATIONS.notEmpty.test(passwordValue)) { errors.push(PASSWORD_VALIDATIONS.notEmpty.message) - return errors // Return early for empty field + return errors } return errors @@ -104,11 +104,9 @@ export default function LoginPage({ const [showValidationError, setShowValidationError] = useState(false) const [buttonClass, setButtonClass] = useState('auth-button-gradient') - // Initialize state for URL parameters const [callbackUrl, setCallbackUrl] = useState('/workspace') const [isInviteFlow, setIsInviteFlow] = useState(false) - // Forgot password states const [forgotPasswordOpen, setForgotPasswordOpen] = useState(false) const [forgotPasswordEmail, setForgotPasswordEmail] = useState('') const [isSubmittingReset, setIsSubmittingReset] = useState(false) @@ -117,25 +115,20 @@ export default function LoginPage({ message: string }>({ type: null, message: '' }) - // Email validation state const [email, setEmail] = useState('') const [emailErrors, setEmailErrors] = useState([]) const [showEmailValidationError, setShowEmailValidationError] = useState(false) - // Extract URL parameters after component mounts to avoid SSR issues useEffect(() => { setMounted(true) - // Only access search params on the client side if (searchParams) { const callback = searchParams.get('callbackUrl') if (callback) { - // Validate the callbackUrl before setting it if (validateCallbackUrl(callback)) { setCallbackUrl(callback) } else { logger.warn('Invalid callback URL detected and blocked:', { url: callback }) - // Keep the default safe value ('/workspace') } } @@ -143,12 +136,10 @@ export default function LoginPage({ setIsInviteFlow(inviteFlow) } - // Check if CSS variable has been customized const checkCustomBrand = () => { const computedStyle = getComputedStyle(document.documentElement) const brandAccent = computedStyle.getPropertyValue('--brand-accent-hex').trim() - // Check if the CSS variable exists and is different from the default if (brandAccent && brandAccent !== '#6f3dfa') { setButtonClass('auth-button-custom') } else { @@ -158,7 +149,6 @@ export default function LoginPage({ checkCustomBrand() - // Also check on window resize or theme changes window.addEventListener('resize', checkCustomBrand) const observer = new MutationObserver(checkCustomBrand) observer.observe(document.documentElement, { @@ -189,7 +179,6 @@ export default function LoginPage({ const newEmail = e.target.value setEmail(newEmail) - // Silently validate but don't show errors until submit const errors = validateEmailField(newEmail) setEmailErrors(errors) setShowEmailValidationError(false) @@ -199,7 +188,6 @@ export default function LoginPage({ const newPassword = e.target.value setPassword(newPassword) - // Silently validate but don't show errors until submit const errors = validatePassword(newPassword) setPasswordErrors(errors) setShowValidationError(false) @@ -210,26 +198,23 @@ export default function LoginPage({ setIsLoading(true) const formData = new FormData(e.currentTarget) - const email = formData.get('email') as string + const emailRaw = formData.get('email') as string + const email = emailRaw.trim().toLowerCase() - // Validate email on submit const emailValidationErrors = validateEmailField(email) setEmailErrors(emailValidationErrors) setShowEmailValidationError(emailValidationErrors.length > 0) - // Validate password on submit const passwordValidationErrors = validatePassword(password) setPasswordErrors(passwordValidationErrors) setShowValidationError(passwordValidationErrors.length > 0) - // If there are validation errors, stop submission if (emailValidationErrors.length > 0 || passwordValidationErrors.length > 0) { setIsLoading(false) return } try { - // Final validation before submission const safeCallbackUrl = validateCallbackUrl(callbackUrl) ? callbackUrl : '/workspace' const result = await client.signIn.email( @@ -291,33 +276,13 @@ export default function LoginPage({ setIsLoading(false) return } - - // Mark that the user has previously logged in - if (typeof window !== 'undefined') { - localStorage.setItem('has_logged_in_before', 'true') - document.cookie = 'has_logged_in_before=true; path=/; max-age=31536000; SameSite=Lax' // 1 year expiry - } } catch (err: any) { - // Handle only the special verification case that requires a redirect if (err.message?.includes('not verified') || err.code?.includes('EMAIL_NOT_VERIFIED')) { - try { - await client.emailOtp.sendVerificationOtp({ - email, - type: 'email-verification', - }) - - if (typeof window !== 'undefined') { - sessionStorage.setItem('verificationEmail', email) - } - - router.push('/verify') - return - } catch (_verifyErr) { - setPasswordErrors(['Failed to send verification code. Please try again later.']) - setShowValidationError(true) - setIsLoading(false) - return + if (typeof window !== 'undefined') { + sessionStorage.setItem('verificationEmail', email) } + router.push('/verify') + return } console.error('Uncaught login error:', err) diff --git a/apps/sim/app/(auth)/reset-password/page.tsx b/apps/sim/app/(auth)/reset-password/page.tsx index 478ea777a8..8474d054e0 100644 --- a/apps/sim/app/(auth)/reset-password/page.tsx +++ b/apps/sim/app/(auth)/reset-password/page.tsx @@ -24,7 +24,6 @@ function ResetPasswordContent() { text: '', }) - // Validate token presence useEffect(() => { if (!token) { setStatusMessage({ @@ -60,7 +59,6 @@ function ResetPasswordContent() { text: 'Password reset successful! Redirecting to login...', }) - // Redirect to login page after 1.5 seconds setTimeout(() => { router.push('/login?resetSuccess=true') }, 1500) diff --git a/apps/sim/app/(auth)/reset-password/reset-password-form.tsx b/apps/sim/app/(auth)/reset-password/reset-password-form.tsx index ff6e39f455..fe1377e1bc 100644 --- a/apps/sim/app/(auth)/reset-password/reset-password-form.tsx +++ b/apps/sim/app/(auth)/reset-password/reset-password-form.tsx @@ -30,12 +30,10 @@ export function RequestResetForm({ const [buttonClass, setButtonClass] = useState('auth-button-gradient') useEffect(() => { - // Check if CSS variable has been customized const checkCustomBrand = () => { const computedStyle = getComputedStyle(document.documentElement) const brandAccent = computedStyle.getPropertyValue('--brand-accent-hex').trim() - // Check if the CSS variable exists and is different from the default if (brandAccent && brandAccent !== '#6f3dfa') { setButtonClass('auth-button-custom') } else { @@ -45,7 +43,6 @@ export function RequestResetForm({ checkCustomBrand() - // Also check on window resize or theme changes window.addEventListener('resize', checkCustomBrand) const observer = new MutationObserver(checkCustomBrand) observer.observe(document.documentElement, { @@ -132,12 +129,10 @@ export function SetNewPasswordForm({ const [buttonClass, setButtonClass] = useState('auth-button-gradient') useEffect(() => { - // Check if CSS variable has been customized const checkCustomBrand = () => { const computedStyle = getComputedStyle(document.documentElement) const brandAccent = computedStyle.getPropertyValue('--brand-accent-hex').trim() - // Check if the CSS variable exists and is different from the default if (brandAccent && brandAccent !== '#6f3dfa') { setButtonClass('auth-button-custom') } else { @@ -147,7 +142,6 @@ export function SetNewPasswordForm({ checkCustomBrand() - // Also check on window resize or theme changes window.addEventListener('resize', checkCustomBrand) const observer = new MutationObserver(checkCustomBrand) observer.observe(document.documentElement, { @@ -164,7 +158,6 @@ export function SetNewPasswordForm({ const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() - // Simple validation if (password.length < 8) { setValidationMessage('Password must be at least 8 characters long') return diff --git a/apps/sim/app/(auth)/signup/page.tsx b/apps/sim/app/(auth)/signup/page.tsx index 3fededdd14..6e0734a1f9 100644 --- a/apps/sim/app/(auth)/signup/page.tsx +++ b/apps/sim/app/(auth)/signup/page.tsx @@ -2,7 +2,6 @@ import { env, isTruthy } from '@/lib/env' import { getOAuthProviderStatus } from '@/app/(auth)/components/oauth-provider-checker' import SignupForm from '@/app/(auth)/signup/signup-form' -// Force dynamic rendering to avoid prerender errors with search params export const dynamic = 'force-dynamic' export default async function SignupPage() { diff --git a/apps/sim/app/(auth)/signup/signup-form.tsx b/apps/sim/app/(auth)/signup/signup-form.tsx index f72a40558c..0dbba30255 100644 --- a/apps/sim/app/(auth)/signup/signup-form.tsx +++ b/apps/sim/app/(auth)/signup/signup-form.tsx @@ -95,7 +95,6 @@ function SignupFormContent({ const [isInviteFlow, setIsInviteFlow] = useState(false) const [buttonClass, setButtonClass] = useState('auth-button-gradient') - // Name validation state const [name, setName] = useState('') const [nameErrors, setNameErrors] = useState([]) const [showNameValidationError, setShowNameValidationError] = useState(false) @@ -107,29 +106,24 @@ function SignupFormContent({ setEmail(emailParam) } - // Handle redirection for invitation flow const redirectParam = searchParams.get('redirect') if (redirectParam) { setRedirectUrl(redirectParam) - // Check if this is part of an invitation flow if (redirectParam.startsWith('/invite/')) { setIsInviteFlow(true) } } - // Explicitly check for invite_flow parameter const inviteFlowParam = searchParams.get('invite_flow') if (inviteFlowParam === 'true') { setIsInviteFlow(true) } - // Check if CSS variable has been customized const checkCustomBrand = () => { const computedStyle = getComputedStyle(document.documentElement) const brandAccent = computedStyle.getPropertyValue('--brand-accent-hex').trim() - // Check if the CSS variable exists and is different from the default if (brandAccent && brandAccent !== '#6f3dfa') { setButtonClass('auth-button-custom') } else { @@ -139,7 +133,6 @@ function SignupFormContent({ checkCustomBrand() - // Also check on window resize or theme changes window.addEventListener('resize', checkCustomBrand) const observer = new MutationObserver(checkCustomBrand) observer.observe(document.documentElement, { @@ -153,7 +146,6 @@ function SignupFormContent({ } }, [searchParams]) - // Validate password and return array of error messages const validatePassword = (passwordValue: string): string[] => { const errors: string[] = [] @@ -180,18 +172,17 @@ function SignupFormContent({ return errors } - // Validate name and return array of error messages const validateName = (nameValue: string): string[] => { const errors: string[] = [] if (!NAME_VALIDATIONS.required.test(nameValue)) { errors.push(NAME_VALIDATIONS.required.message) - return errors // Return early for required field + return errors } if (!NAME_VALIDATIONS.notEmpty.test(nameValue)) { errors.push(NAME_VALIDATIONS.notEmpty.message) - return errors // Return early for empty field + return errors } if (!NAME_VALIDATIONS.validCharacters.regex.test(nameValue.trim())) { @@ -209,7 +200,6 @@ function SignupFormContent({ const newPassword = e.target.value setPassword(newPassword) - // Silently validate but don't show errors const errors = validatePassword(newPassword) setPasswordErrors(errors) setShowValidationError(false) @@ -228,12 +218,10 @@ function SignupFormContent({ const newEmail = e.target.value setEmail(newEmail) - // Silently validate but don't show errors until submit const errors = validateEmailField(newEmail) setEmailErrors(errors) setShowEmailValidationError(false) - // Clear any previous server-side email errors when the user starts typing if (emailError) { setEmailError('') } @@ -244,7 +232,8 @@ function SignupFormContent({ setIsLoading(true) const formData = new FormData(e.currentTarget) - const emailValue = formData.get('email') as string + const emailValueRaw = formData.get('email') as string + const emailValue = emailValueRaw.trim().toLowerCase() const passwordValue = formData.get('password') as string const nameValue = formData.get('name') as string @@ -348,7 +337,6 @@ function SignupFormContent({ return } - // Refresh session to get the new user data immediately after signup try { await refetchSession() logger.info('Session refreshed after successful signup') @@ -356,34 +344,23 @@ function SignupFormContent({ logger.error('Failed to refresh session after signup:', sessionError) } - // For new signups, always require verification if (typeof window !== 'undefined') { sessionStorage.setItem('verificationEmail', emailValue) - localStorage.setItem('has_logged_in_before', 'true') - - // Set cookie flag for middleware check - document.cookie = 'requiresEmailVerification=true; path=/; max-age=900; SameSite=Lax' // 15 min expiry - document.cookie = 'has_logged_in_before=true; path=/; max-age=31536000; SameSite=Lax' - - // Store invitation flow state if applicable if (isInviteFlow && redirectUrl) { sessionStorage.setItem('inviteRedirectUrl', redirectUrl) sessionStorage.setItem('isInviteFlow', 'true') } } - // Send verification OTP manually try { await client.emailOtp.sendVerificationOtp({ email: emailValue, - type: 'email-verification', + type: 'sign-in', }) - } catch (otpError) { - logger.error('Failed to send OTP:', otpError) - // Continue anyway - user can use resend button + } catch (otpErr) { + logger.warn('Failed to send sign-in OTP after signup; user can press Resend', otpErr) } - // Always redirect to verification for new signups router.push('/verify?fromSignup=true') } catch (error) { logger.error('Signup error:', error) diff --git a/apps/sim/app/(auth)/verify/page.tsx b/apps/sim/app/(auth)/verify/page.tsx index 55c185675d..7e169b8760 100644 --- a/apps/sim/app/(auth)/verify/page.tsx +++ b/apps/sim/app/(auth)/verify/page.tsx @@ -1,14 +1,11 @@ import { env } from '@/lib/env' import { isProd } from '@/lib/environment' -import { getBaseUrl } from '@/lib/urls/utils' import { VerifyContent } from '@/app/(auth)/verify/verify-content' -// Force dynamic rendering to avoid prerender errors with search params export const dynamic = 'force-dynamic' export default function VerifyPage() { - const baseUrl = getBaseUrl() - const hasResendKey = Boolean(env.RESEND_API_KEY && env.RESEND_API_KEY !== 'placeholder') + const hasResendKey = Boolean(env.RESEND_API_KEY) - return + return } diff --git a/apps/sim/app/(auth)/verify/use-verification.ts b/apps/sim/app/(auth)/verify/use-verification.ts index ecaf68036f..3d4b1d32a0 100644 --- a/apps/sim/app/(auth)/verify/use-verification.ts +++ b/apps/sim/app/(auth)/verify/use-verification.ts @@ -3,7 +3,6 @@ import { useEffect, useState } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { client, useSession } from '@/lib/auth-client' -import { env, isTruthy } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' const logger = createLogger('useVerification') @@ -47,61 +46,39 @@ export function useVerification({ useEffect(() => { if (typeof window !== 'undefined') { - // Get stored email const storedEmail = sessionStorage.getItem('verificationEmail') if (storedEmail) { setEmail(storedEmail) } - // Check for redirect information const storedRedirectUrl = sessionStorage.getItem('inviteRedirectUrl') if (storedRedirectUrl) { setRedirectUrl(storedRedirectUrl) } - // Check if this is an invite flow const storedIsInviteFlow = sessionStorage.getItem('isInviteFlow') if (storedIsInviteFlow === 'true') { setIsInviteFlow(true) } } - // Also check URL parameters for redirect information const redirectParam = searchParams.get('redirectAfter') if (redirectParam) { setRedirectUrl(redirectParam) } - // Check for invite_flow parameter const inviteFlowParam = searchParams.get('invite_flow') if (inviteFlowParam === 'true') { setIsInviteFlow(true) } }, [searchParams]) - // Send initial OTP code if this is the first load useEffect(() => { if (email && !isSendingInitialOtp && hasResendKey) { setIsSendingInitialOtp(true) - - // Only send verification OTP if we're coming from login page - // Skip this if coming from signup since the OTP is already sent - if (!searchParams.get('fromSignup')) { - client.emailOtp - .sendVerificationOtp({ - email, - type: 'email-verification', - }) - .then(() => {}) - .catch((error) => { - logger.error('Failed to send initial verification code:', error) - setErrorMessage('Failed to send verification code. Please use the resend button.') - }) - } } - }, [email, isSendingInitialOtp, searchParams, hasResendKey]) + }, [email, isSendingInitialOtp, hasResendKey]) - // Enable the verify button when all 6 digits are entered const isOtpComplete = otp.length === 6 async function verifyCode() { @@ -112,25 +89,24 @@ export function useVerification({ setErrorMessage('') try { - // Call the verification API with the OTP code - const response = await client.emailOtp.verifyEmail({ - email, + const normalizedEmail = email.trim().toLowerCase() + const response = await client.signIn.emailOtp({ + email: normalizedEmail, otp, }) - // Check if verification was successful if (response && !response.error) { setIsVerified(true) - // Clear verification requirements and session storage + try { + await refetchSession() + } catch (e) { + logger.warn('Failed to refetch session after verification', e) + } + if (typeof window !== 'undefined') { sessionStorage.removeItem('verificationEmail') - // Clear the verification requirement flag - document.cookie = - 'requiresEmailVerification=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' - - // Also clear invite-related items if (isInviteFlow) { sessionStorage.removeItem('inviteRedirectUrl') sessionStorage.removeItem('isInviteFlow') @@ -139,24 +115,20 @@ export function useVerification({ setTimeout(() => { if (isInviteFlow && redirectUrl) { - // For invitation flow, redirect to the invitation page window.location.href = redirectUrl } else { - // Default redirect to dashboard window.location.href = '/workspace' } }, 1000) } else { logger.info('Setting invalid OTP state - API error response') const message = 'Invalid verification code. Please check and try again.' - // Set both state variables to ensure the error shows setIsInvalidOtp(true) setErrorMessage(message) logger.info('Error state after API error:', { isInvalidOtp: true, errorMessage: message, }) - // Clear the OTP input on invalid code setOtp('') } } catch (error: any) { @@ -171,7 +143,6 @@ export function useVerification({ message = 'Too many failed attempts. Please request a new code.' } - // Set both state variables to ensure the error shows setIsInvalidOtp(true) setErrorMessage(message) logger.info('Error state after caught error:', { @@ -179,7 +150,6 @@ export function useVerification({ errorMessage: message, }) - // Clear the OTP input on error setOtp('') } finally { setIsLoading(false) @@ -192,10 +162,11 @@ export function useVerification({ setIsLoading(true) setErrorMessage('') + const normalizedEmail = email.trim().toLowerCase() client.emailOtp .sendVerificationOtp({ - email, - type: 'email-verification', + email: normalizedEmail, + type: 'sign-in', }) .then(() => {}) .catch(() => { @@ -207,7 +178,6 @@ export function useVerification({ } function handleOtpChange(value: string) { - // Only clear error when user is actively typing a new code if (value.length === 6) { setIsInvalidOtp(false) setErrorMessage('') @@ -215,12 +185,11 @@ export function useVerification({ setOtp(value) } - // Auto-submit when OTP is complete useEffect(() => { if (otp.length === 6 && email && !isLoading && !isVerified) { const timeoutId = setTimeout(() => { verifyCode() - }, 300) // Small delay to ensure UI is ready + }, 300) return () => clearTimeout(timeoutId) } @@ -229,17 +198,8 @@ export function useVerification({ useEffect(() => { if (typeof window !== 'undefined') { if (!isProduction || !hasResendKey) { - const storedEmail = sessionStorage.getItem('verificationEmail') - } - - const isDevOrDocker = !isProduction || isTruthy(env.DOCKER_BUILD) - - if (isDevOrDocker || !hasResendKey) { setIsVerified(true) - document.cookie = - 'requiresEmailVerification=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' - const timeoutId = setTimeout(() => { window.location.href = '/workspace' }, 1000) diff --git a/apps/sim/app/(auth)/verify/verify-content.tsx b/apps/sim/app/(auth)/verify/verify-content.tsx index b6dd4e6c53..c402bd9015 100644 --- a/apps/sim/app/(auth)/verify/verify-content.tsx +++ b/apps/sim/app/(auth)/verify/verify-content.tsx @@ -11,7 +11,6 @@ import { soehne } from '@/app/fonts/soehne/soehne' interface VerifyContentProps { hasResendKey: boolean - baseUrl: string isProduction: boolean } @@ -56,30 +55,13 @@ function VerificationForm({ setCountdown(30) } - const handleCancelVerification = () => { - // Clear verification data - if (typeof window !== 'undefined') { - sessionStorage.removeItem('verificationEmail') - sessionStorage.removeItem('inviteRedirectUrl') - sessionStorage.removeItem('isInviteFlow') - - // Clear the verification requirement cookie - document.cookie = 'requiresEmailVerification=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' - } - - // Redirect to login - router.push('/login') - } - const [buttonClass, setButtonClass] = useState('auth-button-gradient') useEffect(() => { - // Check if CSS variable has been customized const checkCustomBrand = () => { const computedStyle = getComputedStyle(document.documentElement) const brandAccent = computedStyle.getPropertyValue('--brand-accent-hex').trim() - // Check if the CSS variable exists and is different from the default if (brandAccent && brandAccent !== '#6f3dfa') { setButtonClass('auth-button-custom') } else { @@ -89,7 +71,6 @@ function VerificationForm({ checkCustomBrand() - // Also check on window resize or theme changes window.addEventListener('resize', checkCustomBrand) const observer = new MutationObserver(checkCustomBrand) observer.observe(document.documentElement, { @@ -232,21 +213,27 @@ function VerificationForm({ )} - {/*
+
-
*/} +
)} ) } -// Fallback component while the verification form is loading function VerificationFormFallback() { return (
@@ -258,7 +245,7 @@ function VerificationFormFallback() { ) } -export function VerifyContent({ hasResendKey, baseUrl, isProduction }: VerifyContentProps) { +export function VerifyContent({ hasResendKey, isProduction }: VerifyContentProps) { return ( }> diff --git a/apps/sim/app/(landing)/components/hero/hero.tsx b/apps/sim/app/(landing)/components/hero/hero.tsx index 154edbe7fa..7169925df1 100644 --- a/apps/sim/app/(landing)/components/hero/hero.tsx +++ b/apps/sim/app/(landing)/components/hero/hero.tsx @@ -32,6 +32,7 @@ import { StripeIcon, SupabaseIcon, } from '@/components/icons' +import { LandingPromptStorage } from '@/lib/browser-storage' import { soehne } from '@/app/fonts/soehne/soehne' import { CARD_WIDTH, @@ -271,6 +272,7 @@ export default function Hero() { */ const handleSubmit = () => { if (!isEmpty) { + LandingPromptStorage.store(textValue) router.push('/signup') } } diff --git a/apps/sim/app/api/__test-utils__/utils.ts b/apps/sim/app/api/__test-utils__/utils.ts index 493de52b22..4cdfdf4c08 100644 --- a/apps/sim/app/api/__test-utils__/utils.ts +++ b/apps/sim/app/api/__test-utils__/utils.ts @@ -349,7 +349,7 @@ export function mockExecutionDependencies() { })), })) - vi.mock('@/db', () => ({ + vi.mock('@sim/db', () => ({ db: mockDb, })) } @@ -395,7 +395,7 @@ export async function getMockedDependencies() { const workflowUtilsModule = await import('@/lib/workflows/utils') const executorModule = await import('@/executor') const serializerModule = await import('@/serializer') - const dbModule = await import('@/db') + const dbModule = await import('@sim/db') return { decryptSecret: utilsModule.decryptSecret, @@ -428,7 +428,7 @@ export function mockScheduleStatusDb({ schedule?: any[] workflow?: any[] } = {}) { - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { let callCount = 0 const select = vi.fn().mockImplementation(() => ({ @@ -469,7 +469,7 @@ export function mockScheduleExecuteDb({ workflowRecord?: any envRecord?: any }): void { - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const select = vi.fn().mockImplementation(() => ({ from: vi.fn().mockImplementation((table: any) => { const tbl = String(table) @@ -544,7 +544,7 @@ export function mockAuth(user: MockUser = mockUser): MockAuthResult { * Mock common schema patterns */ export function mockCommonSchemas() { - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ workflowFolder: { id: 'id', userId: 'userId', @@ -597,7 +597,7 @@ export function mockDrizzleOrm() { * Mock knowledge-related database schemas */ export function mockKnowledgeSchemas() { - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ knowledgeBase: { id: 'kb_id', userId: 'user_id', @@ -1091,7 +1091,7 @@ export function createMockDatabase(options: MockDatabaseOptions = {}) { transaction: createTransactionMock(), } - vi.doMock('@/db', () => ({ db: mockDb })) + vi.doMock('@sim/db', () => ({ db: mockDb })) return { mockDb, diff --git a/apps/sim/app/api/auth/oauth/connections/route.test.ts b/apps/sim/app/api/auth/oauth/connections/route.test.ts index 16797efb13..aced9eed20 100644 --- a/apps/sim/app/api/auth/oauth/connections/route.test.ts +++ b/apps/sim/app/api/auth/oauth/connections/route.test.ts @@ -34,13 +34,11 @@ describe('OAuth Connections API Route', () => { getSession: mockGetSession, })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDb, - })) - - vi.doMock('@/db/schema', () => ({ account: { userId: 'userId', providerId: 'providerId' }, user: { email: 'email', id: 'id' }, + eq: vi.fn((field, value) => ({ field, value, type: 'eq' })), })) vi.doMock('drizzle-orm', () => ({ diff --git a/apps/sim/app/api/auth/oauth/connections/route.ts b/apps/sim/app/api/auth/oauth/connections/route.ts index 4cc270b1fb..881d50a973 100644 --- a/apps/sim/app/api/auth/oauth/connections/route.ts +++ b/apps/sim/app/api/auth/oauth/connections/route.ts @@ -1,11 +1,10 @@ +import { account, db, user } from '@sim/db' import { eq } from 'drizzle-orm' import { jwtDecode } from 'jwt-decode' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { account, user } from '@/db/schema' const logger = createLogger('OAuthConnectionsAPI') diff --git a/apps/sim/app/api/auth/oauth/credentials/route.test.ts b/apps/sim/app/api/auth/oauth/credentials/route.test.ts index 7187a8a6c9..e67b2de1fd 100644 --- a/apps/sim/app/api/auth/oauth/credentials/route.test.ts +++ b/apps/sim/app/api/auth/oauth/credentials/route.test.ts @@ -45,11 +45,11 @@ describe('OAuth Credentials API Route', () => { parseProvider: mockParseProvider, })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDb, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ account: { userId: 'userId', providerId: 'providerId' }, user: { email: 'email', id: 'id' }, })) diff --git a/apps/sim/app/api/auth/oauth/credentials/route.ts b/apps/sim/app/api/auth/oauth/credentials/route.ts index d301e76d03..abb263e8db 100644 --- a/apps/sim/app/api/auth/oauth/credentials/route.ts +++ b/apps/sim/app/api/auth/oauth/credentials/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { account, user, workflow } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { jwtDecode } from 'jwt-decode' import { type NextRequest, NextResponse } from 'next/server' @@ -7,8 +9,6 @@ import type { OAuthService } from '@/lib/oauth/oauth' import { parseProvider } from '@/lib/oauth/oauth' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { account, user, workflow } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/auth/oauth/disconnect/route.test.ts b/apps/sim/app/api/auth/oauth/disconnect/route.test.ts index f4fa9cd08c..deeabb89dd 100644 --- a/apps/sim/app/api/auth/oauth/disconnect/route.test.ts +++ b/apps/sim/app/api/auth/oauth/disconnect/route.test.ts @@ -32,11 +32,11 @@ describe('OAuth Disconnect API Route', () => { getSession: mockGetSession, })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDb, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ account: { userId: 'userId', providerId: 'providerId' }, })) diff --git a/apps/sim/app/api/auth/oauth/disconnect/route.ts b/apps/sim/app/api/auth/oauth/disconnect/route.ts index e7dc062c17..0dae18ef1d 100644 --- a/apps/sim/app/api/auth/oauth/disconnect/route.ts +++ b/apps/sim/app/api/auth/oauth/disconnect/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { and, eq, like, or } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/auth/oauth/microsoft/file/route.ts b/apps/sim/app/api/auth/oauth/microsoft/file/route.ts index 6028242f73..da3e30314d 100644 --- a/apps/sim/app/api/auth/oauth/microsoft/file/route.ts +++ b/apps/sim/app/api/auth/oauth/microsoft/file/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/auth/oauth/microsoft/files/route.ts b/apps/sim/app/api/auth/oauth/microsoft/files/route.ts index 8ce7e39b6e..c3cc6e7f62 100644 --- a/apps/sim/app/api/auth/oauth/microsoft/files/route.ts +++ b/apps/sim/app/api/auth/oauth/microsoft/files/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/auth/oauth/utils.test.ts b/apps/sim/app/api/auth/oauth/utils.test.ts index 7255572948..c76ed05bff 100644 --- a/apps/sim/app/api/auth/oauth/utils.test.ts +++ b/apps/sim/app/api/auth/oauth/utils.test.ts @@ -31,7 +31,7 @@ describe('OAuth Utils', () => { getSession: vi.fn().mockResolvedValue(mockSession), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDb, })) diff --git a/apps/sim/app/api/auth/oauth/utils.ts b/apps/sim/app/api/auth/oauth/utils.ts index 666e20a094..feade337e8 100644 --- a/apps/sim/app/api/auth/oauth/utils.ts +++ b/apps/sim/app/api/auth/oauth/utils.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { account, workflow } from '@sim/db/schema' import { and, desc, eq } from 'drizzle-orm' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { refreshOAuthToken } from '@/lib/oauth/oauth' -import { db } from '@/db' -import { account, workflow } from '@/db/schema' const logger = createLogger('OAuthUtilsAPI') diff --git a/apps/sim/app/api/auth/oauth/wealthbox/item/route.ts b/apps/sim/app/api/auth/oauth/wealthbox/item/route.ts index d691fd5c7e..5a8d9f0845 100644 --- a/apps/sim/app/api/auth/oauth/wealthbox/item/route.ts +++ b/apps/sim/app/api/auth/oauth/wealthbox/item/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/auth/oauth/wealthbox/items/route.ts b/apps/sim/app/api/auth/oauth/wealthbox/items/route.ts index 92511bc1a2..eea0ebff83 100644 --- a/apps/sim/app/api/auth/oauth/wealthbox/items/route.ts +++ b/apps/sim/app/api/auth/oauth/wealthbox/items/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/billing/portal/route.ts b/apps/sim/app/api/billing/portal/route.ts index 838b4bfff5..f7a980cb2f 100644 --- a/apps/sim/app/api/billing/portal/route.ts +++ b/apps/sim/app/api/billing/portal/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { subscription as subscriptionTable, user } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { requireStripeClient } from '@/lib/billing/stripe-client' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { subscription as subscriptionTable, user } from '@/db/schema' const logger = createLogger('BillingPortal') diff --git a/apps/sim/app/api/billing/route.ts b/apps/sim/app/api/billing/route.ts index 616a3fa6f1..b9c7bb4b7f 100644 --- a/apps/sim/app/api/billing/route.ts +++ b/apps/sim/app/api/billing/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { member, userStats } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { getSimplifiedBillingSummary } from '@/lib/billing/core/billing' import { getOrganizationBillingData } from '@/lib/billing/core/organization' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { member, userStats } from '@/db/schema' const logger = createLogger('UnifiedBillingAPI') diff --git a/apps/sim/app/api/billing/update-cost/route.ts b/apps/sim/app/api/billing/update-cost/route.ts index 137f5b164a..816b7e9973 100644 --- a/apps/sim/app/api/billing/update-cost/route.ts +++ b/apps/sim/app/api/billing/update-cost/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { userStats } from '@sim/db/schema' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { checkInternalApiKey } from '@/lib/copilot/utils' import { isBillingEnabled } from '@/lib/environment' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { userStats } from '@/db/schema' import { calculateCost } from '@/providers/utils' const logger = createLogger('billing-update-cost') diff --git a/apps/sim/app/api/chat/[subdomain]/otp/route.ts b/apps/sim/app/api/chat/[subdomain]/otp/route.ts index a4185b1470..6b000f8d45 100644 --- a/apps/sim/app/api/chat/[subdomain]/otp/route.ts +++ b/apps/sim/app/api/chat/[subdomain]/otp/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { chat } from '@sim/db/schema' import { eq } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { z } from 'zod' @@ -8,8 +10,6 @@ import { getRedisClient, markMessageAsProcessed, releaseLock } from '@/lib/redis import { generateRequestId } from '@/lib/utils' import { addCorsHeaders, setChatAuthCookie } from '@/app/api/chat/utils' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { chat } from '@/db/schema' const logger = createLogger('ChatOtpAPI') diff --git a/apps/sim/app/api/chat/[subdomain]/route.test.ts b/apps/sim/app/api/chat/[subdomain]/route.test.ts index e4dc365830..bce1e005f9 100644 --- a/apps/sim/app/api/chat/[subdomain]/route.test.ts +++ b/apps/sim/app/api/chat/[subdomain]/route.test.ts @@ -84,7 +84,7 @@ describe('Chat Subdomain API Route', () => { }), })) - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockSelect = vi.fn().mockImplementation((fields) => { if (fields && fields.isDeployed !== undefined) { return { @@ -153,7 +153,7 @@ describe('Chat Subdomain API Route', () => { }) it('should return 404 for non-existent subdomain', async () => { - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockLimit = vi.fn().mockReturnValue([]) const mockWhere = vi.fn().mockReturnValue({ limit: mockLimit }) const mockFrom = vi.fn().mockReturnValue({ where: mockWhere }) @@ -181,7 +181,7 @@ describe('Chat Subdomain API Route', () => { }) it('should return 403 for inactive chat', async () => { - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockLimit = vi.fn().mockReturnValue([ { id: 'chat-id', @@ -299,7 +299,7 @@ describe('Chat Subdomain API Route', () => { it('should return 503 when workflow is not available', async () => { // Override the default workflow result to return non-deployed - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { // Track call count to return different results let callCount = 0 diff --git a/apps/sim/app/api/chat/[subdomain]/route.ts b/apps/sim/app/api/chat/[subdomain]/route.ts index abd18a12db..d667b2e85d 100644 --- a/apps/sim/app/api/chat/[subdomain]/route.ts +++ b/apps/sim/app/api/chat/[subdomain]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { chat, workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' @@ -10,8 +12,6 @@ import { validateChatAuth, } from '@/app/api/chat/utils' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { chat, workflow } from '@/db/schema' const logger = createLogger('ChatSubdomainAPI') diff --git a/apps/sim/app/api/chat/edit/[id]/route.test.ts b/apps/sim/app/api/chat/edit/[id]/route.test.ts index 13367a1fbc..445ed4abfd 100644 --- a/apps/sim/app/api/chat/edit/[id]/route.test.ts +++ b/apps/sim/app/api/chat/edit/[id]/route.test.ts @@ -30,7 +30,7 @@ describe('Chat Edit API Route', () => { mockSet.mockReturnValue({ where: mockWhere }) mockDelete.mockReturnValue({ where: mockWhere }) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, update: mockUpdate, @@ -38,7 +38,7 @@ describe('Chat Edit API Route', () => { }, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ chat: { id: 'id', subdomain: 'subdomain', userId: 'userId' }, })) diff --git a/apps/sim/app/api/chat/edit/[id]/route.ts b/apps/sim/app/api/chat/edit/[id]/route.ts index 08babbcd58..2a56fe9559 100644 --- a/apps/sim/app/api/chat/edit/[id]/route.ts +++ b/apps/sim/app/api/chat/edit/[id]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { chat } from '@sim/db/schema' import { eq } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { z } from 'zod' @@ -8,8 +10,6 @@ import { getEmailDomain } from '@/lib/urls/utils' import { encryptSecret } from '@/lib/utils' import { checkChatAccess } from '@/app/api/chat/utils' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { chat } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/chat/route.test.ts b/apps/sim/app/api/chat/route.test.ts index f1172695a3..030871a92e 100644 --- a/apps/sim/app/api/chat/route.test.ts +++ b/apps/sim/app/api/chat/route.test.ts @@ -29,14 +29,14 @@ describe('Chat API Route', () => { mockInsert.mockReturnValue({ values: mockValues }) mockValues.mockReturnValue({ returning: mockReturning }) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, insert: mockInsert, }, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ chat: { userId: 'userId', subdomain: 'subdomain' }, workflow: { id: 'id', userId: 'userId', isDeployed: 'isDeployed' }, })) diff --git a/apps/sim/app/api/chat/route.ts b/apps/sim/app/api/chat/route.ts index 77f055bf9b..333643e9cb 100644 --- a/apps/sim/app/api/chat/route.ts +++ b/apps/sim/app/api/chat/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { chat } from '@sim/db/schema' import { eq } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { v4 as uuidv4 } from 'uuid' @@ -9,8 +11,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { encryptSecret } from '@/lib/utils' import { checkWorkflowAccessForChatCreation } from '@/app/api/chat/utils' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { chat } from '@/db/schema' const logger = createLogger('ChatAPI') diff --git a/apps/sim/app/api/chat/subdomains/validate/route.test.ts b/apps/sim/app/api/chat/subdomains/validate/route.test.ts index 6887cdb889..4a20e1784d 100644 --- a/apps/sim/app/api/chat/subdomains/validate/route.test.ts +++ b/apps/sim/app/api/chat/subdomains/validate/route.test.ts @@ -27,14 +27,14 @@ describe('Subdomain Validation API Route', () => { mockWhere.mockReturnValue({ limit: mockLimit }) // Mock the database - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, }, })) // Mock the schema - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ chat: { subdomain: 'subdomain', }, diff --git a/apps/sim/app/api/chat/subdomains/validate/route.ts b/apps/sim/app/api/chat/subdomains/validate/route.ts index 2ff743f1e6..2bafb4fca4 100644 --- a/apps/sim/app/api/chat/subdomains/validate/route.ts +++ b/apps/sim/app/api/chat/subdomains/validate/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { chat } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { chat } from '@/db/schema' const logger = createLogger('SubdomainValidateAPI') diff --git a/apps/sim/app/api/chat/utils.test.ts b/apps/sim/app/api/chat/utils.test.ts index b9f756b77e..8a50e51617 100644 --- a/apps/sim/app/api/chat/utils.test.ts +++ b/apps/sim/app/api/chat/utils.test.ts @@ -7,7 +7,7 @@ import type { NextResponse } from 'next/server' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { env } from '@/lib/env' -vi.mock('@/db', () => ({ +vi.mock('@sim/db', () => ({ db: { select: vi.fn(), update: vi.fn(), diff --git a/apps/sim/app/api/chat/utils.ts b/apps/sim/app/api/chat/utils.ts index 67ab219ac4..c69e41ad09 100644 --- a/apps/sim/app/api/chat/utils.ts +++ b/apps/sim/app/api/chat/utils.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { chat, userStats, workflow } from '@sim/db/schema' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v4 as uuidv4 } from 'uuid' @@ -12,8 +14,6 @@ import { processStreamingBlockLogs } from '@/lib/tokenization' import { getEmailDomain } from '@/lib/urls/utils' import { decryptSecret, generateRequestId } from '@/lib/utils' import { getBlock } from '@/blocks' -import { db } from '@/db' -import { chat, userStats, workflow } from '@/db/schema' import { Executor } from '@/executor' import type { BlockLog, ExecutionResult } from '@/executor/types' import { Serializer } from '@/serializer' diff --git a/apps/sim/app/api/copilot/api-keys/validate/route.ts b/apps/sim/app/api/copilot/api-keys/validate/route.ts index d1c257ee41..48b063f692 100644 --- a/apps/sim/app/api/copilot/api-keys/validate/route.ts +++ b/apps/sim/app/api/copilot/api-keys/validate/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { userStats } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { checkInternalApiKey } from '@/lib/copilot/utils' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { userStats } from '@/db/schema' const logger = createLogger('CopilotApiKeysValidate') diff --git a/apps/sim/app/api/copilot/chat/route.test.ts b/apps/sim/app/api/copilot/chat/route.test.ts index e92ddf7384..2a57ccb687 100644 --- a/apps/sim/app/api/copilot/chat/route.test.ts +++ b/apps/sim/app/api/copilot/chat/route.test.ts @@ -46,7 +46,7 @@ describe('Copilot Chat API Route', () => { mockUpdate.mockReturnValue({ set: mockSet }) mockSet.mockReturnValue({ where: mockWhere }) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, insert: mockInsert, @@ -54,7 +54,7 @@ describe('Copilot Chat API Route', () => { }, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ copilotChats: { id: 'id', userId: 'userId', diff --git a/apps/sim/app/api/copilot/chat/route.ts b/apps/sim/app/api/copilot/chat/route.ts index 1945258784..8bf4b676f2 100644 --- a/apps/sim/app/api/copilot/chat/route.ts +++ b/apps/sim/app/api/copilot/chat/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { copilotChats } from '@sim/db/schema' import { and, desc, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -18,8 +20,6 @@ import { generateChatTitle } from '@/lib/sim-agent/utils' import { createFileContent, isSupportedFileType } from '@/lib/uploads/file-utils' import { S3_COPILOT_CONFIG } from '@/lib/uploads/setup' import { downloadFile, getStorageProvider } from '@/lib/uploads/storage-client' -import { db } from '@/db' -import { copilotChats } from '@/db/schema' const logger = createLogger('CopilotChatAPI') diff --git a/apps/sim/app/api/copilot/chat/update-messages/route.test.ts b/apps/sim/app/api/copilot/chat/update-messages/route.test.ts index 0d6818e1bc..4ab1e654b9 100644 --- a/apps/sim/app/api/copilot/chat/update-messages/route.test.ts +++ b/apps/sim/app/api/copilot/chat/update-messages/route.test.ts @@ -32,14 +32,14 @@ describe('Copilot Chat Update Messages API Route', () => { mockUpdate.mockReturnValue({ set: mockSet }) mockSet.mockReturnValue({ where: vi.fn().mockResolvedValue(undefined) }) // Different where for update - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, update: mockUpdate, }, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ copilotChats: { id: 'id', userId: 'userId', diff --git a/apps/sim/app/api/copilot/chat/update-messages/route.ts b/apps/sim/app/api/copilot/chat/update-messages/route.ts index d64f6b3b66..d4e0ebfae8 100644 --- a/apps/sim/app/api/copilot/chat/update-messages/route.ts +++ b/apps/sim/app/api/copilot/chat/update-messages/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { copilotChats } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -9,8 +11,6 @@ import { createUnauthorizedResponse, } from '@/lib/copilot/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { copilotChats } from '@/db/schema' const logger = createLogger('CopilotChatUpdateAPI') diff --git a/apps/sim/app/api/copilot/chats/route.ts b/apps/sim/app/api/copilot/chats/route.ts index 46ce9b624d..49301e8db1 100644 --- a/apps/sim/app/api/copilot/chats/route.ts +++ b/apps/sim/app/api/copilot/chats/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { copilotChats } from '@sim/db/schema' import { desc, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { @@ -6,8 +8,6 @@ import { createUnauthorizedResponse, } from '@/lib/copilot/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { copilotChats } from '@/db/schema' const logger = createLogger('CopilotChatsListAPI') diff --git a/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts b/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts index 60acef180e..3cd75ccd0b 100644 --- a/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts +++ b/apps/sim/app/api/copilot/checkpoints/revert/route.test.ts @@ -28,13 +28,13 @@ describe('Copilot Checkpoints Revert API Route', () => { mockWhere.mockReturnValue({ then: mockThen }) mockThen.mockResolvedValue(null) // Default: no data found - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, }, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ workflowCheckpoints: { id: 'id', userId: 'userId', diff --git a/apps/sim/app/api/copilot/checkpoints/revert/route.ts b/apps/sim/app/api/copilot/checkpoints/revert/route.ts index 12851cdddd..a6c70de3fd 100644 --- a/apps/sim/app/api/copilot/checkpoints/revert/route.ts +++ b/apps/sim/app/api/copilot/checkpoints/revert/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflowCheckpoints, workflow as workflowTable } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -9,8 +11,6 @@ import { createUnauthorizedResponse, } from '@/lib/copilot/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { workflowCheckpoints, workflow as workflowTable } from '@/db/schema' const logger = createLogger('CheckpointRevertAPI') diff --git a/apps/sim/app/api/copilot/checkpoints/route.test.ts b/apps/sim/app/api/copilot/checkpoints/route.test.ts index cbddd0c1e9..a344573398 100644 --- a/apps/sim/app/api/copilot/checkpoints/route.test.ts +++ b/apps/sim/app/api/copilot/checkpoints/route.test.ts @@ -49,14 +49,14 @@ describe('Copilot Checkpoints API Route', () => { mockInsert.mockReturnValue({ values: mockValues }) mockValues.mockReturnValue({ returning: mockReturning }) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, insert: mockInsert, }, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ copilotChats: mockCopilotChats, workflowCheckpoints: mockWorkflowCheckpoints, })) diff --git a/apps/sim/app/api/copilot/checkpoints/route.ts b/apps/sim/app/api/copilot/checkpoints/route.ts index 391e4ac905..55722b430e 100644 --- a/apps/sim/app/api/copilot/checkpoints/route.ts +++ b/apps/sim/app/api/copilot/checkpoints/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { copilotChats, workflowCheckpoints } from '@sim/db/schema' import { and, desc, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -9,8 +11,6 @@ import { createUnauthorizedResponse, } from '@/lib/copilot/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { copilotChats, workflowCheckpoints } from '@/db/schema' const logger = createLogger('WorkflowCheckpointsAPI') diff --git a/apps/sim/app/api/copilot/feedback/route.ts b/apps/sim/app/api/copilot/feedback/route.ts index e2b129a06e..a71e293f89 100644 --- a/apps/sim/app/api/copilot/feedback/route.ts +++ b/apps/sim/app/api/copilot/feedback/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { copilotFeedback } from '@sim/db/schema' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { @@ -8,8 +10,6 @@ import { createUnauthorizedResponse, } from '@/lib/copilot/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { copilotFeedback } from '@/db/schema' const logger = createLogger('CopilotFeedbackAPI') diff --git a/apps/sim/app/api/environment/route.ts b/apps/sim/app/api/environment/route.ts index 4f575c49d4..c26c1dbfd6 100644 --- a/apps/sim/app/api/environment/route.ts +++ b/apps/sim/app/api/environment/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { environment } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { decryptSecret, encryptSecret, generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { environment } from '@/db/schema' import type { EnvironmentVariable } from '@/stores/settings/environment/types' const logger = createLogger('EnvironmentAPI') diff --git a/apps/sim/app/api/folders/[id]/route.test.ts b/apps/sim/app/api/folders/[id]/route.test.ts index b9d26eb599..9fdd18cd40 100644 --- a/apps/sim/app/api/folders/[id]/route.test.ts +++ b/apps/sim/app/api/folders/[id]/route.test.ts @@ -127,7 +127,7 @@ describe('Individual Folder API Route', () => { mockAuthenticatedUser() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder Name', @@ -152,7 +152,7 @@ describe('Individual Folder API Route', () => { mockAuthenticatedUser() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -171,7 +171,7 @@ describe('Individual Folder API Route', () => { mockUnauthenticated() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -193,7 +193,7 @@ describe('Individual Folder API Route', () => { mockGetUserEntityPermissions.mockResolvedValue('read') // Read-only permissions const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -215,7 +215,7 @@ describe('Individual Folder API Route', () => { mockGetUserEntityPermissions.mockResolvedValue('write') // Write permissions const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -237,7 +237,7 @@ describe('Individual Folder API Route', () => { mockGetUserEntityPermissions.mockResolvedValue('admin') // Admin permissions const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -258,7 +258,7 @@ describe('Individual Folder API Route', () => { mockAuthenticatedUser() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -293,7 +293,7 @@ describe('Individual Folder API Route', () => { }), }) - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: ' Folder With Spaces ', @@ -314,7 +314,7 @@ describe('Individual Folder API Route', () => { const dbMock = createFolderDbMock({ throwError: true, }) - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder', @@ -340,7 +340,7 @@ describe('Individual Folder API Route', () => { mockAuthenticatedUser() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: '', // Empty name @@ -359,7 +359,7 @@ describe('Individual Folder API Route', () => { mockAuthenticatedUser() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) // Create a request with invalid JSON const req = new Request('http://localhost:3000/api/folders/folder-1', { @@ -396,7 +396,7 @@ describe('Individual Folder API Route', () => { folderLookupResult: { id: 'folder-3', parentId: null, name: 'Folder 3' }, circularCheckResults, }) - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('PUT', { name: 'Updated Folder 3', @@ -425,7 +425,7 @@ describe('Individual Folder API Route', () => { }) // Mock the recursive deletion function - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('DELETE') const params = Promise.resolve({ id: 'folder-1' }) @@ -445,7 +445,7 @@ describe('Individual Folder API Route', () => { mockUnauthenticated() const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('DELETE') const params = Promise.resolve({ id: 'folder-1' }) @@ -465,7 +465,7 @@ describe('Individual Folder API Route', () => { mockGetUserEntityPermissions.mockResolvedValue('read') // Read-only permissions const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('DELETE') const params = Promise.resolve({ id: 'folder-1' }) @@ -485,7 +485,7 @@ describe('Individual Folder API Route', () => { mockGetUserEntityPermissions.mockResolvedValue('write') // Write permissions (not enough for delete) const dbMock = createFolderDbMock() - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('DELETE') const params = Promise.resolve({ id: 'folder-1' }) @@ -507,7 +507,7 @@ describe('Individual Folder API Route', () => { const dbMock = createFolderDbMock({ folderLookupResult: mockFolder, }) - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('DELETE') const params = Promise.resolve({ id: 'folder-1' }) @@ -528,7 +528,7 @@ describe('Individual Folder API Route', () => { const dbMock = createFolderDbMock({ throwError: true, }) - vi.doMock('@/db', () => dbMock) + vi.doMock('@sim/db', () => dbMock) const req = createMockRequest('DELETE') const params = Promise.resolve({ id: 'folder-1' }) diff --git a/apps/sim/app/api/folders/[id]/route.ts b/apps/sim/app/api/folders/[id]/route.ts index a686fca0be..4ebad9e4c8 100644 --- a/apps/sim/app/api/folders/[id]/route.ts +++ b/apps/sim/app/api/folders/[id]/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { workflow, workflowFolder } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' -import { db } from '@/db' -import { workflow, workflowFolder } from '@/db/schema' const logger = createLogger('FoldersIDAPI') diff --git a/apps/sim/app/api/folders/route.test.ts b/apps/sim/app/api/folders/route.test.ts index f05aff1e1a..6f59c4a888 100644 --- a/apps/sim/app/api/folders/route.test.ts +++ b/apps/sim/app/api/folders/route.test.ts @@ -75,7 +75,7 @@ describe('Folders API Route', () => { mockGetUserEntityPermissions.mockResolvedValue('admin') - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, insert: mockInsert, diff --git a/apps/sim/app/api/folders/route.ts b/apps/sim/app/api/folders/route.ts index 0451870cbd..7e11b17823 100644 --- a/apps/sim/app/api/folders/route.ts +++ b/apps/sim/app/api/folders/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { workflowFolder } from '@sim/db/schema' import { and, asc, desc, eq, isNull } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' -import { db } from '@/db' -import { workflowFolder } from '@/db/schema' const logger = createLogger('FoldersAPI') diff --git a/apps/sim/app/api/knowledge/[id]/documents/[documentId]/route.test.ts b/apps/sim/app/api/knowledge/[id]/documents/[documentId]/route.test.ts index 8d3449407b..22c37b90f8 100644 --- a/apps/sim/app/api/knowledge/[id]/documents/[documentId]/route.test.ts +++ b/apps/sim/app/api/knowledge/[id]/documents/[documentId]/route.test.ts @@ -83,7 +83,7 @@ describe('Document By ID API Route', () => { beforeEach(async () => { resetMocks() - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) diff --git a/apps/sim/app/api/knowledge/[id]/documents/route.test.ts b/apps/sim/app/api/knowledge/[id]/documents/route.test.ts index 84ef5cf9bd..8709c1ba2d 100644 --- a/apps/sim/app/api/knowledge/[id]/documents/route.test.ts +++ b/apps/sim/app/api/knowledge/[id]/documents/route.test.ts @@ -90,7 +90,7 @@ describe('Knowledge Base Documents API Route', () => { beforeEach(async () => { resetMocks() - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) diff --git a/apps/sim/app/api/knowledge/[id]/route.test.ts b/apps/sim/app/api/knowledge/[id]/route.test.ts index 66b9e544b9..bbe491d465 100644 --- a/apps/sim/app/api/knowledge/[id]/route.test.ts +++ b/apps/sim/app/api/knowledge/[id]/route.test.ts @@ -72,7 +72,7 @@ describe('Knowledge Base By ID API Route', () => { beforeEach(async () => { vi.clearAllMocks() - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) diff --git a/apps/sim/app/api/knowledge/route.test.ts b/apps/sim/app/api/knowledge/route.test.ts index 0d3d81fcd1..a80fe27740 100644 --- a/apps/sim/app/api/knowledge/route.test.ts +++ b/apps/sim/app/api/knowledge/route.test.ts @@ -33,7 +33,7 @@ describe('Knowledge Base API Route', () => { beforeEach(async () => { vi.clearAllMocks() - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) diff --git a/apps/sim/app/api/knowledge/search/route.test.ts b/apps/sim/app/api/knowledge/search/route.test.ts index ea0885924c..68e5b97ba9 100644 --- a/apps/sim/app/api/knowledge/search/route.test.ts +++ b/apps/sim/app/api/knowledge/search/route.test.ts @@ -128,7 +128,7 @@ describe('Knowledge Search API Route', () => { beforeEach(async () => { vi.clearAllMocks() - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) diff --git a/apps/sim/app/api/knowledge/search/utils.test.ts b/apps/sim/app/api/knowledge/search/utils.test.ts index c71757b9be..0261349eb1 100644 --- a/apps/sim/app/api/knowledge/search/utils.test.ts +++ b/apps/sim/app/api/knowledge/search/utils.test.ts @@ -15,7 +15,7 @@ vi.mock('@/lib/logs/console/logger', () => ({ error: vi.fn(), })), })) -vi.mock('@/db') +vi.mock('@sim/db') vi.mock('@/lib/knowledge/documents/utils', () => ({ retryWithExponentialBackoff: (fn: any) => fn(), })) diff --git a/apps/sim/app/api/knowledge/search/utils.ts b/apps/sim/app/api/knowledge/search/utils.ts index d3f03e375f..365623e87c 100644 --- a/apps/sim/app/api/knowledge/search/utils.ts +++ b/apps/sim/app/api/knowledge/search/utils.ts @@ -1,7 +1,7 @@ +import { db } from '@sim/db' +import { document, embedding } from '@sim/db/schema' import { and, eq, inArray, isNull, sql } from 'drizzle-orm' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { document, embedding } from '@/db/schema' const logger = createLogger('KnowledgeSearchUtils') diff --git a/apps/sim/app/api/knowledge/utils.test.ts b/apps/sim/app/api/knowledge/utils.test.ts index a35ca9a768..19ac490a97 100644 --- a/apps/sim/app/api/knowledge/utils.test.ts +++ b/apps/sim/app/api/knowledge/utils.test.ts @@ -84,7 +84,7 @@ vi.stubGlobal( }) ) -vi.mock('@/db', () => { +vi.mock('@sim/db', () => { const selectBuilder = { from(table: any) { return { diff --git a/apps/sim/app/api/knowledge/utils.ts b/apps/sim/app/api/knowledge/utils.ts index 215163878f..29ec910b25 100644 --- a/apps/sim/app/api/knowledge/utils.ts +++ b/apps/sim/app/api/knowledge/utils.ts @@ -1,7 +1,7 @@ +import { db } from '@sim/db' +import { document, embedding, knowledgeBase } from '@sim/db/schema' import { and, eq, isNull } from 'drizzle-orm' import { getUserEntityPermissions } from '@/lib/permissions/utils' -import { db } from '@/db' -import { document, embedding, knowledgeBase } from '@/db/schema' export interface KnowledgeBaseData { id: string diff --git a/apps/sim/app/api/logs/[id]/route.ts b/apps/sim/app/api/logs/[id]/route.ts index 1f94fa18f6..015197597a 100644 --- a/apps/sim/app/api/logs/[id]/route.ts +++ b/apps/sim/app/api/logs/[id]/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowExecutionLogs } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { permissions, workflow, workflowExecutionLogs } from '@/db/schema' const logger = createLogger('LogDetailsByIdAPI') diff --git a/apps/sim/app/api/logs/cleanup/route.ts b/apps/sim/app/api/logs/cleanup/route.ts index 55ca2b35b5..a64cbdf7fc 100644 --- a/apps/sim/app/api/logs/cleanup/route.ts +++ b/apps/sim/app/api/logs/cleanup/route.ts @@ -1,4 +1,7 @@ import { PutObjectCommand } from '@aws-sdk/client-s3' +// Dynamic import for S3 client to avoid client-side bundling +import { db } from '@sim/db' +import { subscription, user, workflow, workflowExecutionLogs } from '@sim/db/schema' import { and, eq, inArray, lt, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { verifyCronAuth } from '@/lib/auth/internal' @@ -6,9 +9,6 @@ import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' import { snapshotService } from '@/lib/logs/execution/snapshot/service' import { deleteFile, isUsingCloudStorage } from '@/lib/uploads' -// Dynamic import for S3 client to avoid client-side bundling -import { db } from '@/db' -import { subscription, user, workflow, workflowExecutionLogs } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/logs/execution/[executionId]/route.ts b/apps/sim/app/api/logs/execution/[executionId]/route.ts index decfeea953..0a6058c10c 100644 --- a/apps/sim/app/api/logs/execution/[executionId]/route.ts +++ b/apps/sim/app/api/logs/execution/[executionId]/route.ts @@ -1,8 +1,8 @@ +import { db } from '@sim/db' +import { workflowExecutionLogs, workflowExecutionSnapshots } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { workflowExecutionLogs, workflowExecutionSnapshots } from '@/db/schema' const logger = createLogger('LogsByExecutionIdAPI') diff --git a/apps/sim/app/api/logs/route.ts b/apps/sim/app/api/logs/route.ts index cfe6fbfb60..a359a2f6db 100644 --- a/apps/sim/app/api/logs/route.ts +++ b/apps/sim/app/api/logs/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowExecutionLogs } from '@sim/db/schema' import { and, desc, eq, gte, inArray, lte, type SQL, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { permissions, workflow, workflowExecutionLogs } from '@/db/schema' const logger = createLogger('LogsAPI') diff --git a/apps/sim/app/api/mcp/servers/[id]/refresh/route.ts b/apps/sim/app/api/mcp/servers/[id]/refresh/route.ts index 3f1da8b06a..df1adfd02c 100644 --- a/apps/sim/app/api/mcp/servers/[id]/refresh/route.ts +++ b/apps/sim/app/api/mcp/servers/[id]/refresh/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { mcpServers } from '@sim/db/schema' import { and, eq, isNull } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { withMcpAuth } from '@/lib/mcp/middleware' import { mcpService } from '@/lib/mcp/service' import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils' -import { db } from '@/db' -import { mcpServers } from '@/db/schema' const logger = createLogger('McpServerRefreshAPI') diff --git a/apps/sim/app/api/mcp/servers/[id]/route.ts b/apps/sim/app/api/mcp/servers/[id]/route.ts index a60b275c1a..e64ca9a63f 100644 --- a/apps/sim/app/api/mcp/servers/[id]/route.ts +++ b/apps/sim/app/api/mcp/servers/[id]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { mcpServers } from '@sim/db/schema' import { and, eq, isNull } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' @@ -5,8 +7,6 @@ import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware' import { mcpService } from '@/lib/mcp/service' import { validateMcpServerUrl } from '@/lib/mcp/url-validator' import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils' -import { db } from '@/db' -import { mcpServers } from '@/db/schema' const logger = createLogger('McpServerAPI') diff --git a/apps/sim/app/api/mcp/servers/route.ts b/apps/sim/app/api/mcp/servers/route.ts index de3151c31f..6c82eb275c 100644 --- a/apps/sim/app/api/mcp/servers/route.ts +++ b/apps/sim/app/api/mcp/servers/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { mcpServers } from '@sim/db/schema' import { and, eq, isNull } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' @@ -6,8 +8,6 @@ import { mcpService } from '@/lib/mcp/service' import type { McpTransport } from '@/lib/mcp/types' import { validateMcpServerUrl } from '@/lib/mcp/url-validator' import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils' -import { db } from '@/db' -import { mcpServers } from '@/db/schema' const logger = createLogger('McpServersAPI') diff --git a/apps/sim/app/api/memory/[id]/route.ts b/apps/sim/app/api/memory/[id]/route.ts index 5887fb450a..de33f2e56a 100644 --- a/apps/sim/app/api/memory/[id]/route.ts +++ b/apps/sim/app/api/memory/[id]/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { memory } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { memory } from '@/db/schema' const logger = createLogger('MemoryByIdAPI') diff --git a/apps/sim/app/api/memory/route.ts b/apps/sim/app/api/memory/route.ts index 3c23fcb8d8..8ce962be6d 100644 --- a/apps/sim/app/api/memory/route.ts +++ b/apps/sim/app/api/memory/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { memory } from '@sim/db/schema' import { and, eq, isNull, like } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { memory } from '@/db/schema' const logger = createLogger('MemoryAPI') diff --git a/apps/sim/app/api/organizations/[id]/invitations/[invitationId]/route.ts b/apps/sim/app/api/organizations/[id]/invitations/[invitationId]/route.ts index 236ffd3a91..13519d3b9b 100644 --- a/apps/sim/app/api/organizations/[id]/invitations/[invitationId]/route.ts +++ b/apps/sim/app/api/organizations/[id]/invitations/[invitationId]/route.ts @@ -1,9 +1,5 @@ import { randomUUID } from 'crypto' -import { and, eq } from 'drizzle-orm' -import { type NextRequest, NextResponse } from 'next/server' -import { getSession } from '@/lib/auth' -import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' +import { db } from '@sim/db' import { invitation, member, @@ -12,7 +8,11 @@ import { user, type WorkspaceInvitationStatus, workspaceInvitation, -} from '@/db/schema' +} from '@sim/db/schema' +import { and, eq } from 'drizzle-orm' +import { type NextRequest, NextResponse } from 'next/server' +import { getSession } from '@/lib/auth' +import { createLogger } from '@/lib/logs/console/logger' const logger = createLogger('OrganizationInvitation') diff --git a/apps/sim/app/api/organizations/[id]/invitations/route.ts b/apps/sim/app/api/organizations/[id]/invitations/route.ts index 86de13aa15..cb2d966537 100644 --- a/apps/sim/app/api/organizations/[id]/invitations/route.ts +++ b/apps/sim/app/api/organizations/[id]/invitations/route.ts @@ -1,4 +1,14 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { + invitation, + member, + organization, + user, + type WorkspaceInvitationStatus, + workspace, + workspaceInvitation, +} from '@sim/db/schema' import { and, eq, inArray, isNull } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { @@ -16,16 +26,6 @@ import { quickValidateEmail } from '@/lib/email/validation' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' import { hasWorkspaceAdminAccess } from '@/lib/permissions/utils' -import { db } from '@/db' -import { - invitation, - member, - organization, - user, - type WorkspaceInvitationStatus, - workspace, - workspaceInvitation, -} from '@/db/schema' const logger = createLogger('OrganizationInvitations') diff --git a/apps/sim/app/api/organizations/[id]/members/[memberId]/route.ts b/apps/sim/app/api/organizations/[id]/members/[memberId]/route.ts index 7a26e29aec..ab4deaca6c 100644 --- a/apps/sim/app/api/organizations/[id]/members/[memberId]/route.ts +++ b/apps/sim/app/api/organizations/[id]/members/[memberId]/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { member, user, userStats } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { getUserUsageData } from '@/lib/billing/core/usage' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { member, user, userStats } from '@/db/schema' const logger = createLogger('OrganizationMemberAPI') diff --git a/apps/sim/app/api/organizations/[id]/members/route.ts b/apps/sim/app/api/organizations/[id]/members/route.ts index 445539a001..193ace3699 100644 --- a/apps/sim/app/api/organizations/[id]/members/route.ts +++ b/apps/sim/app/api/organizations/[id]/members/route.ts @@ -1,4 +1,6 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { invitation, member, organization, user, userStats } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getEmailSubject, renderInvitationEmail } from '@/components/emails/render-email' @@ -9,8 +11,6 @@ import { sendEmail } from '@/lib/email/mailer' import { quickValidateEmail } from '@/lib/email/validation' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { invitation, member, organization, user, userStats } from '@/db/schema' const logger = createLogger('OrganizationMembersAPI') diff --git a/apps/sim/app/api/organizations/[id]/route.ts b/apps/sim/app/api/organizations/[id]/route.ts index 2096e2a157..f05a52c786 100644 --- a/apps/sim/app/api/organizations/[id]/route.ts +++ b/apps/sim/app/api/organizations/[id]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { member, organization } from '@sim/db/schema' import { and, eq, ne } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' @@ -7,8 +9,6 @@ import { updateOrganizationSeats, } from '@/lib/billing/validation/seat-management' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { member, organization } from '@/db/schema' const logger = createLogger('OrganizationAPI') diff --git a/apps/sim/app/api/organizations/[id]/workspaces/route.ts b/apps/sim/app/api/organizations/[id]/workspaces/route.ts index 8fb95ce81b..b4f3fb5079 100644 --- a/apps/sim/app/api/organizations/[id]/workspaces/route.ts +++ b/apps/sim/app/api/organizations/[id]/workspaces/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { member, permissions, user, workspace } from '@sim/db/schema' import { and, eq, or } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { member, permissions, user, workspace } from '@/db/schema' const logger = createLogger('OrganizationWorkspacesAPI') diff --git a/apps/sim/app/api/schedules/[id]/route.ts b/apps/sim/app/api/schedules/[id]/route.ts index c9c5b5fc17..2c7492993b 100644 --- a/apps/sim/app/api/schedules/[id]/route.ts +++ b/apps/sim/app/api/schedules/[id]/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { workflow, workflowSchedule } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { workflow, workflowSchedule } from '@/db/schema' const logger = createLogger('ScheduleAPI') diff --git a/apps/sim/app/api/schedules/[id]/status/route.ts b/apps/sim/app/api/schedules/[id]/status/route.ts index 7756ed2574..3f3d3d7b29 100644 --- a/apps/sim/app/api/schedules/[id]/status/route.ts +++ b/apps/sim/app/api/schedules/[id]/status/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { workflow, workflowSchedule } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { workflow, workflowSchedule } from '@/db/schema' const logger = createLogger('ScheduleStatusAPI') diff --git a/apps/sim/app/api/schedules/execute/route.test.ts b/apps/sim/app/api/schedules/execute/route.test.ts index c7d14b89ab..6adfe533ac 100644 --- a/apps/sim/app/api/schedules/execute/route.test.ts +++ b/apps/sim/app/api/schedules/execute/route.test.ts @@ -33,7 +33,7 @@ describe('Scheduled Workflow Execution API Route', () => { })), })) - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockDb = { select: vi.fn().mockImplementation(() => ({ from: vi.fn().mockImplementation((table: string) => { @@ -147,7 +147,7 @@ describe('Scheduled Workflow Execution API Route', () => { }) it('should handle case with no due schedules', async () => { - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockDb = { select: vi.fn().mockImplementation(() => ({ from: vi.fn().mockImplementation(() => ({ @@ -183,7 +183,7 @@ describe('Scheduled Workflow Execution API Route', () => { }) it('should handle scheduler-level errors gracefully', async () => { - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockDb = { select: vi.fn().mockImplementation(() => { throw new Error('Database error') diff --git a/apps/sim/app/api/schedules/execute/route.ts b/apps/sim/app/api/schedules/execute/route.ts index 1a00f741c0..a58030639d 100644 --- a/apps/sim/app/api/schedules/execute/route.ts +++ b/apps/sim/app/api/schedules/execute/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { userStats, workflow, workflowSchedule } from '@sim/db/schema' import { Cron } from 'croner' import { and, eq, lte, not, sql } from 'drizzle-orm' import { NextResponse } from 'next/server' @@ -18,8 +20,6 @@ import { import { decryptSecret, generateRequestId } from '@/lib/utils' import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers' import { updateWorkflowRunCounts } from '@/lib/workflows/utils' -import { db } from '@/db' -import { userStats, workflow, workflowSchedule } from '@/db/schema' import { Executor } from '@/executor' import { Serializer } from '@/serializer' import { RateLimiter } from '@/services/queue' diff --git a/apps/sim/app/api/schedules/route.test.ts b/apps/sim/app/api/schedules/route.test.ts index 6638820a52..a118560c64 100644 --- a/apps/sim/app/api/schedules/route.test.ts +++ b/apps/sim/app/api/schedules/route.test.ts @@ -52,7 +52,7 @@ describe('Schedule Configuration API Route', () => { // Create mock database with test schedules // Mock the database to return workflow data for authorization check - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { let callCount = 0 const mockDb = { select: vi.fn().mockImplementation(() => ({ @@ -201,7 +201,7 @@ describe('Schedule Configuration API Route', () => { where: vi.fn().mockResolvedValue([]), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockImplementation(() => ({ from: vi.fn().mockImplementation(() => ({ @@ -271,7 +271,7 @@ describe('Schedule Configuration API Route', () => { */ it('should handle errors gracefully', async () => { // Mock the db to throw an error on insert - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockImplementation(() => ({ from: vi.fn().mockImplementation(() => ({ diff --git a/apps/sim/app/api/schedules/route.ts b/apps/sim/app/api/schedules/route.ts index dc610a6d58..a47acec329 100644 --- a/apps/sim/app/api/schedules/route.ts +++ b/apps/sim/app/api/schedules/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow, workflowSchedule } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -13,8 +15,6 @@ import { validateCronExpression, } from '@/lib/schedules/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { workflow, workflowSchedule } from '@/db/schema' const logger = createLogger('ScheduledAPI') diff --git a/apps/sim/app/api/templates/[id]/route.ts b/apps/sim/app/api/templates/[id]/route.ts index b7e5039ae8..8420e6b51b 100644 --- a/apps/sim/app/api/templates/[id]/route.ts +++ b/apps/sim/app/api/templates/[id]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { templates, workflow } from '@sim/db/schema' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { hasAdminPermission } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { templates, workflow } from '@/db/schema' const logger = createLogger('TemplateByIdAPI') diff --git a/apps/sim/app/api/templates/[id]/star/route.ts b/apps/sim/app/api/templates/[id]/star/route.ts index da281ca497..9bcf55e319 100644 --- a/apps/sim/app/api/templates/[id]/star/route.ts +++ b/apps/sim/app/api/templates/[id]/star/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { templateStars, templates } from '@sim/db/schema' import { and, eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v4 as uuidv4 } from 'uuid' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { templateStars, templates } from '@/db/schema' const logger = createLogger('TemplateStarAPI') diff --git a/apps/sim/app/api/templates/[id]/use/route.ts b/apps/sim/app/api/templates/[id]/use/route.ts index 33a02976c0..f228ec6664 100644 --- a/apps/sim/app/api/templates/[id]/use/route.ts +++ b/apps/sim/app/api/templates/[id]/use/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { templates, workflow, workflowBlocks, workflowEdges } from '@sim/db/schema' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v4 as uuidv4 } from 'uuid' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { templates, workflow, workflowBlocks, workflowEdges } from '@/db/schema' const logger = createLogger('TemplateUseAPI') diff --git a/apps/sim/app/api/templates/route.ts b/apps/sim/app/api/templates/route.ts index 9bc8ec9b6e..76383d647f 100644 --- a/apps/sim/app/api/templates/route.ts +++ b/apps/sim/app/api/templates/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { templateStars, templates, workflow } from '@sim/db/schema' import { and, desc, eq, ilike, or, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v4 as uuidv4 } from 'uuid' @@ -5,8 +7,6 @@ import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { templateStars, templates, workflow } from '@/db/schema' const logger = createLogger('TemplatesAPI') diff --git a/apps/sim/app/api/tools/custom/route.test.ts b/apps/sim/app/api/tools/custom/route.test.ts index 949ad1e647..6f34f26fd6 100644 --- a/apps/sim/app/api/tools/custom/route.test.ts +++ b/apps/sim/app/api/tools/custom/route.test.ts @@ -91,7 +91,7 @@ describe('Custom Tools API Routes', () => { mockDelete.mockReturnValue({ where: mockWhere }) // Mock database - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: mockSelect, insert: mockInsert, @@ -110,7 +110,7 @@ describe('Custom Tools API Routes', () => { })) // Mock schema - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ customTools: { userId: 'userId', // Add these properties to enable WHERE clauses with eq() id: 'id', diff --git a/apps/sim/app/api/tools/custom/route.ts b/apps/sim/app/api/tools/custom/route.ts index 885a697177..23327c9a3d 100644 --- a/apps/sim/app/api/tools/custom/route.ts +++ b/apps/sim/app/api/tools/custom/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { customTools } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { getUserId } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { customTools } from '@/db/schema' const logger = createLogger('CustomToolsAPI') diff --git a/apps/sim/app/api/tools/gmail/label/route.ts b/apps/sim/app/api/tools/gmail/label/route.ts index 2d3ae5df49..5a0e8aa6d9 100644 --- a/apps/sim/app/api/tools/gmail/label/route.ts +++ b/apps/sim/app/api/tools/gmail/label/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/gmail/labels/route.ts b/apps/sim/app/api/tools/gmail/labels/route.ts index aa90e28f08..3b177d4f4e 100644 --- a/apps/sim/app/api/tools/gmail/labels/route.ts +++ b/apps/sim/app/api/tools/gmail/labels/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' const logger = createLogger('GmailLabelsAPI') diff --git a/apps/sim/app/api/tools/microsoft_planner/tasks/route.ts b/apps/sim/app/api/tools/microsoft_planner/tasks/route.ts index f25802e8c8..c898e03383 100644 --- a/apps/sim/app/api/tools/microsoft_planner/tasks/route.ts +++ b/apps/sim/app/api/tools/microsoft_planner/tasks/route.ts @@ -1,11 +1,11 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' import type { PlannerTask } from '@/tools/microsoft_planner/types' const logger = createLogger('MicrosoftPlannerTasksAPI') diff --git a/apps/sim/app/api/tools/onedrive/folder/route.ts b/apps/sim/app/api/tools/onedrive/folder/route.ts index d29ad7e57b..49d2befb6a 100644 --- a/apps/sim/app/api/tools/onedrive/folder/route.ts +++ b/apps/sim/app/api/tools/onedrive/folder/route.ts @@ -1,11 +1,11 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/onedrive/folders/route.ts b/apps/sim/app/api/tools/onedrive/folders/route.ts index 4194addfba..b62d41179d 100644 --- a/apps/sim/app/api/tools/onedrive/folders/route.ts +++ b/apps/sim/app/api/tools/onedrive/folders/route.ts @@ -1,11 +1,11 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/outlook/folders/route.ts b/apps/sim/app/api/tools/outlook/folders/route.ts index 0e52c164d1..78d75e494d 100644 --- a/apps/sim/app/api/tools/outlook/folders/route.ts +++ b/apps/sim/app/api/tools/outlook/folders/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/sharepoint/site/route.ts b/apps/sim/app/api/tools/sharepoint/site/route.ts index 225bd748e7..a31a8ed94e 100644 --- a/apps/sim/app/api/tools/sharepoint/site/route.ts +++ b/apps/sim/app/api/tools/sharepoint/site/route.ts @@ -1,11 +1,11 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/sharepoint/sites/route.ts b/apps/sim/app/api/tools/sharepoint/sites/route.ts index 93bc5bd094..3448ff22e2 100644 --- a/apps/sim/app/api/tools/sharepoint/sites/route.ts +++ b/apps/sim/app/api/tools/sharepoint/sites/route.ts @@ -1,11 +1,11 @@ import { randomUUID } from 'crypto' +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' import type { SharepointSite } from '@/tools/sharepoint/types' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/wealthbox/item/route.ts b/apps/sim/app/api/tools/wealthbox/item/route.ts index ee0c21108e..a57d405441 100644 --- a/apps/sim/app/api/tools/wealthbox/item/route.ts +++ b/apps/sim/app/api/tools/wealthbox/item/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/tools/wealthbox/items/route.ts b/apps/sim/app/api/tools/wealthbox/items/route.ts index 999df67bbd..579cd90871 100644 --- a/apps/sim/app/api/tools/wealthbox/items/route.ts +++ b/apps/sim/app/api/tools/wealthbox/items/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { account } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { account } from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/users/me/api-keys/[id]/route.ts b/apps/sim/app/api/users/me/api-keys/[id]/route.ts index c0e13defa0..cbd093092e 100644 --- a/apps/sim/app/api/users/me/api-keys/[id]/route.ts +++ b/apps/sim/app/api/users/me/api-keys/[id]/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { apiKey } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { apiKey } from '@/db/schema' const logger = createLogger('ApiKeyAPI') diff --git a/apps/sim/app/api/users/me/api-keys/route.ts b/apps/sim/app/api/users/me/api-keys/route.ts index 4f24a43022..ca4e78d577 100644 --- a/apps/sim/app/api/users/me/api-keys/route.ts +++ b/apps/sim/app/api/users/me/api-keys/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { apiKey } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { nanoid } from 'nanoid' import { type NextRequest, NextResponse } from 'next/server' import { createApiKey, getApiKeyDisplayFormat } from '@/lib/api-key/auth' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { apiKey } from '@/db/schema' const logger = createLogger('ApiKeysAPI') diff --git a/apps/sim/app/api/users/me/profile/route.ts b/apps/sim/app/api/users/me/profile/route.ts index 6801376bc6..074ca0add4 100644 --- a/apps/sim/app/api/users/me/profile/route.ts +++ b/apps/sim/app/api/users/me/profile/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { user } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { user } from '@/db/schema' const logger = createLogger('UpdateUserProfileAPI') diff --git a/apps/sim/app/api/users/me/settings/route.ts b/apps/sim/app/api/users/me/settings/route.ts index 658ff3c293..a5a2d72650 100644 --- a/apps/sim/app/api/users/me/settings/route.ts +++ b/apps/sim/app/api/users/me/settings/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { settings } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { nanoid } from 'nanoid' import { NextResponse } from 'next/server' @@ -5,8 +7,6 @@ import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { settings } from '@/db/schema' const logger = createLogger('UserSettingsAPI') diff --git a/apps/sim/app/api/users/me/subscription/[id]/transfer/route.test.ts b/apps/sim/app/api/users/me/subscription/[id]/transfer/route.test.ts index 8606665bfe..77192d8d77 100644 --- a/apps/sim/app/api/users/me/subscription/[id]/transfer/route.test.ts +++ b/apps/sim/app/api/users/me/subscription/[id]/transfer/route.test.ts @@ -29,7 +29,7 @@ describe('Subscription Transfer API Routes', () => { createLogger: vi.fn().mockReturnValue(mockLogger), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDb, })) @@ -60,7 +60,7 @@ describe('Subscription Transfer API Routes', () => { }), })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ subscription: { id: 'id', referenceId: 'referenceId' }, organization: { id: 'id' }, member: { userId: 'userId', organizationId: 'organizationId', role: 'role' }, diff --git a/apps/sim/app/api/users/me/subscription/[id]/transfer/route.ts b/apps/sim/app/api/users/me/subscription/[id]/transfer/route.ts index a7a8ca7e85..3a2986b537 100644 --- a/apps/sim/app/api/users/me/subscription/[id]/transfer/route.ts +++ b/apps/sim/app/api/users/me/subscription/[id]/transfer/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { member, organization, subscription } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { member, organization, subscription } from '@/db/schema' const logger = createLogger('SubscriptionTransferAPI') diff --git a/apps/sim/app/api/v1/logs/[id]/route.ts b/apps/sim/app/api/v1/logs/[id]/route.ts index f2be5918ac..aa53fb496c 100644 --- a/apps/sim/app/api/v1/logs/[id]/route.ts +++ b/apps/sim/app/api/v1/logs/[id]/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowExecutionLogs } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta' import { checkRateLimit, createRateLimitResponse } from '@/app/api/v1/middleware' -import { db } from '@/db' -import { permissions, workflow, workflowExecutionLogs } from '@/db/schema' const logger = createLogger('V1LogDetailsAPI') diff --git a/apps/sim/app/api/v1/logs/executions/[executionId]/route.ts b/apps/sim/app/api/v1/logs/executions/[executionId]/route.ts index 6800a11551..a68cd0f313 100644 --- a/apps/sim/app/api/v1/logs/executions/[executionId]/route.ts +++ b/apps/sim/app/api/v1/logs/executions/[executionId]/route.ts @@ -1,15 +1,15 @@ -import { and, eq } from 'drizzle-orm' -import { type NextRequest, NextResponse } from 'next/server' -import { createLogger } from '@/lib/logs/console/logger' -import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta' -import { checkRateLimit, createRateLimitResponse } from '@/app/api/v1/middleware' -import { db } from '@/db' +import { db } from '@sim/db' import { permissions, workflow, workflowExecutionLogs, workflowExecutionSnapshots, -} from '@/db/schema' +} from '@sim/db/schema' +import { and, eq } from 'drizzle-orm' +import { type NextRequest, NextResponse } from 'next/server' +import { createLogger } from '@/lib/logs/console/logger' +import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta' +import { checkRateLimit, createRateLimitResponse } from '@/app/api/v1/middleware' const logger = createLogger('V1ExecutionAPI') diff --git a/apps/sim/app/api/v1/logs/filters.ts b/apps/sim/app/api/v1/logs/filters.ts index d2061d4a4e..825739daaf 100644 --- a/apps/sim/app/api/v1/logs/filters.ts +++ b/apps/sim/app/api/v1/logs/filters.ts @@ -1,5 +1,5 @@ +import { workflow, workflowExecutionLogs } from '@sim/db/schema' import { and, desc, eq, gte, inArray, lte, type SQL, sql } from 'drizzle-orm' -import { workflow, workflowExecutionLogs } from '@/db/schema' export interface LogFilters { workspaceId: string diff --git a/apps/sim/app/api/v1/logs/route.ts b/apps/sim/app/api/v1/logs/route.ts index aba568c580..69b95273d7 100644 --- a/apps/sim/app/api/v1/logs/route.ts +++ b/apps/sim/app/api/v1/logs/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowExecutionLogs } from '@sim/db/schema' import { and, eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { buildLogFilters, getOrderBy } from '@/app/api/v1/logs/filters' import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta' import { checkRateLimit, createRateLimitResponse } from '@/app/api/v1/middleware' -import { db } from '@/db' -import { permissions, workflow, workflowExecutionLogs } from '@/db/schema' const logger = createLogger('V1LogsAPI') diff --git a/apps/sim/app/api/wand-generate/route.ts b/apps/sim/app/api/wand-generate/route.ts index 9a1954e2e9..099bc3ea55 100644 --- a/apps/sim/app/api/wand-generate/route.ts +++ b/apps/sim/app/api/wand-generate/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { userStats, workflow } from '@sim/db/schema' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import OpenAI, { AzureOpenAI } from 'openai' @@ -5,8 +7,6 @@ import { env } from '@/lib/env' import { getCostMultiplier, isBillingEnabled } from '@/lib/environment' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { userStats, workflow } from '@/db/schema' import { getModelPricing } from '@/providers/utils' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/webhooks/[id]/route.ts b/apps/sim/app/api/webhooks/[id]/route.ts index 31d465c327..672d04a2d3 100644 --- a/apps/sim/app/api/webhooks/[id]/route.ts +++ b/apps/sim/app/api/webhooks/[id]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { webhook, workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' @@ -6,8 +8,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' import { getOAuthToken } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { webhook, workflow } from '@/db/schema' const logger = createLogger('WebhookAPI') diff --git a/apps/sim/app/api/webhooks/route.ts b/apps/sim/app/api/webhooks/route.ts index 64cd2eb4a1..04727bc33f 100644 --- a/apps/sim/app/api/webhooks/route.ts +++ b/apps/sim/app/api/webhooks/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { webhook, workflow } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { nanoid } from 'nanoid' import { type NextRequest, NextResponse } from 'next/server' @@ -7,8 +9,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' import { getOAuthToken } from '@/app/api/auth/oauth/utils' -import { db } from '@/db' -import { webhook, workflow } from '@/db/schema' const logger = createLogger('WebhooksAPI') diff --git a/apps/sim/app/api/webhooks/test/route.ts b/apps/sim/app/api/webhooks/test/route.ts index 698a385d3c..3bd05846c8 100644 --- a/apps/sim/app/api/webhooks/test/route.ts +++ b/apps/sim/app/api/webhooks/test/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { webhook } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { webhook } from '@/db/schema' const logger = createLogger('WebhookTestAPI') diff --git a/apps/sim/app/api/webhooks/trigger/[path]/route.test.ts b/apps/sim/app/api/webhooks/trigger/[path]/route.test.ts index e0c0eb1f3f..15ee84509e 100644 --- a/apps/sim/app/api/webhooks/trigger/[path]/route.test.ts +++ b/apps/sim/app/api/webhooks/trigger/[path]/route.test.ts @@ -86,7 +86,7 @@ vi.mock('@/executor', () => ({ })), })) -vi.mock('@/db', () => { +vi.mock('@sim/db', () => { const dbMock = { select: vi.fn().mockImplementation((columns) => ({ from: vi.fn().mockImplementation((table) => ({ @@ -202,7 +202,7 @@ describe('Webhook Trigger API Route', () => { const req = new NextRequest(new URL(mockUrl)) // Mock database to return a WhatsApp webhook with matching token - const { db } = await import('@/db') + const { db } = await import('@sim/db') const whereMock = vi.fn().mockReturnValue([ { id: 'webhook-id', @@ -250,7 +250,7 @@ describe('Webhook Trigger API Route', () => { */ it('should handle 404 for non-existent webhooks', async () => { // Configure DB mock to return empty result (no webhook found) - const { db } = await import('@/db') + const { db } = await import('@sim/db') const limitMock = vi.fn().mockReturnValue([]) const whereMock = vi.fn().mockReturnValue({ limit: limitMock }) const innerJoinMock = vi.fn().mockReturnValue({ where: whereMock }) @@ -281,7 +281,7 @@ describe('Webhook Trigger API Route', () => { describe('Generic Webhook Authentication', () => { const setupGenericWebhook = async (config: Record) => { - const { db } = await import('@/db') + const { db } = await import('@sim/db') const limitMock = vi.fn().mockReturnValue([ { webhook: { diff --git a/apps/sim/app/api/webhooks/trigger/[path]/route.ts b/apps/sim/app/api/webhooks/trigger/[path]/route.ts index 76ca29e834..74dbb08971 100644 --- a/apps/sim/app/api/webhooks/trigger/[path]/route.ts +++ b/apps/sim/app/api/webhooks/trigger/[path]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { webhook, workflow } from '@sim/db/schema' import { tasks } from '@trigger.dev/sdk' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' @@ -13,8 +15,6 @@ import { validateMicrosoftTeamsSignature, } from '@/lib/webhooks/utils' import { executeWebhookJob } from '@/background/webhook-execution' -import { db } from '@/db' -import { webhook, workflow } from '@/db/schema' import { RateLimiter } from '@/services/queue' const logger = createLogger('WebhookTriggerAPI') diff --git a/apps/sim/app/api/workflows/[id]/autolayout/route.ts b/apps/sim/app/api/workflows/[id]/autolayout/route.ts index 0d8e86f0d8..23ee28ccd5 100644 --- a/apps/sim/app/api/workflows/[id]/autolayout/route.ts +++ b/apps/sim/app/api/workflows/[id]/autolayout/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow as workflowTable } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -10,8 +12,6 @@ import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers' import { getAllBlocks } from '@/blocks/registry' import type { BlockConfig } from '@/blocks/types' import { resolveOutputType } from '@/blocks/utils' -import { db } from '@/db' -import { workflow as workflowTable } from '@/db/schema' import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/workflow/utils' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/workflows/[id]/chat/status/route.ts b/apps/sim/app/api/workflows/[id]/chat/status/route.ts index 137c25136c..d6d98dfbe3 100644 --- a/apps/sim/app/api/workflows/[id]/chat/status/route.ts +++ b/apps/sim/app/api/workflows/[id]/chat/status/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { chat } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { chat } from '@/db/schema' const logger = createLogger('ChatStatusAPI') diff --git a/apps/sim/app/api/workflows/[id]/deploy/route.test.ts b/apps/sim/app/api/workflows/[id]/deploy/route.test.ts index 753e99fded..3b085bf2bb 100644 --- a/apps/sim/app/api/workflows/[id]/deploy/route.test.ts +++ b/apps/sim/app/api/workflows/[id]/deploy/route.test.ts @@ -99,7 +99,7 @@ describe('Workflow Deployment API Route', () => { })) // Mock the database schema module - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ workflow: {}, apiKey: {}, workflowBlocks: {}, @@ -115,7 +115,7 @@ describe('Workflow Deployment API Route', () => { // Mock the database module with proper chainable query builder let selectCallCount = 0 - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockImplementation(() => { selectCallCount++ @@ -186,7 +186,7 @@ describe('Workflow Deployment API Route', () => { * Test GET deployment status */ it('should fetch deployment info successfully', async () => { - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -234,7 +234,7 @@ describe('Workflow Deployment API Route', () => { }), }) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { update: mockUpdate, }, diff --git a/apps/sim/app/api/workflows/[id]/deploy/route.ts b/apps/sim/app/api/workflows/[id]/deploy/route.ts index caaedee424..ab13d28d43 100644 --- a/apps/sim/app/api/workflows/[id]/deploy/route.ts +++ b/apps/sim/app/api/workflows/[id]/deploy/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { apiKey, workflow, workflowBlocks, workflowEdges, workflowSubflows } from '@sim/db/schema' import { and, desc, eq } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { v4 as uuidv4 } from 'uuid' @@ -6,8 +8,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { validateWorkflowAccess } from '@/app/api/workflows/middleware' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { apiKey, workflow, workflowBlocks, workflowEdges, workflowSubflows } from '@/db/schema' const logger = createLogger('WorkflowDeployAPI') diff --git a/apps/sim/app/api/workflows/[id]/deployed/route.ts b/apps/sim/app/api/workflows/[id]/deployed/route.ts index f4662627cf..bf6e91492c 100644 --- a/apps/sim/app/api/workflows/[id]/deployed/route.ts +++ b/apps/sim/app/api/workflows/[id]/deployed/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import type { NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { validateWorkflowAccess } from '@/app/api/workflows/middleware' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { workflow } from '@/db/schema' const logger = createLogger('WorkflowDeployedStateAPI') diff --git a/apps/sim/app/api/workflows/[id]/duplicate/route.ts b/apps/sim/app/api/workflows/[id]/duplicate/route.ts index 8f1dc984ee..8cf53b742a 100644 --- a/apps/sim/app/api/workflows/[id]/duplicate/route.ts +++ b/apps/sim/app/api/workflows/[id]/duplicate/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow, workflowBlocks, workflowEdges, workflowSubflows } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { workflow, workflowBlocks, workflowEdges, workflowSubflows } from '@/db/schema' import type { Variable } from '@/stores/panel/variables/types' import type { LoopConfig, ParallelConfig } from '@/stores/workflows/workflow/types' diff --git a/apps/sim/app/api/workflows/[id]/execute/route.test.ts b/apps/sim/app/api/workflows/[id]/execute/route.test.ts index 8d7aceb531..ebdd92dba7 100644 --- a/apps/sim/app/api/workflows/[id]/execute/route.test.ts +++ b/apps/sim/app/api/workflows/[id]/execute/route.test.ts @@ -78,7 +78,7 @@ describe('Workflow Execution API Route', () => { }), })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ subscription: { plan: 'plan', referenceId: 'referenceId', @@ -205,7 +205,7 @@ describe('Workflow Execution API Route', () => { }), })) - vi.doMock('@/db', () => { + vi.doMock('@sim/db', () => { const mockDb = { select: vi.fn().mockImplementation((columns) => ({ from: vi.fn().mockImplementation((table) => ({ diff --git a/apps/sim/app/api/workflows/[id]/execute/route.ts b/apps/sim/app/api/workflows/[id]/execute/route.ts index e71ae5f620..73c10606c4 100644 --- a/apps/sim/app/api/workflows/[id]/execute/route.ts +++ b/apps/sim/app/api/workflows/[id]/execute/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { userStats } from '@sim/db/schema' import { tasks } from '@trigger.dev/sdk' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' @@ -19,8 +21,6 @@ import { } from '@/lib/workflows/utils' import { validateWorkflowAccess } from '@/app/api/workflows/middleware' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { userStats } from '@/db/schema' import { Executor } from '@/executor' import { Serializer } from '@/serializer' import { RateLimitError, RateLimiter, type TriggerType } from '@/services/queue' diff --git a/apps/sim/app/api/workflows/[id]/log-webhook/[webhookId]/route.ts b/apps/sim/app/api/workflows/[id]/log-webhook/[webhookId]/route.ts index f08297cb26..db2100fda1 100644 --- a/apps/sim/app/api/workflows/[id]/log-webhook/[webhookId]/route.ts +++ b/apps/sim/app/api/workflows/[id]/log-webhook/[webhookId]/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowLogWebhook } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { encryptSecret } from '@/lib/utils' -import { db } from '@/db' -import { permissions, workflow, workflowLogWebhook } from '@/db/schema' const logger = createLogger('WorkflowLogWebhookUpdate') diff --git a/apps/sim/app/api/workflows/[id]/log-webhook/route.ts b/apps/sim/app/api/workflows/[id]/log-webhook/route.ts index b60bb05ca3..5287effc7b 100644 --- a/apps/sim/app/api/workflows/[id]/log-webhook/route.ts +++ b/apps/sim/app/api/workflows/[id]/log-webhook/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowLogWebhook } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v4 as uuidv4 } from 'uuid' @@ -5,8 +7,6 @@ import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { encryptSecret } from '@/lib/utils' -import { db } from '@/db' -import { permissions, workflow, workflowLogWebhook } from '@/db/schema' const logger = createLogger('WorkflowLogWebhookAPI') diff --git a/apps/sim/app/api/workflows/[id]/log-webhook/test/route.ts b/apps/sim/app/api/workflows/[id]/log-webhook/test/route.ts index e7497f6191..fdd9be09d9 100644 --- a/apps/sim/app/api/workflows/[id]/log-webhook/test/route.ts +++ b/apps/sim/app/api/workflows/[id]/log-webhook/test/route.ts @@ -1,12 +1,12 @@ import { createHmac } from 'crypto' +import { db } from '@sim/db' +import { permissions, workflow, workflowLogWebhook } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v4 as uuidv4 } from 'uuid' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { decryptSecret } from '@/lib/utils' -import { db } from '@/db' -import { permissions, workflow, workflowLogWebhook } from '@/db/schema' const logger = createLogger('WorkflowLogWebhookTestAPI') diff --git a/apps/sim/app/api/workflows/[id]/revert-to-deployed/route.ts b/apps/sim/app/api/workflows/[id]/revert-to-deployed/route.ts index 078ff9f5e7..42327774b3 100644 --- a/apps/sim/app/api/workflows/[id]/revert-to-deployed/route.ts +++ b/apps/sim/app/api/workflows/[id]/revert-to-deployed/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { env } from '@/lib/env' @@ -6,8 +8,6 @@ import { generateRequestId } from '@/lib/utils' import { saveWorkflowToNormalizedTables } from '@/lib/workflows/db-helpers' import { validateWorkflowAccess } from '@/app/api/workflows/middleware' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { workflow } from '@/db/schema' import type { WorkflowState } from '@/stores/workflows/workflow/types' const logger = createLogger('RevertToDeployedAPI') diff --git a/apps/sim/app/api/workflows/[id]/route.test.ts b/apps/sim/app/api/workflows/[id]/route.test.ts index 4ed6bf1140..fb099ac7f8 100644 --- a/apps/sim/app/api/workflows/[id]/route.test.ts +++ b/apps/sim/app/api/workflows/[id]/route.test.ts @@ -60,7 +60,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -105,7 +105,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -154,7 +154,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -200,7 +200,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -250,7 +250,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -294,7 +294,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -340,7 +340,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -391,7 +391,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -439,7 +439,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -488,7 +488,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -542,7 +542,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -587,7 +587,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ @@ -625,7 +625,7 @@ describe('Workflow By ID API Route', () => { }), })) - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ diff --git a/apps/sim/app/api/workflows/[id]/route.ts b/apps/sim/app/api/workflows/[id]/route.ts index 5a4a24a3a5..26e92cef98 100644 --- a/apps/sim/app/api/workflows/[id]/route.ts +++ b/apps/sim/app/api/workflows/[id]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { templates, workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -9,8 +11,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions, hasAdminPermission } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers' -import { db } from '@/db' -import { templates, workflow } from '@/db/schema' const logger = createLogger('WorkflowByIdAPI') diff --git a/apps/sim/app/api/workflows/[id]/state/route.ts b/apps/sim/app/api/workflows/[id]/state/route.ts index 8bef22f51b..3d593339d9 100644 --- a/apps/sim/app/api/workflows/[id]/state/route.ts +++ b/apps/sim/app/api/workflows/[id]/state/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -7,8 +9,6 @@ import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' import { saveWorkflowToNormalizedTables } from '@/lib/workflows/db-helpers' import { sanitizeAgentToolsInBlocks } from '@/lib/workflows/validation' -import { db } from '@/db' -import { workflow } from '@/db/schema' const logger = createLogger('WorkflowStateAPI') diff --git a/apps/sim/app/api/workflows/[id]/stats/route.ts b/apps/sim/app/api/workflows/[id]/stats/route.ts index cf7da2b8f6..69e4513f3d 100644 --- a/apps/sim/app/api/workflows/[id]/stats/route.ts +++ b/apps/sim/app/api/workflows/[id]/stats/route.ts @@ -1,8 +1,8 @@ +import { db } from '@sim/db' +import { userStats, workflow } from '@sim/db/schema' import { eq, sql } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { userStats, workflow } from '@/db/schema' const logger = createLogger('WorkflowStatsAPI') diff --git a/apps/sim/app/api/workflows/[id]/variables/route.ts b/apps/sim/app/api/workflows/[id]/variables/route.ts index 91f7b2ef33..3c3ea5c22c 100644 --- a/apps/sim/app/api/workflows/[id]/variables/route.ts +++ b/apps/sim/app/api/workflows/[id]/variables/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { workflow } from '@/db/schema' import type { Variable } from '@/stores/panel/variables/types' const logger = createLogger('WorkflowVariablesAPI') diff --git a/apps/sim/app/api/workflows/[id]/yaml/route.ts b/apps/sim/app/api/workflows/[id]/yaml/route.ts index 54e33237fa..4507e795f0 100644 --- a/apps/sim/app/api/workflows/[id]/yaml/route.ts +++ b/apps/sim/app/api/workflows/[id]/yaml/route.ts @@ -1,4 +1,6 @@ import crypto from 'crypto' +import { db } from '@sim/db' +import { customTools, workflowCheckpoints, workflow as workflowTable } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -15,8 +17,6 @@ import { getUserId } from '@/app/api/auth/oauth/utils' import { getAllBlocks, getBlock } from '@/blocks' import type { BlockConfig } from '@/blocks/types' import { resolveOutputType } from '@/blocks/utils' -import { db } from '@/db' -import { customTools, workflowCheckpoints, workflow as workflowTable } from '@/db/schema' import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/workflow/utils' const logger = createLogger('YamlWorkflowAPI') diff --git a/apps/sim/app/api/workflows/public/[id]/route.ts b/apps/sim/app/api/workflows/public/[id]/route.ts index 55dc8f1b39..b94c849b45 100644 --- a/apps/sim/app/api/workflows/public/[id]/route.ts +++ b/apps/sim/app/api/workflows/public/[id]/route.ts @@ -1,10 +1,10 @@ +import { db } from '@sim/db' +import { marketplace, workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import type { NextRequest } from 'next/server' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils' -import { db } from '@/db' -import { marketplace, workflow } from '@/db/schema' const logger = createLogger('PublicWorkflowAPI') diff --git a/apps/sim/app/api/workflows/route.ts b/apps/sim/app/api/workflows/route.ts index eff74ee62f..3dfee755dd 100644 --- a/apps/sim/app/api/workflows/route.ts +++ b/apps/sim/app/api/workflows/route.ts @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { workflow, workflowBlocks, workspace } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { workflow, workflowBlocks, workspace } from '@/db/schema' import { verifyWorkspaceMembership } from './utils' const logger = createLogger('WorkflowAPI') diff --git a/apps/sim/app/api/workflows/yaml/export/route.ts b/apps/sim/app/api/workflows/yaml/export/route.ts index 1373528582..5603fec3ec 100644 --- a/apps/sim/app/api/workflows/yaml/export/route.ts +++ b/apps/sim/app/api/workflows/yaml/export/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { workflow } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' @@ -9,8 +11,6 @@ import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers' import { getAllBlocks } from '@/blocks/registry' import type { BlockConfig } from '@/blocks/types' import { resolveOutputType } from '@/blocks/utils' -import { db } from '@/db' -import { workflow } from '@/db/schema' import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/workflow/utils' const logger = createLogger('WorkflowYamlExportAPI') diff --git a/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts b/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts index 96cd1ef2b1..bca567aa50 100644 --- a/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts +++ b/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { apiKey } from '@sim/db/schema' import { and, eq, not } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { apiKey } from '@/db/schema' const logger = createLogger('WorkspaceApiKeyAPI') diff --git a/apps/sim/app/api/workspaces/[id]/api-keys/route.ts b/apps/sim/app/api/workspaces/[id]/api-keys/route.ts index c33ec087a4..8b5b190e0e 100644 --- a/apps/sim/app/api/workspaces/[id]/api-keys/route.ts +++ b/apps/sim/app/api/workspaces/[id]/api-keys/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { apiKey, workspace } from '@sim/db/schema' import { and, eq, inArray } from 'drizzle-orm' import { nanoid } from 'nanoid' import { type NextRequest, NextResponse } from 'next/server' @@ -7,8 +9,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { apiKey, workspace } from '@/db/schema' const logger = createLogger('WorkspaceApiKeysAPI') diff --git a/apps/sim/app/api/workspaces/[id]/environment/route.ts b/apps/sim/app/api/workspaces/[id]/environment/route.ts index 31aa42f980..6ea1478ae2 100644 --- a/apps/sim/app/api/workspaces/[id]/environment/route.ts +++ b/apps/sim/app/api/workspaces/[id]/environment/route.ts @@ -1,3 +1,5 @@ +import { db } from '@sim/db' +import { environment, workspace, workspaceEnvironment } from '@sim/db/schema' import { eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' @@ -5,8 +7,6 @@ import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUserEntityPermissions } from '@/lib/permissions/utils' import { decryptSecret, encryptSecret, generateRequestId } from '@/lib/utils' -import { db } from '@/db' -import { environment, workspace, workspaceEnvironment } from '@/db/schema' const logger = createLogger('WorkspaceEnvironmentAPI') diff --git a/apps/sim/app/api/workspaces/[id]/permissions/route.ts b/apps/sim/app/api/workspaces/[id]/permissions/route.ts index 3d8947621c..531ea7475b 100644 --- a/apps/sim/app/api/workspaces/[id]/permissions/route.ts +++ b/apps/sim/app/api/workspaces/[id]/permissions/route.ts @@ -1,11 +1,11 @@ import crypto from 'crypto' +import { db } from '@sim/db' +import { permissions, type permissionTypeEnum } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import { getUsersWithPermissions, hasWorkspaceAdminAccess } from '@/lib/permissions/utils' -import { db } from '@/db' -import { permissions, type permissionTypeEnum } from '@/db/schema' const logger = createLogger('WorkspacesPermissionsAPI') diff --git a/apps/sim/app/api/workspaces/[id]/route.ts b/apps/sim/app/api/workspaces/[id]/route.ts index b5c53bf04b..10389e8fc1 100644 --- a/apps/sim/app/api/workspaces/[id]/route.ts +++ b/apps/sim/app/api/workspaces/[id]/route.ts @@ -1,14 +1,14 @@ +import { workflow } from '@sim/db/schema' import { and, eq, inArray } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' -import { workflow } from '@/db/schema' const logger = createLogger('WorkspaceByIdAPI') +import { db } from '@sim/db' +import { knowledgeBase, permissions, templates, workspace } from '@sim/db/schema' import { getUserEntityPermissions } from '@/lib/permissions/utils' -import { db } from '@/db' -import { knowledgeBase, permissions, templates, workspace } from '@/db/schema' export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { const { id } = await params diff --git a/apps/sim/app/api/workspaces/invitations/[invitationId]/route.test.ts b/apps/sim/app/api/workspaces/invitations/[invitationId]/route.test.ts index 3958102d26..322642bb1d 100644 --- a/apps/sim/app/api/workspaces/invitations/[invitationId]/route.test.ts +++ b/apps/sim/app/api/workspaces/invitations/[invitationId]/route.test.ts @@ -89,11 +89,11 @@ describe('Workspace Invitation [invitationId] API Route', () => { transaction: mockTransaction, } - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ workspaceInvitation: { id: 'id', workspaceId: 'workspaceId', @@ -376,7 +376,7 @@ describe('Workspace Invitation [invitationId] API Route', () => { then: vi.fn().mockRejectedValue(new Error('Database connection failed')), } - vi.doMock('@/db', () => ({ db: mockErrorDb })) + vi.doMock('@sim/db', () => ({ db: mockErrorDb })) vi.doMock('@/lib/auth', () => ({ getSession: vi.fn().mockResolvedValue({ user: mockUser }), })) @@ -393,7 +393,7 @@ describe('Workspace Invitation [invitationId] API Route', () => { ? value.toLowerCase() === 'true' || value === '1' : Boolean(value), })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ workspaceInvitation: { id: 'id' }, })) vi.doMock('drizzle-orm', () => ({ diff --git a/apps/sim/app/api/workspaces/invitations/[invitationId]/route.ts b/apps/sim/app/api/workspaces/invitations/[invitationId]/route.ts index 27701b9010..9b8a379cd5 100644 --- a/apps/sim/app/api/workspaces/invitations/[invitationId]/route.ts +++ b/apps/sim/app/api/workspaces/invitations/[invitationId]/route.ts @@ -1,5 +1,13 @@ import { randomUUID } from 'crypto' import { render } from '@react-email/render' +import { db } from '@sim/db' +import { + permissions, + user, + type WorkspaceInvitationStatus, + workspace, + workspaceInvitation, +} from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitation' @@ -8,14 +16,6 @@ import { sendEmail } from '@/lib/email/mailer' import { getFromEmailAddress } from '@/lib/email/utils' import { env } from '@/lib/env' import { hasWorkspaceAdminAccess } from '@/lib/permissions/utils' -import { db } from '@/db' -import { - permissions, - user, - type WorkspaceInvitationStatus, - workspace, - workspaceInvitation, -} from '@/db/schema' // GET /api/workspaces/invitations/[invitationId] - Get invitation details OR accept via token export async function GET( diff --git a/apps/sim/app/api/workspaces/invitations/route.test.ts b/apps/sim/app/api/workspaces/invitations/route.test.ts index e4eb4b0300..d27221b547 100644 --- a/apps/sim/app/api/workspaces/invitations/route.test.ts +++ b/apps/sim/app/api/workspaces/invitations/route.test.ts @@ -43,11 +43,11 @@ describe('Workspace Invitations API Route', () => { values: mockInsertValues, } - vi.doMock('@/db', () => ({ + vi.doMock('@sim/db', () => ({ db: mockDbChain, })) - vi.doMock('@/db/schema', () => ({ + vi.doMock('@sim/db/schema', () => ({ user: { id: 'user_id', email: 'user_email', name: 'user_name', image: 'user_image' }, workspace: { id: 'workspace_id', name: 'workspace_name', ownerId: 'owner_id' }, permissions: { diff --git a/apps/sim/app/api/workspaces/invitations/route.ts b/apps/sim/app/api/workspaces/invitations/route.ts index 5889a431e6..e15885a802 100644 --- a/apps/sim/app/api/workspaces/invitations/route.ts +++ b/apps/sim/app/api/workspaces/invitations/route.ts @@ -1,5 +1,14 @@ import { randomUUID } from 'crypto' import { render } from '@react-email/render' +import { db } from '@sim/db' +import { + permissions, + type permissionTypeEnum, + user, + type WorkspaceInvitationStatus, + workspace, + workspaceInvitation, +} from '@sim/db/schema' import { and, eq, inArray } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitation' @@ -8,15 +17,6 @@ import { sendEmail } from '@/lib/email/mailer' import { getFromEmailAddress } from '@/lib/email/utils' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { - permissions, - type permissionTypeEnum, - user, - type WorkspaceInvitationStatus, - workspace, - workspaceInvitation, -} from '@/db/schema' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/workspaces/members/[id]/route.ts b/apps/sim/app/api/workspaces/members/[id]/route.ts index 6d0c536e3c..68f1e4b5d0 100644 --- a/apps/sim/app/api/workspaces/members/[id]/route.ts +++ b/apps/sim/app/api/workspaces/members/[id]/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { permissions } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { hasWorkspaceAdminAccess } from '@/lib/permissions/utils' -import { db } from '@/db' -import { permissions } from '@/db/schema' // DELETE /api/workspaces/members/[id] - Remove a member from a workspace export async function DELETE(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { diff --git a/apps/sim/app/api/workspaces/members/route.ts b/apps/sim/app/api/workspaces/members/route.ts index 3bbf485890..f7f2e5d4c6 100644 --- a/apps/sim/app/api/workspaces/members/route.ts +++ b/apps/sim/app/api/workspaces/members/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { permissions, type permissionTypeEnum, user } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { hasAdminPermission } from '@/lib/permissions/utils' -import { db } from '@/db' -import { permissions, type permissionTypeEnum, user } from '@/db/schema' type PermissionType = (typeof permissionTypeEnum.enumValues)[number] diff --git a/apps/sim/app/api/workspaces/route.ts b/apps/sim/app/api/workspaces/route.ts index ddb4246e74..a42e35cc00 100644 --- a/apps/sim/app/api/workspaces/route.ts +++ b/apps/sim/app/api/workspaces/route.ts @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { permissions, workflow, workflowBlocks, workspace } from '@sim/db/schema' import { and, desc, eq, isNull } from 'drizzle-orm' import { NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' -import { db } from '@/db' -import { permissions, workflow, workflowBlocks, workspace } from '@/db/schema' const logger = createLogger('Workspaces') diff --git a/apps/sim/app/workspace/[workspaceId]/templates/[id]/page.tsx b/apps/sim/app/workspace/[workspaceId]/templates/[id]/page.tsx index ee6293106a..44725c06c4 100644 --- a/apps/sim/app/workspace/[workspaceId]/templates/[id]/page.tsx +++ b/apps/sim/app/workspace/[workspaceId]/templates/[id]/page.tsx @@ -1,11 +1,11 @@ +import { db } from '@sim/db' +import { templateStars, templates } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' import { notFound } from 'next/navigation' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' import TemplateDetails from '@/app/workspace/[workspaceId]/templates/[id]/template' import type { Template } from '@/app/workspace/[workspaceId]/templates/templates' -import { db } from '@/db' -import { templateStars, templates } from '@/db/schema' const logger = createLogger('TemplatePage') diff --git a/apps/sim/app/workspace/[workspaceId]/templates/page.tsx b/apps/sim/app/workspace/[workspaceId]/templates/page.tsx index d5e7e593b5..cf57765f13 100644 --- a/apps/sim/app/workspace/[workspaceId]/templates/page.tsx +++ b/apps/sim/app/workspace/[workspaceId]/templates/page.tsx @@ -1,9 +1,9 @@ +import { db } from '@sim/db' +import { templateStars, templates } from '@sim/db/schema' import { and, desc, eq, sql } from 'drizzle-orm' import { getSession } from '@/lib/auth' import type { Template } from '@/app/workspace/[workspaceId]/templates/templates' import Templates from '@/app/workspace/[workspaceId]/templates/templates' -import { db } from '@/db' -import { templateStars, templates } from '@/db/schema' export default async function TemplatesPage() { const session = await getSession() diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/welcome/welcome.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/welcome/welcome.tsx index 79415b13ad..84aafbbd03 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/welcome/welcome.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/welcome/welcome.tsx @@ -1,6 +1,6 @@ 'use client' -import { Blocks, Bot, LibraryBig, Workflow } from 'lucide-react' +import { Blocks, LibraryBig, Workflow } from 'lucide-react' interface CopilotWelcomeProps { onQuestionClick?: (question: string) => void @@ -59,7 +59,6 @@ export function CopilotWelcome({ onQuestionClick, mode = 'ask' }: CopilotWelcome
{/* Header */}
-

{subtitle}

diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/copilot.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/copilot.tsx index 8bfa7a0e6e..1665032e7a 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/copilot.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/copilot.tsx @@ -30,6 +30,7 @@ interface CopilotProps { interface CopilotRef { createNewChat: () => void + setInputValueAndFocus: (value: string) => void } export const Copilot = forwardRef(({ panelWidth }, ref) => { @@ -326,13 +327,24 @@ export const Copilot = forwardRef(({ panelWidth }, ref }, 100) // Small delay to ensure DOM updates are complete }, [createNewChat]) + const handleSetInputValueAndFocus = useCallback( + (value: string) => { + setInputValue(value) + setTimeout(() => { + userInputRef.current?.focus() + }, 150) + }, + [setInputValue] + ) + // Expose functions to parent useImperativeHandle( ref, () => ({ createNewChat: handleStartNewChat, + setInputValueAndFocus: handleSetInputValueAndFocus, }), - [handleStartNewChat] + [handleStartNewChat, handleSetInputValueAndFocus] ) // Handle abort action diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx index 6c26be1b9b..e0d2a7a51c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx @@ -9,6 +9,7 @@ import { } from '@/components/ui/dropdown-menu' import { ScrollArea } from '@/components/ui/scroll-area' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' +import { LandingPromptStorage } from '@/lib/browser-storage' import { createLogger } from '@/lib/logs/console/logger' import { useCopilotStore } from '@/stores/copilot/store' import { useChatStore } from '@/stores/panel/chat/store' @@ -31,6 +32,7 @@ export function Panel() { const [resizeStartWidth, setResizeStartWidth] = useState(0) const copilotRef = useRef<{ createNewChat: () => void + setInputValueAndFocus: (value: string) => void }>(null) const lastLoadedWorkflowRef = useRef(null) @@ -289,17 +291,40 @@ export function Panel() { } }, [activeWorkflowId, copilotWorkflowId, ensureCopilotDataLoaded]) + useEffect(() => { + const storedPrompt = LandingPromptStorage.consume() + + if (storedPrompt && storedPrompt.trim().length > 0) { + setActiveTab('copilot') + if (!isOpen) { + togglePanel() + } + + setTimeout(() => { + if (copilotRef.current) { + copilotRef.current.setInputValueAndFocus(storedPrompt) + } else { + setTimeout(() => { + if (copilotRef.current) { + copilotRef.current.setInputValueAndFocus(storedPrompt) + } + }, 500) + } + }, 200) + } + }, []) // eslint-disable-line react-hooks/exhaustive-deps -- Run only on mount + return ( <> {/* Tab Selector - Always visible */}