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
JavaScript
/**
* 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