/** * Reliability Validation Utilities * Checks for retry policies, fallbacks, monitoring presence */ import type { WorkflowGraph, N8nWorkflow } from '../../apps/worker/src/types/workflow'; export interface ReliabilityCheckResult { passed: boolean; score: number; findings: string[]; recommendations: string[]; } export function checkReliability(workflow: N8nWorkflow, graph: WorkflowGraph): ReliabilityCheckResult { const findings: string[] = []; const recommendations: string[] = []; let deductions = 0; // Check retry on external API nodes const externalNodes = workflow.nodes.filter((n) => n.type.includes('httpRequest') || n.type.includes('openAi') || n.type.includes('telegram') || n.type.includes('slack') || n.type.includes('gmail'), ); externalNodes.forEach((node) => { if (!node.retryOnFail) { findings.push(`Node "${node.name}" calls external service without retry policy`); recommendations.push(`Add retryOnFail: true, maxTries: 3, waitBetweenTries: 1000 to "${node.name}"`); deductions += 10; } }); // Check for error workflow if (!workflow.settings?.errorWorkflow) { findings.push('No error workflow configured for global error handling'); recommendations.push('Set settings.errorWorkflow to an alert/notification workflow ID'); deductions += 8; } // Check for monitoring nodes const monitoringNodes = graph.nodes.filter((n) => n.layer === 'monitoring'); if (monitoringNodes.length === 0) { findings.push('No monitoring layer nodes detected in workflow'); recommendations.push('Add at least one structured logging or notification node'); deductions += 10; } // Check for fallback nodes on critical nodes const criticalWithoutFallback = graph.nodes.filter( (n) => n.isCritical && !n.fallbackNodeId, ); if (criticalWithoutFallback.length > 0) { criticalWithoutFallback.forEach((n) => { findings.push(`Critical node "${n.label}" has no fallback path`); recommendations.push(`Add fallbackNodeId to "${n.label}" pointing to an error handler`); deductions += 8; }); } const score = Math.max(0, 100 - deductions); return { passed: deductions < 30, score, findings, recommendations, }; }