first commit
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
const path = require('path');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
// Load environment variables
|
||||
require('dotenv').config();
|
||||
|
||||
const appConfig = {
|
||||
// Server Configuration
|
||||
server: {
|
||||
port: parseInt(process.env.PORT) || 8000,
|
||||
host: process.env.HOST || 'localhost',
|
||||
env: process.env.NODE_ENV || 'development',
|
||||
corsOrigin: process.env.CORS_ORIGIN || 'http://localhost:3000'
|
||||
},
|
||||
|
||||
// Database Configuration
|
||||
database: {
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
port: parseInt(process.env.DB_PORT) || 5432,
|
||||
name: process.env.DB_NAME || 'reason_flow',
|
||||
user: process.env.DB_USER || 'postgres',
|
||||
password: process.env.DB_PASSWORD,
|
||||
ssl: process.env.DB_SSL === 'true'
|
||||
},
|
||||
|
||||
// API Configuration
|
||||
apis: {
|
||||
groq: {
|
||||
apiKey: process.env.GROQ_API_KEY,
|
||||
model: process.env.GROQ_MODEL || 'moonshotai/kimi-k2-instruct-0905',
|
||||
baseUrl: process.env.GROQ_BASE_URL || 'https://api.groq.com'
|
||||
},
|
||||
openai: {
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
baseUrl: process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1'
|
||||
},
|
||||
serp: {
|
||||
apiKey: process.env.SERP_API_KEY,
|
||||
engine: process.env.SERP_ENGINE || 'google'
|
||||
}
|
||||
},
|
||||
|
||||
// Authentication Configuration
|
||||
auth: {
|
||||
jwtSecret: process.env.JWT_SECRET,
|
||||
jwtExpiresIn: process.env.JWT_EXPIRES_IN || '7d',
|
||||
adminEmail: process.env.ADMIN_EMAIL || 'admin@reasonflow.com',
|
||||
adminPassword: process.env.ADMIN_PASSWORD || 'admin123',
|
||||
adminFirstName: process.env.ADMIN_FIRST_NAME || 'Admin',
|
||||
adminLastName: process.env.ADMIN_LAST_NAME || 'User'
|
||||
},
|
||||
|
||||
// File Upload Configuration
|
||||
upload: {
|
||||
maxFileSize: process.env.MAX_FILE_SIZE || '50MB',
|
||||
uploadPath: process.env.UPLOAD_PATH || './uploads',
|
||||
allowedFileTypes: (process.env.ALLOWED_FILE_TYPES || 'pdf,txt,doc,docx').split(',')
|
||||
},
|
||||
|
||||
// Rate Limiting Configuration
|
||||
rateLimit: {
|
||||
enabled: process.env.RATE_LIMIT_ENABLED !== 'false',
|
||||
maxRequests: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 100,
|
||||
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 900000
|
||||
},
|
||||
|
||||
// Logging Configuration
|
||||
logging: {
|
||||
level: process.env.LOG_LEVEL || 'info',
|
||||
file: process.env.LOG_FILE || './logs/app.log',
|
||||
maxSize: process.env.LOG_MAX_SIZE || '10MB',
|
||||
maxFiles: parseInt(process.env.LOG_MAX_FILES) || 5
|
||||
},
|
||||
|
||||
// Model Configuration
|
||||
models: {
|
||||
model1: {
|
||||
temperature: parseFloat(process.env.MODEL1_TEMPERATURE) || 0.3,
|
||||
maxTokens: parseInt(process.env.MODEL1_MAX_TOKENS) || 3000
|
||||
},
|
||||
queryModel: {
|
||||
temperature: parseFloat(process.env.QUERYMODEL_TEMPERATURE) || 0.5,
|
||||
maxTokens: parseInt(process.env.QUERYMODEL_MAX_TOKENS) || 4000
|
||||
}
|
||||
},
|
||||
|
||||
// Fine-tuning Configuration
|
||||
fineTuning: {
|
||||
enabled: process.env.FINE_TUNING_ENABLED === 'true',
|
||||
schedule: process.env.FINE_TUNING_SCHEDULE || 'weekly',
|
||||
batchSize: parseInt(process.env.FINE_TUNING_BATCH_SIZE) || 10
|
||||
},
|
||||
|
||||
// Feedback Configuration
|
||||
feedback: {
|
||||
processingEnabled: process.env.FEEDBACK_PROCESSING_ENABLED === 'true',
|
||||
batchSize: parseInt(process.env.FEEDBACK_BATCH_SIZE) || 50,
|
||||
schedule: process.env.FEEDBACK_PROCESSING_SCHEDULE || 'daily'
|
||||
},
|
||||
|
||||
// Security Configuration
|
||||
security: {
|
||||
helmetEnabled: process.env.HELMET_ENABLED !== 'false',
|
||||
corsOrigin: process.env.CORS_ORIGIN || 'http://localhost:3000'
|
||||
},
|
||||
|
||||
// Monitoring Configuration
|
||||
monitoring: {
|
||||
healthCheckEnabled: process.env.HEALTH_CHECK_ENABLED !== 'false',
|
||||
metricsEnabled: process.env.METRICS_ENABLED === 'true',
|
||||
performanceMonitoring: process.env.PERFORMANCE_MONITORING === 'true'
|
||||
},
|
||||
|
||||
// Development Configuration
|
||||
development: {
|
||||
debugMode: process.env.DEBUG_MODE === 'true',
|
||||
verboseLogging: process.env.VERBOSE_LOGGING === 'true',
|
||||
hotReload: process.env.HOT_RELOAD === 'true'
|
||||
},
|
||||
|
||||
// Redis Configuration
|
||||
redis: {
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379',
|
||||
password: process.env.REDIS_PASSWORD
|
||||
},
|
||||
|
||||
// Vector Database Configuration
|
||||
vectorDb: {
|
||||
url: process.env.VECTOR_DB_URL,
|
||||
apiKey: process.env.VECTOR_DB_API_KEY
|
||||
}
|
||||
};
|
||||
|
||||
// Validation function
|
||||
const validateConfig = () => {
|
||||
const errors = [];
|
||||
const warnings = [];
|
||||
|
||||
// Required fields validation
|
||||
if (!appConfig.apis.groq.apiKey) {
|
||||
errors.push('GROQ_API_KEY is required');
|
||||
}
|
||||
|
||||
if (!appConfig.auth.jwtSecret) {
|
||||
errors.push('JWT_SECRET is required');
|
||||
}
|
||||
|
||||
if (!appConfig.database.password) {
|
||||
errors.push('DB_PASSWORD is required');
|
||||
}
|
||||
|
||||
// Production-specific validations
|
||||
if (appConfig.server.env === 'production') {
|
||||
if (appConfig.auth.jwtSecret === 'dev_secret_key_change_in_production') {
|
||||
errors.push('JWT_SECRET must be changed for production');
|
||||
}
|
||||
|
||||
if (!appConfig.apis.openai.apiKey) {
|
||||
warnings.push('OPENAI_API_KEY is recommended for production');
|
||||
}
|
||||
|
||||
if (appConfig.database.ssl === false) {
|
||||
warnings.push('Database SSL is recommended for production');
|
||||
}
|
||||
}
|
||||
|
||||
// Development warnings
|
||||
if (appConfig.server.env === 'development') {
|
||||
if (appConfig.auth.jwtSecret === 'dev_secret_key_change_in_production') {
|
||||
warnings.push('Using default JWT secret for development');
|
||||
}
|
||||
}
|
||||
|
||||
// Log warnings
|
||||
warnings.forEach(warning => {
|
||||
logger.warn(`Configuration warning: ${warning}`);
|
||||
});
|
||||
|
||||
// Throw errors
|
||||
if (errors.length > 0) {
|
||||
const errorMessage = `Configuration errors: ${errors.join(', ')}`;
|
||||
logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
logger.info('Configuration validated successfully');
|
||||
return true;
|
||||
};
|
||||
|
||||
// Get configuration for specific environment
|
||||
const getConfigForEnv = (env) => {
|
||||
const envConfig = { ...appConfig };
|
||||
|
||||
switch (env) {
|
||||
case 'production':
|
||||
envConfig.server.port = parseInt(process.env.PORT) || 8000;
|
||||
envConfig.server.host = '0.0.0.0';
|
||||
envConfig.development.debugMode = false;
|
||||
envConfig.development.verboseLogging = false;
|
||||
envConfig.logging.level = 'info';
|
||||
break;
|
||||
|
||||
case 'test':
|
||||
envConfig.server.port = parseInt(process.env.PORT) || 8001;
|
||||
envConfig.database.name = process.env.DB_NAME || 'reason_flow_test';
|
||||
envConfig.development.debugMode = false;
|
||||
envConfig.logging.level = 'error';
|
||||
break;
|
||||
|
||||
case 'development':
|
||||
default:
|
||||
envConfig.development.debugMode = true;
|
||||
envConfig.logging.level = 'debug';
|
||||
break;
|
||||
}
|
||||
|
||||
return envConfig;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
appConfig,
|
||||
validateConfig,
|
||||
getConfigForEnv
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
const { Sequelize } = require('sequelize');
|
||||
const logger = require('../utils/logger');
|
||||
const { getConfig } = require('./databaseConfig');
|
||||
|
||||
const sequelize = new Sequelize(getConfig());
|
||||
|
||||
// Test database connection
|
||||
const testConnection = async () => {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
logger.info('Database connection established successfully');
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error('Unable to connect to the database:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Sync database (create tables)
|
||||
const syncDatabase = async (force = false) => {
|
||||
try {
|
||||
await sequelize.sync({ force, alter: !force });
|
||||
logger.info(`Database synchronized successfully (force: ${force})`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error('Database synchronization failed:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Drop all tables
|
||||
const dropDatabase = async () => {
|
||||
try {
|
||||
await sequelize.drop();
|
||||
logger.info('Database dropped successfully');
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error('Database drop failed:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Close database connection
|
||||
const closeConnection = async () => {
|
||||
try {
|
||||
await sequelize.close();
|
||||
logger.info('Database connection closed');
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error('Error closing database connection:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
sequelize,
|
||||
testConnection,
|
||||
syncDatabase,
|
||||
dropDatabase,
|
||||
closeConnection
|
||||
};
|
||||
@@ -0,0 +1,119 @@
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
const databaseConfig = {
|
||||
development: {
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
port: process.env.DB_PORT || 5432,
|
||||
database: process.env.DB_NAME || 'reason_flow_dev',
|
||||
username: process.env.DB_USER || 'postgres',
|
||||
password: process.env.DB_PASSWORD || 'password',
|
||||
dialect: 'postgres',
|
||||
logging: (msg) => logger.debug(msg),
|
||||
pool: {
|
||||
max: 5,
|
||||
min: 0,
|
||||
acquire: 30000,
|
||||
idle: 10000
|
||||
},
|
||||
define: {
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
freezeTableName: true
|
||||
}
|
||||
},
|
||||
|
||||
test: {
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
port: process.env.DB_PORT || 5432,
|
||||
database: process.env.DB_NAME || 'reason_flow_test',
|
||||
username: process.env.DB_USER || 'postgres',
|
||||
password: process.env.DB_PASSWORD || 'password',
|
||||
dialect: 'postgres',
|
||||
logging: false,
|
||||
pool: {
|
||||
max: 5,
|
||||
min: 0,
|
||||
acquire: 30000,
|
||||
idle: 10000
|
||||
},
|
||||
define: {
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
freezeTableName: true
|
||||
}
|
||||
},
|
||||
|
||||
production: {
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT || 5432,
|
||||
database: process.env.DB_NAME,
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
dialect: 'postgres',
|
||||
logging: false,
|
||||
pool: {
|
||||
max: 20,
|
||||
min: 5,
|
||||
acquire: 60000,
|
||||
idle: 10000
|
||||
},
|
||||
define: {
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
freezeTableName: true
|
||||
},
|
||||
dialectOptions: {
|
||||
ssl: process.env.DB_SSL === 'true' ? {
|
||||
require: true,
|
||||
rejectUnauthorized: false
|
||||
} : false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getConfig = () => {
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
const config = databaseConfig[env];
|
||||
|
||||
if (!config) {
|
||||
throw new Error(`Database configuration not found for environment: ${env}`);
|
||||
}
|
||||
|
||||
// Validate required fields for production
|
||||
if (env === 'production') {
|
||||
const requiredFields = ['host', 'database', 'username', 'password'];
|
||||
const missingFields = requiredFields.filter(field => !config[field]);
|
||||
|
||||
if (missingFields.length > 0) {
|
||||
throw new Error(`Missing required database configuration: ${missingFields.join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`Using database configuration for environment: ${env}`);
|
||||
return config;
|
||||
};
|
||||
|
||||
const validateConnection = async (sequelize) => {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
logger.info('Database connection validated successfully');
|
||||
return true;
|
||||
} catch (error) {
|
||||
logger.error('Database connection validation failed:', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getDatabaseUrl = () => {
|
||||
const config = getConfig();
|
||||
const { host, port, database, username, password } = config;
|
||||
|
||||
return `postgresql://${username}:${password}@${host}:${port}/${database}`;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
databaseConfig,
|
||||
getConfig,
|
||||
validateConnection,
|
||||
getDatabaseUrl
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
const groqConfig = {
|
||||
// API Configuration
|
||||
apiKey: process.env.GROQ_API_KEY,
|
||||
model: process.env.GROQ_MODEL || 'moonshotai/kimi-k2-instruct-0905',
|
||||
baseURL: process.env.GROQ_BASE_URL || 'https://api.groq.com',
|
||||
|
||||
// Model-specific configurations
|
||||
models: {
|
||||
MODEL1: {
|
||||
model: 'moonshotai/kimi-k2-instruct-0905',
|
||||
temperature: 0.3,
|
||||
maxTokens: 300,
|
||||
topP: 0.9,
|
||||
systemPrompt: `You are MODEL1, an expert engineering reasoning system. Your primary function is to analyze complex engineering problems and create detailed, step-by-step plans to solve them.`
|
||||
},
|
||||
QUERYMODEL: {
|
||||
model: 'moonshotai/kimi-k2-instruct-0905',
|
||||
temperature: 0.5,
|
||||
maxTokens: 400,
|
||||
topP: 0.9,
|
||||
systemPrompt: `You are QUERYMODEL, an expert engineering execution system. Your primary function is to execute engineering plans using various tools and resources.`
|
||||
}
|
||||
},
|
||||
|
||||
// Rate limiting
|
||||
rateLimit: {
|
||||
requestsPerMinute: 60,
|
||||
requestsPerHour: 1000,
|
||||
burstLimit: 10
|
||||
},
|
||||
|
||||
// Retry configuration
|
||||
retry: {
|
||||
maxRetries: 3,
|
||||
retryDelay: 1000,
|
||||
backoffMultiplier: 2
|
||||
},
|
||||
|
||||
// Timeout configuration
|
||||
timeout: {
|
||||
request: 30000, // 30 seconds
|
||||
connection: 10000 // 10 seconds
|
||||
},
|
||||
|
||||
// Logging configuration
|
||||
logging: {
|
||||
logRequests: process.env.NODE_ENV === 'development',
|
||||
logResponses: process.env.NODE_ENV === 'development',
|
||||
logErrors: true
|
||||
}
|
||||
};
|
||||
|
||||
const validateConfig = () => {
|
||||
const errors = [];
|
||||
|
||||
if (!groqConfig.apiKey) {
|
||||
errors.push('GROQ_API_KEY is required');
|
||||
}
|
||||
|
||||
if (!groqConfig.model) {
|
||||
errors.push('GROQ_MODEL is required');
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
logger.error('Groq configuration errors:', errors);
|
||||
throw new Error(`Groq configuration invalid: ${errors.join(', ')}`);
|
||||
}
|
||||
|
||||
logger.info('Groq configuration validated successfully');
|
||||
return true;
|
||||
};
|
||||
|
||||
const getModelConfig = (modelType) => {
|
||||
return groqConfig.models[modelType] || groqConfig.models.MODEL1;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
groqConfig,
|
||||
validateConfig,
|
||||
getModelConfig
|
||||
};
|
||||
Reference in New Issue
Block a user