@echo off REM SerpentRace Backend Production Deployment Script for Windows REM This script handles the complete deployment process setlocal EnableDelayedExpansion set "SCRIPT_START=%TIME%" REM Colors simulation for Windows (using echo with different prefixes) set "LOG_PREFIX=[INFO]" set "ERROR_PREFIX=[ERROR]" set "WARN_PREFIX=[WARN]" :log echo %LOG_PREFIX% [%DATE% %TIME%] %~1 goto :eof :error echo %ERROR_PREFIX% [%DATE% %TIME%] %~1 goto :eof :warn echo %WARN_PREFIX% [%DATE% %TIME%] %~1 goto :eof :check_env call :log "Checking environment variables..." set "required_vars=DB_HOST DB_PORT DB_USERNAME DB_PASSWORD DB_NAME JWT_SECRET REDIS_HOST REDIS_PORT" set "missing_vars=" for %%v in (%required_vars%) do ( call set "var_value=%%!%%v!%%" if "!var_value!"=="" ( set "missing_vars=!missing_vars! %%v" ) ) if not "!missing_vars!"==" " ( call :error "Missing required environment variables:!missing_vars!" call :error "Please set these variables before running the deployment" exit /b 1 ) call :log "All required environment variables are set" goto :eof :install_dependencies call :log "Installing production dependencies..." npm ci --only=production if !errorlevel! neq 0 ( call :error "Failed to install dependencies" exit /b 1 ) call :log "Dependencies installed successfully" goto :eof :run_build call :log "Running production build..." npm run build:production if !errorlevel! neq 0 ( call :error "Build failed" exit /b 1 ) call :log "Build completed successfully" goto :eof :test_database call :log "Testing database connectivity..." echo import { AppDataSource } from './src/Infrastructure/ormconfig'; > test-db-temp.ts echo. >> test-db-temp.ts echo async function testConnection() { >> test-db-temp.ts echo try { >> test-db-temp.ts echo await AppDataSource.initialize(); >> test-db-temp.ts echo console.log('✅ Database connection successful'^); >> test-db-temp.ts echo await AppDataSource.destroy(); >> test-db-temp.ts echo process.exit(0^); >> test-db-temp.ts echo } catch (error^) { >> test-db-temp.ts echo console.error('❌ Database connection failed:', error^); >> test-db-temp.ts echo process.exit(1^); >> test-db-temp.ts echo } >> test-db-temp.ts echo } >> test-db-temp.ts echo. >> test-db-temp.ts echo testConnection(); >> test-db-temp.ts npx ts-node test-db-temp.ts set "db_test_result=!errorlevel!" del test-db-temp.ts 2>nul if !db_test_result! neq 0 ( call :error "Database connectivity test failed" exit /b 1 ) call :log "Database connectivity test passed" goto :eof :test_redis call :log "Testing Redis connectivity..." echo import { createClient } from 'redis'; > test-redis-temp.ts echo. >> test-redis-temp.ts echo async function testRedis() { >> test-redis-temp.ts echo const client = createClient({ >> test-redis-temp.ts echo socket: { >> test-redis-temp.ts echo host: process.env.REDIS_HOST ^|^| 'localhost', >> test-redis-temp.ts echo port: parseInt(process.env.REDIS_PORT ^|^| '6379'^) >> test-redis-temp.ts echo } >> test-redis-temp.ts echo }^); >> test-redis-temp.ts echo. >> test-redis-temp.ts echo try { >> test-redis-temp.ts echo await client.connect(); >> test-redis-temp.ts echo await client.ping(); >> test-redis-temp.ts echo console.log('✅ Redis connection successful'^); >> test-redis-temp.ts echo await client.disconnect(); >> test-redis-temp.ts echo process.exit(0^); >> test-redis-temp.ts echo } catch (error^) { >> test-redis-temp.ts echo console.error('❌ Redis connection failed:', error^); >> test-redis-temp.ts echo process.exit(1^); >> test-redis-temp.ts echo } >> test-redis-temp.ts echo } >> test-redis-temp.ts echo. >> test-redis-temp.ts echo testRedis(); >> test-redis-temp.ts npx ts-node test-redis-temp.ts set "redis_test_result=!errorlevel!" del test-redis-temp.ts 2>nul if !redis_test_result! neq 0 ( call :warn "Redis connectivity test failed - continuing anyway" ) else ( call :log "Redis connectivity test passed" ) goto :eof :setup_directories call :log "Setting up required directories..." if not exist "logs" mkdir logs if not exist "uploads" mkdir uploads call :log "Directories created" goto :eof :start_app call :log "Starting application for validation..." REM Start the app in background start /B "" npm start REM Wait for app to start timeout /t 10 /nobreak >nul REM Test if the health endpoint responds (using curl if available) set "PORT_VAR=!PORT!" if "!PORT_VAR!"=="" set "PORT_VAR=3000" curl -f http://localhost:!PORT_VAR!/health >nul 2>&1 if !errorlevel! equ 0 ( call :log "Application health check passed" REM Try to stop the background process (this is tricky in batch) taskkill /F /IM node.exe /FI "WINDOWTITLE eq npm start*" >nul 2>&1 ) else ( call :error "Application health check failed" taskkill /F /IM node.exe /FI "WINDOWTITLE eq npm start*" >nul 2>&1 exit /b 1 ) goto :eof :deploy call :log "🚀 Starting SerpentRace Backend production deployment..." call :check_env if !errorlevel! neq 0 exit /b 1 call :install_dependencies if !errorlevel! neq 0 exit /b 1 call :run_build if !errorlevel! neq 0 exit /b 1 call :setup_directories if !errorlevel! neq 0 exit /b 1 call :test_database if !errorlevel! neq 0 exit /b 1 call :test_redis REM Redis test failure is not fatal if not "%SKIP_APP_TEST%"=="true" ( call :start_app if !errorlevel! neq 0 exit /b 1 ) else ( call :warn "Skipping application startup test" ) call :log "🎉 Deployment completed successfully!" call :log "You can now start the application with: npm start" goto :eof :build_only call :log "Running build-only deployment..." call :check_env if !errorlevel! neq 0 exit /b 1 call :install_dependencies if !errorlevel! neq 0 exit /b 1 call :run_build if !errorlevel! neq 0 exit /b 1 call :setup_directories call :log "Build-only deployment completed" goto :eof :test_connections call :log "Testing connections only..." call :check_env if !errorlevel! neq 0 exit /b 1 call :test_database if !errorlevel! neq 0 exit /b 1 call :test_redis call :log "Connection tests completed" goto :eof REM Main script logic if "%1"=="" goto deploy if "%1"=="deploy" goto deploy if "%1"=="build-only" goto build_only if "%1"=="test-connections" goto test_connections 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 /b 1