fix(deployed-version-check): check deployed version existence pre-queuing (#1508)

* fix(deployed-version-check): check deployed version existence pre-queuing

* fix tests

* fix edge case
This commit is contained in:
Vikhyath Mondreti
2025-09-30 19:20:21 -07:00
committed by GitHub
parent 7e6a5dc7e2
commit 0d881ecc00
3 changed files with 40 additions and 4 deletions

View File

@@ -133,6 +133,7 @@ describe('Webhook Trigger API Route', () => {
parallels: {},
isFromNormalizedTables: true,
}),
blockExistsInDeployment: vi.fn().mockResolvedValue(true),
}))
hasProcessedMessageMock.mockResolvedValue(false)

View File

@@ -10,6 +10,7 @@ import {
queueWebhookExecution,
verifyProviderAuth,
} from '@/lib/webhooks/processor'
import { blockExistsInDeployment } from '@/lib/workflows/db-helpers'
const logger = createLogger('WebhookTriggerAPI')
@@ -62,6 +63,16 @@ export async function POST(
return usageLimitError
}
if (foundWebhook.blockId) {
const blockExists = await blockExistsInDeployment(foundWorkflow.id, foundWebhook.blockId)
if (!blockExists) {
logger.warn(
`[${requestId}] Trigger block ${foundWebhook.blockId} not found in deployment for workflow ${foundWorkflow.id}`
)
return new NextResponse('Trigger block not deployed', { status: 404 })
}
}
return queueWebhookExecution(foundWebhook, foundWorkflow, body, request, {
requestId,
path,

View File

@@ -36,10 +36,34 @@ export interface NormalizedWorkflowData {
isFromNormalizedTables: boolean // Flag to indicate source (true = normalized tables, false = deployed state)
}
/**
* Load deployed workflow state for execution
* Returns deployed state if available, otherwise throws error
*/
export async function blockExistsInDeployment(
workflowId: string,
blockId: string
): Promise<boolean> {
try {
const [result] = await db
.select({ state: workflowDeploymentVersion.state })
.from(workflowDeploymentVersion)
.where(
and(
eq(workflowDeploymentVersion.workflowId, workflowId),
eq(workflowDeploymentVersion.isActive, true)
)
)
.limit(1)
if (!result?.state) {
return false
}
const state = result.state as WorkflowState
return !!state.blocks?.[blockId]
} catch (error) {
logger.error(`Error checking block ${blockId} in deployment for workflow ${workflowId}:`, error)
return false
}
}
export async function loadDeployedWorkflowState(
workflowId: string
): Promise<NormalizedWorkflowData> {