Shatteredvoid/config/startup.config.js
MegaProxy e681c446b6 feat: implement comprehensive startup system and fix authentication
Major improvements:
- Created startup orchestration system with health monitoring and graceful shutdown
- Fixed user registration and login with simplified authentication flow
- Rebuilt authentication forms from scratch with direct API integration
- Implemented comprehensive debugging and error handling
- Added Redis fallback functionality for disabled environments
- Fixed CORS configuration for cross-origin frontend requests
- Simplified password validation to 6+ characters (removed complexity requirements)
- Added toast notifications at app level for better UX feedback
- Created comprehensive startup/shutdown scripts with OODA methodology
- Fixed database validation and connection issues
- Implemented TokenService memory fallback when Redis is disabled

Technical details:
- New SimpleLoginForm.tsx and SimpleRegisterForm.tsx components
- Enhanced CORS middleware with additional allowed origins
- Simplified auth validators and removed strict password requirements
- Added extensive logging and diagnostic capabilities
- Fixed authentication middleware token validation
- Implemented graceful Redis error handling throughout the stack
- Created modular startup system with configurable health checks

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-03 12:53:25 +00:00

380 lines
No EOL
9 KiB
JavaScript

/**
* Shattered Void MMO - Startup Configuration
*
* Central configuration file for the startup system, allowing easy customization
* of startup behavior, timeouts, and service settings.
*/
const path = require('path');
/**
* Default startup configuration
*/
const defaultConfig = {
// Environment settings
environment: {
mode: process.env.NODE_ENV || 'development',
logLevel: process.env.LOG_LEVEL || 'info',
enableDebug: process.env.NODE_ENV === 'development'
},
// Backend server configuration
backend: {
port: parseInt(process.env.PORT) || 3000,
host: process.env.HOST || '0.0.0.0',
script: 'src/server.js',
startupTimeout: 30000,
healthEndpoint: '/health',
gracefulShutdownTimeout: 10000
},
// Frontend configuration
frontend: {
enabled: process.env.ENABLE_FRONTEND !== 'false',
port: parseInt(process.env.FRONTEND_PORT) || 5173,
host: process.env.FRONTEND_HOST || '0.0.0.0',
directory: './frontend',
buildDirectory: './frontend/dist',
startupTimeout: 45000,
buildTimeout: 120000,
devCommand: 'dev',
buildCommand: 'build',
previewCommand: 'preview'
},
// Database configuration
database: {
enabled: process.env.DISABLE_DATABASE !== 'true',
connectionTimeout: 10000,
migrationTimeout: 60000,
seedTimeout: 30000,
autoMigrate: process.env.AUTO_MIGRATE !== 'false',
autoSeed: process.env.AUTO_SEED === 'true',
integrityChecks: process.env.SKIP_DB_INTEGRITY !== 'true',
retryAttempts: 3,
retryDelay: 2000
},
// Redis configuration
redis: {
enabled: process.env.DISABLE_REDIS !== 'true',
optional: true,
connectionTimeout: 5000,
retryAttempts: 3,
retryDelay: 1000,
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT) || 6379
},
// Health monitoring configuration
healthMonitoring: {
enabled: process.env.ENABLE_HEALTH_MONITORING !== 'false',
interval: parseInt(process.env.HEALTH_CHECK_INTERVAL) || 30000,
timeout: 5000,
alertThresholds: {
responseTime: 5000,
memoryUsage: 80,
cpuUsage: 90,
errorRate: 10,
consecutiveFailures: 3
},
systemMetricsInterval: 10000,
historySize: 100
},
// Startup process configuration
startup: {
maxRetries: parseInt(process.env.STARTUP_MAX_RETRIES) || 3,
retryDelay: parseInt(process.env.STARTUP_RETRY_DELAY) || 2000,
enableBanner: process.env.DISABLE_BANNER !== 'true',
enableColors: process.env.DISABLE_COLORS !== 'true',
verboseLogging: process.env.VERBOSE_STARTUP === 'true',
failFast: process.env.FAIL_FAST === 'true',
gracefulShutdown: true
},
// Pre-flight checks configuration
preflightChecks: {
enabled: process.env.SKIP_PREFLIGHT !== 'true',
timeout: 30000,
required: {
nodeVersion: true,
npmAvailability: true,
environmentConfig: true,
directoryStructure: true,
packageDependencies: true,
portAvailability: true,
databaseConfig: true,
logDirectories: true,
filePermissions: true,
systemMemory: true,
diskSpace: true
},
optional: {
redisConfig: true,
frontendDependencies: true
},
requirements: {
nodeMinVersion: 18,
memoryMinGB: 1,
diskSpaceMaxUsage: 90
}
},
// Logging configuration
logging: {
level: process.env.LOG_LEVEL || 'info',
colorize: process.env.DISABLE_COLORS !== 'true',
timestamp: true,
includeProcessId: true,
startupLog: true,
errorStackTrace: process.env.NODE_ENV === 'development'
},
// Performance configuration
performance: {
measureStartupTime: true,
measurePhaseTime: true,
memoryMonitoring: true,
cpuMonitoring: process.env.NODE_ENV === 'development',
performanceReporting: process.env.PERFORMANCE_REPORTING === 'true'
},
// Security configuration
security: {
hidePasswords: true,
sanitizeEnvironment: true,
validatePorts: true,
checkFilePermissions: true
},
// Development specific settings
development: {
hotReload: true,
autoRestart: process.env.AUTO_RESTART === 'true',
debugEndpoints: process.env.ENABLE_DEBUG_ENDPOINTS === 'true',
verboseErrors: true,
showDeprecations: true
},
// Production specific settings
production: {
compressionEnabled: true,
cachingEnabled: true,
minifyAssets: true,
enableCDN: process.env.ENABLE_CDN === 'true',
healthEndpoints: true,
metricsCollection: true
},
// Service dependencies
dependencies: {
required: ['database'],
optional: ['redis', 'frontend'],
order: ['database', 'redis', 'backend', 'frontend', 'healthMonitoring']
},
// Error handling
errorHandling: {
retryFailedServices: true,
continueOnOptionalFailure: true,
detailedErrorMessages: process.env.NODE_ENV === 'development',
errorNotifications: process.env.ERROR_NOTIFICATIONS === 'true',
crashReporting: process.env.CRASH_REPORTING === 'true'
},
// Paths and directories
paths: {
root: process.cwd(),
src: path.join(process.cwd(), 'src'),
config: path.join(process.cwd(), 'config'),
logs: path.join(process.cwd(), 'logs'),
scripts: path.join(process.cwd(), 'scripts'),
frontend: path.join(process.cwd(), 'frontend'),
database: path.join(process.cwd(), 'src', 'database'),
migrations: path.join(process.cwd(), 'src', 'database', 'migrations'),
seeds: path.join(process.cwd(), 'src', 'database', 'seeds')
}
};
/**
* Environment-specific configurations
*/
const environmentConfigs = {
development: {
backend: {
startupTimeout: 20000
},
frontend: {
startupTimeout: 30000
},
database: {
integrityChecks: false,
autoSeed: true
},
healthMonitoring: {
interval: 15000
},
logging: {
level: 'debug'
},
startup: {
verboseLogging: true,
failFast: false
}
},
production: {
backend: {
startupTimeout: 45000
},
frontend: {
enabled: false // Assume pre-built assets are served by nginx/CDN
},
database: {
integrityChecks: true,
autoSeed: false,
retryAttempts: 5
},
healthMonitoring: {
interval: 60000,
alertThresholds: {
responseTime: 3000,
memoryUsage: 85,
cpuUsage: 85
}
},
logging: {
level: 'warn'
},
startup: {
verboseLogging: false,
failFast: true
},
errorHandling: {
retryFailedServices: true,
continueOnOptionalFailure: false
}
},
staging: {
backend: {
startupTimeout: 30000
},
database: {
integrityChecks: true,
autoSeed: true
},
healthMonitoring: {
interval: 30000
},
logging: {
level: 'info'
}
},
testing: {
backend: {
port: 0, // Use random available port
startupTimeout: 10000
},
frontend: {
enabled: false
},
database: {
autoMigrate: true,
autoSeed: true,
integrityChecks: false
},
healthMonitoring: {
enabled: false
},
preflightChecks: {
enabled: false
},
startup: {
enableBanner: false,
verboseLogging: false
}
}
};
/**
* Merge configurations based on environment
*/
function mergeConfigs(base, override) {
const result = { ...base };
for (const [key, value] of Object.entries(override)) {
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
result[key] = mergeConfigs(result[key] || {}, value);
} else {
result[key] = value;
}
}
return result;
}
/**
* Get configuration for current environment
*/
function getConfig() {
const environment = process.env.NODE_ENV || 'development';
const envConfig = environmentConfigs[environment] || {};
return mergeConfigs(defaultConfig, envConfig);
}
/**
* Validate configuration
*/
function validateConfig(config) {
const errors = [];
// Validate ports
if (config.backend.port < 1 || config.backend.port > 65535) {
errors.push(`Invalid backend port: ${config.backend.port}`);
}
if (config.frontend.enabled && (config.frontend.port < 1 || config.frontend.port > 65535)) {
errors.push(`Invalid frontend port: ${config.frontend.port}`);
}
// Validate timeouts
if (config.backend.startupTimeout < 1000) {
errors.push('Backend startup timeout too low (minimum 1000ms)');
}
if (config.database.connectionTimeout < 1000) {
errors.push('Database connection timeout too low (minimum 1000ms)');
}
// Validate required paths
const requiredPaths = ['root', 'src', 'config'];
for (const pathKey of requiredPaths) {
if (!config.paths[pathKey]) {
errors.push(`Missing required path: ${pathKey}`);
}
}
if (errors.length > 0) {
throw new Error(`Configuration validation failed:\n${errors.join('\n')}`);
}
return true;
}
/**
* Export configuration
*/
const config = getConfig();
validateConfig(config);
module.exports = {
config,
getConfig,
validateConfig,
defaultConfig,
environmentConfigs
};