CDeX
Event-driven competitive programming & assignment platform built as a NestJS. gRPC internal RPC, Kafka event streaming, Redis caching/pubsub, Postgres + MongoDB persistence, MinIO artifact storage, Judge0 for code execution, and realtime via WebSockets.
Timeline
Role
Status
In-progressTechnology Stack
CDeX
A production-grade, microservices platform for competitive programming, contests, and assignments — built as a NestJS monorepo with gRPC services, Kafka event streaming, and real-time WebSockets. Students submit code, Judge0 executes it in a sandbox, and live leaderboards stream to every participant.
NestJS monorepo · 11 microservices · gRPC + Protobuf · Kafka (53 topics) · multi-database
Architecture · Microservices · Tech Stack · Getting Started
Overview
CDeX is a complete backend platform for running coding problems, code submissions, contests, and assignments at scale. It is built with NestJS and a monorepo (Nx + Turborepo + pnpm) architecture, with 9 gRPC microservices behind a REST API gateway, an auth edge, a dedicated WebSocket gateway, and a Judge0 integration adapter.
The platform manages:
- Coding Problems — programming challenges with versioned test cases
- Code Submissions — judged in multiple languages (C++, Python, Java, …)
- Contests — competitive events with real-time leaderboards (ACM / ICPC / IOI scoring)
- Assignments — student assignments with per-student progress tracking
- User Management — role-based access (Student, Admin, Judge, Staff) with JWT + Google OAuth2
- Real-time Notifications — event-driven updates over email and WebSocket
Key Features
| Feature | Description |
|---|---|
| Microservices | 9 independent gRPC services + edge/gateway/WS, communicating over Protocol Buffers |
| Event-Driven | Kafka (53 topics) decouples submission, judging, scoring, notifications, and analytics |
| Multi-Database | PostgreSQL (per-service DBs via pgBouncer) for relational data, MongoDB for contests |
| Sandboxed Execution | Judge0 (8 workers) runs untrusted code with isolation and resource limits |
| Real-Time | cdex-ws pushes submission results, leaderboard updates, and proctoring events over WebSockets |
| Auth | Google OAuth2 + JWT, httpOnly cookie sessions (14d), short-lived OAuth exchange codes |
| Caching & Queues | Redis for caching, rate limiting, leaderboards (sorted sets), and the judge queue |
| Object Storage | MinIO (S3-compatible) for test cases, submission source, avatars, and email templates |
| Proctoring | Violation reporting and penalty tracking during contests |
| AI | ai-svc integrates Pinecone + Groq LLM for problem assistance |
Architecture
1. Service Topology
2. Data Layer
PostgreSQL Databases: user_svc_db · problem_svc_db · submission_svc_db · assignment_svc_db · notification_svc_db · payment_svc_db
3. Kafka Event Flows
4. Redis Usage
5. S3 Storage & External Services
6. Judge Flow
7. WebSocket Message Types (cdex-ws)
Room Types: contest:{id} · assignment:{id} · submission:{id} · college:{id} · batch:{id} · problem:{id} · user:{id} · global
8. Flow: Code Submission → Verdict
9. Flow: Auth Login
10. Flow: Contest Lifecycle
Microservices
| Service | Port | Transport | Data | Responsibility |
|---|---|---|---|---|
| api-gateway | 3000 | REST | -- | Single entry point; routes REST → gRPC, JWT auth, role guards, response enrichment |
| auth-edge | 3001 | HTTP | Redis | Registration, login (email/password + Google OAuth), token + session management |
| judge-adapter | 3002 | HTTP | Redis | Judge0 integration: batch submit, webhook callbacks, result transformation |
| user-svc | 50051 | gRPC | PostgreSQL | Users, profiles, roles (Student/Admin/Judge/Staff), ratings, statistics |
| problem-svc | 50052 | gRPC | PostgreSQL + Redis | Problems, test cases (bulk), difficulty/tags, visibility, partial scoring |
| contest-svc | 50053 | gRPC | MongoDB + Redis | Contest lifecycle, leaderboards (ACM/ICPC/IOI), proctoring, freezing, virtual contests |
| submission-svc | 50054 | gRPC | PostgreSQL + Redis | Submission intake, judge queue, verdicts (AC/WA/TLE/MLE/RE/CE), metrics |
| assignment-svc | 50055 | gRPC | PostgreSQL | Assignments, per-student progress, score aggregation, deadlines |
| notification-svc | 50056 | gRPC | -- | Email + WebSocket notifications, template rendering, event triggers |
| payment-svc | 50057 | gRPC | PostgreSQL | Payments via Dodo Payments |
| ai-svc | -- | -- | Redis | Problem assistance via Pinecone (vectors) + Groq (LLM) |
Plus cdex-ws (:8081) — the dedicated WebSocket gateway that fans Kafka events out to connected clients.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | NestJS 11 · TypeScript 5.9 |
| Monorepo | Nx + Turborepo + pnpm workspaces |
| Inter-service RPC | gRPC (@grpc/grpc-js) + Protocol Buffers (ts-proto) |
| Event Streaming | Apache Kafka (KRaft 3.7.1) — 53 topics |
| Realtime | Socket.io / WebSockets (cdex-ws) |
| Relational DB | PostgreSQL 16 via pgBouncer · TypeORM |
| Document DB | MongoDB 6 · Mongoose (contests) |
| Cache / Queue | Redis 7 — cache, sessions, leaderboards (sorted sets), judge queue |
| Object Storage | MinIO (S3-compatible) via AWS SDK v3 |
| Code Execution | Judge0 1.13.1 (8 workers, isolated PG + Redis) |
| Auth | JWT · Passport · Google OAuth2 · bcrypt · Firebase Admin |
| External | Resend + Nodemailer (email) · Firebase FCM (push) · Dodo Payments · Pinecone · Groq |
| Frontend | Next.js 16 · React 19 · TailwindCSS · Zustand |
| Tooling | ESLint · Prettier · Docker & Docker Compose |
Repository Layout
The product is split across several repos/workspaces:
CDeX/
├── cdex-server/ # NestJS monorepo — all backend microservices
│ ├── apps/
│ │ ├── api-gateway/ # REST entry point (:3000)
│ │ ├── auth-edge/ # Auth edge: OAuth + sessions (:3001)
│ │ ├── judge-adapter/ # Judge0 integration (:3002)
│ │ ├── user-svc/ # Users, roles (gRPC :50051)
│ │ ├── problem-svc/ # Problems + test cases (gRPC :50052)
│ │ ├── contest-svc/ # Contests + leaderboards (gRPC :50053)
│ │ ├── submission-svc/ # Submissions + judge queue (gRPC :50054)
│ │ ├── assignment-svc/ # Assignments + progress (gRPC :50055)
│ │ ├── notification-svc/ # Email + WS notifications (gRPC :50056)
│ │ ├── payment-svc/ # Payments (gRPC :50057)
│ │ └── ai-svc/ # Pinecone + Groq assistance
│ ├── libs/ # Shared: kafka, redis, storage
│ ├── docker/ # Service Dockerfiles
│ └── docker-compose.yml # Full infra stack
│
├── cdex-client/ # Next.js 16 / React 19 student & professor app
├── cdex-super-admin/ # Next.js super-admin console
├── cdex-ws/ # WebSocket gateway (:8081)
├── landing/ # Marketing landing page
└── diagrams/ # Architecture diagrams
Infrastructure (Docker)
| Service | Image | Port |
|---|---|---|
| PostgreSQL | postgres:16-alpine | 5432 |
| pgBouncer | edoburu/pgbouncer | 6432 |
| MongoDB | mongo:6.0 | 27017 |
| Redis | redis:7.0-alpine | 6379 |
| Kafka (KRaft) | apache/kafka:3.7.1 | 9092 |
| Kafka UI | provectuslabs/kafka-ui | 8080 |
| MinIO | minio/minio | 9000 / 9001 |
| Judge0 Server | judge0/judge0:1.13.1 | 2358 |
| Judge0 Workers (×8) | judge0/judge0:1.13.1 | — |
| Judge0 Postgres | postgres:16-alpine | 5435 |
| Judge0 Redis | redis:7.0-alpine | 6380 |
Getting Started
Prerequisites
- Node.js 20+ and pnpm
- Docker & Docker Compose
1. Start infrastructure
cd cdex-server
docker compose up -d # PostgreSQL, pgBouncer, MongoDB, Redis, Kafka, MinIO, Judge0 (+8 workers)
2. Install & generate protos
pnpm install
pnpm proto:generate # generate TypeScript gRPC stubs from .proto files
3. Run the services
# Everything in watch mode
pnpm dev
# …or a single service
pnpm dev:api-gateway
pnpm dev:submission-svc
4. Run the frontends
cd ../cdex-client && pnpm install && pnpm dev # student/professor app
cd ../cdex-ws && pnpm install && pnpm dev # WebSocket gateway
API Surface (api-gateway)
/api/v1/auth/* Authentication
/api/v1/user/* User management
/api/v1/problem/* Problem CRUD
/api/v1/submission/* Code submission
/api/v1/contest/* Contest management
/api/v1/assignment/* Assignment management
Contributing
- Branch from the monorepo:
feat/<what-you-are-building>. - Update protos in
cdex-server/libs/ serviceprotodirs first (proto-first), thenpnpm proto:generate. - Keep changes scoped to a single
apps/<service>where possible. pnpm lintandpnpm typecheckbefore opening a PR.- Describe event-contract changes (Kafka topics) and migrations in the PR.
License
MIT License — see LICENSE for details.
Built by Varun Hotani
