A Mini Event Management System built with Node.js, Express, and MySQL.
- Runtime: Node.js
- Framework: Express.js
- Database: MySQL 8
- Validation: express-validator
- Docs: OpenAPI 3.0 / Swagger UI
- Other: uuid, dotenv, mysql2
event-booking-system/
├── src/
│ ├── app.js # Entry point
│ ├── config/
│ │ └── db.js # MySQL connection pool
│ ├── controllers/
│ │ ├── eventController.js
│ │ ├── bookingController.js
│ │ └── attendanceController.js
│ ├── routes/
│ │ ├── eventRoutes.js
│ │ ├── bookingRoutes.js
│ │ ├── userRoutes.js
│ │ └── attendanceRoutes.js
│ └── middleware/
│ ├── errorHandler.js
│ └── validate.js
├── docs/
│ └── swagger.yaml # OpenAPI spec
├── schema.sql # Database schema + seed data
├── postman_collection.json
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md
One command starts both MySQL and the API server.
# 1. Clone the repository
git clone <your-repo-url>
cd event-booking-system
# 2. Start everything
docker-compose up --build
# API is live at: http://localhost:3000
# Swagger docs at: http://localhost:3000/api-docsTo stop:
docker-compose downTo stop and wipe the database volume:
docker-compose down -v- Node.js >= 18
- MySQL 8 running locally
# 1. Clone the repository
git clone <your-repo-url>
cd event-booking-system
# 2. Install dependencies
npm install
# 3. Configure environment variables
cp .env.example .env
# Edit .env and fill in your MySQL credentials
# 4. Set up the database
mysql -u root -p < schema.sql
# This creates the database, tables, and seed data
# 5. Start the server
npm start # production
npm run dev # development (nodemon, auto-reload)| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
HTTP port |
DB_HOST |
localhost |
MySQL host |
DB_PORT |
3306 |
MySQL port |
DB_USER |
root |
MySQL username |
DB_PASSWORD |
(empty) | MySQL password |
DB_NAME |
event_booking_db |
MySQL database name |
| Method | Endpoint | Description |
|---|---|---|
| GET | /events |
List all upcoming events |
| POST | /events |
Create a new event |
| POST | /bookings |
Book a ticket (transactional, race-safe) |
| GET | /users/:id/bookings |
Get all bookings for a user |
| POST | /events/:id/attendance |
Record attendance using a booking code |
| GET | /health |
Health check |
Full interactive documentation: http://localhost:3000/api-docs
POST /bookings uses a MySQL transaction with SELECT … FOR UPDATE to lock
the event row before decrementing remaining_tickets. This ensures that two
simultaneous requests cannot both read remaining_tickets = 1 and both succeed.
Each booking receives a UUID v4 as its booking_code. This is returned to
the user post-booking and is required for event check-in via /events/:id/attendance.
- A user cannot book the same event twice (
UNIQUE KEY uq_user_event). - A booking code cannot be used for entry more than once (
UNIQUE KEY uq_attendance_booking).
- Open Postman
- Click Import → select
postman_collection.json - Set the
baseUrlvariable tohttp://localhost:3000(already set by default) - Run requests in order: create event → book ticket → copy
booking_code→ record attendance
The schema.sql file contains the full schema with all tables, constraints, and seed data.
To re-export after making changes:
mysqldump -u root -p --no-data event_booking_db > schema.sql