Source: compose/workflows/BaseWorkflow.js

/**
 * BaseWorkflow - Base class for all workflow components
 * 
 * This abstract base class provides common functionality and patterns for
 * workflow implementations. All workflow components should extend this class
 * and implement the execute() method.
 * 
 * API: execute(input, resources, options)
 */

import logger from 'loglevel';

export default class BaseWorkflow {
    constructor(workflowType = 'base') {
        this.workflowType = workflowType;
    }

    /**
     * Execute the workflow - must be implemented by subclasses
     * 
     * @param {Object} input - Workflow input data
     * @param {Object} resources - External dependencies
     * @param {Object} options - Configuration options
     * @returns {Promise<Object>} Workflow execution results
     */
    async execute(input, resources, options = {}) {
        throw new Error('execute() method must be implemented by subclass');
    }

    /**
     * Validate required input parameters
     * @protected
     */
    _validateInput(input, requiredFields = []) {
        for (const field of requiredFields) {
            if (!(field in input)) {
                throw new Error(`Required input field missing: ${field}`);
            }
        }
    }

    /**
     * Validate required resources
     * @protected
     */
    _validateResources(resources, requiredResources = []) {
        for (const resource of requiredResources) {
            if (!(resource in resources)) {
                throw new Error(`Required resource missing: ${resource}`);
            }
        }
    }

    /**
     * Create standard workflow result object
     * @protected
     */
    _createResult(success, data = {}, error = null, metadata = {}) {
        return {
            success,
            workflowType: this.workflowType,
            data,
            error,
            metadata: {
                timestamp: new Date().toISOString(),
                ...metadata
            }
        };
    }

    /**
     * Log workflow step with consistent formatting
     * @protected
     */
    _logStep(step, message, level = 'info') {
        const formattedMessage = `[${this.workflowType.toUpperCase()}] ${step}: ${message}`;
        logger[level](formattedMessage);
    }

    /**
     * Measure execution time for workflow steps
     * @protected
     */
    _measureTime(fn) {
        return async (...args) => {
            const start = Date.now();
            const result = await fn(...args);
            const duration = Date.now() - start;
            return { ...result, duration };
        };
    }

    /**
     * Handle errors with consistent format
     * @protected
     */
    _handleError(error, step = 'unknown') {
        const errorMessage = `${this.workflowType} workflow failed at step ${step}: ${error.message}`;
        logger.error(errorMessage);
        
        return this._createResult(false, {}, errorMessage, {
            errorStep: step,
            errorType: error.constructor.name
        });
    }

    /**
     * Merge configuration with defaults
     * @protected
     */
    _mergeConfig(options, defaults) {
        return {
            ...defaults,
            ...options
        };
    }

    /**
     * Extract and validate common resources
     * @protected
     */
    _extractCommonResources(resources) {
        const common = {};
        
        if (resources.llmHandler) {
            common.llmHandler = resources.llmHandler;
        }
        
        if (resources.sparqlHelper) {
            common.sparqlHelper = resources.sparqlHelper;
        }
        
        if (resources.config) {
            common.config = resources.config;
        }
        
        return common;
    }

    /**
     * Get workflow metadata for tracking
     * @protected
     */
    _getWorkflowMetadata(startTime, additionalMeta = {}) {
        return {
            workflowType: this.workflowType,
            startTime,
            duration: Date.now() - startTime,
            timestamp: new Date().toISOString(),
            ...additionalMeta
        };
    }
}