Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions apps/sim/app/api/copilot/checkpoints/revert/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ describe('Copilot Checkpoints Revert API Route', () => {
parallels: {},
isDeployed: true,
deploymentStatuses: { production: 'deployed' },
hasActiveWebhook: false,
},
}

Expand Down Expand Up @@ -287,7 +286,6 @@ describe('Copilot Checkpoints Revert API Route', () => {
parallels: {},
isDeployed: true,
deploymentStatuses: { production: 'deployed' },
hasActiveWebhook: false,
lastSaved: 1640995200000,
},
},
Expand All @@ -309,7 +307,6 @@ describe('Copilot Checkpoints Revert API Route', () => {
parallels: {},
isDeployed: true,
deploymentStatuses: { production: 'deployed' },
hasActiveWebhook: false,
lastSaved: 1640995200000,
}),
}
Expand Down Expand Up @@ -445,7 +442,6 @@ describe('Copilot Checkpoints Revert API Route', () => {
parallels: {},
isDeployed: false,
deploymentStatuses: {},
hasActiveWebhook: false,
lastSaved: 1640995200000,
})
})
Expand Down Expand Up @@ -722,7 +718,6 @@ describe('Copilot Checkpoints Revert API Route', () => {
production: 'deployed',
staging: 'pending',
},
hasActiveWebhook: true,
deployedAt: '2024-01-01T10:00:00.000Z',
},
}
Expand Down Expand Up @@ -769,7 +764,6 @@ describe('Copilot Checkpoints Revert API Route', () => {
production: 'deployed',
staging: 'pending',
},
hasActiveWebhook: true,
deployedAt: '2024-01-01T10:00:00.000Z',
lastSaved: 1640995200000,
})
Expand Down
1 change: 0 additions & 1 deletion apps/sim/app/api/copilot/checkpoints/revert/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export async function POST(request: NextRequest) {
parallels: checkpointState?.parallels || {},
isDeployed: checkpointState?.isDeployed || false,
deploymentStatuses: checkpointState?.deploymentStatuses || {},
hasActiveWebhook: checkpointState?.hasActiveWebhook || false,
lastSaved: Date.now(),
// Only include deployedAt if it's a valid date string that can be converted
...(checkpointState?.deployedAt &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export async function POST(
isDeployed: true,
deployedAt: new Date(),
deploymentStatuses: deployedState.deploymentStatuses || {},
hasActiveWebhook: deployedState.hasActiveWebhook || false,
})

if (!saveResult.success) {
Expand Down
1 change: 0 additions & 1 deletion apps/sim/app/api/workflows/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
state: {
// Default values for expected properties
deploymentStatuses: {},
hasActiveWebhook: false,
// Data from normalized tables
blocks: normalizedData.blocks,
edges: normalizedData.edges,
Expand Down
13 changes: 1 addition & 12 deletions apps/sim/app/api/workflows/[id]/state/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,14 @@ const ParallelSchema = z.object({
parallelType: z.enum(['count', 'collection']).optional(),
})

const DeploymentStatusSchema = z.object({
id: z.string(),
status: z.enum(['deploying', 'deployed', 'failed', 'stopping', 'stopped']),
deployedAt: z.date().optional(),
error: z.string().optional(),
})

const WorkflowStateSchema = z.object({
blocks: z.record(BlockStateSchema),
edges: z.array(EdgeSchema),
loops: z.record(LoopSchema).optional(),
parallels: z.record(ParallelSchema).optional(),
lastSaved: z.number().optional(),
isDeployed: z.boolean().optional(),
deployedAt: z.date().optional(),
deploymentStatuses: z.record(DeploymentStatusSchema).optional(),
hasActiveWebhook: z.boolean().optional(),
deployedAt: z.coerce.date().optional(),
})

/**
Expand Down Expand Up @@ -204,8 +195,6 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
lastSaved: state.lastSaved || Date.now(),
isDeployed: state.isDeployed || false,
deployedAt: state.deployedAt,
deploymentStatuses: state.deploymentStatuses || {},
hasActiveWebhook: state.hasActiveWebhook || false,
}

const saveResult = await saveWorkflowToNormalizedTables(workflowId, workflowState as any)
Expand Down
1 change: 0 additions & 1 deletion apps/sim/app/api/workflows/yaml/export/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ export async function GET(request: NextRequest) {
// Use normalized table data - construct state from normalized tables
workflowState = {
deploymentStatuses: {},
hasActiveWebhook: false,
blocks: normalizedData.blocks,
edges: normalizedData.edges,
loops: normalizedData.loops,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export function DiffControls() {
lastSaved: rawState.lastSaved || Date.now(),
isDeployed: rawState.isDeployed || false,
deploymentStatuses: rawState.deploymentStatuses || {},
hasActiveWebhook: rawState.hasActiveWebhook || false,
// Only include deployedAt if it's a valid date, never include null/undefined
...(rawState.deployedAt && rawState.deployedAt instanceof Date
? { deployedAt: rawState.deployedAt }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export interface CurrentWorkflow {
deployedAt?: Date
deploymentStatuses?: Record<string, DeploymentStatus>
needsRedeployment?: boolean
hasActiveWebhook?: boolean

// Mode information
isDiffMode: boolean
Expand Down Expand Up @@ -66,7 +65,6 @@ export function useCurrentWorkflow(): CurrentWorkflow {
deployedAt: activeWorkflow.deployedAt,
deploymentStatuses: activeWorkflow.deploymentStatuses,
needsRedeployment: activeWorkflow.needsRedeployment,
hasActiveWebhook: activeWorkflow.hasActiveWebhook,

// Mode information - update to reflect ready state
isDiffMode: shouldUseDiff,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,19 @@ export async function applyAutoLayoutAndUpdateStore(
useWorkflowStore.getState().updateLastSaved()

// Clean up the workflow state for API validation
// Destructure out UI-only fields that shouldn't be persisted
const { deploymentStatuses, needsRedeployment, dragStartPosition, ...stateToSave } =
newWorkflowState

const cleanedWorkflowState = {
...newWorkflowState,
...stateToSave,
// Convert null dates to undefined (since they're optional)
deployedAt: newWorkflowState.deployedAt ? new Date(newWorkflowState.deployedAt) : undefined,
deployedAt: stateToSave.deployedAt ? new Date(stateToSave.deployedAt) : undefined,
// Ensure other optional fields are properly handled
loops: newWorkflowState.loops || {},
parallels: newWorkflowState.parallels || {},
deploymentStatuses: newWorkflowState.deploymentStatuses || {},
loops: stateToSave.loops || {},
parallels: stateToSave.parallels || {},
// Sanitize edges: remove null/empty handle fields to satisfy schema (optional strings)
edges: (newWorkflowState.edges || []).map((edge: any) => {
edges: (stateToSave.edges || []).map((edge: any) => {
const { sourceHandle, targetHandle, ...rest } = edge || {}
const sanitized: any = { ...rest }
if (typeof sourceHandle === 'string' && sourceHandle.length > 0) {
Expand Down
1 change: 0 additions & 1 deletion apps/sim/contexts/socket-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,6 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
isDeployed: workflowState.isDeployed ?? false,
deployedAt: workflowState.deployedAt,
deploymentStatuses: workflowState.deploymentStatuses || {},
hasActiveWebhook: workflowState.hasActiveWebhook ?? false,
})

// Replace subblock store values for this workflow
Expand Down
1 change: 0 additions & 1 deletion apps/sim/hooks/use-collaborative-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ export function useCollaborativeWorkflow() {
isDeployed: workflowData.state.isDeployed || false,
deployedAt: workflowData.state.deployedAt,
lastSaved: workflowData.state.lastSaved || Date.now(),
hasActiveWebhook: workflowData.state.hasActiveWebhook || false,
deploymentStatuses: workflowData.state.deploymentStatuses || {},
})

Expand Down
21 changes: 0 additions & 21 deletions apps/sim/lib/workflows/db-helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ const mockWorkflowState: WorkflowState = {
lastSaved: Date.now(),
isDeployed: false,
deploymentStatuses: {},
hasActiveWebhook: false,
}

describe('Database Helpers', () => {
Expand Down Expand Up @@ -452,11 +451,6 @@ describe('Database Helpers', () => {
)

expect(result.success).toBe(true)
expect(result.jsonBlob).toBeDefined()
expect(result.jsonBlob.blocks).toEqual(mockWorkflowState.blocks)
expect(result.jsonBlob.edges).toEqual(mockWorkflowState.edges)
expect(result.jsonBlob.loops).toEqual(mockWorkflowState.loops)
expect(result.jsonBlob.parallels).toEqual(mockWorkflowState.parallels)

// Verify transaction was called
expect(mockTransaction).toHaveBeenCalledTimes(1)
Expand All @@ -471,7 +465,6 @@ describe('Database Helpers', () => {
lastSaved: Date.now(),
isDeployed: false,
deploymentStatuses: {},
hasActiveWebhook: false,
}

const mockTransaction = vi.fn().mockImplementation(async (callback) => {
Expand All @@ -494,10 +487,6 @@ describe('Database Helpers', () => {
)

expect(result.success).toBe(true)
expect(result.jsonBlob.blocks).toEqual({})
expect(result.jsonBlob.edges).toEqual([])
expect(result.jsonBlob.loops).toEqual({})
expect(result.jsonBlob.parallels).toEqual({})
})

it('should return error when transaction fails', async () => {
Expand Down Expand Up @@ -650,7 +639,6 @@ describe('Database Helpers', () => {
lastSaved: Date.now(),
isDeployed: false,
deploymentStatuses: {},
hasActiveWebhook: false,
}

it('should successfully migrate workflow from JSON to normalized tables', async () => {
Expand Down Expand Up @@ -737,7 +725,6 @@ describe('Database Helpers', () => {
lastSaved: Date.now(),
isDeployed: false,
deploymentStatuses: {},
hasActiveWebhook: false,
}

// Create 1000 blocks
Expand Down Expand Up @@ -782,8 +769,6 @@ describe('Database Helpers', () => {
)

expect(result.success).toBe(true)
expect(Object.keys(result.jsonBlob.blocks)).toHaveLength(1000)
expect(result.jsonBlob.edges).toHaveLength(999)
})
})

Expand Down Expand Up @@ -1020,7 +1005,6 @@ describe('Database Helpers', () => {
loops: {},
parallels: {},
deploymentStatuses: {},
hasActiveWebhook: false,
}

// Mock the transaction for save operation
Expand Down Expand Up @@ -1058,10 +1042,6 @@ describe('Database Helpers', () => {
)
expect(saveResult.success).toBe(true)

// Step 6: Verify the JSON blob also preserves advancedMode
expect(saveResult.jsonBlob?.blocks['agent-original'].advancedMode).toBe(true)
expect(saveResult.jsonBlob?.blocks['agent-duplicate'].advancedMode).toBe(true)

// Verify the database insert was called with the correct values
expect(mockTransaction).toHaveBeenCalled()
})
Expand Down Expand Up @@ -1161,7 +1141,6 @@ describe('Database Helpers', () => {
loops: {},
parallels: {},
deploymentStatuses: {},
hasActiveWebhook: false,
}

// Mock successful save
Expand Down
33 changes: 4 additions & 29 deletions apps/sim/lib/workflows/db-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,11 @@ export async function loadWorkflowFromNormalizedTables(

/**
* Save workflow state to normalized tables
* Also returns the JSON blob for backward compatibility
*/
export async function saveWorkflowToNormalizedTables(
workflowId: string,
state: WorkflowState
): Promise<{ success: boolean; jsonBlob?: any; error?: string }> {
): Promise<{ success: boolean; error?: string }> {
try {
// Start a transaction
await db.transaction(async (tx) => {
Expand Down Expand Up @@ -302,27 +301,9 @@ export async function saveWorkflowToNormalizedTables(
if (subflowInserts.length > 0) {
await tx.insert(workflowSubflows).values(subflowInserts)
}

return { success: true }
})

// Create JSON blob for backward compatibility
const jsonBlob = {
blocks: state.blocks,
edges: state.edges,
loops: state.loops || {},
parallels: state.parallels || {},
lastSaved: Date.now(),
isDeployed: state.isDeployed,
deployedAt: state.deployedAt,
deploymentStatuses: state.deploymentStatuses,
hasActiveWebhook: state.hasActiveWebhook,
}

return {
success: true,
jsonBlob,
}
return { success: true }
} catch (error) {
logger.error(`Error saving workflow ${workflowId} to normalized tables:`, error)
return {
Expand Down Expand Up @@ -359,6 +340,7 @@ export async function migrateWorkflowToNormalizedTables(
): Promise<{ success: boolean; error?: string }> {
try {
// Convert JSON state to WorkflowState format
// Only include fields that are actually persisted to normalized tables
const workflowState: WorkflowState = {
blocks: jsonState.blocks || {},
edges: jsonState.edges || [],
Expand All @@ -367,16 +349,9 @@ export async function migrateWorkflowToNormalizedTables(
lastSaved: jsonState.lastSaved,
isDeployed: jsonState.isDeployed,
deployedAt: jsonState.deployedAt,
deploymentStatuses: jsonState.deploymentStatuses || {},
hasActiveWebhook: jsonState.hasActiveWebhook,
}

const result = await saveWorkflowToNormalizedTables(workflowId, workflowState)

if (result.success) {
return { success: true }
}
return { success: false, error: result.error }
return await saveWorkflowToNormalizedTables(workflowId, workflowState)
} catch (error) {
logger.error(`Error migrating workflow ${workflowId} to normalized tables:`, error)
return {
Expand Down
2 changes: 0 additions & 2 deletions apps/sim/lib/workflows/diff/use-workflow-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export function useWorkflowDiff(): UseWorkflowDiffReturn {
isDeployed: currentState.isDeployed,
deployedAt: currentState.deployedAt,
deploymentStatuses: { ...currentState.deploymentStatuses },
hasActiveWebhook: currentState.hasActiveWebhook,
},
subblockValues: JSON.parse(JSON.stringify(currentSubblockValues)), // Deep copy
timestamp: Date.now(),
Expand Down Expand Up @@ -107,7 +106,6 @@ export function useWorkflowDiff(): UseWorkflowDiffReturn {
isDeployed: backup.workflowState.isDeployed,
deployedAt: backup.workflowState.deployedAt,
deploymentStatuses: backup.workflowState.deploymentStatuses,
hasActiveWebhook: backup.workflowState.hasActiveWebhook,
})

// Restore subblock values
Expand Down
1 change: 0 additions & 1 deletion apps/sim/lib/workflows/json-sanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,5 @@ export function mergeWithUIState(
isDeployed: fullState.isDeployed,
deployedAt: fullState.deployedAt,
deploymentStatuses: fullState.deploymentStatuses,
hasActiveWebhook: fullState.hasActiveWebhook,
}
}
1 change: 0 additions & 1 deletion apps/sim/socket-server/database/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ export async function getWorkflowState(workflowId: string) {
const finalState = {
// Default values for expected properties
deploymentStatuses: {},
hasActiveWebhook: false,
// Data from normalized tables
blocks: normalizedData.blocks,
edges: normalizedData.edges,
Expand Down
1 change: 0 additions & 1 deletion apps/sim/stores/copilot/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1953,7 +1953,6 @@ export const useCopilotStore = create<CopilotStore>()(
isDeployed: !!reverted.isDeployed,
...(reverted.deployedAt ? { deployedAt: new Date(reverted.deployedAt) } : {}),
deploymentStatuses: reverted.deploymentStatuses || {},
hasActiveWebhook: !!reverted.hasActiveWebhook,
})

// Extract and apply subblock values
Expand Down
Loading