Skip to content

Commit f754531

Browse files
fix: trigger deletion
1 parent aa25fbc commit f754531

File tree

4 files changed

+413
-69
lines changed

4 files changed

+413
-69
lines changed

api/server/services/Workflows/WorkflowService.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,11 @@ class WorkflowService {
185185
},
186186
};
187187

188-
// Clean up paused deployed triggers when switching away from app triggers
188+
// Clean up paused deployed triggers when explicitly switching away from app triggers
189+
// Only delete if we have explicit trigger type change in updateData
189190
if (currentTask.trigger?.type === 'app' &&
191+
updateData.trigger && updateData.trigger.type &&
192+
updateData.trigger.type !== 'app' &&
190193
(updateData.trigger.type === 'manual' || updateData.trigger.type === 'schedule')) {
191194
try {
192195
const PipedreamComponents = require('~/server/services/Pipedream/PipedreamComponents');
@@ -434,6 +437,12 @@ class WorkflowService {
434437
);
435438
throw new Error('Scheduled workflow is missing cron expression');
436439
}
440+
} else if (triggerType === 'app') {
441+
// For app-based triggers, set next_run to null as they are event-driven
442+
updateData.next_run = null;
443+
logger.info(
444+
`[WorkflowService] Setting next_run to null for app-triggered workflow ${workflowId}`,
445+
);
437446
} else {
438447
// For manual workflows, explicitly set next_run to null to prevent immediate execution
439448
updateData.next_run = null;

api/test/cleanup-orphaned.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Clean up orphaned trigger deployment records
5+
*/
6+
7+
const path = require('path');
8+
const mongoose = require('mongoose');
9+
10+
// Set up proper paths
11+
process.chdir(path.join(__dirname, '..', '..'));
12+
require('dotenv').config();
13+
14+
async function cleanupOrphanedRecords() {
15+
console.log('🧹 CLEANING UP ORPHANED TRIGGER RECORDS');
16+
console.log('=======================================');
17+
18+
try {
19+
// Connect to MongoDB
20+
await mongoose.connect(process.env.MONGO_URI || 'mongodb://127.0.0.1:27017/LibreChat');
21+
console.log('✅ Connected to MongoDB');
22+
23+
// Define the TriggerDeployment schema
24+
const TriggerDeploymentSchema = new mongoose.Schema({
25+
userId: { type: mongoose.Schema.Types.ObjectId, required: true },
26+
workflowId: { type: String, required: true },
27+
componentId: { type: String, required: true },
28+
triggerKey: { type: String, required: true },
29+
appSlug: { type: String, required: true },
30+
webhookUrl: { type: String, required: true },
31+
deploymentId: { type: String, required: true },
32+
configuredProps: { type: Object, default: {} },
33+
status: { type: String, enum: ['deployed', 'paused', 'failed'], default: 'deployed' },
34+
deployedAt: { type: Date, default: Date.now },
35+
error: { type: String, default: null },
36+
}, { timestamps: true });
37+
38+
const TriggerDeployment = mongoose.model('TriggerDeployment', TriggerDeploymentSchema);
39+
40+
const userId = '68627669a4d589b864fbaabc';
41+
42+
// Find all deployment records for this user
43+
const allRecords = await TriggerDeployment.find({ userId });
44+
console.log(`🔍 Found ${allRecords.length} deployment records for user ${userId}`);
45+
46+
for (const record of allRecords) {
47+
console.log(`📋 Record: ${record.workflowId} - ${record.deploymentId} (${record.status})`);
48+
}
49+
50+
// Delete all records for clean slate
51+
const deleteResult = await TriggerDeployment.deleteMany({ userId });
52+
console.log(`🗑️ Deleted ${deleteResult.deletedCount} orphaned records`);
53+
54+
console.log('✅ Cleanup completed successfully');
55+
56+
await mongoose.disconnect();
57+
console.log('✅ Disconnected from MongoDB');
58+
59+
} catch (error) {
60+
console.error('❌ Error during cleanup:', error.message);
61+
process.exit(1);
62+
}
63+
}
64+
65+
cleanupOrphanedRecords();

api/test/test-specific-trigger.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Test specific trigger by ID to diagnose the missing trigger issue
5+
*/
6+
7+
const path = require('path');
8+
9+
// Set up proper paths for LibreChat
10+
process.chdir(path.join(__dirname, '..', '..'));
11+
require('dotenv').config();
12+
13+
const { createBackendClient } = require('@pipedream/sdk/server');
14+
15+
// Initialize Pipedream client
16+
const client = createBackendClient({
17+
environment: process.env.NODE_ENV === 'production' ? 'production' : 'development',
18+
projectId: process.env.PIPEDREAM_PROJECT_ID,
19+
credentials: {
20+
clientId: process.env.PIPEDREAM_CLIENT_ID,
21+
clientSecret: process.env.PIPEDREAM_CLIENT_SECRET,
22+
},
23+
});
24+
25+
async function testSpecificTrigger() {
26+
console.log('🔍 TESTING SPECIFIC TRIGGER');
27+
console.log('============================');
28+
29+
const userId = '68627669a4d589b864fbaabc';
30+
const deploymentId = 'dc_Ajuvkm0'; // New deployment ID from latest deploy
31+
32+
console.log(`User ID: ${userId}`);
33+
console.log(`Deployment ID: ${deploymentId}`);
34+
35+
// Test 1: Try to get the specific trigger by ID
36+
console.log('\n📋 Test 1: Get trigger by ID');
37+
try {
38+
const triggerResult = await client.getTrigger({
39+
id: deploymentId,
40+
externalUserId: userId,
41+
});
42+
console.log('✅ Trigger found:', JSON.stringify(triggerResult, null, 2));
43+
} catch (error) {
44+
console.log('❌ Error getting trigger by ID:', error.message);
45+
if (error.response) {
46+
console.log(' Response status:', error.response.status);
47+
console.log(' Response data:', JSON.stringify(error.response.data, null, 2));
48+
}
49+
}
50+
51+
// Test 2: Try to update the trigger
52+
console.log('\n⚙️ Test 2: Update trigger (test if it exists)');
53+
try {
54+
const updateResult = await client.updateTrigger({
55+
id: deploymentId,
56+
externalUserId: userId,
57+
active: true,
58+
});
59+
console.log('✅ Update successful:', JSON.stringify(updateResult, null, 2));
60+
} catch (error) {
61+
console.log('❌ Error updating trigger:', error.message);
62+
if (error.response) {
63+
console.log(' Response status:', error.response.status);
64+
console.log(' Response data:', JSON.stringify(error.response.data, null, 2));
65+
}
66+
}
67+
68+
// Test 3: Try to delete the trigger (to clean up if it exists)
69+
console.log('\n🗑️ Test 3: Delete trigger (cleanup test)');
70+
try {
71+
const deleteResult = await client.deleteTrigger({
72+
id: deploymentId,
73+
externalUserId: userId,
74+
});
75+
console.log('✅ Delete successful:', JSON.stringify(deleteResult, null, 2));
76+
} catch (error) {
77+
console.log('❌ Error deleting trigger:', error.message);
78+
if (error.response) {
79+
console.log(' Response status:', error.response.status);
80+
console.log(' Response data:', JSON.stringify(error.response.data, null, 2));
81+
}
82+
}
83+
84+
// Test 4: List all triggers for user (different approach)
85+
console.log('\n📋 Test 4: List all triggers for user');
86+
try {
87+
const triggersResult = await client.getTriggers({
88+
externalUserId: userId,
89+
limit: 50,
90+
});
91+
console.log('✅ Triggers list:', JSON.stringify(triggersResult, null, 2));
92+
} catch (error) {
93+
console.log('❌ Error listing triggers:', error.message);
94+
if (error.response) {
95+
console.log(' Response status:', error.response.status);
96+
console.log(' Response data:', JSON.stringify(error.response.data, null, 2));
97+
}
98+
}
99+
}
100+
101+
// Run the test
102+
if (require.main === module) {
103+
testSpecificTrigger().catch(console.error);
104+
}
105+
106+
module.exports = { testSpecificTrigger };

0 commit comments

Comments
 (0)