Overview
The backend uses a layered architecture with clear separation of concerns:Key Services
DistributionService
Core service that orchestrates product distribution from warehouses to stores. Location:services/DistributionService.java:24
Key Features:
- Strategy pattern for warehouse selection
- Transaction management with
@Transactional - Cache eviction with
@CacheEvict - Demand fulfillment algorithm
- Load data from JSON sources
- For each store, process demand items
- Select warehouses using configured strategy
- Calculate quantities considering capacity constraints
- Create assignments and track unfulfilled demands
- Persist results to database
application.properties:
distanceOnlyStrategy- Select nearest warehousedistanceWithToleranceStrategy- Consider nearby warehouses within tolerance
ProductService
Manages product data and CRUD operations. Location:services/ProductService.java:16
Key Methods:
ResourceNotFoundException when product not found:
StoreService
Manages store data and operations. Location:services/StoreService.java:16
Similar pattern to ProductService:
- Load stores from JSON
- Refresh database
- CRUD operations
- Transaction management with
EntityManager.clear()
WarehouseService
Manages warehouse data and inventory. Location:services/WarehouseService.java:16
Key Operations:
- Load warehouses from external JSON
- Manage warehouse inventory
- Track stock availability
- Handle capacity constraints
MetricsService
Calculates distribution metrics and performance indicators. Location:services/MetricsService.java:17
Caching Strategy:
Repository Pattern
All services use Spring Data JPA repositories for database access.Standard Repository Interface
Custom Queries
Repositories can define custom queries using:- Method name conventions
@Queryannotations- Native SQL queries
- Criteria API
MapStruct DTOs
MapStruct automatically generates mapping code between entities and DTOs.Mapper Interface
Usage in Controllers
Benefits
- Type-safe - Compile-time validation
- Performance - No reflection, generated code
- Maintainable - Single source of truth
- Flexible - Custom mapping methods supported
Generated Code
MapStruct generates implementation classes during compilation:Caching Strategy
Spring’s caching abstraction improves performance for expensive operations.Configuration
Inapplication.properties:
Cache Annotations
@Cacheable - Cache method results:Cache Key Strategy
For complex cache keys, use SpEL expressions:Transaction Management
Spring manages transactions declaratively using@Transactional.
Service-Level Transactions
Transaction Propagation
Spring supports different propagation behaviors:Rollback Rules
By default, transactions rollback on runtime exceptions:Dependency Injection
Services use constructor injection (recommended over field injection):- Immutable dependencies
- Easier testing (can use constructor without Spring)
- Clear required dependencies
Exception Handling
Custom exceptions provide meaningful error messages:Best Practices
- Keep services focused - Single responsibility principle
- Use constructor injection - Better testability
- Transaction boundaries - Mark transactional methods appropriately
- Cache strategically - Only cache expensive operations
- Clear cache on updates - Prevent stale data
- Handle exceptions - Provide meaningful error messages
- Log appropriately - Info for important operations, debug for details
- Entity manager awareness - Clear context after bulk operations