86211923db
Repository Interface Optimization: - Created IBaseRepository.ts and IPaginatedRepository.ts - Refactored all 7 repository interfaces to extend base interfaces - Eliminated ~200 lines of redundant code (70% reduction) - Improved type safety and maintainability Dependency Injection Improvements: - Added EmailService and GameTokenService to DIContainer - Updated CreateUserCommandHandler constructor for DI - Updated RequestPasswordResetCommandHandler constructor for DI - Enhanced testability and service consistency Environment Configuration: - Created comprehensive .env.example with 40+ variables - Organized into 12 logical sections (Database, Security, Email, etc.) - Added security guidelines and best practices - Documented all backend environment requirements Documentation: - Added comprehensive codebase review - Created refactoring summary report - Added frontend implementation guide Impact: Improved code quality, reduced maintenance overhead, enhanced developer experience
238 lines
5.5 KiB
Bash
238 lines
5.5 KiB
Bash
#!/bin/bash
|
|
|
|
# SerpentRace Backend Production Deployment Script
|
|
# This script handles the complete deployment process
|
|
|
|
set -e # Exit on any error
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log() {
|
|
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
|
|
}
|
|
|
|
info() {
|
|
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
|
|
}
|
|
|
|
# Check if required environment variables are set
|
|
check_env() {
|
|
log "Checking environment variables..."
|
|
|
|
required_vars=(
|
|
"DB_HOST"
|
|
"DB_PORT"
|
|
"DB_USERNAME"
|
|
"DB_PASSWORD"
|
|
"DB_NAME"
|
|
"JWT_SECRET"
|
|
"REDIS_HOST"
|
|
"REDIS_PORT"
|
|
)
|
|
|
|
missing_vars=()
|
|
for var in "${required_vars[@]}"; do
|
|
if [ -z "${!var}" ]; then
|
|
missing_vars+=("$var")
|
|
fi
|
|
done
|
|
|
|
if [ ${#missing_vars[@]} -ne 0 ]; then
|
|
error "Missing required environment variables: ${missing_vars[*]}"
|
|
error "Please set these variables before running the deployment"
|
|
exit 1
|
|
fi
|
|
|
|
log "All required environment variables are set"
|
|
}
|
|
|
|
# Install dependencies
|
|
install_dependencies() {
|
|
log "Installing production dependencies..."
|
|
npm ci --only=production
|
|
log "Dependencies installed successfully"
|
|
}
|
|
|
|
# Run the comprehensive build process
|
|
run_build() {
|
|
log "Running production build..."
|
|
npm run build:production
|
|
log "Build completed successfully"
|
|
}
|
|
|
|
# Test database connectivity
|
|
test_database() {
|
|
log "Testing database connectivity..."
|
|
|
|
# Use a simple TypeScript script to test connection
|
|
cat > /tmp/test-db.ts << 'EOF'
|
|
import { AppDataSource } from './src/Infrastructure/ormconfig';
|
|
|
|
async function testConnection() {
|
|
try {
|
|
await AppDataSource.initialize();
|
|
console.log('✅ Database connection successful');
|
|
await AppDataSource.destroy();
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error('❌ Database connection failed:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
testConnection();
|
|
EOF
|
|
|
|
npx ts-node /tmp/test-db.ts || {
|
|
error "Database connectivity test failed"
|
|
exit 1
|
|
}
|
|
|
|
rm -f /tmp/test-db.ts
|
|
log "Database connectivity test passed"
|
|
}
|
|
|
|
# Test Redis connectivity
|
|
test_redis() {
|
|
log "Testing Redis connectivity..."
|
|
|
|
# Use a simple script to test Redis connection
|
|
cat > /tmp/test-redis.ts << 'EOF'
|
|
import { createClient } from 'redis';
|
|
|
|
async function testRedis() {
|
|
const client = createClient({
|
|
socket: {
|
|
host: process.env.REDIS_HOST || 'localhost',
|
|
port: parseInt(process.env.REDIS_PORT || '6379')
|
|
}
|
|
});
|
|
|
|
try {
|
|
await client.connect();
|
|
await client.ping();
|
|
console.log('✅ Redis connection successful');
|
|
await client.disconnect();
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error('❌ Redis connection failed:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
testRedis();
|
|
EOF
|
|
|
|
npx ts-node /tmp/test-redis.ts || {
|
|
warn "Redis connectivity test failed - continuing anyway"
|
|
}
|
|
|
|
rm -f /tmp/test-redis.ts
|
|
log "Redis connectivity test completed"
|
|
}
|
|
|
|
# Create required directories
|
|
setup_directories() {
|
|
log "Setting up required directories..."
|
|
mkdir -p logs
|
|
mkdir -p uploads
|
|
log "Directories created"
|
|
}
|
|
|
|
# Start the application (for testing)
|
|
start_app() {
|
|
log "Starting application for validation..."
|
|
|
|
# Start the app in background and test if it responds
|
|
npm start &
|
|
APP_PID=$!
|
|
|
|
# Wait for app to start
|
|
sleep 10
|
|
|
|
# Test if the health endpoint responds
|
|
if curl -f http://localhost:${PORT:-3000}/health > /dev/null 2>&1; then
|
|
log "Application health check passed"
|
|
kill $APP_PID
|
|
wait $APP_PID 2>/dev/null
|
|
else
|
|
error "Application health check failed"
|
|
kill $APP_PID 2>/dev/null || true
|
|
wait $APP_PID 2>/dev/null || true
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Main deployment function
|
|
deploy() {
|
|
log "🚀 Starting SerpentRace Backend production deployment..."
|
|
|
|
# Check environment
|
|
check_env
|
|
|
|
# Install dependencies
|
|
install_dependencies
|
|
|
|
# Run build process
|
|
run_build
|
|
|
|
# Setup directories
|
|
setup_directories
|
|
|
|
# Test connections
|
|
test_database
|
|
test_redis
|
|
|
|
# Test application startup
|
|
if [ "${SKIP_APP_TEST}" != "true" ]; then
|
|
start_app
|
|
else
|
|
warn "Skipping application startup test"
|
|
fi
|
|
|
|
log "🎉 Deployment completed successfully!"
|
|
info "You can now start the application with: npm start"
|
|
}
|
|
|
|
# Handle script arguments
|
|
case "${1:-deploy}" in
|
|
"deploy")
|
|
deploy
|
|
;;
|
|
"build-only")
|
|
log "Running build-only deployment..."
|
|
check_env
|
|
install_dependencies
|
|
run_build
|
|
setup_directories
|
|
log "Build-only deployment completed"
|
|
;;
|
|
"test-connections")
|
|
log "Testing connections only..."
|
|
check_env
|
|
test_database
|
|
test_redis
|
|
log "Connection tests completed"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [deploy|build-only|test-connections]"
|
|
echo " deploy - Full deployment (default)"
|
|
echo " build-only - Only build, skip tests"
|
|
echo " test-connections - Test database and Redis connections"
|
|
exit 1
|
|
;;
|
|
esac
|