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

478 lines 20.3 kB
/** * Enhanced Batch Processor for Phase 2 * * Orchestrates the complete Adobe Creative Suite pipeline for * batch processing of documents with professional layouts, * visualizations, and multi-format output. */ import { promises as fs } from 'fs'; import path from 'path'; import { InDesignAPIClient } from './indesign-client.js'; import { IllustratorAPIClient } from './illustrator-client.js'; import { PhotoshopAPIClient } from './photoshop-client.js'; import { DocumentGenerationAPIClient } from './document-generation-client.js'; import { brandGuidelines } from './brand-guidelines.js'; export class EnhancedBatchProcessor { indesignClient; illustratorClient; photoshopClient; documentGenClient; constructor() { this.indesignClient = new InDesignAPIClient(); this.illustratorClient = new IllustratorAPIClient(); this.photoshopClient = new PhotoshopAPIClient(); this.documentGenClient = new DocumentGenerationAPIClient(); } /** * Initialize all Adobe Creative Suite clients */ async initialize() { await Promise.all([ this.indesignClient.initialize(), this.illustratorClient.initialize(), this.photoshopClient.initialize(), this.documentGenClient.initialize() ]); } /** * Process batch of documents with enhanced Adobe Creative Suite pipeline */ async processBatch(request) { const startTime = Date.now(); const results = []; const errors = []; const performance = { analysisTime: 0, templateSelectionTime: 0, indesignProcessingTime: 0, illustratorProcessingTime: 0, photoshopProcessingTime: 0, outputGenerationTime: 0, memoryUsage: { peak: 0, average: 0 } }; try { // 1. Discover and filter documents const documents = await this.discoverDocuments(request); console.log(`Found ${documents.length} documents to process`); // 2. Create output directory structure await this.createOutputStructure(request); // 3. Process documents in batches for (let i = 0; i < documents.length; i += request.options.concurrency) { const batch = documents.slice(i, i + request.options.concurrency); const batchPromises = batch.map(doc => this.processDocument(doc, request, performance)); const batchResults = await Promise.allSettled(batchPromises); batchResults.forEach((result, index) => { if (result.status === 'fulfilled') { results.push(result.value); } else { errors.push({ file: batch[index], error: result.reason.message, stage: 'analysis', timestamp: new Date() }); } }); // Progress report const processed = Math.min(i + request.options.concurrency, documents.length); console.log(`Processed ${processed}/${documents.length} documents (${Math.round(processed / documents.length * 100)}%)`); } // 4. Generate batch summary const summary = this.generateSummary(results, errors, startTime); return { processedFiles: results, summary, errors, performance }; } catch (error) { console.error('Batch processing failed:', error); throw new Error(`Batch processing failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Process a single document through the enhanced pipeline */ async processDocument(documentPath, request, performance) { const docStartTime = Date.now(); const outputs = []; try { // 1. Analyze document content const analysisStart = Date.now(); const analysis = await this.analyzeDocument(documentPath); performance.analysisTime += Date.now() - analysisStart; // 2. Select template const templateStart = Date.now(); const template = await this.selectTemplate(analysis, request.options.templateSelection); performance.templateSelectionTime += Date.now() - templateStart; // 3. Generate visualizations if enabled if (request.options.enableDataVisualization && analysis.visualizableData) { const illustratorStart = Date.now(); const visualizations = await this.generateVisualizations(analysis.visualizableData); performance.illustratorProcessingTime += Date.now() - illustratorStart; visualizations.forEach(viz => { outputs.push({ type: 'illustrator', filePath: viz.outputPath, fileSize: viz.fileSize, format: viz.format, metadata: viz.metadata }); }); } // 4. Enhance images if enabled if (request.options.enableImageEnhancement && analysis.images.length > 0) { const photoshopStart = Date.now(); const enhancedImages = await this.enhanceImages(analysis.images); performance.photoshopProcessingTime += Date.now() - photoshopStart; enhancedImages.forEach(img => { outputs.push({ type: 'photoshop', filePath: img.outputPath, fileSize: img.fileSize, format: img.format, metadata: img.metadata }); }); } // 5. Generate professional layouts if enabled if (request.options.enableInDesignLayouts) { const indesignStart = Date.now(); const layoutDoc = await this.generateInDesignLayout(documentPath, analysis, template); performance.indesignProcessingTime += Date.now() - indesignStart; outputs.push({ type: 'indesign', filePath: layoutDoc.outputPath, fileSize: layoutDoc.fileSize, format: layoutDoc.format, metadata: layoutDoc.metadata }); } // 6. Generate multi-format outputs if enabled if (request.options.enableMultiFormat) { const outputStart = Date.now(); const multiFormatOutputs = await this.generateMultiFormatOutputs(documentPath, analysis, request.options.outputFormats); performance.outputGenerationTime += Date.now() - outputStart; outputs.push(...multiFormatOutputs); } const processingTime = Date.now() - docStartTime; const qualityScore = this.calculateQualityScore(analysis, outputs); return { sourceFile: documentPath, analysis, outputs, processingTime, qualityScore }; } catch (error) { console.error(`Failed to process document ${documentPath}:`, error); throw error; } } /** * Analyze document content and structure */ async analyzeDocument(filePath) { const content = await fs.readFile(filePath, 'utf-8'); // Document type detection const documentType = this.detectDocumentType(content, filePath); // Content structure analysis const contentStructure = this.analyzeContentStructure(content); // Extract visualizable data const visualizableData = await this.extractVisualizableData(content); // Find referenced images const images = this.findImages(content, path.dirname(filePath)); // Assess complexity const complexity = this.assessComplexity(contentStructure); // Recommend template const recommendedTemplate = this.recommendTemplate(documentType, contentStructure); // Estimate processing time const estimatedProcessingTime = this.estimateProcessingTime(contentStructure, complexity); return { filePath, documentType, contentStructure, visualizableData, images, complexity, recommendedTemplate, estimatedProcessingTime }; } /** * Generate data visualizations from extracted data */ async generateVisualizations(data) { const visualizations = []; const guidelines = await brandGuidelines.getGuidelines(); const style = { colorScheme: guidelines.visualizations.charts.colorPalette, fontFamily: guidelines.typography.body.fontFamily, theme: 'corporate', branding: { primaryColor: guidelines.colors.primary, secondaryColor: guidelines.colors.secondary, accentColor: guidelines.colors.accent } }; // Generate timelines for (const timeline of data.timelines) { const viz = await this.illustratorClient.generateTimeline(timeline, style); visualizations.push(viz); } // Generate charts for (const chart of data.charts) { const viz = await this.illustratorClient.generateChart(chart, style); visualizations.push(viz); } // Generate process flows for (const process of data.processes) { const viz = await this.illustratorClient.generateProcessFlow(process, style); visualizations.push(viz); } return visualizations; } /** * Enhance images for professional presentation */ async enhanceImages(imagePaths) { return this.photoshopClient.enhanceDocumentImages(imagePaths, 'standard'); } /** * Generate professional InDesign layout */ async generateInDesignLayout(documentPath, analysis, template) { const content = await fs.readFile(documentPath, 'utf-8'); const guidelines = await brandGuidelines.getGuidelines(); const request = { templateId: template, content: { title: this.extractTitle(content), author: 'Generated by Adobe Creative Suite', date: new Date(), sections: this.convertToSections(content), metadata: { sourceFile: documentPath } }, branding: { colorScheme: 'corporate', typography: { headingFont: guidelines.typography.headings.fontFamily, bodyFont: guidelines.typography.body.fontFamily, codeFont: guidelines.typography.monospace.fontFamily, lineHeight: guidelines.typography.body.lineHeight, margins: { top: guidelines.layout.margins.page, right: guidelines.layout.margins.page, bottom: guidelines.layout.margins.page, left: guidelines.layout.margins.page } } }, outputOptions: { format: 'pdf', quality: 'high' } }; return this.indesignClient.createDocument(request); } // Private helper methods async discoverDocuments(request) { const documents = []; const entries = await fs.readdir(request.sourceDirectory, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(request.sourceDirectory, entry.name); if (entry.isFile() && entry.name.endsWith('.md')) { if (this.passesFilters(fullPath, request.filters)) { documents.push(fullPath); } } else if (entry.isDirectory() && request.options.preserveDirectoryStructure) { const subRequest = { ...request, sourceDirectory: fullPath }; const subDocuments = await this.discoverDocuments(subRequest); documents.push(...subDocuments); } } return documents; } passesFilters(filePath, filters) { if (!filters) return true; // Include patterns if (filters.includePatterns?.length > 0) { const passes = filters.includePatterns.some(pattern => filePath.includes(pattern) || path.basename(filePath).includes(pattern)); if (!passes) return false; } // Exclude patterns if (filters.excludePatterns?.length > 0) { const excluded = filters.excludePatterns.some(pattern => filePath.includes(pattern) || path.basename(filePath).includes(pattern)); if (excluded) return false; } return true; } detectDocumentType(content, filePath) { const fileName = path.basename(filePath).toLowerCase(); const lowerContent = content.toLowerCase(); if (fileName.includes('charter') || lowerContent.includes('project charter')) { return 'project-charter'; } if (fileName.includes('requirements') || lowerContent.includes('requirements')) { return 'requirements-doc'; } if (fileName.includes('management') || lowerContent.includes('management plan')) { return 'management-plan'; } if (fileName.includes('technical') || lowerContent.includes('technical specification')) { return 'technical-spec'; } return 'unknown'; } analyzeContentStructure(content) { const lines = content.split('\n'); return { hasTitle: /^#\s/.test(lines[0] || ''), hasTOC: content.includes('Table of Contents') || content.includes('## Contents'), sectionCount: (content.match(/^##\s/gm) || []).length, tableCount: (content.match(/\|.*\|/g) || []).length / 3, // Rough estimate imageCount: (content.match(/!\[.*\]\(/g) || []).length, codeBlockCount: (content.match(/```/g) || []).length / 2, listCount: (content.match(/^[-*+]\s/gm) || []).length, headingLevels: [...new Set((content.match(/^#{1,6}\s/gm) || []).map(h => h.length - 1))] }; } async extractVisualizableData(content) { // Phase 2: Implement intelligent data extraction return { timelines: [], charts: [], processes: [], matrices: [] }; } findImages(content, baseDir) { const imageRegex = /!\[.*?\]\((.*?)\)/g; const images = []; let match; while ((match = imageRegex.exec(content)) !== null) { const imagePath = match[1]; if (!imagePath.startsWith('http')) { images.push(path.resolve(baseDir, imagePath)); } } return images; } assessComplexity(structure) { const score = structure.sectionCount + structure.tableCount + structure.imageCount + structure.codeBlockCount; if (score <= 5) return 'simple'; if (score <= 15) return 'moderate'; return 'complex'; } recommendTemplate(documentType, structure) { switch (documentType) { case 'project-charter': return 'project-charter-template'; case 'requirements-doc': return 'requirements-doc-template'; case 'management-plan': return 'management-plan-template'; case 'technical-spec': return 'technical-spec-template'; default: return structure.hasTitle && structure.sectionCount > 0 ? 'general-document-template' : 'simple-document-template'; } } estimateProcessingTime(structure, complexity) { let baseTime = 30000; // 30 seconds base baseTime += structure.sectionCount * 2000; // 2s per section baseTime += structure.tableCount * 3000; // 3s per table baseTime += structure.imageCount * 5000; // 5s per image if (complexity === 'complex') baseTime *= 1.5; return baseTime; } async selectTemplate(analysis, mode) { if (mode === 'auto') { return analysis.recommendedTemplate; } // Phase 2: Implement manual template selection interface return analysis.recommendedTemplate; } async createOutputStructure(request) { await fs.mkdir(request.outputDirectory, { recursive: true }); if (request.options.preserveDirectoryStructure) { await fs.mkdir(path.join(request.outputDirectory, 'indesign'), { recursive: true }); await fs.mkdir(path.join(request.outputDirectory, 'visualizations'), { recursive: true }); await fs.mkdir(path.join(request.outputDirectory, 'enhanced-images'), { recursive: true }); await fs.mkdir(path.join(request.outputDirectory, 'multi-format'), { recursive: true }); } } async generateMultiFormatOutputs(documentPath, analysis, formats) { const outputs = []; // Phase 2: Implement multi-format generation for (const format of formats) { outputs.push({ type: 'pdf', filePath: documentPath.replace('.md', `.${format}`), fileSize: 1024000, format, metadata: { generated: new Date() } }); } return outputs; } calculateQualityScore(analysis, outputs) { let score = 50; // Base score // Structure quality if (analysis.contentStructure.hasTitle) score += 10; if (analysis.contentStructure.hasTOC) score += 10; if (analysis.contentStructure.sectionCount > 0) score += 10; // Output variety score += outputs.length * 5; // Complexity handling if (analysis.complexity === 'complex' && outputs.length > 2) score += 15; return Math.min(100, score); } generateSummary(results, errors, startTime) { const totalTime = Date.now() - startTime; const successCount = results.length; const totalFiles = successCount + errors.length; return { totalFiles, successfullyProcessed: successCount, failed: errors.length, skipped: 0, totalProcessingTime: totalTime, averageProcessingTime: successCount > 0 ? totalTime / successCount : 0, totalOutputSize: results.reduce((sum, r) => sum + r.outputs.reduce((s, o) => s + o.fileSize, 0), 0), templatesUsed: [...new Set(results.map(r => r.analysis.recommendedTemplate))], visualizationsGenerated: results.reduce((sum, r) => sum + r.outputs.filter(o => o.type === 'illustrator').length, 0), imagesEnhanced: results.reduce((sum, r) => sum + r.outputs.filter(o => o.type === 'photoshop').length, 0) }; } extractTitle(content) { const lines = content.split('\n'); const titleLine = lines.find(line => line.startsWith('#')); return titleLine ? titleLine.replace(/^#+\s*/, '') : 'Untitled Document'; } convertToSections(content) { // Phase 2: Convert markdown to structured sections return [{ id: '1', type: 'paragraph', content: content.substring(0, 1000) + '...' }]; } } export const enhancedBatchProcessor = new EnhancedBatchProcessor(); //# sourceMappingURL=enhanced-batch-processor.js.map