11import { apiKey , db , workflow , workflowDeploymentVersion } from '@sim/db'
2- import { and , desc , eq , sql } from 'drizzle-orm'
2+ import { and , desc , eq } from 'drizzle-orm'
33import { type NextRequest , NextResponse } from 'next/server'
4- import { v4 as uuidv4 } from 'uuid'
54import { createLogger } from '@/lib/logs/console/logger'
65import { generateRequestId } from '@/lib/utils'
7- import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers'
6+ import { deployWorkflow } from '@/lib/workflows/db-helpers'
87import { validateWorkflowPermissions } from '@/lib/workflows/utils'
98import { createErrorResponse , createSuccessResponse } from '@/app/api/workflows/utils'
109
@@ -138,37 +137,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
138137 }
139138 } catch ( _err ) { }
140139
141- logger . debug ( `[${ requestId } ] Getting current workflow state for deployment` )
142-
143- const normalizedData = await loadWorkflowFromNormalizedTables ( id )
144-
145- if ( ! normalizedData ) {
146- logger . error ( `[${ requestId } ] Failed to load workflow from normalized tables` )
147- return createErrorResponse ( 'Failed to load workflow state' , 500 )
148- }
149-
150- const currentState = {
151- blocks : normalizedData . blocks ,
152- edges : normalizedData . edges ,
153- loops : normalizedData . loops ,
154- parallels : normalizedData . parallels ,
155- lastSaved : Date . now ( ) ,
156- }
157-
158- logger . debug ( `[${ requestId } ] Current state retrieved from normalized tables:` , {
159- blocksCount : Object . keys ( currentState . blocks ) . length ,
160- edgesCount : currentState . edges . length ,
161- loopsCount : Object . keys ( currentState . loops ) . length ,
162- parallelsCount : Object . keys ( currentState . parallels ) . length ,
163- } )
164-
165- if ( ! currentState || ! currentState . blocks ) {
166- logger . error ( `[${ requestId } ] Invalid workflow state retrieved` , { currentState } )
167- throw new Error ( 'Invalid workflow state: missing blocks' )
168- }
169-
170- const deployedAt = new Date ( )
171- logger . debug ( `[${ requestId } ] Proceeding with deployment at ${ deployedAt . toISOString ( ) } ` )
140+ logger . debug ( `[${ requestId } ] Validating API key for deployment` )
172141
173142 let keyInfo : { name : string ; type : 'personal' | 'workspace' } | null = null
174143 let matchedKey : {
@@ -260,45 +229,19 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
260229 return createErrorResponse ( 'Unable to determine deploying user' , 400 )
261230 }
262231
263- await db . transaction ( async ( tx ) => {
264- const [ { maxVersion } ] = await tx
265- . select ( { maxVersion : sql `COALESCE(MAX("version"), 0)` } )
266- . from ( workflowDeploymentVersion )
267- . where ( eq ( workflowDeploymentVersion . workflowId , id ) )
268-
269- const nextVersion = Number ( maxVersion ) + 1
270-
271- await tx
272- . update ( workflowDeploymentVersion )
273- . set ( { isActive : false } )
274- . where (
275- and (
276- eq ( workflowDeploymentVersion . workflowId , id ) ,
277- eq ( workflowDeploymentVersion . isActive , true )
278- )
279- )
280-
281- await tx . insert ( workflowDeploymentVersion ) . values ( {
282- id : uuidv4 ( ) ,
283- workflowId : id ,
284- version : nextVersion ,
285- state : currentState ,
286- isActive : true ,
287- createdAt : deployedAt ,
288- createdBy : actorUserId ,
289- } )
232+ const deployResult = await deployWorkflow ( {
233+ workflowId : id ,
234+ deployedBy : actorUserId ,
235+ pinnedApiKeyId : matchedKey ?. id ,
236+ includeDeployedState : true ,
237+ workflowName : workflowData ! . name ,
238+ } )
290239
291- const updateData : Record < string , unknown > = {
292- isDeployed : true ,
293- deployedAt,
294- deployedState : currentState ,
295- }
296- if ( providedApiKey && matchedKey ) {
297- updateData . pinnedApiKeyId = matchedKey . id
298- }
240+ if ( ! deployResult . success ) {
241+ return createErrorResponse ( deployResult . error || 'Failed to deploy workflow' , 500 )
242+ }
299243
300- await tx . update ( workflow ) . set ( updateData ) . where ( eq ( workflow . id , id ) )
301- } )
244+ const deployedAt = deployResult . deployedAt !
302245
303246 if ( matchedKey ) {
304247 try {
@@ -313,31 +256,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
313256
314257 logger . info ( `[${ requestId } ] Workflow deployed successfully: ${ id } ` )
315258
316- // Track workflow deployment
317- try {
318- const { trackPlatformEvent } = await import ( '@/lib/telemetry/tracer' )
319-
320- // Aggregate block types to understand which blocks are being used
321- const blockTypeCounts : Record < string , number > = { }
322- for ( const block of Object . values ( currentState . blocks ) ) {
323- const blockType = ( block as any ) . type || 'unknown'
324- blockTypeCounts [ blockType ] = ( blockTypeCounts [ blockType ] || 0 ) + 1
325- }
326-
327- trackPlatformEvent ( 'platform.workflow.deployed' , {
328- 'workflow.id' : id ,
329- 'workflow.name' : workflowData ! . name ,
330- 'workflow.blocks_count' : Object . keys ( currentState . blocks ) . length ,
331- 'workflow.edges_count' : currentState . edges . length ,
332- 'workflow.has_loops' : Object . keys ( currentState . loops ) . length > 0 ,
333- 'workflow.has_parallels' : Object . keys ( currentState . parallels ) . length > 0 ,
334- 'workflow.api_key_type' : keyInfo ?. type || 'default' ,
335- 'workflow.block_types' : JSON . stringify ( blockTypeCounts ) ,
336- } )
337- } catch ( _e ) {
338- // Silently fail
339- }
340-
341259 const responseApiKeyInfo = keyInfo ? `${ keyInfo . name } (${ keyInfo . type } )` : 'Default key'
342260
343261 return createSuccessResponse ( {
0 commit comments