- Overview
- Features
- Technology Stack
- Prerequisites
- Installation & Setup
- Configuration
- API Documentation
- Database Schema
- Security Features
- File Structure
- Usage Examples
- Troubleshooting
- Contributing
- License
ShopSmart is a comprehensive sales management system built with Spring Boot that helps businesses manage their inventory, track sales, handle suppliers, and generate detailed reports. The system provides a secure, multi-user environment where each user can manage their own business data independently.
- User Registration & Login: Secure JWT-based authentication
- Account Activation: Email-based account activation system
- Password Reset: Forgot password functionality with email verification
- Role-based Access: User and Admin roles
- Multi-user Isolation: Each user sees only their own data
- Product Management: Add, edit, delete products with images
- Stock Tracking: Real-time stock quantity monitoring
- Stock Alerts: Low stock level notifications
- Category Management: Organize products by categories
- Supplier Integration: Link products to suppliers
- Sales Recording: Track individual sales transactions
- Sales Analytics: Comprehensive sales reports and summaries
- Profit Calculation: Automatic profit margin calculations
- Period-based Reports: Daily, weekly, monthly sales analysis
- Top Products: Identify best-selling products
- Supplier Directory: Manage supplier information
- Contact Details: Store supplier contact information
- Active/Inactive Status: Track supplier availability
- Category-based Filtering: Organize suppliers by category
- Customer Debts: Track outstanding customer payments
- Due Date Tracking: Monitor payment deadlines
- Payment Status: Mark debts as paid/unpaid
- Debt History: Maintain payment records
- Sales Reports: Generate detailed sales reports
- CSV Export: Export data in CSV format
- Category-wise Analysis: Sales breakdown by product categories
- Profit Analysis: Detailed profit and margin reports
- Period Comparison: Compare sales across different time periods
- Java 21: Core programming language
- Spring Boot 3.2.3: Main framework
- Spring Security: Authentication and authorization
- Spring Data JPA: Database operations
- MySQL: Primary database
- JWT: Token-based authentication
- Maven: Dependency management
- Lombok: Reduces boilerplate code
- Jakarta Validation: Input validation
- JJWT: JWT token handling
- Spring Mail: Email functionality
Before running ShopSmart, ensure you have the following installed:
- Java 21 or higher
- MySQL 8.0 or higher
- Maven 3.6 or higher
- Git (for cloning the repository)
git clone <repository-url>
cd ShopSmartCREATE DATABASE shopsmart;
CREATE USER 'shopsmart_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON shopsmart.* TO 'shopsmart_user'@'localhost';
FLUSH PRIVILEGES;Create or update src/main/resources/application.properties:
# Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/shopsmart?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=shopsmart_user
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.format_sql=true
# JWT Configuration
jwt.secret=your_jwt_secret_key_here_make_it_long_and_secure
jwt.expiration=86400000
# Email Configuration (for account activation and password reset)
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=your_email@gmail.com
spring.mail.password=your_app_password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
# File Upload Configuration
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
product.images.upload-dir=./uploads
# Server Configuration
server.port=8080# Clean and build the project
mvn clean install
# Run the application
mvn spring-boot:runThe application will start on http://localhost:8080
You can override configuration using environment variables:
export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/shopsmart
export SPRING_DATASOURCE_USERNAME=your_username
export SPRING_DATASOURCE_PASSWORD=your_password
export JWT_SECRET=your_jwt_secret
export SPRING_MAIL_USERNAME=your_email@gmail.com
export SPRING_MAIL_PASSWORD=your_app_passwordFor Gmail, you need to:
- Enable 2-Factor Authentication
- Generate an App Password
- Use the App Password in your configuration
POST /api/auth/signup
Content-Type: application/json
{
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"password": "password123",
"confirmPassword": "password123",
"shopName": "John's Shop",
"address": {
"street": "123 Main St",
"city": "Springfield",
"country": "USA",
"postalCode": "12345"
},
"role": "USER"
}POST /api/auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "password123"
}POST /api/auth/activate-account?token=activation_token_herePOST /api/auth/forgot-password
Content-Type: application/json
{
"email": "john@example.com"
}POST /api/auth/reset-password
Content-Type: application/json
{
"token": "reset_token_here",
"newPassword": "newpassword123"
}GET /inventory/all?page=0&size=10&sortBy=name&direction=asc
Authorization: Bearer <jwt_token>POST /inventory/add
Content-Type: multipart/form-data
Authorization: Bearer <jwt_token>
name: "Product Name"
category: "Electronics"
quantity: 100
unit: "pieces"
costPrice: 50.00
sellingPrice: 75.00
supplier: "Supplier Name"
stockAlertLevel: 10
image: [file]PUT /inventory/{id}
Content-Type: multipart/form-data
Authorization: Bearer <jwt_token>
name: "Updated Product Name"
category: "Electronics"
quantity: 150
unit: "pieces"
costPrice: 45.00
sellingPrice: 80.00
supplier: "Updated Supplier"
stockAlertLevel: 15
image: [file]DELETE /inventory/{id}
Authorization: Bearer <jwt_token>POST /sales
Content-Type: application/json
Authorization: Bearer <jwt_token>
{
"productId": 1,
"quantitySold": 5,
"totalAmount": 375.00
}GET /sales/summary
Authorization: Bearer <jwt_token>GET /sales/summary/period?startDate=2024-01-01&endDate=2024-01-31
Authorization: Bearer <jwt_token>GET /suppliers?page=0&size=10&sortBy=name&direction=asc
Authorization: Bearer <jwt_token>POST /suppliers
Content-Type: application/json
Authorization: Bearer <jwt_token>
{
"name": "Supplier Name",
"category": "Electronics",
"contactPerson": "John Doe",
"phoneNumber": "+1234567890",
"email": "supplier@example.com",
"address": "123 Supplier St",
"city": "Supplier City",
"state": "Supplier State",
"postalCode": "12345",
"country": "USA",
"isActive": true
}GET /debts
Authorization: Bearer <jwt_token>POST /debts
Content-Type: application/json
Authorization: Bearer <jwt_token>
{
"customerName": "Customer Name",
"amount": 500.00,
"createdDate": "2024-01-01",
"dueDate": "2024-02-01",
"isPaid": false
}POST /api/reports/generate
Content-Type: application/json
Authorization: Bearer <jwt_token>
{
"periodType": "monthly",
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}POST /api/reports/export/csv
Content-Type: application/json
Authorization: Bearer <jwt_token>
{
"periodType": "monthly",
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}id(Primary Key)firstName,lastName,emailpassword(encrypted)shopName,roleactivated,activationTokenresetToken,resetTokenExpiryaddress(embedded)
id(Primary Key)name,category,unitstockQuantity,stockAlertLevelcostPrice,sellingPricesupplier,imageUrluser(Foreign Key)
id(Primary Key)quantitySold,totalAmountsaleDateuser(Foreign Key)product(Foreign Key)
id(Primary Key)name,categorycontactPerson,phoneNumber,emailaddress,city,state,postalCode,countryisActiveuser(Foreign Key)
id(Primary Key)customerName,amountcreatedDate,dueDateisPaiduser(Foreign Key)
- Secure token-based authentication
- Token expiration (24 hours by default)
- Automatic token validation on protected endpoints
- BCrypt password hashing
- Password validation (minimum 6 characters)
- Secure password reset flow
- Multi-tenant architecture
- User-specific data access
- No cross-user data leakage
- Comprehensive input validation
- SQL injection prevention
- XSS protection
ShopSmart/
βββ src/
β βββ main/
β β βββ java/com/amnii/ShopSmart/
β β β βββ Controller/ # REST controllers
β β β βββ DTO/ # Data Transfer Objects
β β β βββ Exception/ # Custom exceptions
β β β βββ Models/ # Entity classes
β β β βββ Repository/ # Data access layer
β β β βββ Security/ # Security configuration
β β β βββ Services/ # Business logic
β β β βββ JwtService.java # JWT utilities
β β β βββ ShopSmartApplication.java
β β βββ resources/
β β βββ application.properties
β βββ test/ # Test files
βββ uploads/ # File uploads
βββ pom.xml # Maven configuration
βββ README.md # This file
// Login
const login = async (email, password) => {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
const data = await response.json();
localStorage.setItem('token', data.token);
return data;
};
// Get Products
const getProducts = async () => {
const token = localStorage.getItem('token');
const response = await fetch('/inventory/all', {
headers: {
'Authorization': `Bearer ${token}`,
},
});
return await response.json();
};# Login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}'
# Get Products (with token)
curl -X GET http://localhost:8080/inventory/all \
-H "Authorization: Bearer YOUR_JWT_TOKEN"# Check MySQL service
sudo systemctl status mysql
# Check database credentials
mysql -u shopsmart_user -p- Ensure the JWT secret is properly configured
- Check token expiration
- Verify token format in Authorization header
- Verify SMTP configuration
- Check Gmail App Password
- Ensure 2FA is enabled for Gmail
- Check upload directory permissions
- Verify file size limits
- Ensure multipart configuration
- Check application logs for stack traces
- Verify all required fields are provided
- Ensure user authentication
Application logs are available in the console when running the application. For production, configure proper logging:
# Logging configuration
logging.level.com.amnii.ShopSmart=DEBUG
logging.file.name=logs/shopsmart.log
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} - %msg%n- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Java coding conventions
- Add proper documentation
- Include unit tests for new features
- Ensure all tests pass before submitting
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions:
- Create an issue in the repository
- Contact the development team
- Check the troubleshooting section above
ShopSmart - Empowering businesses with smart sales management solutions.