In-progressNestJSNextJSgRPC+7 more

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-progress

Technology Stack

NestJS
NextJS
gRPC
Kafka
Redis
PostgreSQL
MongoDB
Docker
Jenkins
TypeScript

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

NestJS TypeScript gRPC Kafka


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

FeatureDescription
Microservices9 independent gRPC services + edge/gateway/WS, communicating over Protocol Buffers
Event-DrivenKafka (53 topics) decouples submission, judging, scoring, notifications, and analytics
Multi-DatabasePostgreSQL (per-service DBs via pgBouncer) for relational data, MongoDB for contests
Sandboxed ExecutionJudge0 (8 workers) runs untrusted code with isolation and resource limits
Real-Timecdex-ws pushes submission results, leaderboard updates, and proctoring events over WebSockets
AuthGoogle OAuth2 + JWT, httpOnly cookie sessions (14d), short-lived OAuth exchange codes
Caching & QueuesRedis for caching, rate limiting, leaderboards (sorted sets), and the judge queue
Object StorageMinIO (S3-compatible) for test cases, submission source, avatars, and email templates
ProctoringViolation reporting and penalty tracking during contests
AIai-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

ServicePortTransportDataResponsibility
api-gateway3000REST--Single entry point; routes REST → gRPC, JWT auth, role guards, response enrichment
auth-edge3001HTTPRedisRegistration, login (email/password + Google OAuth), token + session management
judge-adapter3002HTTPRedisJudge0 integration: batch submit, webhook callbacks, result transformation
user-svc50051gRPCPostgreSQLUsers, profiles, roles (Student/Admin/Judge/Staff), ratings, statistics
problem-svc50052gRPCPostgreSQL + RedisProblems, test cases (bulk), difficulty/tags, visibility, partial scoring
contest-svc50053gRPCMongoDB + RedisContest lifecycle, leaderboards (ACM/ICPC/IOI), proctoring, freezing, virtual contests
submission-svc50054gRPCPostgreSQL + RedisSubmission intake, judge queue, verdicts (AC/WA/TLE/MLE/RE/CE), metrics
assignment-svc50055gRPCPostgreSQLAssignments, per-student progress, score aggregation, deadlines
notification-svc50056gRPC--Email + WebSocket notifications, template rendering, event triggers
payment-svc50057gRPCPostgreSQLPayments via Dodo Payments
ai-svc----RedisProblem assistance via Pinecone (vectors) + Groq (LLM)

Plus cdex-ws (:8081) — the dedicated WebSocket gateway that fans Kafka events out to connected clients.


Tech Stack

LayerTechnology
FrameworkNestJS 11 · TypeScript 5.9
MonorepoNx + Turborepo + pnpm workspaces
Inter-service RPCgRPC (@grpc/grpc-js) + Protocol Buffers (ts-proto)
Event StreamingApache Kafka (KRaft 3.7.1) — 53 topics
RealtimeSocket.io / WebSockets (cdex-ws)
Relational DBPostgreSQL 16 via pgBouncer · TypeORM
Document DBMongoDB 6 · Mongoose (contests)
Cache / QueueRedis 7 — cache, sessions, leaderboards (sorted sets), judge queue
Object StorageMinIO (S3-compatible) via AWS SDK v3
Code ExecutionJudge0 1.13.1 (8 workers, isolated PG + Redis)
AuthJWT · Passport · Google OAuth2 · bcrypt · Firebase Admin
ExternalResend + Nodemailer (email) · Firebase FCM (push) · Dodo Payments · Pinecone · Groq
FrontendNext.js 16 · React 19 · TailwindCSS · Zustand
ToolingESLint · 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)

ServiceImagePort
PostgreSQLpostgres:16-alpine5432
pgBounceredoburu/pgbouncer6432
MongoDBmongo:6.027017
Redisredis:7.0-alpine6379
Kafka (KRaft)apache/kafka:3.7.19092
Kafka UIprovectuslabs/kafka-ui8080
MinIOminio/minio9000 / 9001
Judge0 Serverjudge0/judge0:1.13.12358
Judge0 Workers (×8)judge0/judge0:1.13.1
Judge0 Postgrespostgres:16-alpine5435
Judge0 Redisredis:7.0-alpine6380

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

  1. Branch from the monorepo: feat/<what-you-are-building>.
  2. Update protos in cdex-server/libs / service proto dirs first (proto-first), then pnpm proto:generate.
  3. Keep changes scoped to a single apps/<service> where possible.
  4. pnpm lint and pnpm typecheck before opening a PR.
  5. Describe event-contract changes (Kafka topics) and migrations in the PR.

License

MIT License — see LICENSE for details.


Built by Varun Hotani

Developed by Varun Hotani
© 2026. All rights reserved.