snow-flow 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +49 -0
- package/.mcp.json +106 -0
- package/.mcp.json.template +106 -0
- package/LICENSE +21 -0
- package/README.md +236 -0
- package/bin/snow-flow +4 -0
- package/bin/snow-flow.js +3 -0
- package/claude-flow +79 -0
- package/claude-flow.bat +18 -0
- package/claude-flow.config.json +20 -0
- package/claude-flow.ps1 +24 -0
- package/dist/agents/app-creator.agent.d.ts +55 -0
- package/dist/agents/app-creator.agent.d.ts.map +1 -0
- package/dist/agents/app-creator.agent.js +1292 -0
- package/dist/agents/app-creator.agent.js.map +1 -0
- package/dist/agents/base-snow-agent.d.ts +63 -0
- package/dist/agents/base-snow-agent.d.ts.map +1 -0
- package/dist/agents/base-snow-agent.js +296 -0
- package/dist/agents/base-snow-agent.js.map +1 -0
- package/dist/agents/script-generator.agent.d.ts +32 -0
- package/dist/agents/script-generator.agent.d.ts.map +1 -0
- package/dist/agents/script-generator.agent.js +772 -0
- package/dist/agents/script-generator.agent.js.map +1 -0
- package/dist/agents/ui-builder.agent.d.ts +50 -0
- package/dist/agents/ui-builder.agent.d.ts.map +1 -0
- package/dist/agents/ui-builder.agent.js +1539 -0
- package/dist/agents/ui-builder.agent.js.map +1 -0
- package/dist/agents/widget-builder.agent.d.ts +32 -0
- package/dist/agents/widget-builder.agent.d.ts.map +1 -0
- package/dist/agents/widget-builder.agent.js +439 -0
- package/dist/agents/widget-builder.agent.js.map +1 -0
- package/dist/agents/workflow-designer.agent.d.ts +31 -0
- package/dist/agents/workflow-designer.agent.d.ts.map +1 -0
- package/dist/agents/workflow-designer.agent.js +583 -0
- package/dist/agents/workflow-designer.agent.js.map +1 -0
- package/dist/api/error-handling.d.ts +214 -0
- package/dist/api/error-handling.d.ts.map +1 -0
- package/dist/api/error-handling.js +594 -0
- package/dist/api/error-handling.js.map +1 -0
- package/dist/api/flow-designer-api.d.ts +167 -0
- package/dist/api/flow-designer-api.d.ts.map +1 -0
- package/dist/api/flow-designer-api.js +555 -0
- package/dist/api/flow-designer-api.js.map +1 -0
- package/dist/api/natural-language-mapper.d.ts +126 -0
- package/dist/api/natural-language-mapper.d.ts.map +1 -0
- package/dist/api/natural-language-mapper.js +498 -0
- package/dist/api/natural-language-mapper.js.map +1 -0
- package/dist/api/performance-optimizer.d.ts +240 -0
- package/dist/api/performance-optimizer.d.ts.map +1 -0
- package/dist/api/performance-optimizer.js +701 -0
- package/dist/api/performance-optimizer.js.map +1 -0
- package/dist/api/transaction-manager.d.ts +189 -0
- package/dist/api/transaction-manager.d.ts.map +1 -0
- package/dist/api/transaction-manager.js +576 -0
- package/dist/api/transaction-manager.js.map +1 -0
- package/dist/cli/deploy-artifact.d.ts +7 -0
- package/dist/cli/deploy-artifact.d.ts.map +1 -0
- package/dist/cli/deploy-artifact.js +279 -0
- package/dist/cli/deploy-artifact.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2057 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/scope-manager.d.ts +75 -0
- package/dist/managers/scope-manager.d.ts.map +1 -0
- package/dist/managers/scope-manager.js +448 -0
- package/dist/managers/scope-manager.js.map +1 -0
- package/dist/mcp/mcp-wrapper.d.ts +8 -0
- package/dist/mcp/mcp-wrapper.d.ts.map +1 -0
- package/dist/mcp/mcp-wrapper.js +77 -0
- package/dist/mcp/mcp-wrapper.js.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-automation-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-automation-mcp.js +683 -0
- package/dist/mcp/servicenow-automation-mcp.js.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-deployment-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-deployment-mcp.js +972 -0
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-flow-composer-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js +1121 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-graph-memory-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js +703 -0
- package/dist/mcp/servicenow-graph-memory-mcp.js.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-integration-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-integration-mcp.js +689 -0
- package/dist/mcp/servicenow-integration-mcp.js.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-intelligent-mcp.js +1138 -0
- package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -0
- package/dist/mcp/servicenow-mcp-server.d.ts +37 -0
- package/dist/mcp/servicenow-mcp-server.d.ts.map +1 -0
- package/dist/mcp/servicenow-mcp-server.js +648 -0
- package/dist/mcp/servicenow-mcp-server.js.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts +15 -0
- package/dist/mcp/servicenow-operations-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-operations-mcp.js +1287 -0
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-platform-development-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-platform-development-mcp.js +557 -0
- package/dist/mcp/servicenow-platform-development-mcp.js.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts +79 -0
- package/dist/mcp/servicenow-progressive-indexer.d.ts.map +1 -0
- package/dist/mcp/servicenow-progressive-indexer.js +320 -0
- package/dist/mcp/servicenow-progressive-indexer.js.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js +888 -0
- package/dist/mcp/servicenow-reporting-analytics-mcp.js.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts +8 -0
- package/dist/mcp/servicenow-security-compliance-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js +812 -0
- package/dist/mcp/servicenow-security-compliance-mcp.js.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts +7 -0
- package/dist/mcp/servicenow-update-set-mcp.d.ts.map +1 -0
- package/dist/mcp/servicenow-update-set-mcp.js +599 -0
- package/dist/mcp/servicenow-update-set-mcp.js.map +1 -0
- package/dist/mcp/start-all-mcp-servers.d.ts +6 -0
- package/dist/mcp/start-all-mcp-servers.d.ts.map +1 -0
- package/dist/mcp/start-all-mcp-servers.js +65 -0
- package/dist/mcp/start-all-mcp-servers.js.map +1 -0
- package/dist/mcp/start-servicenow-mcp.d.ts +7 -0
- package/dist/mcp/start-servicenow-mcp.d.ts.map +1 -0
- package/dist/mcp/start-servicenow-mcp.js +64 -0
- package/dist/mcp/start-servicenow-mcp.js.map +1 -0
- package/dist/mcp/test-simple-mcp.d.ts +6 -0
- package/dist/mcp/test-simple-mcp.d.ts.map +1 -0
- package/dist/mcp/test-simple-mcp.js +64 -0
- package/dist/mcp/test-simple-mcp.js.map +1 -0
- package/dist/orchestrator/flow-composer.d.ts +269 -0
- package/dist/orchestrator/flow-composer.d.ts.map +1 -0
- package/dist/orchestrator/flow-composer.js +2221 -0
- package/dist/orchestrator/flow-composer.js.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts +260 -0
- package/dist/orchestrator/flow-pattern-templates.d.ts.map +1 -0
- package/dist/orchestrator/flow-pattern-templates.js +906 -0
- package/dist/orchestrator/flow-pattern-templates.js.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts +202 -0
- package/dist/orchestrator/flow-subflow-decision-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js +769 -0
- package/dist/orchestrator/flow-subflow-decision-engine.js.map +1 -0
- package/dist/orchestrator/flow-validation-engine.d.ts +145 -0
- package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -0
- package/dist/orchestrator/flow-validation-engine.js +663 -0
- package/dist/orchestrator/flow-validation-engine.js.map +1 -0
- package/dist/orchestrator/snow-orchestrator.d.ts +49 -0
- package/dist/orchestrator/snow-orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/snow-orchestrator.js +235 -0
- package/dist/orchestrator/snow-orchestrator.js.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts +230 -0
- package/dist/orchestrator/subflow-creation-handler.d.ts.map +1 -0
- package/dist/orchestrator/subflow-creation-handler.js +791 -0
- package/dist/orchestrator/subflow-creation-handler.js.map +1 -0
- package/dist/strategies/global-scope-strategy.d.ts +123 -0
- package/dist/strategies/global-scope-strategy.d.ts.map +1 -0
- package/dist/strategies/global-scope-strategy.js +585 -0
- package/dist/strategies/global-scope-strategy.js.map +1 -0
- package/dist/types/index.d.ts +138 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/servicenow.types.d.ts +260 -0
- package/dist/types/servicenow.types.d.ts.map +1 -0
- package/dist/types/servicenow.types.js +3 -0
- package/dist/types/servicenow.types.js.map +1 -0
- package/dist/types/snow-flow.types.d.ts +114 -0
- package/dist/types/snow-flow.types.d.ts.map +1 -0
- package/dist/types/snow-flow.types.js +3 -0
- package/dist/types/snow-flow.types.js.map +1 -0
- package/dist/utils/action-type-cache.d.ts +66 -0
- package/dist/utils/action-type-cache.d.ts.map +1 -0
- package/dist/utils/action-type-cache.js +237 -0
- package/dist/utils/action-type-cache.js.map +1 -0
- package/dist/utils/agent-detector.d.ts +35 -0
- package/dist/utils/agent-detector.d.ts.map +1 -0
- package/dist/utils/agent-detector.js +353 -0
- package/dist/utils/agent-detector.js.map +1 -0
- package/dist/utils/flow-api-discovery.d.ts +151 -0
- package/dist/utils/flow-api-discovery.d.ts.map +1 -0
- package/dist/utils/flow-api-discovery.js +440 -0
- package/dist/utils/flow-api-discovery.js.map +1 -0
- package/dist/utils/flow-xml-generator.d.ts +41 -0
- package/dist/utils/flow-xml-generator.d.ts.map +1 -0
- package/dist/utils/flow-xml-generator.js +258 -0
- package/dist/utils/flow-xml-generator.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +51 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-auth-middleware.d.ts +58 -0
- package/dist/utils/mcp-auth-middleware.d.ts.map +1 -0
- package/dist/utils/mcp-auth-middleware.js +227 -0
- package/dist/utils/mcp-auth-middleware.js.map +1 -0
- package/dist/utils/mcp-config-manager.d.ts +126 -0
- package/dist/utils/mcp-config-manager.d.ts.map +1 -0
- package/dist/utils/mcp-config-manager.js +209 -0
- package/dist/utils/mcp-config-manager.js.map +1 -0
- package/dist/utils/mcp-server-manager.d.ts +91 -0
- package/dist/utils/mcp-server-manager.d.ts.map +1 -0
- package/dist/utils/mcp-server-manager.js +338 -0
- package/dist/utils/mcp-server-manager.js.map +1 -0
- package/dist/utils/scope-utils.d.ts +72 -0
- package/dist/utils/scope-utils.d.ts.map +1 -0
- package/dist/utils/scope-utils.js +386 -0
- package/dist/utils/scope-utils.js.map +1 -0
- package/dist/utils/servicenow-client.d.ts +233 -0
- package/dist/utils/servicenow-client.d.ts.map +1 -0
- package/dist/utils/servicenow-client.js +1465 -0
- package/dist/utils/servicenow-client.js.map +1 -0
- package/dist/utils/snow-oauth-old.d.ts +65 -0
- package/dist/utils/snow-oauth-old.d.ts.map +1 -0
- package/dist/utils/snow-oauth-old.js +345 -0
- package/dist/utils/snow-oauth-old.js.map +1 -0
- package/dist/utils/snow-oauth.d.ts +85 -0
- package/dist/utils/snow-oauth.d.ts.map +1 -0
- package/dist/utils/snow-oauth.js +512 -0
- package/dist/utils/snow-oauth.js.map +1 -0
- package/dist/utils/template-engine.d.ts +76 -0
- package/dist/utils/template-engine.d.ts.map +1 -0
- package/dist/utils/template-engine.js +391 -0
- package/dist/utils/template-engine.js.map +1 -0
- package/dist/version.d.ts +35 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +72 -0
- package/dist/version.js.map +1 -0
- package/mcp-wrapper.sh +12 -0
- package/package.json +77 -0
- package/reports/swarm-auto-centralized-1752649029776.json +13 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/setup-mcp.js +89 -0
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ServiceNow Flow Validation Engine
|
|
4
|
+
*
|
|
5
|
+
* This module implements comprehensive validation logic for flow vs subflow decisions,
|
|
6
|
+
* ensuring that the recommendations are sound and the created flows/subflows are valid.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FlowValidationEngine = exports.ValidationRuleType = exports.ValidationSeverity = void 0;
|
|
10
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
11
|
+
const flow_subflow_decision_engine_js_1 = require("./flow-subflow-decision-engine.js");
|
|
12
|
+
/**
|
|
13
|
+
* Validation severity levels
|
|
14
|
+
*/
|
|
15
|
+
var ValidationSeverity;
|
|
16
|
+
(function (ValidationSeverity) {
|
|
17
|
+
ValidationSeverity["INFO"] = "info";
|
|
18
|
+
ValidationSeverity["WARNING"] = "warning";
|
|
19
|
+
ValidationSeverity["ERROR"] = "error";
|
|
20
|
+
ValidationSeverity["CRITICAL"] = "critical";
|
|
21
|
+
})(ValidationSeverity || (exports.ValidationSeverity = ValidationSeverity = {}));
|
|
22
|
+
/**
|
|
23
|
+
* Validation rule types
|
|
24
|
+
*/
|
|
25
|
+
var ValidationRuleType;
|
|
26
|
+
(function (ValidationRuleType) {
|
|
27
|
+
ValidationRuleType["DECISION_LOGIC"] = "decision_logic";
|
|
28
|
+
ValidationRuleType["COMPLEXITY_ANALYSIS"] = "complexity_analysis";
|
|
29
|
+
ValidationRuleType["REUSABILITY_ANALYSIS"] = "reusability_analysis";
|
|
30
|
+
ValidationRuleType["TECHNICAL_FEASIBILITY"] = "technical_feasibility";
|
|
31
|
+
ValidationRuleType["BEST_PRACTICES"] = "best_practices";
|
|
32
|
+
ValidationRuleType["PERFORMANCE"] = "performance";
|
|
33
|
+
ValidationRuleType["MAINTAINABILITY"] = "maintainability";
|
|
34
|
+
ValidationRuleType["SECURITY"] = "security";
|
|
35
|
+
})(ValidationRuleType || (exports.ValidationRuleType = ValidationRuleType = {}));
|
|
36
|
+
/**
|
|
37
|
+
* Flow Validation Engine
|
|
38
|
+
*/
|
|
39
|
+
class FlowValidationEngine {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.rules = new Map();
|
|
42
|
+
this.logger = new logger_js_1.Logger('FlowValidationEngine');
|
|
43
|
+
this.initializeValidationRules();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate flow vs subflow decision
|
|
47
|
+
*/
|
|
48
|
+
validateDecision(analysisResult, instruction) {
|
|
49
|
+
this.logger.info('Validating flow vs subflow decision', {
|
|
50
|
+
recommendedType: analysisResult.recommendedType,
|
|
51
|
+
confidence: analysisResult.confidence
|
|
52
|
+
});
|
|
53
|
+
const context = {
|
|
54
|
+
instruction,
|
|
55
|
+
analysisResult,
|
|
56
|
+
criteria: analysisResult.criteria,
|
|
57
|
+
targetType: analysisResult.recommendedType
|
|
58
|
+
};
|
|
59
|
+
return this.executeValidation(context);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validate subflow definition
|
|
63
|
+
*/
|
|
64
|
+
validateSubflowDefinition(definition, instruction) {
|
|
65
|
+
this.logger.info('Validating subflow definition', {
|
|
66
|
+
name: definition.name,
|
|
67
|
+
activityCount: definition.activities.length
|
|
68
|
+
});
|
|
69
|
+
const context = {
|
|
70
|
+
instruction,
|
|
71
|
+
subflowDefinition: definition,
|
|
72
|
+
targetType: flow_subflow_decision_engine_js_1.FlowType.SUBFLOW
|
|
73
|
+
};
|
|
74
|
+
return this.executeValidation(context);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validate flow template application
|
|
78
|
+
*/
|
|
79
|
+
validateTemplateApplication(template, instruction) {
|
|
80
|
+
this.logger.info('Validating template application', {
|
|
81
|
+
templateId: template.id,
|
|
82
|
+
templateName: template.name
|
|
83
|
+
});
|
|
84
|
+
const context = {
|
|
85
|
+
instruction,
|
|
86
|
+
flowTemplate: template,
|
|
87
|
+
targetType: template.recommendedType
|
|
88
|
+
};
|
|
89
|
+
return this.executeValidation(context);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate subflow candidate
|
|
93
|
+
*/
|
|
94
|
+
validateSubflowCandidate(candidate, instruction) {
|
|
95
|
+
this.logger.info('Validating subflow candidate', {
|
|
96
|
+
name: candidate.name,
|
|
97
|
+
complexity: candidate.complexity
|
|
98
|
+
});
|
|
99
|
+
const context = {
|
|
100
|
+
instruction,
|
|
101
|
+
targetType: flow_subflow_decision_engine_js_1.FlowType.SUBFLOW,
|
|
102
|
+
metadata: {
|
|
103
|
+
candidate
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return this.executeValidation(context);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Execute validation with applicable rules
|
|
110
|
+
*/
|
|
111
|
+
executeValidation(context) {
|
|
112
|
+
const issues = [];
|
|
113
|
+
const recommendations = [];
|
|
114
|
+
let totalScore = 0;
|
|
115
|
+
let maxScore = 0;
|
|
116
|
+
// Get applicable rules
|
|
117
|
+
const applicableRules = this.getApplicableRules(context);
|
|
118
|
+
// Execute each rule
|
|
119
|
+
for (const rule of applicableRules) {
|
|
120
|
+
try {
|
|
121
|
+
const result = rule.validator(context);
|
|
122
|
+
// Calculate score
|
|
123
|
+
totalScore += result.score;
|
|
124
|
+
maxScore += rule.weight;
|
|
125
|
+
// Add issues with rule ID
|
|
126
|
+
for (const issue of result.issues) {
|
|
127
|
+
issues.push({
|
|
128
|
+
...issue,
|
|
129
|
+
id: `${rule.id}_${issues.length + 1}`,
|
|
130
|
+
ruleId: rule.id
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Add recommendations with ID
|
|
134
|
+
for (const recommendation of result.recommendations) {
|
|
135
|
+
recommendations.push({
|
|
136
|
+
...recommendation,
|
|
137
|
+
id: `${rule.id}_rec_${recommendations.length + 1}`
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
this.logger.error(`Validation rule ${rule.id} failed`, error);
|
|
143
|
+
issues.push({
|
|
144
|
+
id: `${rule.id}_error`,
|
|
145
|
+
type: rule.type,
|
|
146
|
+
severity: ValidationSeverity.ERROR,
|
|
147
|
+
message: `Validation rule failed: ${rule.name}`,
|
|
148
|
+
description: `Internal error in validation rule: ${error}`,
|
|
149
|
+
impact: 'Validation incomplete',
|
|
150
|
+
ruleId: rule.id
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Determine overall validation result
|
|
155
|
+
const criticalIssues = issues.filter(i => i.severity === ValidationSeverity.CRITICAL);
|
|
156
|
+
const errorIssues = issues.filter(i => i.severity === ValidationSeverity.ERROR);
|
|
157
|
+
const isValid = criticalIssues.length === 0 && errorIssues.length === 0;
|
|
158
|
+
const overallSeverity = this.determineOverallSeverity(issues);
|
|
159
|
+
return {
|
|
160
|
+
isValid,
|
|
161
|
+
severity: overallSeverity,
|
|
162
|
+
issues,
|
|
163
|
+
recommendations,
|
|
164
|
+
score: totalScore,
|
|
165
|
+
maxScore
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get applicable validation rules for context
|
|
170
|
+
*/
|
|
171
|
+
getApplicableRules(context) {
|
|
172
|
+
const applicableRules = [];
|
|
173
|
+
for (const rule of this.rules.values()) {
|
|
174
|
+
// Check if rule applies to target type
|
|
175
|
+
if (context.targetType && !rule.applicableTypes.includes(context.targetType)) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
// Check if rule applies to context
|
|
179
|
+
if (context.analysisResult?.criteria.context) {
|
|
180
|
+
if (rule.applicableContexts.length > 0 &&
|
|
181
|
+
!rule.applicableContexts.includes(context.analysisResult.criteria.context)) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
applicableRules.push(rule);
|
|
186
|
+
}
|
|
187
|
+
return applicableRules;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Determine overall validation severity
|
|
191
|
+
*/
|
|
192
|
+
determineOverallSeverity(issues) {
|
|
193
|
+
if (issues.some(i => i.severity === ValidationSeverity.CRITICAL)) {
|
|
194
|
+
return ValidationSeverity.CRITICAL;
|
|
195
|
+
}
|
|
196
|
+
if (issues.some(i => i.severity === ValidationSeverity.ERROR)) {
|
|
197
|
+
return ValidationSeverity.ERROR;
|
|
198
|
+
}
|
|
199
|
+
if (issues.some(i => i.severity === ValidationSeverity.WARNING)) {
|
|
200
|
+
return ValidationSeverity.WARNING;
|
|
201
|
+
}
|
|
202
|
+
return ValidationSeverity.INFO;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Initialize validation rules
|
|
206
|
+
*/
|
|
207
|
+
initializeValidationRules() {
|
|
208
|
+
// Decision Logic Validation Rules
|
|
209
|
+
this.rules.set('decision_confidence', {
|
|
210
|
+
id: 'decision_confidence',
|
|
211
|
+
name: 'Decision Confidence',
|
|
212
|
+
description: 'Validate that the decision confidence is reasonable',
|
|
213
|
+
type: ValidationRuleType.DECISION_LOGIC,
|
|
214
|
+
severity: ValidationSeverity.WARNING,
|
|
215
|
+
weight: 10,
|
|
216
|
+
applicableContexts: [],
|
|
217
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
218
|
+
validator: (context) => {
|
|
219
|
+
const confidence = context.analysisResult?.confidence || 0;
|
|
220
|
+
const issues = [];
|
|
221
|
+
const recommendations = [];
|
|
222
|
+
let score = 10;
|
|
223
|
+
if (confidence < 0.5) {
|
|
224
|
+
score = 3;
|
|
225
|
+
issues.push({
|
|
226
|
+
type: ValidationRuleType.DECISION_LOGIC,
|
|
227
|
+
severity: ValidationSeverity.WARNING,
|
|
228
|
+
message: 'Low decision confidence',
|
|
229
|
+
description: `Decision confidence is ${confidence.toFixed(2)}, which is below the recommended threshold of 0.5`,
|
|
230
|
+
impact: 'Decision may not be optimal',
|
|
231
|
+
suggestedFix: 'Review the requirements and consider providing more specific details'
|
|
232
|
+
});
|
|
233
|
+
recommendations.push({
|
|
234
|
+
type: ValidationRuleType.DECISION_LOGIC,
|
|
235
|
+
priority: 'high',
|
|
236
|
+
message: 'Provide more specific requirements',
|
|
237
|
+
description: 'Add more specific details about the workflow to improve decision confidence',
|
|
238
|
+
benefits: ['More accurate recommendations', 'Better fit for requirements'],
|
|
239
|
+
implementation: 'Include specific actions, data flows, and business rules in the instruction',
|
|
240
|
+
effort: 'low'
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
else if (confidence < 0.7) {
|
|
244
|
+
score = 7;
|
|
245
|
+
issues.push({
|
|
246
|
+
type: ValidationRuleType.DECISION_LOGIC,
|
|
247
|
+
severity: ValidationSeverity.INFO,
|
|
248
|
+
message: 'Moderate decision confidence',
|
|
249
|
+
description: `Decision confidence is ${confidence.toFixed(2)}, which is acceptable but could be improved`,
|
|
250
|
+
impact: 'Decision is likely correct but may benefit from refinement',
|
|
251
|
+
suggestedFix: 'Consider adding more context or specific requirements'
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
passed: confidence >= 0.5,
|
|
256
|
+
score,
|
|
257
|
+
issues,
|
|
258
|
+
recommendations
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
this.rules.set('complexity_appropriateness', {
|
|
263
|
+
id: 'complexity_appropriateness',
|
|
264
|
+
name: 'Complexity Appropriateness',
|
|
265
|
+
description: 'Validate that the complexity level matches the recommended flow type',
|
|
266
|
+
type: ValidationRuleType.COMPLEXITY_ANALYSIS,
|
|
267
|
+
severity: ValidationSeverity.WARNING,
|
|
268
|
+
weight: 15,
|
|
269
|
+
applicableContexts: [],
|
|
270
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
271
|
+
validator: (context) => {
|
|
272
|
+
const complexity = context.analysisResult?.criteria.complexity || context.metadata?.candidate?.complexity;
|
|
273
|
+
const recommendedType = context.analysisResult?.recommendedType || context.targetType;
|
|
274
|
+
const issues = [];
|
|
275
|
+
const recommendations = [];
|
|
276
|
+
let score = 15;
|
|
277
|
+
// High complexity should generally favor subflows if reusable
|
|
278
|
+
if (complexity === flow_subflow_decision_engine_js_1.ComplexityLevel.HIGH || complexity === flow_subflow_decision_engine_js_1.ComplexityLevel.VERY_HIGH) {
|
|
279
|
+
const reusability = context.analysisResult?.criteria.reusability || context.metadata?.candidate?.reusability;
|
|
280
|
+
if (recommendedType === flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW && reusability === flow_subflow_decision_engine_js_1.ReusabilityLevel.HIGH) {
|
|
281
|
+
score = 5;
|
|
282
|
+
issues.push({
|
|
283
|
+
type: ValidationRuleType.COMPLEXITY_ANALYSIS,
|
|
284
|
+
severity: ValidationSeverity.WARNING,
|
|
285
|
+
message: 'High complexity with high reusability in main flow',
|
|
286
|
+
description: 'Complex workflows with high reusability potential should consider subflow implementation',
|
|
287
|
+
impact: 'Missed opportunity for reusability and maintainability',
|
|
288
|
+
suggestedFix: 'Consider breaking complex logic into reusable subflows'
|
|
289
|
+
});
|
|
290
|
+
recommendations.push({
|
|
291
|
+
type: ValidationRuleType.COMPLEXITY_ANALYSIS,
|
|
292
|
+
priority: 'medium',
|
|
293
|
+
message: 'Consider subflow implementation',
|
|
294
|
+
description: 'Break complex logic into reusable subflows for better maintainability',
|
|
295
|
+
benefits: ['Improved reusability', 'Better maintainability', 'Easier testing'],
|
|
296
|
+
implementation: 'Identify reusable components and extract them into subflows',
|
|
297
|
+
effort: 'medium'
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// Low complexity should generally favor main flows unless highly reusable
|
|
302
|
+
if (complexity === flow_subflow_decision_engine_js_1.ComplexityLevel.LOW) {
|
|
303
|
+
if (recommendedType === flow_subflow_decision_engine_js_1.FlowType.SUBFLOW) {
|
|
304
|
+
const reusability = context.analysisResult?.criteria.reusability || context.metadata?.candidate?.reusability;
|
|
305
|
+
if (reusability === flow_subflow_decision_engine_js_1.ReusabilityLevel.LOW || reusability === flow_subflow_decision_engine_js_1.ReusabilityLevel.NONE) {
|
|
306
|
+
score = 8;
|
|
307
|
+
issues.push({
|
|
308
|
+
type: ValidationRuleType.COMPLEXITY_ANALYSIS,
|
|
309
|
+
severity: ValidationSeverity.INFO,
|
|
310
|
+
message: 'Low complexity with low reusability as subflow',
|
|
311
|
+
description: 'Simple workflows with low reusability might be better as main flows',
|
|
312
|
+
impact: 'Over-engineering for current needs',
|
|
313
|
+
suggestedFix: 'Consider implementing as main flow unless reusability is important'
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
passed: score >= 10,
|
|
320
|
+
score,
|
|
321
|
+
issues,
|
|
322
|
+
recommendations
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
this.rules.set('reusability_validation', {
|
|
327
|
+
id: 'reusability_validation',
|
|
328
|
+
name: 'Reusability Validation',
|
|
329
|
+
description: 'Validate that reusability assessment is appropriate for the recommended flow type',
|
|
330
|
+
type: ValidationRuleType.REUSABILITY_ANALYSIS,
|
|
331
|
+
severity: ValidationSeverity.WARNING,
|
|
332
|
+
weight: 15,
|
|
333
|
+
applicableContexts: [],
|
|
334
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
335
|
+
validator: (context) => {
|
|
336
|
+
const reusability = context.analysisResult?.criteria.reusability || context.metadata?.candidate?.reusability;
|
|
337
|
+
const recommendedType = context.analysisResult?.recommendedType || context.targetType;
|
|
338
|
+
const issues = [];
|
|
339
|
+
const recommendations = [];
|
|
340
|
+
let score = 15;
|
|
341
|
+
// High reusability should favor subflows
|
|
342
|
+
if (reusability === flow_subflow_decision_engine_js_1.ReusabilityLevel.HIGH && recommendedType === flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW) {
|
|
343
|
+
score = 5;
|
|
344
|
+
issues.push({
|
|
345
|
+
type: ValidationRuleType.REUSABILITY_ANALYSIS,
|
|
346
|
+
severity: ValidationSeverity.WARNING,
|
|
347
|
+
message: 'High reusability potential in main flow',
|
|
348
|
+
description: 'Workflows with high reusability should be implemented as subflows',
|
|
349
|
+
impact: 'Lost opportunity for reuse across multiple flows',
|
|
350
|
+
suggestedFix: 'Implement as subflow to maximize reusability'
|
|
351
|
+
});
|
|
352
|
+
recommendations.push({
|
|
353
|
+
type: ValidationRuleType.REUSABILITY_ANALYSIS,
|
|
354
|
+
priority: 'high',
|
|
355
|
+
message: 'Implement as subflow',
|
|
356
|
+
description: 'Create subflow to enable reuse across multiple workflows',
|
|
357
|
+
benefits: ['Code reuse', 'Consistency', 'Easier maintenance'],
|
|
358
|
+
implementation: 'Design subflow with clear inputs and outputs',
|
|
359
|
+
effort: 'medium'
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
// Low reusability in subflow might be over-engineering
|
|
363
|
+
if (reusability === flow_subflow_decision_engine_js_1.ReusabilityLevel.NONE && recommendedType === flow_subflow_decision_engine_js_1.FlowType.SUBFLOW) {
|
|
364
|
+
score = 8;
|
|
365
|
+
issues.push({
|
|
366
|
+
type: ValidationRuleType.REUSABILITY_ANALYSIS,
|
|
367
|
+
severity: ValidationSeverity.INFO,
|
|
368
|
+
message: 'No reusability in subflow',
|
|
369
|
+
description: 'Creating subflow with no reusability potential might be over-engineering',
|
|
370
|
+
impact: 'Unnecessary complexity',
|
|
371
|
+
suggestedFix: 'Consider main flow implementation unless other factors apply'
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
passed: score >= 10,
|
|
376
|
+
score,
|
|
377
|
+
issues,
|
|
378
|
+
recommendations
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
this.rules.set('technical_feasibility', {
|
|
383
|
+
id: 'technical_feasibility',
|
|
384
|
+
name: 'Technical Feasibility',
|
|
385
|
+
description: 'Validate technical feasibility of the recommended approach',
|
|
386
|
+
type: ValidationRuleType.TECHNICAL_FEASIBILITY,
|
|
387
|
+
severity: ValidationSeverity.ERROR,
|
|
388
|
+
weight: 20,
|
|
389
|
+
applicableContexts: [],
|
|
390
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
391
|
+
validator: (context) => {
|
|
392
|
+
const issues = [];
|
|
393
|
+
const recommendations = [];
|
|
394
|
+
let score = 20;
|
|
395
|
+
// Check for subflow input/output requirements
|
|
396
|
+
if (context.targetType === flow_subflow_decision_engine_js_1.FlowType.SUBFLOW) {
|
|
397
|
+
const candidate = context.metadata?.candidate;
|
|
398
|
+
const definition = context.subflowDefinition;
|
|
399
|
+
if (candidate && candidate.inputs.length === 0) {
|
|
400
|
+
score = 0;
|
|
401
|
+
issues.push({
|
|
402
|
+
type: ValidationRuleType.TECHNICAL_FEASIBILITY,
|
|
403
|
+
severity: ValidationSeverity.ERROR,
|
|
404
|
+
message: 'Subflow has no input parameters',
|
|
405
|
+
description: 'Subflows must have at least one input parameter to be reusable',
|
|
406
|
+
impact: 'Subflow cannot be properly invoked',
|
|
407
|
+
suggestedFix: 'Add appropriate input parameters'
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
if (candidate && candidate.outputs.length === 0) {
|
|
411
|
+
score = Math.min(score, 5);
|
|
412
|
+
issues.push({
|
|
413
|
+
type: ValidationRuleType.TECHNICAL_FEASIBILITY,
|
|
414
|
+
severity: ValidationSeverity.ERROR,
|
|
415
|
+
message: 'Subflow has no output parameters',
|
|
416
|
+
description: 'Subflows should have at least one output parameter',
|
|
417
|
+
impact: 'Subflow results cannot be used by calling flows',
|
|
418
|
+
suggestedFix: 'Add appropriate output parameters'
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
if (definition && definition.activities.length < 3) {
|
|
422
|
+
score = Math.min(score, 10);
|
|
423
|
+
issues.push({
|
|
424
|
+
type: ValidationRuleType.TECHNICAL_FEASIBILITY,
|
|
425
|
+
severity: ValidationSeverity.WARNING,
|
|
426
|
+
message: 'Subflow has very few activities',
|
|
427
|
+
description: 'Subflow should have meaningful processing activities',
|
|
428
|
+
impact: 'Subflow may not provide sufficient value',
|
|
429
|
+
suggestedFix: 'Ensure subflow has adequate processing logic'
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
passed: score >= 15,
|
|
435
|
+
score,
|
|
436
|
+
issues,
|
|
437
|
+
recommendations
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
this.rules.set('best_practices', {
|
|
442
|
+
id: 'best_practices',
|
|
443
|
+
name: 'Best Practices',
|
|
444
|
+
description: 'Validate adherence to ServiceNow flow best practices',
|
|
445
|
+
type: ValidationRuleType.BEST_PRACTICES,
|
|
446
|
+
severity: ValidationSeverity.INFO,
|
|
447
|
+
weight: 10,
|
|
448
|
+
applicableContexts: [],
|
|
449
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
450
|
+
validator: (context) => {
|
|
451
|
+
const issues = [];
|
|
452
|
+
const recommendations = [];
|
|
453
|
+
let score = 10;
|
|
454
|
+
// Check for error handling
|
|
455
|
+
const definition = context.subflowDefinition;
|
|
456
|
+
if (definition && definition.errorHandling.length === 0) {
|
|
457
|
+
score = 7;
|
|
458
|
+
issues.push({
|
|
459
|
+
type: ValidationRuleType.BEST_PRACTICES,
|
|
460
|
+
severity: ValidationSeverity.INFO,
|
|
461
|
+
message: 'No error handling defined',
|
|
462
|
+
description: 'Flow should include error handling for robustness',
|
|
463
|
+
impact: 'Flow may fail ungracefully',
|
|
464
|
+
suggestedFix: 'Add error handling activities'
|
|
465
|
+
});
|
|
466
|
+
recommendations.push({
|
|
467
|
+
type: ValidationRuleType.BEST_PRACTICES,
|
|
468
|
+
priority: 'medium',
|
|
469
|
+
message: 'Add error handling',
|
|
470
|
+
description: 'Include error handling to improve flow robustness',
|
|
471
|
+
benefits: ['Better error recovery', 'Improved user experience'],
|
|
472
|
+
implementation: 'Add try-catch patterns and error notifications',
|
|
473
|
+
effort: 'low'
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
// Check for documentation
|
|
477
|
+
if (definition && (!definition.metadata.documentation || definition.metadata.documentation.length < 50)) {
|
|
478
|
+
score = Math.min(score, 8);
|
|
479
|
+
recommendations.push({
|
|
480
|
+
type: ValidationRuleType.BEST_PRACTICES,
|
|
481
|
+
priority: 'low',
|
|
482
|
+
message: 'Add comprehensive documentation',
|
|
483
|
+
description: 'Document the flow purpose, inputs, outputs, and usage',
|
|
484
|
+
benefits: ['Better maintainability', 'Easier onboarding'],
|
|
485
|
+
implementation: 'Add detailed description and usage examples',
|
|
486
|
+
effort: 'low'
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
passed: score >= 7,
|
|
491
|
+
score,
|
|
492
|
+
issues,
|
|
493
|
+
recommendations
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
this.rules.set('performance_considerations', {
|
|
498
|
+
id: 'performance_considerations',
|
|
499
|
+
name: 'Performance Considerations',
|
|
500
|
+
description: 'Validate performance implications of the recommended approach',
|
|
501
|
+
type: ValidationRuleType.PERFORMANCE,
|
|
502
|
+
severity: ValidationSeverity.WARNING,
|
|
503
|
+
weight: 10,
|
|
504
|
+
applicableContexts: [],
|
|
505
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
506
|
+
validator: (context) => {
|
|
507
|
+
const issues = [];
|
|
508
|
+
const recommendations = [];
|
|
509
|
+
let score = 10;
|
|
510
|
+
// Check for excessive complexity
|
|
511
|
+
const complexity = context.analysisResult?.criteria.complexity;
|
|
512
|
+
if (complexity === flow_subflow_decision_engine_js_1.ComplexityLevel.VERY_HIGH) {
|
|
513
|
+
score = 6;
|
|
514
|
+
issues.push({
|
|
515
|
+
type: ValidationRuleType.PERFORMANCE,
|
|
516
|
+
severity: ValidationSeverity.WARNING,
|
|
517
|
+
message: 'Very high complexity may impact performance',
|
|
518
|
+
description: 'Extremely complex flows can have performance implications',
|
|
519
|
+
impact: 'Slow execution, resource consumption',
|
|
520
|
+
suggestedFix: 'Consider breaking into smaller, more focused flows'
|
|
521
|
+
});
|
|
522
|
+
recommendations.push({
|
|
523
|
+
type: ValidationRuleType.PERFORMANCE,
|
|
524
|
+
priority: 'medium',
|
|
525
|
+
message: 'Optimize for performance',
|
|
526
|
+
description: 'Break complex flows into smaller, more efficient components',
|
|
527
|
+
benefits: ['Better performance', 'Improved scalability'],
|
|
528
|
+
implementation: 'Use subflows to modularize complex logic',
|
|
529
|
+
effort: 'medium'
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
// Check for deep nesting in subflows
|
|
533
|
+
if (context.targetType === flow_subflow_decision_engine_js_1.FlowType.SUBFLOW) {
|
|
534
|
+
const definition = context.subflowDefinition;
|
|
535
|
+
if (definition && definition.activities.length > 20) {
|
|
536
|
+
score = Math.min(score, 7);
|
|
537
|
+
issues.push({
|
|
538
|
+
type: ValidationRuleType.PERFORMANCE,
|
|
539
|
+
severity: ValidationSeverity.INFO,
|
|
540
|
+
message: 'Large subflow may impact performance',
|
|
541
|
+
description: 'Subflows with many activities can impact performance',
|
|
542
|
+
impact: 'Slower execution',
|
|
543
|
+
suggestedFix: 'Consider breaking into smaller subflows'
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return {
|
|
548
|
+
passed: score >= 7,
|
|
549
|
+
score,
|
|
550
|
+
issues,
|
|
551
|
+
recommendations
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
this.rules.set('maintainability_assessment', {
|
|
556
|
+
id: 'maintainability_assessment',
|
|
557
|
+
name: 'Maintainability Assessment',
|
|
558
|
+
description: 'Validate maintainability aspects of the recommended approach',
|
|
559
|
+
type: ValidationRuleType.MAINTAINABILITY,
|
|
560
|
+
severity: ValidationSeverity.INFO,
|
|
561
|
+
weight: 10,
|
|
562
|
+
applicableContexts: [],
|
|
563
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
564
|
+
validator: (context) => {
|
|
565
|
+
const issues = [];
|
|
566
|
+
const recommendations = [];
|
|
567
|
+
let score = 10;
|
|
568
|
+
// Check for maintainability score
|
|
569
|
+
const maintainabilityScore = context.analysisResult?.criteria.maintainabilityScore || 5;
|
|
570
|
+
if (maintainabilityScore < 5) {
|
|
571
|
+
score = 6;
|
|
572
|
+
issues.push({
|
|
573
|
+
type: ValidationRuleType.MAINTAINABILITY,
|
|
574
|
+
severity: ValidationSeverity.INFO,
|
|
575
|
+
message: 'Low maintainability score',
|
|
576
|
+
description: 'Flow may be difficult to maintain over time',
|
|
577
|
+
impact: 'Higher maintenance cost',
|
|
578
|
+
suggestedFix: 'Consider simplifying or modularizing the flow'
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
// Check for appropriate naming
|
|
582
|
+
const definition = context.subflowDefinition;
|
|
583
|
+
if (definition && (definition.name.length < 3 || definition.name.includes('_'))) {
|
|
584
|
+
score = Math.min(score, 8);
|
|
585
|
+
recommendations.push({
|
|
586
|
+
type: ValidationRuleType.MAINTAINABILITY,
|
|
587
|
+
priority: 'low',
|
|
588
|
+
message: 'Improve naming convention',
|
|
589
|
+
description: 'Use clear, descriptive names for better maintainability',
|
|
590
|
+
benefits: ['Better readability', 'Easier understanding'],
|
|
591
|
+
implementation: 'Use descriptive names without underscores',
|
|
592
|
+
effort: 'low'
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
passed: score >= 6,
|
|
597
|
+
score,
|
|
598
|
+
issues,
|
|
599
|
+
recommendations
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
this.rules.set('security_considerations', {
|
|
604
|
+
id: 'security_considerations',
|
|
605
|
+
name: 'Security Considerations',
|
|
606
|
+
description: 'Validate security aspects of the recommended approach',
|
|
607
|
+
type: ValidationRuleType.SECURITY,
|
|
608
|
+
severity: ValidationSeverity.ERROR,
|
|
609
|
+
weight: 15,
|
|
610
|
+
applicableContexts: [],
|
|
611
|
+
applicableTypes: [flow_subflow_decision_engine_js_1.FlowType.MAIN_FLOW, flow_subflow_decision_engine_js_1.FlowType.SUBFLOW],
|
|
612
|
+
validator: (context) => {
|
|
613
|
+
const issues = [];
|
|
614
|
+
const recommendations = [];
|
|
615
|
+
let score = 15;
|
|
616
|
+
// Check for sensitive data handling
|
|
617
|
+
const instruction = context.instruction.toLowerCase();
|
|
618
|
+
if (instruction.includes('password') || instruction.includes('secret') || instruction.includes('token')) {
|
|
619
|
+
score = 10;
|
|
620
|
+
issues.push({
|
|
621
|
+
type: ValidationRuleType.SECURITY,
|
|
622
|
+
severity: ValidationSeverity.WARNING,
|
|
623
|
+
message: 'Potential sensitive data handling',
|
|
624
|
+
description: 'Flow may handle sensitive data that requires special security considerations',
|
|
625
|
+
impact: 'Security risk if not properly handled',
|
|
626
|
+
suggestedFix: 'Ensure proper encryption and access controls'
|
|
627
|
+
});
|
|
628
|
+
recommendations.push({
|
|
629
|
+
type: ValidationRuleType.SECURITY,
|
|
630
|
+
priority: 'high',
|
|
631
|
+
message: 'Implement security controls',
|
|
632
|
+
description: 'Add appropriate security measures for sensitive data',
|
|
633
|
+
benefits: ['Data protection', 'Compliance'],
|
|
634
|
+
implementation: 'Use encryption, access controls, and audit logging',
|
|
635
|
+
effort: 'medium'
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
// Check for external integrations
|
|
639
|
+
if (instruction.includes('api') || instruction.includes('external') || instruction.includes('integration')) {
|
|
640
|
+
score = Math.min(score, 12);
|
|
641
|
+
recommendations.push({
|
|
642
|
+
type: ValidationRuleType.SECURITY,
|
|
643
|
+
priority: 'medium',
|
|
644
|
+
message: 'Secure external integrations',
|
|
645
|
+
description: 'Ensure external integrations follow security best practices',
|
|
646
|
+
benefits: ['Secure data exchange', 'Reduced attack surface'],
|
|
647
|
+
implementation: 'Use secure protocols, authentication, and input validation',
|
|
648
|
+
effort: 'medium'
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
return {
|
|
652
|
+
passed: score >= 10,
|
|
653
|
+
score,
|
|
654
|
+
issues,
|
|
655
|
+
recommendations
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
this.logger.info('Initialized validation rules', { ruleCount: this.rules.size });
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
exports.FlowValidationEngine = FlowValidationEngine;
|
|
663
|
+
//# sourceMappingURL=flow-validation-engine.js.map
|