- Delete unused dataMerger, formatter, Device model, dead service exports, and the empty agents/ + .gitkeep placeholders. - Extract STORE_MODES and MDM device-type filters into a shared constants.js. - Anchor bot regexes (^help|^store|^analyze) so "analyze store 305" no longer fires both handlers; replace catch-all noise. - Hoist inline require() calls in integrations to top-of-file imports. - Harden WebSocket server: Authorization header support, single-agent enforcement, bounded pending requests, server-level error handler, coalesced cache refresh in Meraki client. - Wrap Meraki/MDM network calls with withRetry; add request timeouts. - Migrate all console.* calls onto utils/logger.js (LOG_LEVEL aware); drive Webex framework logLevel from env. - Refactor storeDetail.js: shared renderClientLine + buildMdmSection helpers cut duplication roughly in half. - Refresh README structure, document LOG_LEVEL, add npm run agent script, add jest testMatch + new tests (handlers, HealthReport, Store, ws). Verified: npm run lint clean, 7 suites / 31 tests passing. Co-authored-by: Cursor <cursoragent@cursor.com>
85 lines
2.5 KiB
JavaScript
85 lines
2.5 KiB
JavaScript
require('dotenv').config();
|
|
const logger = require('../utils/logger');
|
|
|
|
/**
|
|
* Required environment variables for core operation.
|
|
* The app will refuse to start if these are missing.
|
|
*/
|
|
const REQUIRED_ENV_VARS = ['WEBEX_ACCESS_TOKEN', 'MERAKI_API_KEY', 'MERAKI_ORG_ID', 'WS_TOKEN'];
|
|
|
|
/**
|
|
* Recommended environment variables for full functionality.
|
|
* Warnings will be logged but startup will continue.
|
|
*/
|
|
const RECOMMENDED_ENV_VARS = [
|
|
'SIW_BASE_URL',
|
|
'SIW_USERNAME',
|
|
'SIW_PASSWORD',
|
|
'WS1_BASE_URL',
|
|
'WS1_TOKEN_URL',
|
|
'WS1_CLIENT_ID',
|
|
'WS1_CLIENT_SECRET',
|
|
'WS1_TENANT_CODE',
|
|
];
|
|
|
|
function validateEnvironment() {
|
|
const missingRequired = REQUIRED_ENV_VARS.filter(
|
|
key => !process.env[key] || process.env[key].trim() === ''
|
|
);
|
|
const missingRecommended = RECOMMENDED_ENV_VARS.filter(
|
|
key => !process.env[key] || process.env[key].trim() === ''
|
|
);
|
|
|
|
if (missingRequired.length > 0) {
|
|
logger.error('Missing required environment variables', { missing: missingRequired });
|
|
throw new Error(`Missing required environment variables: ${missingRequired.join(', ')}`);
|
|
}
|
|
|
|
if (missingRecommended.length > 0) {
|
|
logger.warn('Optional environment variables not set; some features may be limited', {
|
|
missing: missingRecommended,
|
|
});
|
|
}
|
|
|
|
const wsPort = parseInt(process.env.WS_PORT, 10);
|
|
if (process.env.WS_PORT && (isNaN(wsPort) || wsPort < 1 || wsPort > 65535)) {
|
|
throw new Error('WS_PORT must be a valid port number between 1 and 65535');
|
|
}
|
|
|
|
logger.info('Environment validation passed');
|
|
}
|
|
|
|
// Skip validation when running unit tests so tests don't require a fully
|
|
// populated .env. Integration tests can opt in by unsetting JEST_WORKER_ID.
|
|
if (!process.env.JEST_WORKER_ID) {
|
|
validateEnvironment();
|
|
}
|
|
|
|
module.exports = {
|
|
logLevel: process.env.LOG_LEVEL || 'info',
|
|
webex: {
|
|
token: process.env.WEBEX_ACCESS_TOKEN,
|
|
name: process.env.BOT_NAME || 'NetAnalyzer',
|
|
},
|
|
meraki: {
|
|
baseUrl: 'https://api.meraki.com/api/v1',
|
|
apiKey: process.env.MERAKI_API_KEY,
|
|
orgId: process.env.MERAKI_ORG_ID,
|
|
},
|
|
ws: {
|
|
port: parseInt(process.env.WS_PORT) || 8080,
|
|
token: process.env.WS_TOKEN,
|
|
},
|
|
siw: {
|
|
baseUrl: process.env.SIW_BASE_URL,
|
|
username: process.env.SIW_USERNAME,
|
|
password: process.env.SIW_PASSWORD,
|
|
},
|
|
mdm: {
|
|
baseUrl: process.env.WS1_BASE_URL,
|
|
tokenUrl: process.env.WS1_TOKEN_URL,
|
|
clientId: process.env.WS1_CLIENT_ID,
|
|
clientSecret: process.env.WS1_CLIENT_SECRET,
|
|
tenantCode: process.env.WS1_TENANT_CODE,
|
|
},
|
|
};
|