A secure, scalable, and production-ready coupon management system built with Spring Boot, React, and PostgreSQL. Features JWT authentication, role-based access control, rate limiting, and comprehensive security hardening following 2026 best practices.
- Features
- Tech Stack
- Prerequisites
- Quick Start
- Security
- Architecture
- API Documentation
- Deployment
- Development
- Testing
- Monitoring
- Documentation
- Contributing
- License
- Multi-Role System: Admin, Company, and Customer roles with distinct permissions
- Coupon Management: Create, update, delete, and browse coupons with categories
- Purchase System: Customers can purchase and track coupons
- Company Portal: Companies manage their own coupon inventory
- Admin Dashboard: Full system oversight and user management
- React Frontend: Modern Material-UI based single-page application
- JWT Authentication: Secure token-based authentication with refresh tokens
- BCrypt Password Hashing: Industry-standard password encryption (14 rounds)
- Rate Limiting: Bucket4j token bucket algorithm (5 req/min auth, 100 req/min general)
- Account Lockout: Automatic account locking after 5 failed login attempts
- CORS Protection: Configurable cross-origin resource sharing
- SQL Injection Protection: PreparedStatements throughout
- SSL/TLS Support: Production-ready with Let's Encrypt integration
- Security Headers: CSP, HSTS, X-Frame-Options, X-Content-Type-Options
- Non-Root Containers: All containers run as unprivileged users
- Actuator Endpoint Security: Health details only for authorized users
- Connection Pooling: HikariCP with optimized settings (20 max, 5 min idle)
- Database Indexing: 8 strategic indexes for query performance
- Prometheus Metrics: Application metrics exposed on port 9090
- Health Checks: Spring Boot Actuator health endpoints
- Structured Logging: JSON logging with Logback
- Docker Optimization: Multi-stage builds, layer caching (258MB backend, 70MB frontend)
- Java 25 (LTS) - Modern Java with virtual threads support
- Spring Boot 3.5.9 - Framework for production-ready applications
- PostgreSQL 17 - Advanced open-source relational database (replaces MySQL)
- HikariCP - High-performance JDBC connection pool
- Bucket4j - Rate limiting library
- JWT (jjwt 0.12.6) - JSON Web Token implementation
- BCrypt - Password hashing (14 rounds = 16384 iterations)
- Logback - Structured logging with JSON output
- JaCoCo - Code coverage
- JUnit 5 + Mockito - Testing frameworks
- React 19 with TypeScript
- Material-UI v5 - React UI framework
- React Router v6 - Client-side routing
- Axios - HTTP client
- date-fns - Date manipulation
- Docker & Docker Compose - Containerization
- Traefik v3 - Reverse proxy with automatic SSL (production)
- nginx - Frontend web server
- PostgreSQL 17-alpine - Database (285MB container, down from 1GB MySQL)
- GitHub Actions - CI/CD pipeline with OWASP dependency checks
- Docker 24.0+ & Docker Compose 2.20+
- OpenSSL - for generating cryptographically secure secrets
- Java 25 JDK
- Maven 3.9+
- Node.js 18+ & npm
- PostgreSQL Client (psql) - for database administration
- RAM: Minimum 4GB, Recommended 8GB
- Disk: 5GB free space
- OS: Linux, macOS, Windows 10/11 with WSL2
- Network: Ports 3000 (frontend), 8080 (backend), 5432 (PostgreSQL) available
git clone https://github.com/yourusername/CouponSystemProject.git
cd CouponSystemProject# Run the automated secrets setup script
./scripts/setu./scripts/setup/setup-secrets.sh
# Save the admin password shown in the output!What the script does:
- Generates cryptographically secure random secrets
- Updates
.envfile with unique values:POSTGRES_PASSWORD(24-char base64)DB_PASSWORD(24-char base64)JWT_SECRET(32-char base64, 256-bit)ADMIN_PASSWORD(24-char base64)
- Creates backup
.env.backup
π‘ Tip: See scripts/README.md for details on all available scripts
# Start all services (PostgreSQL, Backend, Frontend)
docker compose up -d
# Check status (wait for all containers to be healthy)
docker compose ps
# Expected output:
# coupon-system-postgres Up (healthy)
# coupon-system-app Up (healthy)
# coupon-system-frontend Up
# View logs
docker compose logs -f app- Frontend: http://localhost:3000
- Backend API: http://localhost:8080/api/v1
- Swagger UI: http://localhost:8080/swagger-ui.html
- Health Check: http://localhost:9090/metrics/health
- Prometheus Metrics: http://localhost:9090/metrics/prometheus
Admin Account:
- Email: Change
ADMIN_EMAILin.env(default:admin@yourcompany.com) - Password: Generated by
setup-secrets.sh(displayed during setup)
Demo Users (optional - load sample data):
# Load sample companies and customers (for development/testing only)
cat scripts/db/populate-sample-data-postgres.sql | docker exec -i coupon-system-postgres psql -U appuser -d couponsystem
# Demo login credentials:
# Email: john.smith@email.com
# Password: password123|
Best for: Development, testing, learning Features:
|
Best for: Live applications, staging environments Features:
|
Perfect for development and testing on your local machine.
# Verify installations
docker --version # Should be 20.10+
docker compose version # Should be 2.0+
java --version # Should be 21+
mvn --version # Should be 3.8+
node --version # Should be 18+ (for frontend development)# Clone repository
git clone https://github.com/yourusername/CouponSystemProject.git
cd CouponSystemProject
# Generate secure secrets
./scripts/setu./scripts/setup/setup-secrets.sh
# β οΈ Save the displayed admin password!
# (Optional) Setup local SSL for HTTPS
./scripts/setup/setup-local-ssl.sh# Start all containers
docker compose up -d
# Wait for services to be healthy (~30 seconds)
docker compose ps# Populate database with demo data
cat scripts/db/populate-sample-data-postgres.sql | \
docker exec -i coupon-system-postgres psql -U appuser -d couponsystem
# Test login:
# Email: john.smith@email.com
# Password: password123- Frontend: http://localhost:3000
- Backend API: http://localhost:8080/api/v1
- Swagger Docs: http://localhost:8080/swagger-ui.html
- Prometheus: http://localhost:9090/metrics/prometheus
# Backend development (Spring Boot auto-reloads)
mvn spring-boot:run
# Frontend development (React hot reload)
cd coupon-system-frontend
npm start
# Run tests before committing
./scripts/test/test-local.sh
# Run Docker tests
./scripts/test/test-docker.shDeploy to a production server with SSL/TLS and domain name.
- β
Domain name (e.g.,
myapp.com) with DNS A record pointing to server - β Server with public IP (Ubuntu 22.04 LTS recommended)
- β Ports 80 and 443 open in firewall
- β Docker and Docker Compose installed
- β Email address for Let's Encrypt notifications
# SSH into production server
ssh user@your-server-ip
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker compose version# Clone repository
git clone https://github.com/yourusername/CouponSystemProject.git
cd CouponSystemProject
# Generate production secrets
./scripts/setu./scripts/setup/setup-secrets.sh
# Configure environment
cp .env.example .env
nano .env
# Required changes in .env:
# - ADMIN_EMAIL=admin@yourdomain.com
# - CORS_ALLOWED_ORIGINS=https://yourdomain.com# Edit production compose file
nano docker-compose.production.yml
# Replace these values:
# - yourdomain.com β your actual domain
# - admin@yourdomain.com β your email for Let's Encrypt# Deploy with Traefik for automatic SSL
docker compose -f docker-compose.yml -f docker-compose.production.yml up -d
# Monitor startup
docker compose logs -f
# Wait for Let's Encrypt certificate (~1-2 minutes)# Test HTTPS access
curl https://yourdomain.com
curl https://api.yourdomain.com/api/v1/public/coupons
# Check certificate
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com# Secure Traefik dashboard (edit docker-compose.production.yml)
# Remove or secure the Traefik dashboard port 8080
# Setup monitoring
# Setup backup for PostgreSQL data volume
# Configure firewall to allow only ports 80, 443, and SSHgit pull origin main
docker compose down
docker compose up -d --buildcd CouponSystemProject
git pull origin main
docker compose -f docker-compose.yml -f docker-compose.production.yml down
docker compose -f docker-compose.yml -f docker-compose.production.yml up -d --build
# Verify
curl https://api.yourdomain.com/metrics/health# Run comprehensive test suite
./scripts/test/test-docker.sh
# Performance benchmarks
./scripts/test/performance-test.sh
# Manual API tests
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"john.smith@email.com","password":"password123","clientType":"CUSTOMER"}'CouponSystemProject/
βββ scripts/ # Utility scripts (organized)
β βββ setup/ # Setup scripts
β β βββ setup-secrets.sh # Generate secure secrets
β β βββ setup-local-ssl.sh # Local SSL certificates
β βββ test/ # Testing scripts
β β βββ test-local.sh # Local test runner
β β βββ test-docker.sh # Docker deployment tests
β β βββ performance-test.sh # Performance benchmarks
β βββ db/ # Database scripts
β β βββ populate-sample-data-postgres.sql
β βββ README.md # Scripts documentation
βββ src/ # Java backend source
βββ coupon-system-frontend/ # React frontend
βββ docs/ # Documentation
βββ .github/workflows/ # CI/CD pipelines
βββ docker-compose.yml # Local development
βββ docker-compose.production.yml # Production with SSL
βββ Dockerfile # Backend container
βββ .env.example # Environment template
βββ README.md # This file
# Check logs
docker compose logs
# Check system resources
docker system df
docker system prune # If disk space is low# Verify PostgreSQL is healthy
docker compose ps postgres
# Check database credentials in .env
cat .env | grep -E "DB_USER|DB_PASSWORD|POSTGRES_PASSWORD"
# Restart PostgreSQL
docker compose restart postgres# Check nginx logs
docker compose logs frontend
# Verify API connectivity
curl http://localhost:8080/api/v1/public/coupons
# Rebuild frontend
docker compose up -d --build frontend# Check Traefik logs
docker compose logs traefik
# Verify DNS A record
dig yourdomain.com
# Check ports 80 and 443 are accessible
nc -zv yourdomain.com 80
nc -zv yourdomain.com 443For more help, see:
- scripts/README.md - Detailed script documentation
- docs/ - Additional guides and documentation
- GitHub Issues - Report bugs
- Generated unique secrets with
./scripts/setup/setup-secrets.sh - PostgreSQL port bound to localhost only (
127.0.0.1:5432:5432) - Actuator endpoints restricted (
when-authorized) - Logging levels set to production values (
INFO/WARN) - CI/CD pipeline uses PostgreSQL
- SSL/TLS configured (see
docker-compose.production.yml) - BCrypt rounds increased to 14 (16384 iterations)
- Content Security Policy headers added
- Frontend API URL using relative paths
- Rate limiting implemented and verified
- Containers running as non-root users
- Change
ADMIN_EMAILin.envto your real email - Review and customize
.envsettings (ports, timeouts, etc.) - Configure production domain in
docker-compose.production.yml - Set up SSL certificates (automated with Let's Encrypt via Traefik)
- Configure firewall (allow ports 80, 443; block 5432 externally)
- Set up automated database backups
- Configure monitoring and alerting
- Review security scan results in docs/CRITICAL_CODE_REVIEW.md
# Development: Use ./scripts/setup/setup-secrets.sh
./scripts/setup/setup-secrets.sh
# Production: Use a secrets manager
# - AWS Secrets Manager
# - HashiCorp Vault
# - Azure Key Vault
# - Google Secret Manager
# GitHub Actions: Store in GitHub Secrets (already configured)
# Required secrets:
# - TEST_DB_PASSWORD
# - TEST_POSTGRES_PASSWORD
# - ADMIN_PASSWORD_HASH
# - TEST_JWT_SECRET
# - NVD_API_KEY (for OWASP scans)# Production: Remove PostgreSQL port exposure entirely
# In docker-compose.production.yml:
postgres:
ports: [] # No external access
networks:
- backend # Internal network only# Production with Let's Encrypt (automated)
# 1. Update docker-compose.production.yml with your domain
# 2. Configure DNS A records pointing to your server
# 3. Deploy:
docker compose -f docker-compose.yml -f docker-compose.production.yml up -d
# Development with self-signed certificates
./setup-local-ssl.sh- Authentication endpoints (
/api/v1/auth/*): 5 requests/minute per IP - General API endpoints: 100 requests/minute per IP
- Returns HTTP 429 with
X-RateLimit-Retry-After-Secondsheader - Token bucket algorithm with greedy refill
- Threshold: 5 failed login attempts
- Duration: 30 minutes (configurable via
ACCOUNT_LOCKOUT_DURATION_MINUTES) - Admin lockout: Disabled by default (
ACCOUNT_LOCKOUT_ADMIN_ENABLED=false) - Unlock: Manual unlock via Admin dashboard or automatic after lockout period
Production with SSL/TLS
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Traefik (Ports 80 β 443 redirect) β
β SSL Termination + Load Balancer + Let's Encrypt β
ββββββββββββ¬βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββ
β β
ββββββββΌββββββββββ ββββββββΌβββββββββββ
β Frontend β β Backend β
β React + nginx β β Spring Boot β
β Port: 80 β β Port: 8080 β
β (internal) β β Metrics: 9090 β
ββββββββββββββββββ ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββββββ
β PostgreSQL 17 β
β Port: 5432 β
β (internal only) β
βββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Presentation Layer (REST Controllers) β
β @RestController + Swagger/OpenAPI + Security Filter Chain β
β - RateLimitingFilter (Bucket4j) β
β - JwtAuthenticationFilter β
β - Spring Security CORS & CSRF β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Service Layer β
β Business Logic + JWT Token Management + Account Lockout β
β - AdminService, CompanyService, CustomerService β
β - JwtTokenService (access + refresh tokens) β
β - Validation & Exception Handling β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Data Access Layer (DAO) β
β JDBC + PreparedStatements + DTOs + Connection Pooling β
β - CompaniesDAOImpl, CouponsDAOImpl, CustomerDAOImpl β
β - HikariCP connection pool (max 20, min idle 5) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Database β
β PostgreSQL 17 (couponsystem database) β
β - 8 performance indexes β
β - Foreign key constraints β
β - SERIAL primary keys β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- Core tables
categories (id, name) -- 4 fixed categories
companies (id, name, email, password, failed_login_attempts, account_locked, locked_until, last_failed_login)
customers (id, first_name, last_name, email, password, failed_login_attempts, account_locked, locked_until, last_failed_login)
coupons (id, company_id, category_id, title, description, start_date, end_date, amount, price, image)
customers_vs_coupons (customer_id, coupon_id) -- Junction table (many-to-many)
-- Indexes for performance
idx_companies_name, idx_companies_account_locked
idx_customers_account_locked
idx_coupons_end_date, idx_coupons_company_category, idx_coupons_company_price, idx_coupons_title_company
idx_customers_vs_coupons_couponSee src/main/resources/postgres-schema.sql for complete schema.
Development: http://localhost:8080/api/v1
Production: https://api.yourdomain.com/api/v1
- Swagger UI: http://localhost:8080/swagger-ui.html
- OpenAPI JSON: http://localhost:8080/api-docs
1. Login
POST /api/v1/auth/login
Body: { "email": "user@example.com", "password": "pass", "clientType": "CUSTOMER" }
Response: { "accessToken": "...", "refreshToken": "...", "userInfo": {...} }
2. Authenticated Request
GET /api/v1/customer/coupons
Header: Authorization: Bearer <accessToken>
3. Refresh Token (when access token expires)
POST /api/v1/auth/refresh
Body: { "refreshToken": "..." }
Response: { "accessToken": "...", "refreshToken": "..." }GET /api/v1/public/coupons # List all coupons
GET /api/v1/public/coupons/{id} # Get coupon details
GET /api/v1/public/coupons/category/{categoryId} # Filter by category# Company Management
GET /api/v1/admin/companies
POST /api/v1/admin/companies
PUT /api/v1/admin/companies/{id}
DELETE /api/v1/admin/companies/{id}
POST /api/v1/admin/companies/{id}/unlock
# Customer Management
GET /api/v1/admin/customers
POST /api/v1/admin/customers
PUT /api/v1/admin/customers/{id}
DELETE /api/v1/admin/customers/{id}
POST /api/v1/admin/customers/{id}/unlockGET /api/v1/company/coupons # List own coupons
POST /api/v1/company/coupons # Create coupon
PUT /api/v1/company/coupons/{id} # Update own coupon
DELETE /api/v1/company/coupons/{id} # Delete own coupon
GET /api/v1/company/coupons/category/{categoryId}
GET /api/v1/company/coupons/max-price/{maxPrice}
GET /api/v1/company/details # Company profilePOST /api/v1/customer/coupons/{id}/purchase # Purchase coupon
GET /api/v1/customer/coupons # List purchased coupons
GET /api/v1/customer/coupons/category/{categoryId}
GET /api/v1/customer/coupons/max-price/{maxPrice}
GET /api/v1/customer/details # Customer profile# Login as admin
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@yourcompany.com",
"password": "your_generated_password",
"clientType": "ADMIN"
}'
# Save token from response
TOKEN="eyJhbGciOiJIUzI1NiIs..."
# Get all companies (authenticated)
curl http://localhost:8080/api/v1/admin/companies \
-H "Authorization: Bearer $TOKEN"
# Rate limit test (expect 429 after 5 requests)
for i in {1..10}; do
curl -i http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test","password":"test","clientType":"CUSTOMER"}'
echo "\n---Request $i---"
done# 1. Generate secrets
./scripts/setup/setup-secrets.sh
# 2. Start services
docker compose up -d
# 3. Verify health
docker compose ps
curl http://localhost:9090/metrics/health
# 4. Load sample data (optional)
docker exec -i coupon-system-postgres psql -U appuser -d couponsystem < populate-sample-data-postgres.sql
# 5. Access frontend
open http://localhost:3000# Prerequisites:
# 1. Domain name (e.g., myapp.com) with DNS A record pointing to server IP
# 2. Ports 80 and 443 open on firewall
# 3. Docker and Docker Compose installed on server
# 1. Clone repository on production server
git clone https://github.com/yourusername/CouponSystemProject.git
cd CouponSystemProject
# 2. Configure production settings
cp .env.example .env
./scripts/setu./scripts/setup/setup-secrets.sh # Generate production secrets
# Edit .env with production values
vim .env
# Update: ADMIN_EMAIL, CORS_ALLOWED_ORIGINS
# 3. Configure production docker-compose
vim docker-compose.production.yml
# Replace ALL instances of "yourdomain.com" with your actual domain
# Replace "admin@yourdomain.com" with your email for Let's Encrypt
# 4. Deploy with Traefik for automatic SSL
docker compose -f docker-compose.yml -f docker-compose.production.yml up -d
# 5. Verify SSL certificate (may take 1-2 minutes)
curl https://myapp.com
curl https://api.myapp.com/metrics/health
# 6. Monitor Traefik dashboard (secure it in production!)
open https://traefik.myapp.com# View all containers
docker compose ps
# View logs
docker compose logs -f app
docker compose logs -f postgres
docker compose logs -f frontend
# Restart a service
docker compose restart app
# Update and redeploy
git pull
docker compose build
docker compose up -d
# Stop all services
docker compose down
# Stop and remove volumes (β οΈ deletes database!)
docker compose down -v# Backup PostgreSQL database
docker exec coupon-system-postgres pg_dump -U appuser couponsystem \
> backup_$(date +%Y%m%d_%H%M%S).sql
# Restore from backup
docker exec -i coupon-system-postgres psql -U appuser -d couponsystem \
< backup_20260110_153000.sql
# Automated daily backups (add to cron)
0 2 * * * /path/to/CouponSystemProject/scripts/backup-db.shKey .env variables (see .env.example for all options):
# Database (CRITICAL: Change these!)
POSTGRES_PASSWORD=your_generated_password_24chars
DB_PASSWORD=your_generated_password_24chars
# JWT (CRITICAL: Change this!)
JWT_SECRET=your_generated_secret_32chars
# Admin Account (CRITICAL: Change these!)
ADMIN_EMAIL=admin@yourcompany.com
ADMIN_PASSWORD=your_generated_password_24chars
# Security Settings
PASSWORD_BCRYPT_STRENGTH=14 # 16384 iterations
ACCOUNT_LOCKOUT_MAX_ATTEMPTS=5
ACCOUNT_LOCKOUT_DURATION_MINUTES=30
# Rate Limiting
RATE_LIMIT_AUTH_CAPACITY=5
RATE_LIMIT_GENERAL_CAPACITY=100
# CORS (Update for production)
CORS_ALLOWED_ORIGINS=https://myapp.com,https://www.myapp.com# 1. Start PostgreSQL locally
# Install PostgreSQL 17 or use Docker:
docker run -d --name postgres-dev \
-e POSTGRES_DB=couponsystem \
-e POSTGRES_USER=appuser \
-e POSTGRES_PASSWORD=devpass \
-p 5432:5432 postgres:16-alpine
# 2. Initialize database
psql -U appuser -h localhost -d couponsystem < src/main/resources/postgres-schema.sql
# 3. Run backend
cd CouponSystemProject
mvn spring-boot:run
# 4. Run frontend
cd coupon-system-frontend
npm install
npm start
# Access:
# Frontend: http://localhost:3000
# Backend: http://localhost:8080# Backend JAR
mvn clean package
# Output: target/CouponSystemProject-1.0-SNAPSHOT.jar
# Frontend production build
cd coupon-system-frontend
npm run build
# Output: build/ directory
# Docker images
docker compose build
# Check image sizes
docker images | grep couponsystemproject# Connect to PostgreSQL
docker exec -it coupon-system-postgres psql -U appuser -d couponsystem
# Run SQL commands
\dt # List tables
\d companies # Describe table
SELECT * FROM categories;
# Apply schema changes
# Option 1: Manual SQL
docker exec -i coupon-system-postgres psql -U appuser -d couponsystem < migration.sql
# Option 2: Flyway (recommended for production)
# Place migration files in src/main/resources/db/migration/
# V1__initial_schema.sql
# V2__add_lockout_columns.sql# Run all tests with coverage
mvn test jacoco:report
# Run specific test class
mvn test -Dtest=CustomerServiceTest
# Run specific test method
mvn test -Dtest=CustomerServiceTest#testPurchaseCoupon
# View coverage report
open target/site/jacoco/index.html
# Integration tests (requires Docker)
mvn verify -P integration-testscd coupon-system-frontend
# Run tests
npm test
# Run tests with coverage
npm test -- --coverage --watchAll=false
# Run tests in watch mode
npm test -- --watch
# Coverage report
open coverage/lcov-report/index.html# Health check
curl http://localhost:9090/metrics/health
# Test rate limiting
for i in {1..10}; do curl -i http://localhost:8080/api/v1/public/coupons; done
# Test authentication
TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@yourcompany.com","password":"yourpass","clientType":"ADMIN"}' \
| jq -r '.accessToken')
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/v1/admin/companies# Run OWASP Dependency Check (requires NVD API key)
mvn dependency-check:check -Dowasp.skip=false
# View report
open target/dependency-check-report.html
# CI/CD runs this automatically on main branch# Application health
curl http://localhost:9090/metrics/health | jq .
# Expected response:
{
"status": "UP",
"components": {
"db": { "status": "UP", "details": { "database": "PostgreSQL" } },
"diskSpace": { "status": "UP" },
"ping": { "status": "UP" }
}
}
# Database health
docker exec coupon-system-postgres pg_isready -U appuser -d couponsystem
# Container health
docker compose ps# Metrics endpoint (separate port for security)
curl http://localhost:9090/metrics/prometheus
# Key metrics available:
# - http_server_requests_seconds_* # Request latency & count
# - jvm_memory_used_bytes # JVM memory usage
# - hikaricp_connections_* # Database connection pool
# - system_cpu_usage # CPU usage
# - authentication_attempts_total # Login attempts (custom)
# - account_lockouts_total # Locked accounts (custom)
# - coupon_purchases_total # Purchases (custom)# View logs in JSON format
docker compose logs app | jq .
# Filter by log level
docker compose logs app | jq 'select(.level=="ERROR")'
# Filter by logger
docker compose logs app | jq 'select(.logger_name | contains("security"))'
# View authentication logs
docker compose logs app | jq 'select(.logger_name=="com.jhf.coupon.backend.login")'
# Tail logs with pretty print
docker compose logs -f app | jq -C .# Database connection pool metrics
curl http://localhost:9090/metrics/prometheus | grep hikaricp
# Query performance (from logs)
docker compose logs app | grep "Executing SQL query"
# CPU and memory usage
docker stats coupon-system-app- Critical Code Review - Security analysis and P0/P1 issues (fixed)
- Testing Guide - Comprehensive testing strategies
- Database Indexing Analysis - Performance optimization
- Frontend Usage Guide - React app documentation
- Prometheus Metrics Guide - Monitoring setup
- Structured Logging Guide - Logging configuration
- Dependabot Secrets Setup - GitHub Actions CI/CD
- docs/archive/ - Completed migration plans and session handoffs
We welcome contributions! Please follow these guidelines:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
mvn test && npm test - Commit with conventional commits:
git commit -m 'feat: add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
Follow Conventional Commits:
feat: add new feature
fix: bug fix
docs: documentation changes
style: formatting, missing semicolons, etc
refactor: code refactoring
test: add tests
chore: build process, dependencies
perf: performance improvements
security: security fixes
- Java: Follow Google Java Style Guide
- TypeScript/React: Follow Airbnb JavaScript Style Guide
- Line Length: 120 characters max
- Tests: Maintain >80% code coverage
- Security: Run OWASP scan before PR
- All tests passing (
mvn testandnpm test) - Code coverage >80% (check JaCoCo report)
- No new security vulnerabilities (OWASP check)
- Documentation updated (if applicable)
- Commit messages follow convention
- No merge conflicts with main
- Reviewed by at least one maintainer
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2026 Coupon System Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction...
- Spring Boot Team - Excellent framework for production applications
- PostgreSQL Community - Robust and feature-rich database
- React Team - Modern and efficient UI library
- Material-UI - Beautiful and accessible components
- Traefik Labs - Simplifying reverse proxy and SSL management
- Bucket4j - Elegant rate limiting implementation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: support@yourcompany.com
- Documentation: Wiki
- JWT authentication with refresh tokens
- Role-based access control (Admin/Company/Customer)
- Rate limiting (Bucket4j)
- Account lockout mechanism
- PostgreSQL migration (from MySQL)
- React frontend with Material-UI
- Docker containerization
- SSL/TLS support (Traefik)
- Security hardening (P0 + P1 issues)
- Prometheus metrics
- Structured JSON logging
- CI/CD with GitHub Actions
- OWASP dependency scanning
- Redis caching layer for session storage and frequent queries
- WebSocket support for real-time notifications
- Email service integration (SendGrid/AWS SES) for alerts
- Advanced analytics dashboard with charts
- Multi-language support (i18n with react-i18next)
- Flyway database migrations
- GraphQL API as alternative to REST
- Enhanced admin dashboard with user analytics
- Kubernetes deployment manifests (Helm charts)
- Microservices architecture (separate services for auth, coupons, payments)
- Event-driven design with Apache Kafka
- AI-powered coupon recommendations
- Mobile app (React Native)
- Multi-tenancy support
- Blockchain-based coupon verification
- Lines of Code: ~15,000 (Backend + Frontend)
- Test Coverage: 80%+
- Docker Image Sizes:
- Backend: 258MB (optimized with multi-stage builds)
- Frontend: 70MB (nginx:alpine)
- PostgreSQL: 285MB (down from 1GB MySQL)
- API Endpoints: 30+
- Database Tables: 5
- Security Features: 10+
Made with β€οΈ and β by the Coupon System Team
Last updated: January 10, 2026 Version: 2.0.0