A comprehensive milk delivery application backend built with Spring Boot, providing subscription-based milk delivery services for villagers and urban customers.
This application consists of a Spring Boot backend API that supports:
- User authentication via phone number and OTP
- Subscription management for milk delivery
- Product catalog management
- Payment integration with Razorpay
- Admin panel for managing users, subscriptions, and deliveries
- Phone Number + OTP Authentication: Secure login using mobile verification
- Profile Management: Update personal details and delivery addresses
- Product Catalog: Browse available milk products (Cow Milk, Buffalo Milk)
- Subscription Plans: Choose from 1 week, 15 days, or 1 month plans
- Flexible Delivery: Select delivery days (Mon-Sun) and time slots (Morning/Evening)
- One-time Orders: Place individual orders alongside subscriptions
- Online Payments: Secure payments through Razorpay integration
- Order History: View past orders and subscription details
- User Management: View and manage all registered users
- Subscription Oversight: Monitor and manage all active subscriptions
- Delivery Management: Generate and track daily delivery schedules
- Product Management: Update milk prices and product information
- Payment Tracking: View payment history and transaction details
- Backend: Spring Boot 3.5.7
- Database: MySQL 8.0
- Security: Spring Security with JWT authentication
- ORM: Spring Data JPA with Hibernate
- Build Tool: Maven
- Java Version: 17
- Payment Gateway: Razorpay
- Other Libraries:
- Lombok (code generation)
- ModelMapper (object mapping)
- JJWT (JSON Web Tokens)
- Java 17 or higher
- MySQL 8.0 or higher
- Maven 3.6+
- Git
-
Clone the repository
git clone <repository-url> cd village-milk-app
-
Set up MySQL Database
CREATE DATABASE VilgoMilks;
-
Configure Environment Variables
Create environment variables or update
application-dev.yml:MYSQL_HOST=localhost JWT_SECRET=your-secret-key-here JWT_ISSUER=api.villagemilk.com
-
Build the project
mvn clean install
The application uses Spring profiles for different environments:
- dev: Development profile (default)
- prod: Production profile
Key configuration files:
application.yml: Common configurationapplication-dev.yml: Development-specific settingsapplication-prod.yml: Production settings
Update the datasource URL in application-dev.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/VilgoMilks?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
username: your-username
password: your-passwordConfigure JWT settings:
security:
jwt:
secret: your-jwt-secret
issuer: api.villagemilk.com
access-ttl-seconds: 3600
refresh-ttl-seconds: 2592000mvn spring-boot:runThe application will start on http://localhost:8083 (dev profile).
mvn spring-boot:run -Dspring-boot.run.profiles=prodPOST /api/v1/auth/login- User login with OTPPOST /api/v1/auth/signup- User registrationPOST /api/v1/auth/refresh- Refresh access token
GET /api/v1/users/{userId}- Get user profilePUT /api/v1/users/{userId}- Update user profileGET /api/v1/users/phone/{phone}- Get user by phone
GET /api/v1/products- List all productsGET /api/v1/products/{id}- Get product details
POST /api/v1/subscriptions- Create subscriptionGET /api/v1/subscriptions/user/{userId}- Get user subscriptionsPUT /api/v1/subscriptions/{id}- Update subscriptionDELETE /api/v1/subscriptions/{id}- Cancel subscription
POST /api/v1/orders- Place one-time orderGET /api/v1/orders/user/{userId}- Get user orders
GET /api/v1/admin/users- List all usersGET /api/v1/admin/subscriptions- List all subscriptionsPUT /api/v1/admin/products/{id}/price- Update product price
- users: User accounts and profiles
- products: Milk products catalog
- subscriptions: User subscription plans
- subscription_events: Individual delivery events
- orders: One-time orders
- payments: Payment transactions
- addresses: User delivery addresses
- otp_codes: OTP verification codes
- refresh_tokens: JWT refresh tokens
Run tests with:
mvn testFROM openjdk:17-jdk-slim
COPY target/village-milk-app-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]- Update
application-prod.ymlwith production database - Set
JWT_COOKIE_SECURE=truefor HTTPS - Configure proper logging levels
- Set up database backups
- Configure monitoring and alerts
- 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
Create these environment variables on your server:
# Database Configuration
DB_USERNAME=vilgo_prod_user
DB_PASSWORD=your_secure_db_password
MYSQL_HOST=localhost
# JWT Security
JWT_SECRET=your-256-bit-production-jwt-secret-key-here
JWT_ISSUER=https://yourdomain.com
# Cashfree Payment Gateway (Get from Cashfree Dashboard)
CASHFREE_APP_ID=CF_PROD_APP_ID_HERE
CASHFREE_SECRET_KEY=CF_PROD_SECRET_KEY_HERE
CASHFREE_CLIENT_SECRET=CF_PROD_CLIENT_SECRET_HERE
CASHFREE_BASE_URL=https://api.cashfree.com
# Webhook Configuration
WEBHOOK_BASE_URL=https://yourdomain.com# Update system
sudo apt update && sudo apt upgrade -y
# Install Java 17
sudo apt install openjdk-17-jdk -y
# Install MySQL
sudo apt install mysql-server -y
sudo mysql_secure_installation
# Create database and user
sudo mysql -u root -pCREATE DATABASE VilgoMilks CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'vilgo_prod'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON VilgoMilks.* TO 'vilgo_prod'@'localhost';
FLUSH PRIVILEGES;
EXIT;# Clone your repository
git clone https://github.com/yourusername/village-milk-app.git
cd village-milk-app
# Set environment variables
sudo nano /etc/environment
# Add the environment variables from Step 1
# Build application
chmod +x mvnw
./mvnw clean package -DskipTests
# Create application directory
sudo mkdir -p /opt/village-milk-app
sudo cp target/village-milk-app-*.jar /opt/village-milk-app/
sudo cp -r src/main/resources /opt/village-milk-app/configsudo nano /etc/systemd/system/village-milk-app.serviceAdd this content:
[Unit]
Description=Village Milk App
After=network.target mysql.service
[Service]
Type=simple
User=ubuntu
EnvironmentFile=/etc/environment
WorkingDirectory=/opt/village-milk-app
ExecStart=/usr/bin/java -jar -Dspring.profiles.active=prod village-milk-app-*.jar
SuccessExitStatus=143
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable village-milk-app
sudo systemctl start village-milk-app
sudo systemctl status village-milk-app# Install Nginx
sudo apt install nginx -y
# Create site configuration
sudo nano /etc/nginx/sites-available/village-milk-appAdd this configuration:
server {
listen 80;
server_name yourdomain.com;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 86400;
}
# Webhook endpoint - important for payments
location /api/v1/webhooks/ {
proxy_pass http://localhost:8080;
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;
# Disable buffering for webhooks
proxy_buffering off;
proxy_request_buffering off;
}
}# Enable site
sudo ln -s /etc/nginx/sites-available/village-milk-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx# Install certbot
sudo apt install snapd -y
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# Get SSL certificate
sudo certbot --nginx -d yourdomain.com
# Set up auto-renewal
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet- Login to Cashfree Dashboard
- Go to Payment Gateway β Webhooks
- Add webhook URL:
https://yourdomain.com/api/v1/webhooks/cashfree - Select events:
ORDER_STATUS_UPDATE - Save configuration
# Check application status
sudo systemctl status village-milk-app
# Check application logs
sudo journalctl -u village-milk-app -f
# Test API endpoint
curl https://yourdomain.com/api/v1/products
# Test webhook endpoint (should return 401 without signature)
curl -X POST https://yourdomain.com/api/v1/webhooks/cashfree \
-H "Content-Type: application/json" \
-d '{"test": "data"}'# Install monitoring tools
sudo apt install htop iotop -y
# Set up log rotation
sudo nano /etc/logrotate.d/village-milk-appAdd:
/opt/village-milk-app/logs/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 ubuntu ubuntu
}
# Create backup script
sudo nano /opt/village-milk-app/backup.shAdd:
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
mysqldump -u vilgo_prod -p'your_password' VilgoMilks > /opt/backups/vilgo_db_$DATE.sql
tar -czf /opt/backups/village-milk-app_$DATE.tar.gz /opt/village-milk-app/# Make executable and set up cron
sudo chmod +x /opt/village-milk-app/backup.sh
sudo crontab -e
# Add: 0 2 * * * /opt/village-milk-app/backup.sh- Environment variables set (no hardcoded secrets)
- SSL certificate installed
- Firewall configured (only ports 22, 80, 443 open)
- Database user has minimal privileges
- Webhook signature verification enabled
- Application runs as non-root user
- Logs are rotated and monitored
- Backups are automated
- HTTPS enforced (redirect HTTP to HTTPS)
-
Application won't start
sudo journalctl -u village-milk-app -n 50
-
Database connection issues
sudo mysql -u vilgo_prod -p # Check if you can connect -
Webhook not working
- Check Nginx logs:
sudo tail -f /var/log/nginx/error.log - Verify webhook URL in Cashfree dashboard
- Test with signature verification disabled temporarily
- Check Nginx logs:
-
SSL issues
sudo certbot certificates sudo nginx -t && sudo systemctl reload nginx
-
JVM Tuning (add to systemd service):
ExecStart=/usr/bin/java -Xmx2g -Xms512m -XX:+UseG1GC -jar village-milk-app-*.jar -
Database Optimization:
- Enable query caching
- Set up connection pooling
- Monitor slow queries
-
Caching (consider Redis for session/cache)
- Use smaller EC2 instance initially
- Set up auto-scaling if needed
- Monitor resource usage
- Use CloudWatch for alerts
π Your application is now production-ready!
Remember to:
- Regularly update dependencies
- Monitor application metrics
- Keep backups current
- Renew SSL certificates automatically
- Monitor Cashfree webhook delivery
