( params: PerformRevertToVersionParams )
| 501 | * by both the HTTP route and the mothership tool handler. |
| 502 | */ |
| 503 | export async function performRevertToVersion( |
| 504 | params: PerformRevertToVersionParams |
| 505 | ): Promise<PerformRevertToVersionResult> { |
| 506 | const { workflowId, version, userId, workflow } = params |
| 507 | const actorId = params.actorId ?? userId |
| 508 | const versionLabel = String(version) |
| 509 | |
| 510 | const lastSaved = Date.now() |
| 511 | let saveResult: { success: boolean; error?: string; errorCode?: OrchestrationErrorCode } |
| 512 | try { |
| 513 | await assertWorkflowMutable(workflowId) |
| 514 | saveResult = await db.transaction(async (tx) => { |
| 515 | await tx |
| 516 | .select({ id: workflowTable.id }) |
| 517 | .from(workflowTable) |
| 518 | .where(eq(workflowTable.id, workflowId)) |
| 519 | .limit(1) |
| 520 | .for('update') |
| 521 | |
| 522 | const [stateRow] = |
| 523 | version === 'active' |
| 524 | ? await tx |
| 525 | .select({ state: workflowDeploymentVersion.state }) |
| 526 | .from(workflowDeploymentVersion) |
| 527 | .where( |
| 528 | and( |
| 529 | eq(workflowDeploymentVersion.workflowId, workflowId), |
| 530 | eq(workflowDeploymentVersion.isActive, true) |
| 531 | ) |
| 532 | ) |
| 533 | .limit(1) |
| 534 | : await tx |
| 535 | .select({ state: workflowDeploymentVersion.state }) |
| 536 | .from(workflowDeploymentVersion) |
| 537 | .where( |
| 538 | and( |
| 539 | eq(workflowDeploymentVersion.workflowId, workflowId), |
| 540 | eq(workflowDeploymentVersion.version, version) |
| 541 | ) |
| 542 | ) |
| 543 | .limit(1) |
| 544 | |
| 545 | if (!stateRow?.state) { |
| 546 | return { success: false, error: 'Deployment version not found' } |
| 547 | } |
| 548 | |
| 549 | const deployedState = stateRow.state as { |
| 550 | blocks?: Record<string, unknown> |
| 551 | edges?: unknown[] |
| 552 | loops?: Record<string, unknown> |
| 553 | parallels?: Record<string, unknown> |
| 554 | variables?: WorkflowState['variables'] |
| 555 | } |
| 556 | if (!deployedState.blocks || !deployedState.edges) { |
| 557 | return { success: false, error: 'Invalid deployed state structure' } |
| 558 | } |
| 559 | |
| 560 | const hasDeploymentVariables = Object.hasOwn(deployedState, 'variables') |
no test coverage detected