A modern, scalable live chat backend built with TypeScript, Express, Prisma, and MongoDB. Features real-time communication via WebSockets, JWT authentication, and comprehensive API documentation.
This project was primarily created for the "WEB I" course at HF-Informatik.
- Real-time Communication: WebSocket support for instant message delivery
- Secure Authentication: JWT-based authentication with password hashing
- Type-Safe: Full TypeScript implementation with Prisma ORM
- Clean Architecture: Layered architecture (Controllers > Services > Repositories)
- API Documentation: Interactive Swagger/OpenAPI documentation
- Comprehensive Testing: Full test coverage with Vitest
- Security: Rate limiting, helmet.js, input validation with Zod
- Database: MongoDB with Prisma ORM
- Runtime: Node.js
- Language: TypeScript
- Framework: Express.js
- Database: MongoDB (with replica set support)
- ORM: Prisma
- Authentication: JWT (jsonwebtoken)
- Validation: Zod
- Testing: Vitest + Supertest
- Documentation: Swagger/OpenAPI
- Logging: Pino
- WebSockets: ws (WebSocket library)
- Code Quality: ESLint + Prettier
- Node.js >= 22
- MongoDB >= 7.0 (configured as replica set)
- npm or yarn
- Clone the repository:
git clone <repository-url>
cd livechat-backend- Install dependencies:
npm install- Configure environment variables:
cp .env.example .envEdit .env with your configuration (see Environment Variables section below).
- Set up MongoDB replica set (required for Prisma transactions):
Windows:
- Edit
mongod.cfg(usually inC:\Program Files\MongoDB\Server\<version>\bin\) - Add:
replication: replSetName: "rs0"
- Restart MongoDB service
- Initialize replica set:
mongosh rs.initiate()
Linux/Mac:
- Add to your MongoDB config:
replication: replSetName: "rs0"
- Restart MongoDB
- Initialize:
mongoshthenrs.initiate()
- Generate Prisma client:
npx prisma generate- (Optional) Seed the database:
npm run seedCreate a .env file in the project root with the following variables:
# Server Configuration
NODE_ENV=development
PORT=3000
URL=http://localhost
BEHIND_PROXY=false
# Database
DATABASE_URL=mongodb://localhost:27017/livechat
# JWT Secret (generate a secure random string)
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
# Docker
DOCKER=falseImportant: Set BEHIND_PROXY=true if running behind a reverse proxy (nginx, Apache, etc.)
npm run devServer will start at http://localhost:3000
npm run build
npm startWhen running behind a reverse proxy (e.g., nginx, Apache), ensure WebSocket support is enabled.
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Important: Set BEHIND_PROXY=true in your .env file when using a reverse proxy.
Run all tests:
npm testRun tests with coverage:
npm run test:coverageRun tests in watch mode:
npm run test:watchOnce the server is running, access the interactive Swagger documentation at:
http://localhost:3000/api/docs
Authentication:
POST /api/v1/auth/register- Register a new userPOST /api/v1/auth/login- Login and receive JWT tokenPOST /api/v1/auth/logout- Logout user
Users:
GET /api/v1/users- Get all users (public)GET /api/v1/users/:id- Get user by ID (public)PUT /api/v1/users/:id- Update user profile (authenticated, own profile only)DELETE /api/v1/users/:id- Delete user account (authenticated, own account only)
Chat Messages:
GET /api/v1/messages- Get all messages (public)GET /api/v1/messages/:id- Get message by ID (public)POST /api/v1/messages- Create new message (authenticated)PUT /api/v1/messages/:id- Update message (authenticated, own message only)DELETE /api/v1/messages/:id- Delete message (authenticated, own message only)
Connect to WebSocket at ws://localhost:3000
Events broadcast to all clients:
new_login- User logged innew_message- New chat message createdchanged_message- Message updateddeleted_message- Message deletedchanged_user- User profile updateddeleted_user- User account deletednew_logout- User logged out
livechat-backend/
├── prisma/
│ └── schema.prisma # Prisma database schema
├── src/
│ ├── config/ # Configuration files
│ │ ├── env.ts # Environment validation
│ │ ├── logger.ts # Pino logger setup
│ │ └── swagger.ts # Swagger/OpenAPI config
│ ├── controllers/ # Request handlers
│ │ ├── auth.controller.ts
│ │ ├── chat.controller.ts
│ │ └── user.controller.ts
│ ├── infrastructure/ # External services
│ │ ├── database.ts # Prisma client singleton
│ │ └── websocket.ts # WebSocket server setup
│ ├── middleware/ # Express middleware
│ │ ├── auth.ts # JWT authentication
│ │ ├── errorHandler.ts # Global error handler
│ │ └── validate.ts # Zod validation middleware
│ ├── repositories/ # Data access layer
│ │ ├── chatMessage.repository.ts
│ │ └── user.repository.ts
│ ├── routes/ # API routes
│ │ └── v1/
│ │ ├── index.ts
│ │ ├── auth.routes.ts
│ │ ├── chat.routes.ts
│ │ └── user.routes.ts
│ ├── services/ # Business logic
│ │ ├── auth.service.ts
│ │ ├── chat.service.ts
│ │ └── user.service.ts
│ ├── tests/ # Test files
│ │ ├── setup.ts
│ │ ├── helpers.ts
│ │ ├── auth.test.ts
│ │ ├── chat.test.ts
│ │ └── user.test.ts
│ ├── utils/ # Utility functions
│ │ └── errors.ts # Custom error classes
│ ├── validators/ # Zod schemas
│ │ ├── auth.validator.ts
│ │ ├── chat.validator.ts
│ │ └── user.validator.ts
│ └── server.ts # Application entry point
├── .env.example # Environment variables template
├── package.json
├── tsconfig.json
└── vitest.config.ts # Test configuration
This project follows clean architecture principles with clear separation of concerns:
- Controllers: Handle HTTP requests/responses, delegate to services
- Services: Contain business logic, orchestrate repositories
- Repositories: Data access layer, interact with database via Prisma
- Validators: Input validation using Zod schemas
- Middleware: Cross-cutting concerns (auth, validation, error handling)
- Password Hashing: bcrypt with salt rounds
- JWT Tokens: Secure token-based authentication (1-hour expiration)
- Rate Limiting: Protection against brute force attacks
- Input Validation: Zod schemas validate all inputs
- Helmet.js: Security headers
- CORS: Configurable cross-origin resource sharing
- Ownership Validation: Users can only modify their own resources
npm run dev # Start development server with hot reload
npm run build # Build for production
npm start # Start production server
npm test # Run tests
npm run test:coverage # Run tests with coverage
npm run lint # Check code with ESLint
npm run lint:fix # Auto-fix ESLint issues
npm run format # Format code with Prettier
npm run format:check # Check code formatting
npm run typecheck # Type check with TypeScriptView database in Prisma Studio:
npx prisma studioCreate a new migration:
npx prisma migrate dev --name migration-nameReset database:
npx prisma migrate resetBuild and run with Docker:
docker build -t livechat-backend .
docker run -p 3000:3000 -e DATABASE_URL="mongodb://host:27017/livechat" livechat-backendOr use Docker Compose:
docker-compose up --buildThe codebase follows these principles:
- Self-documenting code with clear naming
- JSDoc comments for public APIs
- Minimal comments (explain "why", not "what")
- TypeScript strict mode
- Comprehensive error handling
- Full test coverage
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License.
Nicolas Dumermuth
For issues and questions, please open an issue in the GitHub repository.