Product Catalog Service ‐ Run Book (Actual Implementation) - Wiz-DevTech/prettygirllz GitHub Wiki
The Product Catalog Service is a Spring Boot 3.2.0 application that manages product inventory with specialized endpoints for Candy and Fashion product categories. The service uses PostgreSQL for data persistence and provides REST APIs documented with OpenAPI/Swagger.
- REST API with Product, Candy, and Fashion controllers
- PostgreSQL database with JPA/Hibernate
- Flyway database migrations
- OpenAPI/Swagger documentation
- Basic error handling
- Inventory management service
- SKU code validation (pattern: [A-Z]{2}[0-9]{6})
- Authentication/Authorization
- Test suite (no tests exist)
- Pagination
- Caching
- Rate limiting
- Input validation annotations
- Health check endpoints
- Java 17+ (tested with 17.0.12)
- PostgreSQL 12+ (tested with 17.4)
- Maven 3.8+ for building
- Minimum 1GB RAM
# Database setup
createdb productdb
createuser productuser
psql productdb
# GRANT ALL PRIVILEGES ON DATABASE productdb TO productuser;
spring:
main:
allow-bean-definition-overriding: true
application:
name: product-service
datasource:
url: jdbc:postgresql://localhost:5432/productdb
username: productuser
password: productpass
driver-class-name: org.postgresql.Driver
jpa:
database-platform: org.hibernate.dialect.PostgreSQLDialect
hibernate:
ddl-auto: validate
show-sql: true
properties:
hibernate:
format_sql: true
flyway:
enabled: true
baseline-on-migrate: true
locations: classpath:db/migration
server:
port: 8080
servlet:
context-path: /api
logging:
level:
com.productcatalog: DEBUG
org.hibernate.SQL: DEBUG
org.springframework: INFO
springdoc:
api-docs:
path: /api-docs
swagger-ui:
path: /swagger-ui.html
operationsSorter: method
-
products
- id (BIGINT, Primary Key)
- name (VARCHAR, NOT NULL)
- description (TEXT)
- category (VARCHAR, NOT NULL)
- created_date, last_modified_date (TIMESTAMP)
- created_by, last_modified_by (VARCHAR)
- active (BOOLEAN, default TRUE)
-
skus
- id (BIGINT, Primary Key)
- sku_code (VARCHAR, UNIQUE, NOT NULL)
- product_id (BIGINT, Foreign Key)
- price (NUMERIC, NOT NULL)
- available_quantity (INTEGER, default 0)
- created_date, last_modified_date (TIMESTAMP)
- created_by, last_modified_by (VARCHAR)
- active (BOOLEAN, default TRUE)
-
color_variants
- id (BIGINT, Primary Key)
- sku_id (BIGINT, Foreign Key)
- color_name (VARCHAR, NOT NULL)
- color_code (VARCHAR)
- image_url (VARCHAR)
- created_date, last_modified_date (TIMESTAMP)
- created_by, last_modified_by (VARCHAR)
- Foreign keys: skus.product_id → products.id
- Foreign keys: color_variants.sku_id → skus.id
- Check: skus.price > 0
- Check: skus.available_quantity >= 0
- Unique: skus.sku_code
- Spring Boot 3.2.0
- Spring Data JPA
- PostgreSQL Driver
- Flyway Core
- SpringDoc OpenAPI 2.3.0
- Lombok 1.18.28
- Testcontainers (for testing, not used)
- Maven with Spring Boot plugin
- Java 17 compatibility
- Lombok exclusion in final JAR
# Using Maven
mvn spring-boot:run
# Using JAR (after mvn package)
java -jar target/product-service-0.0.1-SNAPSHOT.jar
# Build Docker image
docker build -t product-catalog .
# Run container
docker run -p 8080:8080 product-catalog
- Application starts with Spring Boot 3.2.0
- Connects to PostgreSQL on port 5432
- Flyway runs migrations (currently V1 and V2)
- Hibernate initializes with 2 JPA repositories
- Tomcat starts on port 8080 with context path
/api
- Startup time: ~5.1 seconds
-
API Base:
http://localhost:8080/api
-
Swagger UI:
http://localhost:8080/api/swagger-ui.html
-
API Docs:
http://localhost:8080/api/api-docs
- Console output with formatted SQL
- DEBUG level for com.productcatalog package
- SQL queries are logged when show-sql=true
# Check Flyway status
mvn flyway:info
# Run migrations
mvn flyway:migrate
# Clean database (dev only)
mvn flyway:clean
# Get all products
curl http://localhost:8080/api/products
# Create a product
curl -X POST http://localhost:8080/api/products \
-H "Content-Type: application/json" \
-d '{"name":"Test Product","category":"CANDY","description":"Test"}'
# Get candy products
curl http://localhost:8080/api/candy
- GlobalExceptionHandler handles:
- InvalidSKUException → 400 Bad Request
- MethodArgumentNotValidException → 400 Bad Request
- General Exception → 500 Internal Server Error
- Custom API error format with timestamp, status, message
- MessageSource integration for internationalization
{
"status": "BAD_REQUEST",
"timestamp": "2025-05-16T07:04:37.206",
"message": "Invalid SKU format: XX1234567",
"path": null
}
- No authentication/authorization implemented
- All endpoints are publicly accessible
- Database credentials are in plain text in config files
- No unit tests exist
- No integration tests
- Testcontainers dependency exists but unused
- Only SKU code pattern validation (application-level)
- No Bean Validation annotations on entities
- No input sanitization
- No pagination implemented
- No caching strategy
- No connection pooling configuration
- No rate limiting
-
Port 8080 in use
# Check and kill process netstat -tlnp | grep 8080 kill -9 <PID>
-
Database connection failure
- Verify PostgreSQL is running
- Check credentials in application.yml
- Ensure database 'productdb' exists
-
Flyway migration errors
# Check migration status mvn flyway:info # Repair metadata table if needed mvn flyway:repair
-
SKU validation errors
- Ensure SKU codes match pattern: [A-Z]{2}[0-9]{6}
- Example valid SKU: "AB123456"
- No connection pooling settings
- Default JPA/Hibernate settings
- SQL queries logged (impacts performance)
# Add to application.yml
spring:
datasource:
hikari:
maximum-pool-size: 10
minimum-idle: 2
connection-timeout: 30000
- Multi-stage build (Maven + OpenJDK 17)
- Final image based on openjdk:17-jdk-slim
- Exposes port 8080
- No environment-specific configuration
- Database URL needs to be updated for containerized deployment
- Consider using docker-compose for complete stack
- No health checks defined in Dockerfile
-- Products
id=3: Fashion Item (FASHION)
id=4: Sweet Treat (CANDY)
id=5: Sample Product (CANDY)
id=6: Fashion Item (FASHION)
id=7: Sweet Treat (CANDY)
-- All created by 'system' user
-- Created dates around 2025-05-10
- Add authentication mechanism
- Encrypt database credentials
- Implement input validation
- Add CORS configuration
- Remove SQL logging in production
# Add security headers
server:
servlet:
session:
cookie:
secure: true
http-only: true
- Implement authentication/authorization
- Add unit and integration tests
- Add input validation annotations
- Implement pagination
- Add health check endpoints
- Add caching mechanism
- Implement rate limiting
- Add monitoring/metrics
- Improve error messages
- Add API versioning
- Add batch operations
- Implement soft delete consistently
- Add audit logging
- Optimize database queries
- Add API documentation examples
# Production deployment
export SPRING_PROFILES_ACTIVE=prod
export DB_URL=jdbc:postgresql://prod-db:5432/productdb
export DB_USERNAME=prod_user
export DB_PASSWORD=secure_password
export JWT_SECRET=your-secure-secret
- Application: Product Catalog Service
- Version: 0.0.1-SNAPSHOT
- Java: 17.0.12
- Spring Boot: 3.2.0
- Build Tool: Maven
- Database: PostgreSQL 17.4