Skip to content

Codura is a scalable online coding platform where users solve problems, submit code, and receive real-time execution results using an event-driven backend, background job processing, and AWS EC2 with load balancing.

Notifications You must be signed in to change notification settings

chatanyapra/Codura_Coding_Platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

30 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Codura - Online Coding Platform

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.


πŸ“‹ Table of Contents


🎯 Overview

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

Key Features

  • 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

πŸ—οΈ Architecture & Flow

System Architecture & Flow Diagram

Codura Architecture Flow Diagram

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:

  1. User submits code through the client
  2. Request is routed through AWS Load Balancer to available EC2 instance
  3. Server validates and stores submission in PostgreSQL database
  4. Submission job is published to BullMQ queue via Redis Pub/Sub
  5. Worker picks up job from queue
  6. Judge0 API compiles and executes the code in isolated environment
  7. Results are updated in database
  8. 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

πŸ› οΈ Technology Stack

Frontend

  • 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

Backend

  • 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

Worker

  • Runtime: Node.js
  • Queue Manager: BullMQ
  • HTTP Client: Axios
  • Cache: ioRedis
  • Pub/Sub: Redis Pub/Sub for job subscription
  • Authentication: bcrypt
  • Validation: Zod

DevOps & Tools

  • 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

Deployment Benefits

  • 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

πŸ“ Project Structure

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

πŸš€ Installation

Prerequisites

  • 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)

Clone Repository

git clone https://github.com/chatanyapra/Codura_Coding_Platform.git
cd Codura_Coding_Platform

Install Dependencies

npm install

This command will install dependencies for all workspaces (client, server, worker, packages).

Start Judge0 Service

docker-compose -f docker-compose.judge0.yml up -d

This starts:

  • Judge0 Server (Code execution engine)
  • PostgreSQL (Judge0 database)
  • Redis (Judge0 cache)

βš™οΈ Configuration

Server Environment Variables

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_key

Client Environment Variables

Create .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.com

Worker Environment Variables

Create .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-1

πŸ› οΈ Development

Run All Services in Development Mode

npm run dev

This 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

Run Individual Services

# Client only
turbo dev --filter=client

# Server only (includes WebSocket server)
turbo dev --filter=server

# Worker only (includes Pub/Sub subscriber)
turbo dev --filter=worker

Lint Code

npm run lint

Format Code

npm run format

Check Types

npm run check-types

πŸ—οΈ Building & Deployment

Build All Applications

npm run build

This builds:

  • Client: Vite production build (dist/)
  • Server: TypeScript compilation (dist/)
  • Worker: TypeScript compilation (dist/)

Build Specific Application

turbo build --filter=client
turbo build --filter=server
turbo build --filter=worker

Local Production Deployment

  1. Build containers:

    docker build -t codura-client ./apps/client
    docker build -t codura-server ./apps/server
    docker build -t codura-worker ./apps/worker
  2. Deploy with Docker Compose (update docker-compose.yml with your services)

AWS EC2 Deployment

  1. 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
  2. Setup Load Balancer:

    • Create Application Load Balancer
    • Configure target groups for EC2 instances
    • Setup health checks
    • Configure SSL certificates for HTTPS

πŸ“‘ API Documentation

Authentication Endpoints

Method Endpoint Description
POST /api/users/signup Register new user
POST /api/users/login Login user
GET /api/users/profile Get user profile

Problem Endpoints

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)

Problem Code Endpoints

Method Endpoint Description
GET /api/problem-codes/:problemId Get boilerplate code
POST /api/problem-codes Add language template

Submission Endpoints

Method Endpoint Description
GET /api/submissions Get user submissions
GET /api/submissions/:id Get submission details
POST /api/submit Submit solution

WebSocket Events

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

Redis Pub/Sub Channels

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

πŸ—„οΈ Database Schema

User Model

- 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[]

Problem Model

- 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[]

Submission Model

- 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

ProblemCode Model

- id: Int (Primary Key)
- problemId: Int (Foreign Key)
- language: String
- wrapperCode: String
- boilerplateCode: String
- createdAt: DateTime
- updatedAt: DateTime
- Relationships: problem
- Unique Constraint: (problemId, language)

πŸ“ License

This project is licensed under the ISC License - see the LICENSE file for details.


πŸ™‹ Support

For issues, questions, or suggestions:

  • Open an issue on GitHub: Issues
  • Contact the development team

πŸ”— Links

About

Codura is a scalable online coding platform where users solve problems, submit code, and receive real-time execution results using an event-driven backend, background job processing, and AWS EC2 with load balancing.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •