Full-stack web application for managing esports teams, tournaments, matches and player participation.
Built with React, TypeScript, Node.js, Express and MySQL using layered architecture, dependency injection and scalable deployment practices.
- Live Demo
- System Overview
- Tech Stack
- Features
- Screenshots
- Architecture
- Tournament Engine
- Core Domain Model
- Project Structure
- Custom Load Balancer
- Authentication & Security
- Health Monitoring
- Load Balancing Strategies
- CI / CD Pipeline
- Configuration
- Deployment
- Deployment Topology
- Getting Started
- Engineering Challenges
- Team Development
- Future Improvements
https://odp-c2-s-tim-01.vercel.app
https://odp-c2s-tim-01-loadbalancer.onrender.com
-
Render Instance https://odp-c2s-tim-01.onrender.com
-
Railway Instance https://odpc2stim01-production.up.railway.app
Esports Tournament Platform is built as a multi-layer distributed system:
- Client Layer → React-based SPA for users and admins
- Load Balancer Layer → Intelligent traffic distribution across backend instances
- Backend Layer → Node.js/Express API with layered architecture
- Data Layer → MySQL database with optional local replication support
- Infrastructure Layer → Docker + cloud deployment (Render, Aiven, Vercel)
Note
Local development includes a MySQL master–slave replication setup for experimentation and learning purposes. Production deployment currently uses a single managed MySQL instance hosted on Aiven.
- React
- TypeScript
- Vite
- React Router
- Node.js
- Express
- TypeScript
- JWT Authentication
- MySQL
- Aiven
- Render
- Railway
- Custom Load Balancer
- User registration and authentication
- Role-based authorization (Player / Admin)
- Team creation and management
- Tournament creation and administration
- Automated bracket generation
- Match scheduling and progression
- Lineup management
- Player performance tracking
- Invitation system
- Audit logging
- API and database health monitoring
- Distributed deployment with load balancing
User administration, audit logging, and system monitoring.
The backend follows a layered architecture:
Repository Layer
↓
Service Layer
↓
Controller Layer
↓
REST API
Key design principles:
- Dependency Injection
- Result Pattern
- SOLID principles
- Separation of Concerns
- Repository Pattern
The platform automatically generates tournament brackets and match relations.
Main responsibilities:
- Bracket generation
- Temporary node mapping
- Match persistence
- Parent-child match linking
- Automatic advancement of winners
Tournament
↓
Bracket Generator
↓
Bracket Nodes
↓
Persist Matches
↓
Map Temp IDs
↓
Link Matches
↓
Ready Tournament Tree
- Users
- Teams
- Tournaments
- Matches
- MatchPlayers
- Games
- Invitations
- AuditLogs
project/
├── client/ # React frontend (SPA)
├── server/ # Express backend (domain-driven structure)
├── loadbalancer/ # Custom Node.js load balancer
└── docker/ # MySQL master-slave replication setup
A separate Node.js load balancer was developed and deployed.
Features:
- Weighted Round Robin algorithm
- Strategy Pattern based balancing algorithms
- Factory-based strategy resolution
- Background health checks
- Proxy routing
- Server pool management
- Dependency Injection support
- JWT-based stateless authentication
- Role-based access control (Admin/User separation)
- Password hashing using bcrypt
- Protected routes via middleware chain
- Token validation on every protected request
Each backend instance exposes:
GET /api/v1/health
The load balancer periodically:
- checks server availability
- marks unhealthy nodes as inactive
- removes them from routing pool
- reintegrates them when recovered
Sequential distribution of requests across healthy nodes.
Routes traffic to the least loaded server based on active connections.
Ensures session consistency by mapping client IP → server instance.
Assigns higher traffic share to more powerful servers.
GitHub Actions pipeline ensures:
- TypeScript compilation success
- Build verification
- Protection of main branch via required checks
The application uses environment variables for:
- database connectivity
- JWT secrets
- deployment settings
- load balancing configuration
- health monitoring configuration
Production deployment consists of:
- Render (Load Balancer)
- Render (Server Instance #1)
- Render (Server Instance #2)
- Railway (Server Instance #3)
- Aiven MySQL Database
Traffic distribution is handled using a Weighted Round Robin balancing strategy.
Users
↓
Load Balancer (Render)
↓
┌──────────────┬──────────────┬──────────────┐
│ Server #1 │ Server #2 │ Server #3 │
│ Render │ Render │ Railway │
└──────────────┴──────────────┴──────────────┘
↓
Aiven MySQL
docker-compose up -ddocker cp docker/setup-replication.sh project_master:/setup.sh
docker exec project_master sh /setup.shcd server
cp .env.example .env
npm install
npm run devcd loadbalancer
npm install
npm run devcd client
npm install
npm run devGenerating tournament brackets required mapping temporary bracket nodes to persisted database entities while maintaining match relationships.
Repository methods were extended to support bulk retrieval operations, reducing unnecessary database round trips.
The application was deployed across multiple cloud providers and routed through a custom load balancer with health monitoring.
This project was developed by a team of four students.
To ensure broad exposure to the full stack, all team members contributed across frontend and backend layers.
Key contributions included:
- tournament management
- match lifecycle management
- authentication and authorization
- administrative dashboard
- load balancing infrastructure
- deployment and cloud hosting
- Database transaction support through Unit of Work pattern
- Database provider abstraction
- Soft delete support
- Cloud object storage for images
- External game metadata integration
- Real-time or polling-based invitation updates
- Invite read/unread tracking






