1- import { AuditAction , AuditResourceType , recordAudit } from '@sim/audit'
2- import { db , workflow } from '@sim/db'
31import { createLogger } from '@sim/logger'
4- import { assertWorkflowMutable , WorkflowLockedError } from '@sim/platform-authz/workflow'
52import { getErrorMessage } from '@sim/utils/errors'
6- import { eq } from 'drizzle-orm'
73import type { NextRequest } from 'next/server'
84import { updatePublicApiContract } from '@/lib/api/contracts/deployments'
95import { parseRequest } from '@/lib/api/server'
@@ -12,18 +8,13 @@ import { asOrchestrationError, statusForOrchestrationError } from '@/lib/core/or
128import { generateRequestId } from '@/lib/core/utils/request'
139import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
1410import { captureServerEvent } from '@/lib/posthog/server'
15- import { deployWorkflow , undeployWorkflow } from '@/lib/workflows/application/deployments'
16- import { getWorkflowDeploymentSummary } from '@/lib/workflows/orchestration'
17- import { validateWorkflowPermissions } from '@/lib/workflows/utils'
1811import {
19- checkNeedsRedeployment ,
20- createErrorResponse ,
21- createSuccessResponse ,
22- } from '@/app/api/workflows/utils'
23- import {
24- PublicApiNotAllowedError ,
25- validatePublicApiAllowed ,
26- } from '@/ee/access-control/utils/permission-check'
12+ deployWorkflow ,
13+ readWorkflowDeploymentStatus ,
14+ undeployWorkflow ,
15+ } from '@/lib/workflows/application/deployments'
16+ import { updateWorkflowPublicApi } from '@/lib/workflows/application/update-workflow-deployment-settings'
17+ import { createErrorResponse , createSuccessResponse } from '@/app/api/workflows/utils'
2718
2819const logger = createLogger ( 'WorkflowDeployAPI' )
2920
@@ -37,14 +28,13 @@ export const GET = withRouteHandler(
3728 const { id } = await params
3829
3930 try {
40- const { error, workflow : workflowData } = await validateWorkflowPermissions (
41- id ,
42- requestId ,
43- 'read'
44- )
45- if ( error ) {
46- return createErrorResponse ( error . message , error . status )
47- }
31+ const principal = await internalSessionAuth . authenticate ( )
32+ const result = await readWorkflowDeploymentStatus . execute ( {
33+ principal,
34+ input : { workflowId : id } ,
35+ request,
36+ } )
37+ const workflowData = result . workflow
4838
4939 /**
5040 * A workflow is deployed only when an active version snapshot exists —
@@ -53,8 +43,7 @@ export const GET = withRouteHandler(
5343 * disagrees with the version table the workflow cannot actually serve
5444 * traffic, so reporting it as live would be untruthful.
5545 */
56- const deploymentSummary = await getWorkflowDeploymentSummary ( id )
57- const isDeployed = deploymentSummary . activeDeployment !== null
46+ const isDeployed = result . isDeployed
5847
5948 if ( ! isDeployed ) {
6049 logger . info ( `[${ requestId } ] Workflow is not deployed: ${ id } ` )
@@ -64,18 +53,12 @@ export const GET = withRouteHandler(
6453 apiKey : null ,
6554 needsRedeployment : false ,
6655 isPublicApi : workflowData . isPublicApi ?? false ,
67- activeDeployment : deploymentSummary . activeDeployment ,
68- latestDeploymentAttempt : deploymentSummary . latestDeploymentAttempt ,
69- warnings : deploymentSummary . warnings ,
56+ activeDeployment : result . activeDeployment ,
57+ latestDeploymentAttempt : result . latestDeploymentAttempt ,
58+ warnings : result . warnings ,
7059 } )
7160 }
7261
73- const attemptStatus = deploymentSummary . latestDeploymentAttempt ?. status
74- const needsRedeployment =
75- attemptStatus === 'preparing' || attemptStatus === 'activating'
76- ? false
77- : await checkNeedsRedeployment ( id )
78-
7962 logger . info ( `[${ requestId } ] Successfully retrieved deployment info: ${ id } ` )
8063
8164 const responseApiKeyInfo = workflowData . workspaceId
@@ -85,14 +68,24 @@ export const GET = withRouteHandler(
8568 return createSuccessResponse ( {
8669 apiKey : responseApiKeyInfo ,
8770 isDeployed,
88- deployedAt : deploymentSummary . activeDeployment ?. deployedAt ?? workflowData . deployedAt ,
89- needsRedeployment,
71+ deployedAt : result . activeDeployment ?. deployedAt ?? workflowData . deployedAt ,
72+ needsRedeployment : result . needsRedeployment ,
9073 isPublicApi : workflowData . isPublicApi ?? false ,
91- activeDeployment : deploymentSummary . activeDeployment ,
92- latestDeploymentAttempt : deploymentSummary . latestDeploymentAttempt ,
93- warnings : deploymentSummary . warnings ,
74+ activeDeployment : result . activeDeployment ,
75+ latestDeploymentAttempt : result . latestDeploymentAttempt ,
76+ warnings : result . warnings ,
9477 } )
9578 } catch ( error : unknown ) {
79+ if ( error instanceof InternalUnauthenticatedError ) {
80+ return createErrorResponse ( error . message , 401 )
81+ }
82+ const orchestrationError = asOrchestrationError ( error )
83+ if ( orchestrationError ) {
84+ return createErrorResponse (
85+ orchestrationError . message ,
86+ statusForOrchestrationError ( orchestrationError . code )
87+ )
88+ }
9689 logger . error ( `[${ requestId } ] Error fetching deployment info: ${ id } ` , {
9790 error : getErrorMessage ( error , 'Unknown error' ) ,
9891 } )
@@ -152,6 +145,7 @@ export const PATCH = withRouteHandler(
152145 const requestId = generateRequestId ( )
153146
154147 try {
148+ const principal = await internalSessionAuth . authenticate ( )
155149 const parsed = await parseRequest ( updatePublicApiContract , request , context , {
156150 validationErrorResponse : ( ) =>
157151 createErrorResponse ( 'Invalid request body: isPublicApi must be a boolean' , 400 ) ,
@@ -161,56 +155,32 @@ export const PATCH = withRouteHandler(
161155 const { id } = parsed . data . params
162156 const { isPublicApi } = parsed . data . body
163157
164- const {
165- error,
166- session,
167- workflow : workflowData ,
168- } = await validateWorkflowPermissions ( id , requestId , 'admin' )
169- if ( error ) {
170- return createErrorResponse ( error . message , error . status )
171- }
172- await assertWorkflowMutable ( id )
173-
174- if ( isPublicApi ) {
175- try {
176- await validatePublicApiAllowed ( session ?. user ?. id , workflowData ?. workspaceId ?? undefined )
177- } catch ( err ) {
178- if ( err instanceof PublicApiNotAllowedError ) {
179- return createErrorResponse ( 'Public API access is disabled' , 403 )
180- }
181- throw err
182- }
183- }
184-
185- await db . update ( workflow ) . set ( { isPublicApi } ) . where ( eq ( workflow . id , id ) )
186-
187- logger . info ( `[${ requestId } ] Updated isPublicApi for workflow ${ id } to ${ isPublicApi } ` )
188-
189- const wsId = workflowData ?. workspaceId
190-
191- recordAudit ( {
192- workspaceId : wsId ?? null ,
193- actorId : session ! . user . id ,
194- action : AuditAction . WORKFLOW_PUBLIC_API_TOGGLED ,
195- resourceType : AuditResourceType . WORKFLOW ,
196- resourceId : id ,
197- resourceName : workflowData ?. name ?? undefined ,
198- description : `${ isPublicApi ? 'Enabled' : 'Disabled' } public API for workflow "${ workflowData ?. name ?? id } "` ,
199- metadata : { isPublicApi } ,
158+ const result = await updateWorkflowPublicApi . execute ( {
159+ principal,
160+ input : { workflowId : id , isPublicApi } ,
200161 request,
201162 } )
202163
164+ logger . info ( `[${ requestId } ] Updated isPublicApi for workflow ${ id } to ${ isPublicApi } ` )
165+
203166 captureServerEvent (
204- session ! . user . id ,
167+ principal . userId ,
205168 'workflow_public_api_toggled' ,
206- { workflow_id : id , workspace_id : wsId ?? '' , is_public : isPublicApi } ,
207- wsId ? { groups : { workspace : wsId } } : undefined
169+ { workflow_id : id , workspace_id : result . workspaceId , is_public : isPublicApi } ,
170+ { groups : { workspace : result . workspaceId } }
208171 )
209172
210173 return createSuccessResponse ( { isPublicApi } )
211174 } catch ( error : unknown ) {
212- if ( error instanceof WorkflowLockedError ) {
213- return createErrorResponse ( error . message , error . status )
175+ if ( error instanceof InternalUnauthenticatedError ) {
176+ return createErrorResponse ( error . message , 401 )
177+ }
178+ const orchestrationError = asOrchestrationError ( error )
179+ if ( orchestrationError ) {
180+ return createErrorResponse (
181+ orchestrationError . message ,
182+ statusForOrchestrationError ( orchestrationError . code )
183+ )
214184 }
215185 logger . error ( `[${ requestId } ] Error updating deployment settings` , {
216186 error : getErrorMessage ( error , 'Unknown error' ) ,
0 commit comments