adpa-enterprise-framework-automation
Version:
Modular, standards-compliant Node.js/TypeScript automation framework for enterprise requirements, project, and data management. Provides CLI and API for BABOK v3, PMBOK 7th Edition, and DMBOK 2.0 (in progress). Production-ready Express.js API with TypeSpe
255 lines • 10.5 kB
JavaScript
/**
* Validation Processing Factory
*
* Core orchestrator for the ADPA Quality Assurance Engine validation system.
* Manages the execution of multiple validators and aggregates results into
* comprehensive compliance reports.
*
* This factory provides the main interface for running validation checks
* and follows the same architectural pattern as the DocumentGenerator's
* ProcessorFactory for consistency and maintainability.
*
* @version 1.0.0
* @author ADPA Quality Assurance Engine Team
* @created June 2025
*/
import { ValidationRegistry } from './ValidationRegistry.js';
/**
* Main validation processing factory
*/
export class ValidationFactory {
registry;
constructor() {
this.registry = ValidationRegistry.getInstance();
}
/**
* Run comprehensive validation on the provided documents
* @param config Validation configuration
* @param options Execution options
* @returns Comprehensive validation report
*/
async runComprehensiveValidation(config, options = {}) {
const startTime = Date.now();
console.log('🔍 Starting comprehensive PMBOK validation...');
// Get applicable validators
const filter = {
enabledOnly: true,
documentTypes: Object.keys(config.documents),
validatorIds: options.validatorIds,
tags: options.tags
};
const validatorRegistrations = this.registry.getValidators(filter);
const validators = validatorRegistrations.map(reg => reg.validator);
if (validators.length === 0) {
console.warn('⚠️ No applicable validators found for the provided documents');
}
console.log(`📋 Running ${validators.length} validators...`);
// Execute validators
const validatorResults = [];
if (options.parallel && validators.length > 1) {
validatorResults.push(...await this.runValidatorsInParallel(validators, config, options));
}
else {
validatorResults.push(...await this.runValidatorsSequentially(validators, config, options));
}
// Aggregate results
const report = this.aggregateResults(validatorResults, config, options);
report.summary.executionTimeMs = Date.now() - startTime;
report.summary.timestamp = new Date();
console.log(`✅ Validation complete in ${report.summary.executionTimeMs}ms`);
console.log(`📊 Overall Score: ${report.summary.overallScore}/${report.summary.maxPossibleScore}`);
console.log(`📋 Status: ${report.summary.overallPassed ? '✅ COMPLIANT' : '❌ NON-COMPLIANT'}`);
return report;
}
/**
* Run a specific validator
* @param validatorId The validator ID to run
* @param config Validation configuration
* @returns Validation result
*/
async runValidator(validatorId, config) {
const registration = this.registry.getValidator(validatorId);
if (!registration || !registration.enabled) {
console.warn(`⚠️ Validator '${validatorId}' not found or disabled`);
return null;
}
console.log(`🔍 Running validator: ${registration.validator.name}`);
try {
const result = await registration.validator.validate(config);
console.log(`${result.passed ? '✅' : '❌'} ${registration.validator.name}: ${result.score}/${result.maxScore}`);
return result;
}
catch (error) {
console.error(`❌ Error running validator '${validatorId}':`, error);
// Return error result
return {
validatorId,
validatorName: registration.validator.name,
passed: false,
score: 0,
maxScore: 100,
issues: [`Validator execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`],
strengths: [],
severity: 'critical',
recommendations: ['Fix validator implementation'],
executionTimeMs: 0,
metadata: { error: error instanceof Error ? error.message : 'Unknown error' }
};
}
}
/**
* Get available validators for the given document types
* @param documentTypes Document types to check
* @returns Array of applicable validators
*/
getApplicableValidators(documentTypes) {
const filter = {
enabledOnly: true,
documentTypes
};
return this.registry.getValidators(filter).map(reg => reg.validator);
}
/**
* Register a new validator
* @param validator The validator to register
* @param options Registration options
*/
registerValidator(validator, options = {}) {
this.registry.register(validator, options);
}
/**
* Get registry statistics
*/
getStats() {
return this.registry.getStats();
}
/**
* List all registered validators
*/
listValidators() {
this.registry.listValidators();
}
/**
* Run validators in parallel
*/
async runValidatorsInParallel(validators, config, options) {
const maxConcurrency = options.maxConcurrency || 3;
const results = [];
// Process validators in batches
for (let i = 0; i < validators.length; i += maxConcurrency) {
const batch = validators.slice(i, i + maxConcurrency);
const batchPromises = batch.map(validator => this.runValidatorSafely(validator, config));
const batchResults = await Promise.all(batchPromises);
results.push(...batchResults.filter(result => result !== null));
// Check for critical failures
if (options.stopOnCriticalFailure) {
const criticalFailure = batchResults.find(result => result && result.severity === 'critical' && !result.passed);
if (criticalFailure) {
console.warn(`🚨 Critical failure detected, stopping validation: ${criticalFailure.validatorName}`);
break;
}
}
}
return results;
}
/**
* Run validators sequentially
*/
async runValidatorsSequentially(validators, config, options) {
const results = [];
for (const validator of validators) {
const result = await this.runValidatorSafely(validator, config);
if (result) {
results.push(result);
// Check for critical failures
if (options.stopOnCriticalFailure && result.severity === 'critical' && !result.passed) {
console.warn(`🚨 Critical failure detected, stopping validation: ${result.validatorName}`);
break;
}
}
}
return results;
}
/**
* Safely run a validator with error handling
*/
async runValidatorSafely(validator, config) {
try {
const result = await validator.validate(config);
console.log(`${result.passed ? '✅' : '❌'} ${validator.name}: ${result.score}/${result.maxScore}`);
return result;
}
catch (error) {
console.error(`❌ Error running validator '${validator.id}':`, error);
return null;
}
}
/**
* Aggregate validation results into comprehensive report
*/
aggregateResults(validatorResults, config, options) {
const totalValidators = validatorResults.length;
const passedValidators = validatorResults.filter(r => r.passed).length;
const failedValidators = totalValidators - passedValidators;
// Calculate overall score
const totalScore = validatorResults.reduce((sum, r) => sum + r.score, 0);
const maxPossibleScore = validatorResults.reduce((sum, r) => sum + r.maxScore, 0);
const overallScore = maxPossibleScore > 0 ? Math.round((totalScore / maxPossibleScore) * 100) : 0;
// Determine compliance
const complianceThreshold = options.complianceThreshold || 70;
const overallPassed = overallScore >= complianceThreshold && failedValidators === 0;
// Aggregate issues by severity
const issuesSummary = {
critical: [],
warning: [],
info: []
};
const strengths = [];
const recommendations = [];
for (const result of validatorResults) {
issuesSummary[result.severity].push(...result.issues);
strengths.push(...result.strengths);
recommendations.push(...result.recommendations);
}
// Calculate document scores (simplified for now)
const documentScores = {};
for (const docType of Object.keys(config.documents)) {
const docResults = validatorResults.filter(r => r.metadata?.documentType === docType || r.validatorId.includes(docType));
if (docResults.length > 0) {
const docScore = docResults.reduce((sum, r) => sum + r.score, 0);
const docMaxScore = docResults.reduce((sum, r) => sum + r.maxScore, 0);
documentScores[docType] = {
score: docMaxScore > 0 ? Math.round((docScore / docMaxScore) * 100) : 0,
maxScore: 100,
issues: docResults.flatMap(r => r.issues),
strengths: docResults.flatMap(r => r.strengths)
};
}
}
return {
summary: {
totalValidators,
passedValidators,
failedValidators,
overallScore,
maxPossibleScore: 100,
overallPassed,
executionTimeMs: 0, // Will be set by caller
timestamp: new Date()
},
validatorResults,
issuesSummary,
strengths: [...new Set(strengths)], // Remove duplicates
recommendations: [...new Set(recommendations)], // Remove duplicates
consistencyScore: overallScore, // Simplified for now
documentScores,
pmbokCompliance: {
score: overallScore,
isCompliant: overallPassed,
missingElements: issuesSummary.critical,
documentQuality: documentScores
}
};
}
}
//# sourceMappingURL=ValidationFactory.js.map