A modern, full-stack online coding platform built with TypeScript, React, Express, and PostgreSQL. Codura enables users to solve coding challenges, submit solutions, and receive real-time execution results with code validation.
- Overview
- Architecture & Flow
- Technology Stack
- AWS Infrastructure
- Project Structure
- Installation
- Configuration
- Development
- Building & Deployment
- API Documentation
- Database Schema
Codura is a monorepo-based online judge platform that enables users to:
- β Create & Browse coding problems with detailed descriptions
- β Write & Execute code in multiple languages
- β Get Real-time Feedback through WebSocket connections
- β Track Submissions with status, runtime, and memory metrics
- β Manage Admin Features for problem creation and management
- β Queue Processing via BullMQ for asynchronous code execution
- β Scalable Deployment on AWS with EC2 and Load Balancer
- Real-time Collaboration: WebSocket and Pub/Sub architecture for live code feedback
- Scalable Architecture: Monorepo setup with independent client, server, and worker services
- Secure Authentication: JWT-based user authentication with bcrypt password hashing
- Code Execution: Integration with Judge0 API for safe code compilation and execution
- Database Persistence: PostgreSQL with Prisma ORM for type-safe database operations
- Job Queue Management: BullMQ for handling asynchronous code submission jobs
- Cloud Infrastructure: Deployed on AWS EC2 instances with Load Balancer for high availability
The diagram above illustrates the complete architecture and flow of the Codura platform:
Key Components:
- Client (React): User-facing interface with authentication, problem browsing, and code submission
- Server (Express.js): API layer managing all business logic, user sessions, and WebSocket connections
- Worker (Node.js): Background job processor handling asynchronous code execution
- Judge0 API: Secure code compilation and execution engine with Docker isolation
- PostgreSQL: Main application database storing users, problems, and submissions
- Redis + BullMQ: Queue management and Pub/Sub for handling multiple concurrent code submissions
- AWS EC2: Cloud compute instances hosting application services
- AWS Load Balancer: Distributes incoming traffic across multiple EC2 instances for high availability
Data Flow:
- User submits code through the client
- Request is routed through AWS Load Balancer to available EC2 instance
- Server validates and stores submission in PostgreSQL database
- Submission job is published to BullMQ queue via Redis Pub/Sub
- Worker picks up job from queue
- Judge0 API compiles and executes the code in isolated environment
- Results are updated in database
- Client receives real-time updates via WebSocket connection
Communication Patterns:
- WebSocket: Bidirectional real-time communication between client and server
- Pub/Sub: Redis-based publish/subscribe pattern for distributing jobs across workers
- REST API: Standard HTTP endpoints for CRUD operations
- Framework: React 19 with TypeScript
- Build Tool: Vite 7
- Styling: TailwindCSS + PostCSS
- Code Editor: Monaco Editor (VS Code)
- HTTP Client: Axios
- Real-time: Socket.IO Client (WebSocket)
- Markdown: React Markdown
- UI Components: Custom Lucide React Icons
- Notifications: React Toastify
- Runtime: Node.js 18+
- Framework: Express 5
- Language: TypeScript 5.9
- Database: PostgreSQL
- ORM: Prisma 6
- Authentication: JWT + bcrypt
- Task Queue: BullMQ (with Redis)
- Real-time: Socket.IO (WebSocket)
- Pub/Sub: Redis Pub/Sub for distributed job processing
- Code Execution: Judge0 API
- Validation: Zod
- Runtime: Node.js
- Queue Manager: BullMQ
- HTTP Client: Axios
- Cache: ioRedis
- Pub/Sub: Redis Pub/Sub for job subscription
- Authentication: bcrypt
- Validation: Zod
- Monorepo: Turborepo
- Code Linting: ESLint
- Code Formatter: Prettier
- Package Manager: npm 10.9.2
- Container Orchestration: Docker & Docker Compose
- Judge0 Integration: Docker containers
- AWS Services: EC2, LoadBalancer
- Scalability: Easily scale horizontally by adding more EC2 instances
- High Availability: Load balancer ensures zero downtime during deployments
- Performance: Distributed architecture reduces latency
- Security: VPC isolation and security groups protect resources
- Cost Optimization: Pay-as-you-go pricing with auto-scaling
Codura_Coding_Platform/
βββ apps/
β βββ client/ # React Frontend Application
β β βββ src/
β β β βββ components/ # Reusable React components
β β β β βββ Navbar.tsx
β β β β βββ common/ # Common components
β β β β βββ problem/ # Problem-related components
β β β β βββ ui/ # UI component library
β β β βββ pages/ # Page components
β β β β βββ Login.tsx
β β β β βββ Signup.tsx
β β β β βββ Dashboard.tsx
β β β β βββ ProblemDetail.tsx
β β β β βββ ProblemSubmissionPage.tsx
β β β β βββ ProblemEditPage.tsx
β β β βββ api/ # API service functions
β β β β βββ problems.ts
β β β β βββ problemCodes.ts
β β β βββ context/ # React Context for state
β β β β βββ AuthContext.tsx
β β β βββ hooks/ # Custom React hooks
β β β β βββ useCodeExecution.ts
β β β β βββ useLogin.ts
β β β β βββ useLogout.ts
β β β β βββ useSignup.ts
β β β βββ utils/ # Utility functions
β β β β βββ socket.ts # WebSocket client setup
β β β βββ App.tsx # Main App component
β β β βββ main.tsx # Entry point
β β βββ index.html
β β βββ vite.config.ts
β β βββ tailwind.config.js
β β βββ tsconfig.json
β β βββ package.json
β β
β βββ server/ # Express Backend Application
β β βββ src/
β β β βββ controllers/ # Request handlers
β β β β βββ user.controller.ts
β β β β βββ problem.controller.ts
β β β β βββ submission.controller.ts
β β β β βββ problemCode.controller.ts
β β β β βββ submitController.ts
β β β βββ services/ # Business logic
β β β β βββ user.service.ts
β β β β βββ problem.service.ts
β β β β βββ submission.service.ts
β β β β βββ problemCode.service.ts
β β β βββ routes/ # API endpoints
β β β β βββ user.routes.ts
β β β β βββ problem.routes.ts
β β β β βββ submission.routes.ts
β β β β βββ problemCode.routes.ts
β β β β βββ submitroute.ts
β β β βββ middleware/ # Express middleware
β β β β βββ authenticate.ts # JWT verification
β β β β βββ adminAuth.ts # Admin role check
β β β β βββ errorHandler.ts # Error handling
β β β β βββ validator.ts # Input validation
β β β βββ config/ # Configuration
β β β β βββ bullMQ.ts # BullMQ & Pub/Sub setup
β β β β βββ websocket.ts # Socket.IO WebSocket setup
β β β βββ lib/ # Library utilities
β β β β βββ prisma.ts # Prisma client
β β β βββ types/ # TypeScript types
β β β βββ validators/ # Zod schemas
β β β βββ index.ts # Entry point
β β βββ prisma/
β β β βββ schema.prisma # Database schema
β β βββ tsconfig.json
β β βββ package.json
β β
β βββ worker/ # Background Job Worker
β βββ src/
β β βββ controllers/ # Job controllers
β β βββ services/ # Job processing logic
β β βββ lib/ # Utility functions
β β β βββ redis.ts # Redis Pub/Sub client
β β βββ middleware/
β β βββ routes/
β β βββ types/
β β βββ validators/
β β βββ index.ts # Entry point with Pub/Sub subscriber
β βββ tsconfig.json
β βββ package.json
β
βββ packages/ # Shared packages
β βββ eslint-config/ # Shared ESLint configs
β βββ typescript-config/ # Shared TypeScript configs
β βββ ui/ # Shared UI components library
β
βββ docker-compose.judge0.yml # Judge0 Docker setup
βββ turbo.json # Turborepo config
βββ package.json # Root package.json
βββ README.md # This file
- Node.js: 18.0.0 or higher
- npm: 10.9.2 or higher
- Docker & Docker Compose: For Judge0 service
- PostgreSQL: 13+ (can be containerized or AWS RDS)
- Redis: For BullMQ queue and Pub/Sub (can be containerized or AWS ElastiCache)
- AWS Account: For EC2 and Load Balancer deployment (optional for local development)
git clone https://github.com/chatanyapra/Codura_Coding_Platform.git
cd Codura_Coding_Platformnpm installThis command will install dependencies for all workspaces (client, server, worker, packages).
docker-compose -f docker-compose.judge0.yml up -dThis starts:
- Judge0 Server (Code execution engine)
- PostgreSQL (Judge0 database)
- Redis (Judge0 cache)
Create .env file in the apps/server directory:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/codura_db"
# Server
PORT=3000
NODE_ENV=development
# JWT
JWT_SECRET=your_jwt_secret_key_here
JWT_EXPIRATION=7d
# Judge0
JUDGE0_API_URL=http://localhost:2358
JUDGE0_AUTH_TOKEN=your_judge0_token
# Redis (Queue & Pub/Sub)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# WebSocket
SOCKET_IO_CORS_ORIGIN=http://localhost:5173
# Cors
CORS_ORIGIN=http://localhost:5173
# AWS (Production)
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_keyCreate .env file in the apps/client directory:
# Development
VITE_API_URL=http://localhost:3000
VITE_SOCKET_URL=http://localhost:3000
# Production (AWS Load Balancer)
# VITE_API_URL=https://your-load-balancer-url.com
# VITE_SOCKET_URL=wss://your-load-balancer-url.comCreate .env file in the apps/worker directory:
# Redis (Queue & Pub/Sub)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/codura_db"
# Judge0
JUDGE0_API_URL=http://localhost:2358
# Environment
NODE_ENV=development
# AWS (Production)
AWS_REGION=us-east-1npm run devThis command uses Turborepo to run all apps simultaneously:
- Client:
http://localhost:5173(Vite dev server) - Server:
http://localhost:3000(Express API with WebSocket) - Worker: Processes background jobs via BullMQ and Redis Pub/Sub
# Client only
turbo dev --filter=client
# Server only (includes WebSocket server)
turbo dev --filter=server
# Worker only (includes Pub/Sub subscriber)
turbo dev --filter=workernpm run lintnpm run formatnpm run check-typesnpm run buildThis builds:
- Client: Vite production build (
dist/) - Server: TypeScript compilation (
dist/) - Worker: TypeScript compilation (
dist/)
turbo build --filter=client
turbo build --filter=server
turbo build --filter=worker-
Build containers:
docker build -t codura-client ./apps/client docker build -t codura-server ./apps/server docker build -t codura-worker ./apps/worker
-
Deploy with Docker Compose (update docker-compose.yml with your services)
-
Launch EC2 Instances:
- Create EC2 instances for client, server, and worker
- Configure security groups (allow HTTP/HTTPS, WebSocket ports)
- Assign Elastic IPs for static addressing
-
Setup Load Balancer:
- Create Application Load Balancer
- Configure target groups for EC2 instances
- Setup health checks
- Configure SSL certificates for HTTPS
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/users/signup |
Register new user |
| POST | /api/users/login |
Login user |
| GET | /api/users/profile |
Get user profile |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/problems |
Get all problems |
| GET | /api/problems/:id |
Get problem details |
| POST | /api/problems |
Create problem (admin) |
| PUT | /api/problems/:id |
Update problem (admin) |
| DELETE | /api/problems/:id |
Delete problem (admin) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/problem-codes/:problemId |
Get boilerplate code |
| POST | /api/problem-codes |
Add language template |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/submissions |
Get user submissions |
| GET | /api/submissions/:id |
Get submission details |
| POST | /api/submit |
Submit solution |
| Event | Data | Direction | Description |
|---|---|---|---|
connection |
- | Client β Server | Establish WebSocket connection |
submitted |
{ submissionId } |
Server β Client | Acknowledge submission received |
submission:updated |
{ id, status, runtime, memory } |
Server β Client | Real-time submission status updates |
disconnect |
- | Client β Server | Close WebSocket connection |
| Channel | Publisher | Subscriber | Purpose |
|---|---|---|---|
submission:queue |
Server | Worker | Distribute submission jobs |
submission:result |
Worker | Server | Return execution results |
submission:status |
Worker | Server | Real-time status updates |
- id: Int (Primary Key)
- username: String (Unique)
- email: String (Unique)
- passwordHash: String
- profileImage: String (Optional)
- role: String (Default: "user")
- createdAt: DateTime
- updatedAt: DateTime
- Relationships: problems[], submissions[]- id: Int (Primary Key)
- title: String
- description: String
- difficulty: String
- constraints: String
- examples: Json
- testCases: Json
- tags: String[]
- timeLimit: Int (Default: 1s)
- memoryLimit: Int (Default: 128MB)
- createdBy: Int (Foreign Key)
- createdAt: DateTime
- updatedAt: DateTime
- Relationships: creator, submissions[], problemCodes[]- id: Int (Primary Key)
- userId: Int (Foreign Key)
- problemId: Int (Foreign Key)
- code: String
- language: String
- status: String (queued/processing/accepted/rejected)
- runtime: Int (Optional)
- memory: Int (Optional)
- createdAt: DateTime
- Relationships: user, problem- id: Int (Primary Key)
- problemId: Int (Foreign Key)
- language: String
- wrapperCode: String
- boilerplateCode: String
- createdAt: DateTime
- updatedAt: DateTime
- Relationships: problem
- Unique Constraint: (problemId, language)This project is licensed under the ISC License - see the LICENSE file for details.
For issues, questions, or suggestions:
- Open an issue on GitHub: Issues
- Contact the development team
- GitHub Repository: Codura Coding Platform
- Live Demo: Live Video
- About Project: Project On Portfolio
