All files / src/core ConfigurationResolver.js

100% Statements 38/38
100% Branches 14/14
100% Functions 9/9
100% Lines 36/36

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 1134x               21x             20x     20x 20x     18x     6x     6x   6x   14x 14x               18x                     144x   18x 9x       9x 1x     8x 16x   8x 2x               6x 6x 6x 6x 6x 6x 6x             4x 1x   3x             2x 1x   1x             5x       4x
const fs = require('fs').promises;
 
/**
 * ConfigurationResolver - Handles runtime configuration loading and validation
 * Manages deployment-specific settings from terraform-generated config files
 */
class ConfigurationResolver {
    constructor() {
        this.config = null;
    }
 
    /**
     * Load and validate runtime configuration from deployment
     */
    async loadConfiguration() {
        try {
            // Load runtime configuration created during deployment
            // This file contains Discord IDs, tokens, and channel mappings specific to this deployment
            console.log('Loading runtime configuration...');
            const runtimeConfig = JSON.parse(await fs.readFile('runtime.config.json', 'utf8'));
            
            // Validate required configuration fields
            this.validateConfiguration(runtimeConfig);
            
            // Store validated configuration
            this.config = runtimeConfig;
            
            // Log configuration summary for verification
            this.logConfigurationSummary(runtimeConfig);
            
            return runtimeConfig;
        } catch (error) {
            console.error('Failed to load runtime configuration:', error);
            throw error;
        }
    }
 
    /**
     * Validate that all required configuration fields are present
     */
    validateConfiguration(config) {
        const requiredFields = [
            'guildId',
            'botToken', 
            'moderatorRoleId',
            'memberRoleId',
            'commandChannelId',
            'memberCommandChannelId',
            'dynamodbTable',
            'eventsTable'
        ];
 
        const missingFields = requiredFields.filter(field => !config[field]);
        
        if (missingFields.length > 0) {
            throw new Error(`Missing required configuration fields: ${missingFields.join(', ')}`);
        }
 
        // Validate reminder intervals
        if (!config.reminderIntervals) {
            throw new Error('Reminder intervals not configured in runtime config');
        }
 
        const requiredIntervals = ['weekReminder', 'dayReminder'];
        const missingIntervals = requiredIntervals.filter(interval => !config.reminderIntervals[interval]);
        
        if (missingIntervals.length > 0) {
            throw new Error(`Missing reminder intervals: ${missingIntervals.join(', ')}`);
        }
    }
 
    /**
     * Log configuration summary for deployment verification
     */
    logConfigurationSummary(config) {
        console.log(`Guild ID: ${config.guildId}`);
        console.log(`Bot Run ID: ${config.runId || 'unknown'}`);
        console.log(`Moderator Command Channel ID: ${config.commandChannelId}`);
        console.log(`Member Command Channel ID: ${config.memberCommandChannelId}`);
        console.log(`Proposal config loaded with types:`, Object.keys(config.proposalConfig || {}));
        console.log(`Event management table: ${config.eventsTable}`);
        console.log(`Reminder intervals: ${config.reminderIntervals.weekReminder/60000}min, ${config.reminderIntervals.dayReminder/60000}min`);
    }
 
    /**
     * Get a specific configuration value
     */
    get(key) {
        if (!this.config) {
            throw new Error('Configuration not loaded');
        }
        return this.config[key];
    }
 
    /**
     * Get the full configuration object
     */
    getAll() {
        if (!this.config) {
            throw new Error('Configuration not loaded');
        }
        return this.config;
    }
 
    /**
     * Check if configuration is loaded
     */
    isLoaded() {
        return this.config !== null;
    }
}
 
module.exports = ConfigurationResolver;