Full-stack hotel room booking application built with Spring Boot, PostgreSQL, Docker, React, and JWT authentication.
The project includes a realistic booking workflow: customers can register, browse rooms, create bookings, view reserved dates, and manage their own reservations. Admin users can manage rooms and approve or reject booking requests.
Backend: Java 21, Spring Boot 3, Spring Security, Spring Data JPA, PostgreSQL, Flyway, JWT, Maven, Swagger/OpenAPI, Docker.
Frontend: React, Vite, React Router, Axios, React Datepicker, Plain CSS, nginx Docker image.
- Register and login
- Browse available hotel rooms
- View room type, capacity, price, and status
- Create booking requests
- Select dates using a date picker
- Reserved dates are disabled in the calendar
- View personal bookings
- Cancel pending or confirmed bookings
- Login as admin
- Create rooms
- Edit rooms
- Delete rooms
- View all booking requests
- Approve pending bookings
- Reject pending bookings
- JWT-based authentication
- Role-based authorization
- PostgreSQL persistence
- Flyway database migrations
- Global exception handling
- Booking conflict validation
- Reserved date ranges API
- Swagger API documentation
- Role-based navigation
- Protected frontend routes
- Booking modal with date picker
- Admin room management UI
- Admin booking management UI
- Responsive layout
hotel-booking-system/
client/
src/
api/
auth/
components/
pages/
Dockerfile
nginx.conf
.dockerignore
server/
src/main/java/com/wokioki/hotelbooking/
auth/
booking/
room/
user/
security/
config/
common/
src/main/resources/db/migration/
Dockerfile
.dockerignore
docker-compose.yml
README.md
| Role | Description |
|---|---|
CUSTOMER |
Can browse rooms, create bookings, view own bookings, and cancel own bookings |
ADMIN |
Can manage rooms and approve or reject bookings |
The application creates demo users on startup.
| Role | Password | |
|---|---|---|
| Admin | admin@hotel.com |
admin123 |
| Customer | customer@hotel.com |
customer123 |
Customer logs in
↓
Customer browses rooms
↓
Customer opens booking modal
↓
Frontend loads reserved dates
↓
Customer selects available dates
↓
Booking is created with PENDING status
↓
Admin reviews booking
↓
Admin approves or rejects booking
↓
Customer sees updated booking status
From the project root:
docker compose up --buildServices:
| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:8080 |
| Swagger UI | http://localhost:8080/swagger-ui/index.html |
| Health Check | http://localhost:8080/actuator/health |
| PostgreSQL | localhost:5433 |
Stop containers:
docker compose downRemove containers and database volume:
docker compose down -vStart PostgreSQL:
docker compose up postgresRun the backend:
cd server
mvn spring-boot:runBackend runs on:
http://localhost:8080
cd client
npm install
npm run devFrontend runs on:
http://localhost:5173
The frontend uses this backend URL by default:
http://localhost:8080
Swagger UI is available at:
http://localhost:8080/swagger-ui/index.html
To test protected endpoints:
- Login with
/api/auth/login - Copy the returned JWT token
- Click
Authorizein Swagger UI - Paste the token without the
Bearerprefix
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/register |
Register customer |
POST |
/api/auth/login |
Login |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/rooms |
Get rooms |
GET |
/api/rooms/available |
Search available rooms |
POST |
/api/rooms |
Create room |
PUT |
/api/rooms/{id} |
Update room |
DELETE |
/api/rooms/{id} |
Delete room |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/bookings |
Create booking |
GET |
/api/bookings/my |
Get current user's bookings |
GET |
/api/bookings |
Get all bookings |
GET |
/api/bookings/room/{roomId}/reserved-ranges |
Get reserved date ranges |
PATCH |
/api/bookings/{id}/approve |
Approve booking |
PATCH |
/api/bookings/{id}/reject |
Reject booking |
PATCH |
/api/bookings/{id}/cancel |
Cancel booking |
- Check-in date cannot be in the past.
- Check-out date must be after check-in.
- Only rooms with
AVAILABLEstatus can be booked. PENDINGandCONFIRMEDbookings block reserved dates.CANCELLEDandREJECTEDbookings do not block dates.- Customers can access only their own bookings.
- Admins can manage all bookings.
Database schema is managed with Flyway.
Main tables:
app_users
room_types
rooms
bookings
Implemented:
- Authentication and registration
- JWT security
- Role-based access control
- Room CRUD
- Room type CRUD
- Booking creation
- Booking cancellation
- Booking approval and rejection
- Reserved date calendar
- React frontend
- Protected frontend routes
- Dockerized backend
- Dockerized frontend
- Swagger API documentation