A full-stack food delivery application built with Spring Boot and React, featuring role-based access control, real-time order management, and secure payment integration.
- Overview
- Technology Stack
- System Architecture
- Features
- Prerequisites
- Installation
- Configuration
- Running the Application
- API Documentation
- Database Schema
- Troubleshooting
- Future Enhancements
BiteRush is an enterprise-grade food delivery platform that connects customers with restaurants. The application supports three user roles: Customers, Restaurant Owners, and Administrators. It provides comprehensive features for menu management, order processing, cart operations, and payment handling.
Key Capabilities:
- Secure user authentication and authorization
- Role-based access control (RBAC)
- Real-time order tracking
- Restaurant and menu management
- Shopping cart functionality
- Payment gateway integration
- Ingredient and category management
- Framework: Spring Boot 3.5
- Security: Spring Security with JWT authentication
- ORM: Spring Data JPA with Hibernate
- Database: MySQL 8.0
- Password Encryption: BCrypt
- Build Tool: Maven
- API Architecture: RESTful
- Library: React 18.2
- State Management: Redux with Redux Thunk
- UI Framework: Material-UI (MUI)
- Routing: React Router v6
- HTTP Client: Axios
- Form Handling: Formik
- Styling: Tailwind CSS
- Payment Gateway: Stripe
- Image Storage: Cloudinary
- Session Management: Stateless (JWT-based)
┌─────────────────────────────────────────────────────────┐
│ Client Layer │
│ (React + Redux Frontend) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Controller Layer │
│ (UserController, RestaurantController, OrderController) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Service Layer │
│ (Business Logic & Transaction Management) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Repository Layer │
│ (Spring Data JPA Repositories) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ MySQL Database │
└─────────────────────────────────────────────────────────┘
User Login → Controller → JwtProvider.generateToken()
→ Service validates credentials
→ JWT Token returned to client
→ Client stores token in localStorage
→ Subsequent requests include JWT in Authorization header
→ JwtTokenValidator intercepts and validates
→ Allows/Denies access based on token validity
- User registration with email validation
- Secure login with JWT token generation
- Password encryption using BCrypt
- Role-based authorization (CUSTOMER, RESTAURANT_OWNER, ADMIN)
- User profile management
- Restaurant registration and profile setup
- Operating hours configuration
- Cuisine type categorization
- Multiple image upload support
- Restaurant status management (OPEN/CLOSED)
- Address and contact information
- Create, read, update, delete menu items
- Category-based organization
- Ingredient management with stock tracking
- Price and availability configuration
- Vegetarian/non-vegetarian classification
- Seasonal item support
- Real-time order creation and tracking
- Order status workflow (PENDING → COMPLETED → DELIVERED)
- Order history for customers
- Restaurant-specific order management
- Total price calculation with item quantities
- Add/remove items from cart
- Update item quantities
- Clear cart functionality
- Real-time price calculation
- Persistent cart storage
- Stripe payment gateway integration
- Secure payment processing
- Payment status tracking
- Order confirmation on successful payment
- Search menu items by name
- Filter restaurants by cuisine type
- Filter by vegetarian options
- Category-based filtering
- Add restaurants to favorites
- Remove from favorites
- View favorite restaurants list
Before you begin, ensure you have the following installed:
- Java Development Kit (JDK): Version 17 or higher
- Maven: Version 3.8 or higher
- Node.js: Version 16 or higher
- npm: Version 8 or higher
- MySQL: Version 8.0 or higher
- IntelliJ IDEA or Eclipse (for backend development)
- Visual Studio Code (for frontend development)
- Postman (for API testing)
- MySQL Workbench (for database management)
Check if you have the required software:
# Java
java -version
# Expected: java version "17.x.x" or higher
# Maven
mvn -version
# Expected: Apache Maven 3.8.x or higher
# Node.js
node --version
# Expected: v16.x.x or higher
# npm
npm --version
# Expected: 8.x.x or higher
# MySQL
mysql --version
# Expected: mysql Ver 8.0.xIf using Git:
git clone <repository-url>
cd BiteRushIf downloaded as ZIP:
- Extract the ZIP file to your desired location
- Navigate to the BiteRush directory
- Start MySQL server:
# Windows
net start MySQL80
# macOS/Linux
sudo service mysql start- Create database:
-- Login to MySQL
mysql -u root -p
-- Create database
CREATE DATABASE biterush;
-- Create user (optional, recommended for production)
CREATE USER 'biterush_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON biterush.* TO 'biterush_user'@'localhost';
FLUSH PRIVILEGES;
-- Exit MySQL
EXIT;- Navigate to backend directory:
cd BiteRush- Update
application.properties:
# Windows
notepad src/main/resources/application.properties
# macOS/Linux
nano src/main/resources/application.properties- Configure the following properties:
# Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/biterush
spring.datasource.username=root
spring.datasource.password=your_mysql_password
# JPA/Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
# Server Configuration
server.port=5465
# JWT Configuration (change in production)
jwt.secret=your_secret_key_min_256_bits_for_HS256_algorithm
jwt.expiration=86400000mvn clean installThis command will:
- Download all required dependencies
- Compile the source code
- Run tests (if any)
- Package the application
cd biterush-frontendnpm installThis will install all required packages listed in package.json, including:
- React and React DOM
- Redux and React-Redux
- Material-UI components
- Axios for HTTP requests
- React Router for navigation
- Formik for form handling
- And many more...
- Open
src/component/Config/api.js - Verify the API URL matches your backend:
export const API_URL = "http://localhost:5465";For production deployment, use environment variables instead of hardcoding values.
Create a .env file (not committed to version control):
DB_URL=jdbc:mysql://localhost:3306/biterush
DB_USERNAME=biterush_user
DB_PASSWORD=secure_password
JWT_SECRET=your_production_secret_key_min_256_bits
JWT_EXPIRATION=86400000
STRIPE_API_KEY=sk_live_your_stripe_key
CLOUDINARY_CLOUD_NAME=your_cloudinary_name
CLOUDINARY_API_KEY=your_cloudinary_key
CLOUDINARY_API_SECRET=your_cloudinary_secretCreate .env file in frontend directory:
REACT_APP_API_URL=http://localhost:5465
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_your_stripe_public_keyThe backend is configured to accept requests from:
- http://localhost:3000 (default React port)
- http://localhost:5465 (backend port)
To modify allowed origins, update AppConfig.java:
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000", "http://localhost:5465")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true);
}# Navigate to backend directory
cd BiteRush
# Run the application
mvn spring-boot:run- Open the project in IntelliJ IDEA or Eclipse
- Locate the main class (usually
Application.javaorBiteRushApplication.java) - Right-click and select "Run"
# Build JAR file
mvn clean package
# Run JAR file
java -jar target/biterush-0.0.1-SNAPSHOT.jarThe backend will start on http://localhost:5465
You should see output similar to:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.5.0)
...
Started BiteRushApplication in 5.432 seconds
# Navigate to frontend directory
cd biterush-frontend
# Start development server
npm startThe frontend will automatically open in your browser at http://localhost:3000
If it doesn't open automatically, navigate to http://localhost:3000 manually.
POST /api/auth/signup
Content-Type: application/json
{
"fullName": "John Doe",
"email": "john@example.com",
"password": "securePassword123",
"role": "ROLE_CUSTOMER"
}
Response: 200 OK
{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"message": "Register success",
"role": "ROLE_CUSTOMER"
}POST /api/auth/signin
Content-Type: application/json
{
"email": "john@example.com",
"password": "securePassword123"
}
Response: 200 OK
{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"message": "Login success",
"role": "ROLE_CUSTOMER"
}POST /api/admin/restaurants
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"name": "Tasty Bites",
"description": "Best Italian food in town",
"cuisineType": "Italian",
"address": {
"streetAddress": "123 Main St",
"city": "New York",
"stateProvince": "NY",
"postalCode": "10001",
"country": "USA"
},
"contactInformation": {
"email": "info@tastybites.com",
"mobile": "+1234567890",
"instagram": "@tastybites",
"twitter": "@tastybites"
},
"openingHours": "9:00 AM - 10:00 PM",
"images": ["url1", "url2"]
}
Response: 201 Created
{
"id": 1,
"name": "Tasty Bites",
"description": "Best Italian food in town",
"open": true,
...
}GET /api/restaurants
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
[
{
"id": 1,
"name": "Tasty Bites",
"cuisineType": "Italian",
"address": {...},
"open": true,
...
}
]GET /api/restaurants/search?keyword=pizza
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
[...]POST /api/admin/food
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"name": "Margherita Pizza",
"description": "Classic Italian pizza",
"price": 12.99,
"category": {
"id": 1
},
"images": ["pizza_url"],
"restaurantId": 1,
"vegetarian": true,
"seasonal": false,
"ingredients": [
{"id": 1},
{"id": 2}
]
}
Response: 201 Created
{
"id": 1,
"name": "Margherita Pizza",
"price": 12.99,
...
}GET /api/food/restaurant/{restaurantId}
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
[...]GET /api/food/search?name=pizza
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
[...]PUT /api/cart/add
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"foodId": 1,
"quantity": 2
}
Response: 200 OK
{
"id": 1,
"customer": {...},
"total": 25.98,
"items": [...]
}PUT /api/cart-item/update
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"cartItemId": 1,
"quantity": 3
}
Response: 200 OK
{...}DELETE /api/cart-item/{id}/remove
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
{...}PUT /api/cart/clear
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
{...}POST /api/order
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"restaurantId": 1,
"deliveryAddress": {
"streetAddress": "456 Oak Ave",
"city": "New York",
"stateProvince": "NY",
"postalCode": "10002",
"country": "USA"
}
}
Response: 201 Created
{
"id": 1,
"customer": {...},
"restaurant": {...},
"totalAmount": 25.98,
"orderStatus": "PENDING",
"items": [...]
}GET /api/order/user
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
[...]PUT /api/admin/order/{orderId}/{orderStatus}
Authorization: Bearer <JWT_TOKEN>
Response: 200 OK
{...}User (1) ────────── (*) Address
│
│ (1)
│
│ (1)
│
Cart (1) ────────── (*) CartItem
│ │
│ │ (*)
│ │
│ └─────── (1) Food
│
│ (1)
│
└─────────────────────── (*) Order
│
│ (*1)
│
Restaurant (1) ────── (*) Food
│ │
│ │ (*)
│ │
│ └── (1) Category
│ │
│ └── (*) IngredientsItem
│
└─────────── (*) IngredientCategory
users
- id (Primary Key)
- full_name
- email (Unique)
- password (BCrypt encrypted)
- role (CUSTOMER, RESTAURANT_OWNER, ADMIN)
restaurant
- id (Primary Key)
- owner_id (Foreign Key → users)
- name
- description
- cuisine_type
- opening_hours
- open (boolean)
food
- id (Primary Key)
- name
- description
- price
- food_category_id (Foreign Key → category)
- restaurant_id (Foreign Key → restaurant)
- is_vegetarian
- is_seasonal
- is_available
orders
- id (Primary Key)
- customer_id (Foreign Key → users)
- restaurant_id (Foreign Key → restaurant)
- total_amount
- order_status (PENDING, COMPLETED, DELIVERED, CANCELLED)
- created_at
cart
- id (Primary Key)
- customer_id (Foreign Key → users)
- total
cart_item
- id (Primary Key)
- cart_id (Foreign Key → cart)
- food_id (Foreign Key → food)
- quantity
- total_price
Error: Web server failed to start. Port 5465 was already in use.
Solution:
# Windows - Find and kill process
netstat -ano | findstr :5465
taskkill /PID <process_id> /F
# macOS/Linux - Find and kill process
lsof -i :5465
kill -9 <process_id>
# Or change port in application.properties
server.port=8080Error: Communications link failure
Solutions:
- Verify MySQL is running:
# Windows
net start MySQL80
# macOS/Linux
sudo service mysql status- Check database credentials in
application.properties - Verify database exists:
SHOW DATABASES;- Check firewall settings (MySQL uses port 3306)
Error: JWT signature does not match
Solution:
Ensure jwt.secret in application.properties is at least 256 bits (32 characters) for HS256 algorithm:
jwt.secret=ThisIsASecretKeyForJWTTokenGenerationMinimum256BitsError: Table doesn't exist
Solution:
- Set
spring.jpa.hibernate.ddl-auto=create(first time only) - Restart application
- Change back to
updatefor subsequent runs
Error: Cannot find module 'react'
Solution:
# Delete node_modules and reinstall
rm -rf node_modules package-lock.json
npm installError: CORS policy: No 'Access-Control-Allow-Origin' header
Solution:
- Verify backend CORS configuration in
AppConfig.java - Ensure frontend URL is in allowed origins
- Clear browser cache (Ctrl + Shift + Delete)
- Verify backend is running on correct port
Error: Network Error / Connection refused
Solutions:
- Verify backend is running (
http://localhost:5465) - Check
API_URLinsrc/component/Config/api.js - Verify proxy in
package.json:
"proxy": "http://localhost:5465"Error: Cannot read property of undefined
Solution: Check Redux DevTools in browser:
- Install Redux DevTools Extension
- Inspect state structure
- Verify actions are dispatching correctly
- Check reducer logic
Error: Cannot add or update a child row: foreign key constraint fails
Solution: Ensure referenced entities exist before creating relationships:
// First create/fetch restaurant
Restaurant restaurant = restaurantRepository.findById(id)
.orElseThrow(() -> new Exception("Restaurant not found"));
// Then create food with valid restaurant
Food food = new Food();
food.setRestaurant(restaurant);Version 2.0
- Real-time order tracking with WebSocket
- Push notifications for order updates
- Multi-language support (i18n)
- Dark mode toggle
- Advanced analytics dashboard
Version 2.1
- Integration with multiple payment gateways (PayPal, Razorpay)
- Loyalty points and rewards system
- Coupon and discount management
- Restaurant reviews and ratings
- Driver/Delivery partner management
Version 3.0
- Mobile applications (React Native)
- AI-based food recommendations
- Voice ordering capability
- Scheduled orders
- Subscription meal plans
- Implement Redis caching for frequently accessed data
- Add comprehensive unit and integration tests (JUnit, Mockito)
- Implement API rate limiting
- Add request/response logging with Logback
- Implement database indexing for performance optimization
- Add database migration with Flyway or Liquibase
- Implement Circuit Breaker pattern for external API calls
- Add comprehensive API documentation with Swagger/OpenAPI
BiteRush/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/biterush/
│ │ │ ├── config/ # Configuration classes
│ │ │ │ ├── AppConfig.java
│ │ │ │ ├── JwtProvider.java
│ │ │ │ └── JwtTokenValidator.java
│ │ │ ├── controller/ # REST Controllers
│ │ │ │ ├── AuthController.java
│ │ │ │ ├── RestaurantController.java
│ │ │ │ ├── FoodController.java
│ │ │ │ ├── CartController.java
│ │ │ │ └── OrderController.java
│ │ │ ├── model/ # Entity models
│ │ │ │ ├── User.java
│ │ │ │ ├── Restaurant.java
│ │ │ │ ├── Food.java
│ │ │ │ ├── Cart.java
│ │ │ │ ├── Order.java
│ │ │ │ └── ...
│ │ │ ├── repository/ # Data access layer
│ │ │ │ ├── UserRepository.java
│ │ │ │ ├── RestaurantRepository.java
│ │ │ │ └── ...
│ │ │ ├── service/ # Business logic
│ │ │ │ ├── UserService.java
│ │ │ │ ├── RestaurantService.java
│ │ │ │ └── ...
│ │ │ ├── dto/ # Data Transfer Objects
│ │ │ └── exception/ # Custom exceptions
│ │ └── resources/
│ │ ├── application.properties
│ │ └── static/
│ └── test/ # Test files
│ └── java/
├── biterush-frontend/
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── component/
│ │ │ ├── Auth/ # Authentication components
│ │ │ ├── Cart/ # Cart components
│ │ │ ├── Config/ # API configuration
│ │ │ ├── Home/ # Home page components
│ │ │ ├── Navbar/ # Navigation components
│ │ │ ├── Profile/ # User profile components
│ │ │ ├── Restaurant/ # Restaurant components
│ │ │ └── State/ # Redux state management
│ │ │ ├── Authentication/
│ │ │ ├── Restaurant/
│ │ │ ├── Menu/
│ │ │ ├── Cart/
│ │ │ └── Order/
│ │ ├── AdminComponent/ # Admin dashboard
│ │ ├── Routers/ # Route configuration
│ │ ├── Theme/ # Material-UI theme
│ │ └── App.js
│ ├── package.json
│ └── tailwind.config.js
├── pom.xml
└── README.md
Contributions are welcome. Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request