Merge branch 'external-db-sync' into external-db-sync-clickhouse-default

This commit is contained in:
BilalG1 2026-02-05 12:05:29 -08:00 committed by GitHub
commit 9c340f466d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 11 additions and 47 deletions

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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,
},
};
},

View File

@ -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) => {

View File

@ -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<ExternalDbSyncFusebox> {

View File

@ -57,9 +57,9 @@ function createVercelSandboxEngine(): JsEngine {
return {
name: 'vercel-sandbox',
execute: async (code: string, options: ExecuteJavascriptOptions): Promise<ExecuteResult> => {
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);
}
});

View File

@ -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)}
/>
</div>
<div className="flex items-center justify-between gap-6">
<div>
<Typography type="p" className="text-sm font-medium">Sync engine</Typography>
<Typography type="p" className="text-xs text-muted-foreground">Processes mapping batches for tenants.</Typography>
</div>
<Switch
checked={fusebox.syncEngineEnabled}
onCheckedChange={(checked) => setFusebox((current) => current ? { ...current, syncEngineEnabled: checked } : current)}
/>
</div>
<div className="flex justify-end">
<Button onClick={saveFusebox} disabled={!fuseboxDirty || savingFusebox} loading={savingFusebox}>
Save

View File

@ -468,7 +468,6 @@ describe.sequential('External DB Sync - Basic Tests', () => {
ok: true,
sequencer_enabled: expect.any(Boolean),
poller_enabled: expect.any(Boolean),
sync_engine_enabled: expect.any(Boolean),
});
const postResponse = await niceBackendFetch('/api/latest/internal/external-db-sync/fusebox', {
@ -477,7 +476,6 @@ describe.sequential('External DB Sync - Basic Tests', () => {
body: {
sequencer_enabled: getResponse.body.sequencer_enabled,
poller_enabled: getResponse.body.poller_enabled,
sync_engine_enabled: getResponse.body.sync_engine_enabled,
},
});
@ -486,7 +484,6 @@ describe.sequential('External DB Sync - Basic Tests', () => {
ok: true,
sequencer_enabled: getResponse.body.sequencer_enabled,
poller_enabled: getResponse.body.poller_enabled,
sync_engine_enabled: getResponse.body.sync_engine_enabled,
});
}, TEST_TIMEOUT);
});