diff --git a/apps/backend/.env.development b/apps/backend/.env.development index 37b046cc9..55d58dda4 100644 --- a/apps/backend/.env.development +++ b/apps/backend/.env.development @@ -53,6 +53,7 @@ STACK_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING=yes STACK_INTEGRATION_CLIENTS_CONFIG='[{"client_id": "neon-local", "client_secret": "neon-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}, {"client_id": "custom-local", "client_secret": "custom-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}]' CRON_SECRET=mock_cron_secret STACK_FREESTYLE_API_KEY=mock_stack_freestyle_key +STACK_VERCEL_SANDBOX_TOKEN=vercel_sandbox_disabled_for_local_development STACK_OPENAI_API_KEY=mock_openai_api_key STACK_STRIPE_SECRET_KEY=sk_test_mockstripekey STACK_STRIPE_WEBHOOK_SECRET=mock_stripe_webhook_secret diff --git a/apps/backend/prisma/migrations/20260204014127_external_db_metadata/migration.sql b/apps/backend/prisma/migrations/20260204014127_external_db_metadata/migration.sql index d31ceb3a4..aa0a767c0 100644 --- a/apps/backend/prisma/migrations/20260204014127_external_db_metadata/migration.sql +++ b/apps/backend/prisma/migrations/20260204014127_external_db_metadata/migration.sql @@ -13,7 +13,6 @@ CREATE TABLE "ExternalDbSyncMetadata" ( "singleton" "BooleanTrue" NOT NULL DEFAULT 'TRUE', "sequencerEnabled" BOOLEAN NOT NULL DEFAULT true, "pollerEnabled" BOOLEAN NOT NULL DEFAULT true, - "syncEngineEnabled" BOOLEAN NOT NULL DEFAULT true, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index 1ad18873c..e0cf9744d 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -101,7 +101,6 @@ model ExternalDbSyncMetadata { sequencerEnabled Boolean @default(true) pollerEnabled Boolean @default(true) - syncEngineEnabled Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/apps/backend/src/app/api/latest/internal/external-db-sync/fusebox/route.ts b/apps/backend/src/app/api/latest/internal/external-db-sync/fusebox/route.ts index 99c9d9f08..1039e7fa6 100644 --- a/apps/backend/src/app/api/latest/internal/external-db-sync/fusebox/route.ts +++ b/apps/backend/src/app/api/latest/internal/external-db-sync/fusebox/route.ts @@ -17,7 +17,6 @@ const fuseboxResponseSchema = yupObject({ ok: yupBoolean().defined(), sequencer_enabled: yupBoolean().defined(), poller_enabled: yupBoolean().defined(), - sync_engine_enabled: yupBoolean().defined(), }).defined(), }); @@ -29,7 +28,6 @@ const fuseboxRequestSchema = yupObject({ body: yupObject({ sequencer_enabled: yupBoolean().defined(), poller_enabled: yupBoolean().defined(), - sync_engine_enabled: yupBoolean().defined(), }).defined(), method: yupString().oneOf(["POST"]).defined(), }); @@ -67,7 +65,6 @@ export const GET = createSmartRouteHandler({ ok: true, sequencer_enabled: fusebox.sequencerEnabled, poller_enabled: fusebox.pollerEnabled, - sync_engine_enabled: fusebox.syncEngineEnabled, }, }; }, @@ -87,7 +84,6 @@ export const POST = createSmartRouteHandler({ const fusebox = await updateExternalDbSyncFusebox({ sequencerEnabled: body.sequencer_enabled, pollerEnabled: body.poller_enabled, - syncEngineEnabled: body.sync_engine_enabled, }); return { statusCode: 200, @@ -96,7 +92,6 @@ export const POST = createSmartRouteHandler({ ok: true, sequencer_enabled: fusebox.sequencerEnabled, poller_enabled: fusebox.pollerEnabled, - sync_engine_enabled: fusebox.syncEngineEnabled, }, }; }, diff --git a/apps/backend/src/app/api/latest/internal/external-db-sync/sync-engine/route.tsx b/apps/backend/src/app/api/latest/internal/external-db-sync/sync-engine/route.tsx index f61751d15..444cca370 100644 --- a/apps/backend/src/app/api/latest/internal/external-db-sync/sync-engine/route.tsx +++ b/apps/backend/src/app/api/latest/internal/external-db-sync/sync-engine/route.tsx @@ -36,16 +36,6 @@ export const POST = createSmartRouteHandler({ }, }, async (span) => { await ensureUpstashSignature(fullReq); - - const fusebox = await getExternalDbSyncFusebox(); - span.setAttribute("stack.external-db-sync.sync-engine-enabled", fusebox.syncEngineEnabled); - if (!fusebox.syncEngineEnabled) { - return { - statusCode: 200, - bodyType: "success", - }; - } - const { tenancyId } = body; const tenancy = await traceSpan("external-db-sync.sync-engine.loadTenancy", async (tenancySpan) => { diff --git a/apps/backend/src/lib/external-db-sync-metadata.ts b/apps/backend/src/lib/external-db-sync-metadata.ts index 1bed7226f..dd64cb039 100644 --- a/apps/backend/src/lib/external-db-sync-metadata.ts +++ b/apps/backend/src/lib/external-db-sync-metadata.ts @@ -4,13 +4,11 @@ import { globalPrismaClient } from "@/prisma-client"; export type ExternalDbSyncFusebox = { sequencerEnabled: boolean, pollerEnabled: boolean, - syncEngineEnabled: boolean, }; const fuseboxSelect = { sequencerEnabled: true, pollerEnabled: true, - syncEngineEnabled: true, }; export async function getExternalDbSyncFusebox(): Promise { diff --git a/apps/backend/src/lib/js-execution.tsx b/apps/backend/src/lib/js-execution.tsx index 849d7696a..d98d7b2d2 100644 --- a/apps/backend/src/lib/js-execution.tsx +++ b/apps/backend/src/lib/js-execution.tsx @@ -57,9 +57,9 @@ function createVercelSandboxEngine(): JsEngine { return { name: 'vercel-sandbox', execute: async (code: string, options: ExecuteJavascriptOptions): Promise => { - const teamId = getEnvVariable("STACK_VERCEL_SANDBOX_TEAM_ID", ""); - const projectId = getEnvVariable("STACK_VERCEL_SANDBOX_PROJECT_ID", ""); - const token = getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN", ""); + const teamId = getEnvVariable("STACK_VERCEL_SANDBOX_TEAM_ID"); + const projectId = getEnvVariable("STACK_VERCEL_SANDBOX_PROJECT_ID"); + const token = getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN"); const sandbox = await Sandbox.create({ resources: { vcpus: 2 }, @@ -139,11 +139,7 @@ export async function executeJavascript(code: string, options: ExecuteJavascript } }, async () => { - if (getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN","") != "") { - if (!getNodeEnvironment().includes("prod")) { - throw new StackAssertionError("STACK_VERCEL_SANDBOX_TOKEN is set in non-production environment. We do not use Vercel Sandbox in non-production environments."); - } - + if (getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN") != "vercel_sandbox_disabled_for_local_development") { const shouldSanityTest = Math.random() < 0.05; if (shouldSanityTest) { runAsynchronouslyAndWaitUntil(runSanityTest(code, options)); @@ -151,6 +147,10 @@ export async function executeJavascript(code: string, options: ExecuteJavascript return await runWithFallback(code, options); } else { + if (getNodeEnvironment().includes("prod")) { + throw new StackAssertionError("STACK_VERCEL_SANDBOX_TOKEN is set to the disabled sentinel value in production. Please configure a real Vercel Sandbox token."); + } + return await runWithoutFallback(code, options); } }); diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx index a51d93d84..3a68d8d9d 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/external-db-sync/page-client.tsx @@ -127,14 +127,12 @@ type ExternalDbSyncStatus = { type ExternalDbSyncFusebox = { sequencerEnabled: boolean, pollerEnabled: boolean, - syncEngineEnabled: boolean, }; type ExternalDbSyncFuseboxResponse = { ok: true, sequencer_enabled: boolean, poller_enabled: boolean, - sync_engine_enabled: boolean, }; type AdminAppInternals = { @@ -293,7 +291,6 @@ export default function PageClient() { const nextFusebox = { sequencerEnabled: result.data.sequencer_enabled, pollerEnabled: result.data.poller_enabled, - syncEngineEnabled: result.data.sync_engine_enabled, }; setFusebox(nextFusebox); setSavedFusebox(nextFusebox); @@ -311,7 +308,6 @@ export default function PageClient() { body: JSON.stringify({ sequencer_enabled: fusebox.sequencerEnabled, poller_enabled: fusebox.pollerEnabled, - sync_engine_enabled: fusebox.syncEngineEnabled, }), headers: { "content-type": "application/json" }, }, @@ -335,7 +331,6 @@ export default function PageClient() { const nextFusebox = { sequencerEnabled: result.data.sequencer_enabled, pollerEnabled: result.data.poller_enabled, - syncEngineEnabled: result.data.sync_engine_enabled, }; setFusebox(nextFusebox); setSavedFusebox(nextFusebox); @@ -439,8 +434,7 @@ export default function PageClient() { const fuseboxDirty = useMemo(() => { if (!fusebox || !savedFusebox) return false; return fusebox.sequencerEnabled !== savedFusebox.sequencerEnabled - || fusebox.pollerEnabled !== savedFusebox.pollerEnabled - || fusebox.syncEngineEnabled !== savedFusebox.syncEngineEnabled; + || fusebox.pollerEnabled !== savedFusebox.pollerEnabled; }, [fusebox, savedFusebox]); if (adminApp.projectId !== "internal") { @@ -722,16 +716,7 @@ export default function PageClient() { onCheckedChange={(checked) => setFusebox((current) => current ? { ...current, pollerEnabled: checked } : current)} /> -
-
- Sync engine - Processes mapping batches for tenants. -
- setFusebox((current) => current ? { ...current, syncEngineEnabled: checked } : current)} - /> -
+