All files / src/core ComponentOrchestrator.js

100% Statements 39/39
100% Branches 8/8
100% Functions 8/8
100% Lines 39/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 1154x 4x 4x 4x 4x 4x               27x 27x                 22x 22x 22x 22x 22x 22x     22x   22x             9x     9x 8x       8x         6x       6x 5x 5x     4x 4x                 20x 20x 20x 20x 20x 20x             2x             1x             7x               5x 2x     5x       4x
const ConfigManager = require('../managers/ConfigManager');
const EventHandlers = require('../handlers/EventHandlers');
const CommandRouter = require('../handlers/CommandRouter');
const UserValidator = require('../validators/UserValidator');
const ProposalManager = require('../managers/ProposalManager');
const EventManager = require('../managers/EventManager');
 
/**
 * ComponentOrchestrator - Manages initialization and dependencies of specialized modules
 * Ensures proper dependency injection and initialization order
 */
class ComponentOrchestrator {
    constructor(bot) {
        this.bot = bot;
        this.components = {};
    }
 
    /**
     * Initialize all specialized components in the correct order
     */
    initializeComponents() {
        // Initialize specialized modules - each handles a specific bot responsibility
        // This separation keeps concerns isolated and makes the code more maintainable
        this.components.configManager = new ConfigManager();        // S3-backed reaction configuration
        this.components.userValidator = new UserValidator();        // Permission and eligibility checks
        this.components.proposalManager = new ProposalManager(this.bot); // Community governance system
        this.components.eventHandlers = new EventHandlers(this.bot);    // Discord event processing
        this.components.commandRouter = new CommandRouter(this.bot);     // Bot command routing to specialized handlers
        this.components.eventManager = null;                         // Event system (initialized later with config)
 
        // Attach components to bot for easy access
        this.attachComponentsToBot();
 
        console.log('✅ All components initialized successfully');
    }
 
    /**
     * Initialize components that require runtime configuration
     */
    async initializeConfigurableComponents(runtimeConfig) {
        try {
            // Initialize launch-time reaction role configuration
            // Reaction role configurations are provided via runtime config and stored in memory only
            await this.components.configManager.initialize(runtimeConfig.reactionRoleConfig || []);
            console.log('✅ Config manager initialized');
 
            // Initialize community proposal/voting system with DynamoDB storage
            // This enables democratic governance features with hybrid storage approach
            await this.components.proposalManager.initialize(
                runtimeConfig.dynamodbTable,
                runtimeConfig.guildId,
                runtimeConfig.proposalConfig
            );
            console.log('✅ Proposal manager initialized');
 
            // Initialize event management system with DynamoDB storage
            // This enables community event planning and notification features
            this.components.eventManager = new EventManager(this.bot);
            this.bot.eventManager = this.components.eventManager;
            console.log(`✅ Event management system initialized with table: ${runtimeConfig.eventsTable}`);
 
        } catch (error) {
            console.error('❌ Failed to initialize configurable components:', error);
            throw error;
        }
    }
 
    /**
     * Attach components to bot instance for easy access
     */
    attachComponentsToBot() {
        // Attach components to bot for access by other modules
        this.bot.configManager = this.components.configManager;
        this.bot.userValidator = this.components.userValidator;
        this.bot.proposalManager = this.components.proposalManager;
        this.bot.eventHandlers = this.components.eventHandlers;
        this.bot.commandRouter = this.components.commandRouter;
        this.bot.eventManager = this.components.eventManager;
    }
 
    /**
     * Get a specific component
     */
    getComponent(name) {
        return this.components[name];
    }
 
    /**
     * Get all components
     */
    getAllComponents() {
        return this.components;
    }
 
    /**
     * Check if a component is initialized
     */
    isComponentInitialized(name) {
        return this.components[name] !== null && this.components[name] !== undefined;
    }
 
    /**
     * Clean up all components
     */
    async cleanup() {
        // Cleanup event manager if it exists
        if (this.components.eventManager && typeof this.components.eventManager.cleanup === 'function') {
            this.components.eventManager.cleanup();
        }
 
        console.log('✅ Components cleaned up');
    }
}
 
module.exports = ComponentOrchestrator;