( params: PerformFullUndeployParams )
| 235 | * tools must use this single function. |
| 236 | */ |
| 237 | export async function performFullUndeploy( |
| 238 | params: PerformFullUndeployParams |
| 239 | ): Promise<PerformFullUndeployResult> { |
| 240 | const { workflowId, userId } = params |
| 241 | const actorId = params.actorId ?? userId |
| 242 | const requestId = params.requestId ?? generateRequestId() |
| 243 | |
| 244 | const [workflowRecord] = await db |
| 245 | .select() |
| 246 | .from(workflowTable) |
| 247 | .where(eq(workflowTable.id, workflowId)) |
| 248 | .limit(1) |
| 249 | |
| 250 | if (!workflowRecord) { |
| 251 | return { success: false, error: 'Workflow not found' } |
| 252 | } |
| 253 | |
| 254 | const workflowData = workflowRecord as Record<string, unknown> |
| 255 | let outboxEventId: string | undefined |
| 256 | |
| 257 | const result = await undeployWorkflow({ |
| 258 | workflowId, |
| 259 | onUndeployTransaction: async (tx, undeploy) => { |
| 260 | outboxEventId = await enqueueWorkflowUndeploySideEffects(tx, { |
| 261 | workflowId, |
| 262 | deploymentVersionIds: undeploy.deploymentVersionIds, |
| 263 | userId, |
| 264 | requestId, |
| 265 | }) |
| 266 | }, |
| 267 | }) |
| 268 | if (!result.success) { |
| 269 | return { success: false, error: result.error || 'Failed to undeploy workflow' } |
| 270 | } |
| 271 | |
| 272 | logger.info(`[${requestId}] Workflow undeployed successfully: ${workflowId}`) |
| 273 | |
| 274 | try { |
| 275 | const { PlatformEvents } = await import('@/lib/core/telemetry') |
| 276 | PlatformEvents.workflowUndeployed({ workflowId }) |
| 277 | } catch (_e) { |
| 278 | // Telemetry is best-effort |
| 279 | } |
| 280 | |
| 281 | recordAudit({ |
| 282 | workspaceId: (workflowData.workspaceId as string) || null, |
| 283 | actorId: actorId, |
| 284 | action: AuditAction.WORKFLOW_UNDEPLOYED, |
| 285 | resourceType: AuditResourceType.WORKFLOW, |
| 286 | resourceId: workflowId, |
| 287 | resourceName: (workflowData.name as string) || undefined, |
| 288 | description: `Undeployed workflow "${(workflowData.name as string) || workflowId}"`, |
| 289 | }) |
| 290 | |
| 291 | await notifySocketDeploymentChanged(workflowId) |
| 292 | const sideEffectWarning = await processDeploymentSideEffectsNow(outboxEventId, requestId) |
| 293 | |
| 294 | const undeployWorkspaceId = workflowData.workspaceId as string | null |
no test coverage detected