netanalyzer/config/index.js
Joseph McQueen 0a46d25bd6 chore: project cleanup — dead code, logging, tests, WS hardening
- 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>
2026-06-24 17:21:22 -04:00

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,
},
};