Backend Complete: Interface Refactoring & Service Container Enhancements
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
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
@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
|
||||
Reference in New Issue
Block a user