UNPKG

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

147 lines 5.55 kB
/** * File Existence Validator * * Validates that expected PMBOK documents exist in the file system. * This is a fundamental check that ensures the basic generation process * has completed successfully before running more detailed content analysis. * * @version 1.0.0 * @author ADPA Quality Assurance Engine Team * @created June 2025 */ import * as fs from 'fs/promises'; import * as path from 'path'; export class FileExistenceValidator { name = 'File Existence Validator'; description = 'Verifies that expected PMBOK documents exist in the file system'; id = 'file-existence'; version = '1.0.0'; tags = ['basic', 'filesystem', 'pmbok']; documentsBasePath; // Required interface properties applicableDocuments = []; // Apply to all documents priority = 0; // Highest priority - check files exist first defaultEnabled = true; constructor(documentsBasePath = 'generated-documents') { this.documentsBasePath = documentsBasePath; } isApplicable(documentTypes) { // File existence should always be checked regardless of document types return true; } getConfigSchema() { return {}; } async validate(config) { const startTime = Date.now(); const issues = []; const strengths = []; const recommendations = []; let score = 100; const maxScore = 100; console.log('📁 Validating file existence...'); // Check if base documents directory exists try { await fs.access(this.documentsBasePath); strengths.push('Documents directory exists'); } catch (error) { issues.push(`Documents directory '${this.documentsBasePath}' does not exist`); score = 0; return { validatorId: this.id, validatorName: this.name, passed: false, score, maxScore, issues, strengths, severity: 'critical', recommendations: ['Ensure document generation has completed successfully'], executionTimeMs: Date.now() - startTime, metadata: { basePathMissing: true } }; } // Expected core PMBOK documents const expectedDocuments = [ 'project-charter/project-charter.md', 'stakeholder-management/stakeholder-register.md', 'scope-management/project-scope-statement.md', 'strategic-statements/mission-vision-core-values.md' ]; let foundDocuments = 0; const missingDocuments = []; for (const docPath of expectedDocuments) { const fullPath = path.join(this.documentsBasePath, docPath); try { await fs.access(fullPath); foundDocuments++; strengths.push(`Found: ${docPath}`); } catch (error) { missingDocuments.push(docPath); issues.push(`Missing document: ${docPath}`); } } // Calculate score based on found documents score = Math.round((foundDocuments / expectedDocuments.length) * 100); // Add recommendations for missing documents if (missingDocuments.length > 0) { recommendations.push(`Generate missing documents: ${missingDocuments.join(', ')}`); recommendations.push('Check document generation logs for errors'); } // Check for additional documents that exist try { const allFiles = await this.findAllMarkdownFiles(this.documentsBasePath); if (allFiles.length > expectedDocuments.length) { strengths.push(`Found ${allFiles.length} total documents (${allFiles.length - expectedDocuments.length} additional)`); } } catch (error) { // Non-critical error } const passed = score >= 80; // 80% threshold for file existence return { validatorId: this.id, validatorName: this.name, passed, score, maxScore, issues, strengths, severity: missingDocuments.length > 2 ? 'critical' : missingDocuments.length > 0 ? 'warning' : 'info', recommendations, executionTimeMs: Date.now() - startTime, metadata: { expectedCount: expectedDocuments.length, foundCount: foundDocuments, missingDocuments, documentsBasePath: this.documentsBasePath } }; } /** * Recursively find all markdown files in the documents directory */ async findAllMarkdownFiles(dir) { const files = []; try { const entries = await fs.readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { const subFiles = await this.findAllMarkdownFiles(fullPath); files.push(...subFiles); } else if (entry.name.endsWith('.md')) { files.push(path.relative(this.documentsBasePath, fullPath)); } } } catch (error) { // Directory might not be accessible } return files; } } //# sourceMappingURL=FileExistenceValidator.js.map