Environment Configuration
This guide covers production-specific configuration, optimization, and best practices for your BOOP integration.
🌍 Environment Overview
Environment Comparison
Understanding the differences between dev and production environments is crucial for proper configuration.
Feature Development Production Base URL https://dev.app.boop.ithttps://app.boop.itWebSocket wss://dev.app.boop.it/ws/vendorwss://app.boop.it/ws/vendorRate Limits Relaxed for testing Enforced for stability Data Persistence Temporary (reset weekly) Permanent SSL/TLS Development certificates Production-grade certificates Uptime SLA Best effort 99.9% guaranteed Support Business hours 24/7 monitoring
Production Environment Features
High Availability Redundant infrastructure with automatic failover
Global CDN Optimized performance worldwide
Real-time Monitoring 24/7 monitoring and alerting
⚙️ Configuration Management
Environment Variables
Set up environment-specific configuration:
Environment Variables
Node.js Config
Python Config
# Production Environment
export BOOP_ENV = production
export BOOP_BASE_URL = https :// app . boop . it
export BOOP_VENDOR_ID = ven_live_your_vendor_id
export BOOP_API_KEY = sk_live_your_secret_key
export BOOP_WS_ENDPOINT = wss :// app . boop . it / ws / vendor
# Security Settings
export BOOP_ENFORCE_HTTPS = true
export BOOP_API_TIMEOUT = 30000
export BOOP_WS_HEARTBEAT_INTERVAL = 30000
export BOOP_MAX_RETRIES = 3
# Performance Settings
export BOOP_CONNECTION_POOL_SIZE = 10
export BOOP_CACHE_TTL = 300
export BOOP_BATCH_SIZE = 50
Configuration Validation
Implement configuration validation to catch issues early:
class ConfigValidator {
static validate ( config ) {
const required = [ 'baseUrl' , 'vendorId' , 'apiKey' , 'wsEndpoint' ];
const missing = required . filter ( key => ! config [ key ]);
if ( missing . length > 0 ) {
throw new Error ( `Missing required BOOP configuration: ${ missing . join ( ', ' ) } ` );
}
// Validate URLs
try {
new URL ( config . baseUrl );
new URL ( config . wsEndpoint );
} catch ( error ) {
throw new Error ( `Invalid BOOP URL configuration: ${ error . message } ` );
}
// Validate credentials format
if ( ! config . vendorId . startsWith ( 'ven_live_' )) {
console . warn ( '⚠️ Vendor ID should start with "ven_live_" in production' );
}
if ( ! config . apiKey . startsWith ( 'sk_live_' )) {
console . warn ( '⚠️ API Key should start with "sk_live_" in production' );
}
// Validate environment
if ( config . baseUrl . includes ( 'dev.app.boop.it' )) {
throw new Error ( '🚨 Development URL detected in production configuration!' );
}
console . log ( '✅ BOOP configuration validation passed' );
return true ;
}
}
// Usage
const config = require ( './config/production' );
ConfigValidator . validate ( config . boop );
Connection Management
Optimize connections for production performance:
🔌 WebSocket Connection Pooling
class BoopWebSocketManager {
constructor ( config ) {
this . config = config ;
this . connections = new Map ();
this . maxConnections = config . maxConnections || 5 ;
this . heartbeatInterval = config . heartbeatInterval || 30000 ;
}
async getConnection ( vendorId ) {
if ( this . connections . has ( vendorId )) {
const connection = this . connections . get ( vendorId );
if ( connection . readyState === WebSocket . OPEN ) {
return connection ;
}
}
// Create new connection
const ws = await this . createConnection ( vendorId );
this . connections . set ( vendorId , ws );
this . setupHeartbeat ( ws );
return ws ;
}
setupHeartbeat ( ws ) {
const heartbeat = setInterval (() => {
if ( ws . readyState === WebSocket . OPEN ) {
ws . send ( JSON . stringify ({ type: 'ping' }));
} else {
clearInterval ( heartbeat );
}
}, this . heartbeatInterval );
}
}
class BoopBatchProcessor {
constructor ( batchSize = 50 , batchTimeout = 5000 ) {
this . batchSize = batchSize ;
this . batchTimeout = batchTimeout ;
this . queue = [];
this . timeout = null ;
}
async addRequest ( request ) {
return new Promise (( resolve , reject ) => {
this . queue . push ({ request , resolve , reject });
if ( this . queue . length >= this . batchSize ) {
this . processBatch ();
} else if ( ! this . timeout ) {
this . timeout = setTimeout (() => this . processBatch (), this . batchTimeout );
}
});
}
async processBatch () {
if ( this . timeout ) {
clearTimeout ( this . timeout );
this . timeout = null ;
}
const batch = this . queue . splice ( 0 , this . batchSize );
if ( batch . length === 0 ) return ;
try {
const results = await this . executeBatch ( batch . map ( item => item . request ));
batch . forEach (( item , index ) => {
item . resolve ( results [ index ]);
});
} catch ( error ) {
batch . forEach ( item => item . reject ( error ));
}
}
}
class BoopCache {
constructor ( ttl = 300000 ) { // 5 minutes default
this . cache = new Map ();
this . ttl = ttl ;
}
set ( key , value ) {
this . cache . set ( key , {
value ,
timestamp: Date . now (),
hits: 0
});
}
get ( key ) {
const item = this . cache . get ( key );
if ( ! item ) return null ;
if ( Date . now () - item . timestamp > this . ttl ) {
this . cache . delete ( key );
return null ;
}
item . hits ++ ;
return item . value ;
}
// Cache user attributes for quick access
cacheUserAttributes ( userId , attributes ) {
this . set ( `user_attributes: ${ userId } ` , attributes );
}
getUserAttributes ( userId ) {
return this . get ( `user_attributes: ${ userId } ` );
}
}
Track key performance metrics:
class PerformanceMonitor {
constructor () {
this . metrics = {
authenticationsPerMinute: 0 ,
averageResponseTime: 0 ,
errorRate: 0 ,
activeConnections: 0
};
this . startMonitoring ();
}
recordAuthentication ( responseTime , success ) {
// Update metrics
this . metrics . authenticationsPerMinute ++ ;
this . updateAverageResponseTime ( responseTime );
if ( ! success ) {
this . metrics . errorRate = ( this . metrics . errorRate + 1 ) / this . metrics . authenticationsPerMinute ;
}
// Log to monitoring system
this . logToMonitoring ( 'authentication' , {
responseTime ,
success ,
timestamp: Date . now ()
});
}
getHealthCheck () {
return {
status: this . metrics . errorRate < 0.01 ? 'healthy' : 'degraded' ,
metrics: this . metrics ,
timestamp: new Date (). toISOString ()
};
}
startMonitoring () {
// Reset counters every minute
setInterval (() => {
this . metrics . authenticationsPerMinute = 0 ;
}, 60000 );
}
}
🔒 Security Configuration
API Key Management
Never hardcode production API keys. Use secure environment variable management.
class ApiKeyManager {
constructor () {
this . primaryKey = process . env . BOOP_API_KEY ;
this . secondaryKey = process . env . BOOP_API_KEY_SECONDARY ;
this . rotationDate = process . env . BOOP_KEY_ROTATION_DATE ;
}
getCurrentKey () {
// Use secondary key if rotation is active
if ( this . isRotationActive ()) {
return this . secondaryKey ;
}
return this . primaryKey ;
}
isRotationActive () {
if ( ! this . rotationDate ) return false ;
return new Date () >= new Date ( this . rotationDate );
}
async makeApiCall ( endpoint , data ) {
let apiKey = this . getCurrentKey ();
try {
return await this . request ( endpoint , data , apiKey );
} catch ( error ) {
if ( error . status === 401 && this . secondaryKey ) {
// Try with secondary key
console . warn ( 'Primary key failed, trying secondary key' );
return await this . request ( endpoint , data , this . secondaryKey );
}
throw error ;
}
}
}
class SecurityValidator {
static validateRequest ( request ) {
// Validate HTTPS
if ( ! request . url . startsWith ( 'https://' )) {
throw new Error ( 'HTTPS required for production' );
}
// Validate headers
const requiredHeaders = [ 'X-API-Key' , 'Content-Type' , 'User-Agent' ];
for ( const header of requiredHeaders ) {
if ( ! request . headers [ header ]) {
throw new Error ( `Missing required header: ${ header } ` );
}
}
// Validate API key format
const apiKey = request . headers [ 'X-API-Key' ];
if ( ! apiKey . startsWith ( 'sk_live_' )) {
throw new Error ( 'Invalid production API key format' );
}
return true ;
}
static sanitizeLog ( data ) {
const sensitive = [ 'api_key' , 'apiKey' , 'secret' , 'password' , 'token' ];
const sanitized = { ... data };
for ( const key of sensitive ) {
if ( sanitized [ key ]) {
sanitized [ key ] = '***REDACTED***' ;
}
}
return sanitized ;
}
}
Network Security
Configure production network security:
// HTTPS enforcement
app . use (( req , res , next ) => {
if ( req . header ( 'x-forwarded-proto' ) !== 'https' ) {
res . redirect ( `https:// ${ req . header ( 'host' ) }${ req . url } ` );
} else {
next ();
}
});
// Security headers
app . use (( req , res , next ) => {
res . setHeader ( 'Strict-Transport-Security' , 'max-age=31536000; includeSubDomains' );
res . setHeader ( 'X-Content-Type-Options' , 'nosniff' );
res . setHeader ( 'X-Frame-Options' , 'DENY' );
res . setHeader ( 'X-XSS-Protection' , '1; mode=block' );
next ();
});
// Rate limiting
const rateLimit = require ( 'express-rate-limit' );
const boopLimiter = rateLimit ({
windowMs: 60 * 1000 , // 1 minute
max: 100 , // limit each IP to 100 requests per windowMs
message: 'Too many BOOP API requests from this IP'
});
app . use ( '/api/boop' , boopLimiter );
📊 Error Handling & Logging
Production Error Handling
Implement comprehensive error handling:
class ProductionErrorHandler {
static handleBoopError ( error , context ) {
// Log error with context
console . error ( 'BOOP Error:' , {
error: error . message ,
code: error . code ,
context: SecurityValidator . sanitizeLog ( context ),
timestamp: new Date (). toISOString (),
stack: process . env . NODE_ENV === 'development' ? error . stack : undefined
});
// Send to monitoring service
this . sendToMonitoring ( error , context );
// Return safe error message to client
return this . getSafeErrorMessage ( error );
}
static getSafeErrorMessage ( error ) {
const safeMessages = {
'user-not-found' : 'Authentication failed. Please try again.' ,
'insufficient-balance' : 'Insufficient funds. Please add money to your account.' ,
'vendor-not-consented' : 'Access not authorized. Please check your permissions.' ,
'network-error' : 'Service temporarily unavailable. Please try again.' ,
'timeout' : 'Request timed out. Please try again.'
};
return safeMessages [ error . code ] || 'An error occurred. Please try again.' ;
}
static sendToMonitoring ( error , context ) {
// Integrate with your monitoring service
// Examples: DataDog, New Relic, Sentry, etc.
}
}
Structured Logging
Configure production-grade logging:
const winston = require ( 'winston' );
const logger = winston . createLogger ({
level: 'info' ,
format: winston . format . combine (
winston . format . timestamp (),
winston . format . errors ({ stack: true }),
winston . format . json ()
),
defaultMeta: {
service: 'boop-integration' ,
environment: process . env . NODE_ENV
},
transports: [
new winston . transports . File ({ filename: 'error.log' , level: 'error' }),
new winston . transports . File ({ filename: 'combined.log' }),
new winston . transports . Console ({
format: winston . format . simple ()
})
]
});
// Usage
logger . info ( 'BOOP authentication started' , {
vendorId: 'ven_live_***' ,
userId: userId ,
amount: amount
});
logger . error ( 'BOOP authentication failed' , {
error: error . message ,
code: error . code ,
vendorId: 'ven_live_***' ,
userId: userId
});
🔧 Environment-Specific Features
Production Rate Limits
Understanding and working with production rate limits:
Endpoint Type Rate Limit Burst Limit Window Authentication 100 req/min 10 req/sec 1 minute API Calls 1000 req/min 50 req/sec 1 minute WebSocket Messages 1000 msg/min 100 msg/sec 1 minute User Operations 50 req/min 5 req/sec 1 minute
Feature Flags
Use feature flags for safe production rollouts:
class FeatureFlags {
constructor () {
this . flags = {
useBoopPayments: process . env . ENABLE_BOOP_PAYMENTS === 'true' ,
boopTrafficPercentage: parseInt ( process . env . BOOP_TRAFFIC_PERCENT || '0' ),
enableBoopAttributes: process . env . ENABLE_BOOP_ATTRIBUTES === 'true' ,
boopTimeout: parseInt ( process . env . BOOP_TIMEOUT || '30000' )
};
}
isEnabled ( flag ) {
return this . flags [ flag ] === true ;
}
getPercentage ( flag ) {
return this . flags [ flag ] || 0 ;
}
shouldRouteToBoopForUser ( userId ) {
const percentage = this . getPercentage ( 'boopTrafficPercentage' );
if ( percentage === 0 ) return false ;
if ( percentage === 100 ) return true ;
// Consistent hashing for gradual rollout
const hash = this . hashUserId ( userId );
return ( hash % 100 ) < percentage ;
}
}
📈 Monitoring Integration
Health Check Endpoint
Implement a comprehensive health check:
app . get ( '/health/boop' , async ( req , res ) => {
const health = {
status: 'unknown' ,
timestamp: new Date (). toISOString (),
checks: {}
};
try {
// Test BOOP connectivity
const boopResponse = await fetch ( 'https://app.boop.it/health' , { timeout: 5000 });
health . checks . boopConnectivity = {
status: boopResponse . ok ? 'healthy' : 'unhealthy' ,
responseTime: Date . now () - startTime
};
// Test WebSocket connectivity
const wsHealthy = await testWebSocketConnection ();
health . checks . webSocket = {
status: wsHealthy ? 'healthy' : 'unhealthy'
};
// Check authentication capability
const authHealthy = await testAuthentication ();
health . checks . authentication = {
status: authHealthy ? 'healthy' : 'unhealthy'
};
// Overall status
const allHealthy = Object . values ( health . checks ). every ( check => check . status === 'healthy' );
health . status = allHealthy ? 'healthy' : 'unhealthy' ;
res . status ( allHealthy ? 200 : 503 ). json ( health );
} catch ( error ) {
health . status = 'unhealthy' ;
health . error = error . message ;
res . status ( 503 ). json ( health );
}
});
Metrics Collection
Collect and export metrics for monitoring:
const prometheus = require ( 'prom-client' );
// Create metrics
const authCounter = new prometheus . Counter ({
name: 'boop_authentications_total' ,
help: 'Total number of BOOP authentications' ,
labelNames: [ 'status' , 'vendor_id' ]
});
const responseTime = new prometheus . Histogram ({
name: 'boop_response_time_seconds' ,
help: 'BOOP API response time in seconds' ,
buckets: [ 0.1 , 0.5 , 1 , 2 , 5 , 10 ]
});
// Export metrics endpoint
app . get ( '/metrics' , ( req , res ) => {
res . set ( 'Content-Type' , prometheus . register . contentType );
res . end ( prometheus . register . metrics ());
});
🎯 Next Steps
Production Environment Complete! Your BOOP integration is now properly configured for production use with security, performance, and monitoring best practices in place.