The Cartonization Service is a sophisticated 3D bin-packing optimization microservice that serves as a Core Bounded Context within the PakLog fulfillment platform. Built with Domain-Driven Design (DDD) and Hexagonal Architecture principles, it is responsible for calculating optimal packing solutions to minimize shipping costs while ensuring proper item fit and safety.
Strategic Importance: HIGH - Provides 15-30% shipping cost reduction through optimal carton selection Architecture Pattern: Hexagonal Architecture (Ports & Adapters) Technology Stack: Java 21, Spring Boot 3.2, MongoDB, Apache Kafka, Redis Domain Complexity: HIGH - 3D bin-packing is an NP-hard computational problem
Core Purpose: Single source of truth for calculating optimal packing arrangements of items into shipping cartons using advanced 3D bin-packing algorithms.
Responsibilities (Whatβs IN the Context):
External Dependencies (Whatβs OUT of the Context):
The following terms define the common language used within this bounded context:
| Term | Definition | Business Context |
|---|---|---|
| Packing Solution | The optimal arrangement of items within one or more cartons | Core output of the service |
| Carton | A shipping container with defined dimensions and weight capacity | Basic packaging unit |
| 3D Bin-Packing | Algorithm for placing three-dimensional items into containers | Core algorithmic capability |
| Space Utilization | Percentage of carton volume occupied by items | Key efficiency metric |
| Dimensional Weight | Weight calculated from package dimensions using carrier formula | Shipping cost factor |
| Void Fill | Empty space in carton requiring packing materials | Waste reduction target |
| Package | A single carton with assigned items in a packing solution | Solution component |
| Item Placement | The specific position and orientation of an item in a carton | Algorithm output |
| Carton Type | A specific carton specification with standardized dimensions | Catalog entity |
| Packing Rules | Business constraints for packing (fragile separation, etc.) | Business logic |
graph TB
subgraph "Cartonization Bounded Context"
Core[Core: 3D Bin-Packing Algorithm]
Support1[Supporting: Carton Catalog Management]
Support2[Supporting: Performance Optimization]
Generic1[Generic: Product Dimension Enrichment]
Generic2[Generic: Event Publishing]
end
Core --> Support1
Core --> Support2
Core --> Generic1
Classification: CORE DOMAIN Strategic Value: HIGH - Direct competitive advantage Investment Priority: HIGH - Continuous optimization needed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@DomainService
public class PackingAlgorithmService {
// Core algorithm implementation
public List<Package> bestFitDecreasing(
List<ItemWithDimensions> items,
List<Carton> cartons,
PackingRules rules
);
public List<Package> firstFitDecreasing(
List<ItemWithDimensions> items,
List<Carton> cartons,
PackingRules rules
);
}
Classification: SUPPORTING DOMAIN Strategic Value: MEDIUM - Necessary but not differentiating Investment Priority: MEDIUM - Maintain and enhance as needed
Classification: SUPPORTING DOMAIN Strategic Value: MEDIUM-HIGH - Enables scalability Investment Priority: HIGH - Critical for real-time operations
Classification: GENERIC DOMAIN Strategic Value: LOW - Utility function Investment Priority: LOW - Use standard patterns
Classification: GENERIC DOMAIN Strategic Value: LOW - Standard capability Investment Priority: LOW - Use standard infrastructure
classDiagram
class Carton {
<<Aggregate Root>>
-CartonId id
-String name
-DimensionSet dimensions
-Weight maxWeight
-CartonStatus status
-LocalDateTime createdAt
-LocalDateTime updatedAt
+create()
+activate()
+deactivate()
+canFitItem()
+updateDimensions()
+pullDomainEvents()
}
class PackingSolution {
<<Aggregate Root>>
-String solutionId
-String requestId
-String orderId
-List~Package~ packages
-LocalDateTime createdAt
+create()
+getTotalPackages()
+getAverageUtilization()
+getTotalVolume()
}
class Package {
<<Entity>>
-String cartonId
-DimensionSet cartonDimensions
-List~ItemPlacement~ items
-BigDecimal utilization
+addItem()
+calculateUtilization()
}
class ItemPlacement {
<<Entity>>
-String sku
-int quantity
-Position position
-Orientation orientation
-Volume occupiedVolume
}
PackingSolution --> Package
Package --> ItemPlacement
classDiagram
class DimensionSet {
<<Value Object>>
-BigDecimal length
-BigDecimal width
-BigDecimal height
-DimensionUnit unit
+volume()
+canContain()
+convertTo()
}
class Weight {
<<Value Object>>
-BigDecimal value
-WeightUnit unit
+isGreaterThan()
+convertTo()
}
class PackingRules {
<<Value Object>>
-boolean optimizeForMinimumBoxes
-boolean allowMixedCategories
-boolean separateFragileItems
-BigDecimal maxUtilizationThreshold
}
class SKU {
<<Value Object>>
-String value
+validate()
}
class CartonId {
<<Value Object>>
-String value
+generate()
}
| Event | Trigger | Consumers | Purpose |
|---|---|---|---|
CartonCreatedEvent |
New carton registered | Warehouse Operations | Sync carton catalog |
CartonUpdatedEvent |
Carton specs modified | Cache invalidation | Update cached data |
CartonDeactivatedEvent |
Carton removed from use | Warehouse Operations | Stop using carton |
PackingSolutionCalculatedEvent |
Solution generated | Order Management, WMS | Trigger packing workflow |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
L1: Shipment Optimization
βββ L2: Packing Solution Calculation
β βββ L3: 3D Bin-Packing Algorithm Execution
β βββ L3: Multi-Carton Optimization
β βββ L3: Carton Selection Strategy
β βββ L3: Weight-Based Optimization
β βββ L3: Packing Solution Caching
βββ L2: Carton Catalog Management
β βββ L3: Carton Type Registration
β βββ L3: Carton Specification Management
β βββ L3: Carton Cost Management
β βββ L3: Carton Lifecycle Management
βββ L2: Dimensional Analysis
β βββ L3: Dimensional Weight Calculation
β βββ L3: Volume Utilization Analysis
β βββ L3: Space Efficiency Metrics
βββ L2: Integration & Events
βββ L3: Product Dimension Enrichment
βββ L3: Solution Event Publishing
βββ L3: Request Processing
Business Goal: Minimize shipping costs while ensuring safe product delivery
Key Business Outcomes:
Strategic Value: HIGH - Direct impact on operational costs and sustainability
Purpose: Calculate optimal arrangement of items in 3D space
Business Rules:
Technical Implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public PackingSolution calculateOptimalPacking(
List<ItemWithDimensions> items,
List<Carton> availableCartons,
PackingRules rules
) {
// Sort items by volume (largest first)
List<ItemWithDimensions> sortedItems = sortItemsByVolume(items);
// Sort cartons by volume (smallest first)
List<Carton> sortedCartons = sortCartonsByVolume(cartons);
// Apply selected algorithm
List<Package> packages = rules.shouldOptimizeForMinimumBoxes()
? bestFitDecreasing(sortedItems, sortedCartons, rules)
: firstFitDecreasing(sortedItems, sortedCartons, rules);
return PackingSolution.create(requestId, orderId, packages);
}
Metrics:
Purpose: Distribute items across multiple cartons when single carton insufficient
Business Rules:
Algorithm Strategy:
Purpose: Select most appropriate carton from available inventory
Selection Criteria:
Decision Matrix:
1
2
3
4
5
6
7
8
9
10
11
public Carton selectOptimalCarton(
List<ItemWithDimensions> items,
List<Carton> candidates,
SelectionCriteria criteria
) {
return candidates.stream()
.filter(carton -> canFitAllItems(carton, items))
.filter(carton -> meetsSpecialRequirements(carton, items))
.min(comparatorByCriteria(criteria))
.orElseThrow(() -> new NoSuitableCartonException());
}
Purpose: Optimize packing considering carrier weight brackets
Business Logic:
Dimensional Weight Formula:
1
2
Dimensional Weight = (L Γ W Γ H) / DIM_FACTOR
where DIM_FACTOR = 139 (FedEx/UPS standard)
Purpose: Cache frequently requested packing solutions
Caching Strategy:
Cache Invalidation:
Purpose: Maintain inventory of available carton types
Capabilities:
REST API:
1
2
3
4
5
6
7
8
9
10
POST /api/v1/cartons
{
"name": "Small Box A",
"length": 12.0,
"width": 8.0,
"height": 6.0,
"dimensionUnit": "IN",
"maxWeight": 25.0,
"weightUnit": "LB"
}
Purpose: Manage physical and logical attributes of cartons
Specifications Tracked:
Purpose: Control carton availability and status
Status Transitions:
1
2
3
DRAFT β ACTIVE β DEPRECATED β ARCHIVED
β
INACTIVE (temporary)
Business Rules:
Purpose: Calculate shipping weight based on package dimensions
Business Impact:
Purpose: Measure efficiency of space usage
Metrics Calculated:
Purpose: Track and optimize packing efficiency
KPIs:
graph LR
PC[Product Catalog] -->|Product Dimensions| CS[Cartonization Service]
OMS[Order Management] -->|Packing Requests| CS
style PC fill:#f9f,stroke:#333,stroke-width:2px
style OMS fill:#f9f,stroke:#333,stroke-width:2px
style CS fill:#bbf,stroke:#333,stroke-width:4px
Relationship Type: CONFORMIST
Integration Details:
Anti-Corruption Layer:
1
2
3
4
5
6
7
8
@Component
public class ProductDimensionEnricher {
// Translates external model to our domain model
public ItemWithDimensions enrich(ItemToPack item) {
ProductInfo external = productCatalogClient.getProductInfo(item.sku());
return mapToDomainModel(external, item);
}
}
Relationship Type: OPEN HOST SERVICE
Published API:
1
2
POST /api/v1/packing-solutions
GET /api/v1/packing-solutions/{solutionId}
Published Events:
com.paklog.cartonization.packing.solution.calculated.v1com.paklog.cartonization.carton.created.v1com.paklog.cartonization.carton.updated.v1Relationship Type: PUBLISHED LANGUAGE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Driving Side β
β ββββββββββββββββ ββββββββββββββββ β
β β REST API β β Kafka β β
β β Controller β β Consumer β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββββββββββββββββββββββββββ β
β β Application Layer β β
β β ββββββββββββββββββββββββββββ β β
β β β Use Case Services β β β
β β ββββββββββββ¬ββββββββββββββββ β β
β β β β β
β β βΌ β β
β β ββββββββββββββββββββββββββββ β β
β β β Domain Model β β β
β β β - Aggregates β β β
β β β - Value Objects β β β
β β β - Domain Services β β β
β β ββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββ β
β β² β² β
β β β β
β ββββββββ΄ββββββββ ββββββββ΄ββββββββ β
β β MongoDB β β Redis β β
β β Adapter β β Cache β β
β ββββββββββββββββ ββββββββββββββββ β
β Driven Side β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Language | Java | 21 | Core programming language |
| Framework | Spring Boot | 3.2.0 | Application framework |
| Persistence | MongoDB | 7.0 | Document store for aggregates |
| Caching | Redis | 7.2 | Distributed cache |
| Messaging | Apache Kafka | 3.5 | Event streaming |
| API Docs | SpringDoc OpenAPI | 2.3.0 | API documentation |
| Monitoring | Micrometer + Prometheus | Latest | Metrics collection |
| Logging | Logback + JSON | Latest | Structured logging |
| Resilience | Resilience4j | 2.2.0 | Circuit breaker, retry |
| Testing | JUnit 5 + Testcontainers | Latest | Testing framework |
| Metric | Target | Actual | Status |
|---|---|---|---|
| Packing Calculation p95 | <200ms | 125ms | β |
| API Response Time p95 | <300ms | 180ms | β |
| Cache Hit Rate | >70% | 78% | β |
| Solution Success Rate | >95% | 96.5% | β |
| Concurrent Requests | 100/sec | 150/sec | β |
| Space Utilization | >80% | 82% | β |
| KPI | Description | Target | Current | Impact |
|---|---|---|---|---|
| Shipping Cost Reduction | % reduction vs. naive packing | 20% | 22% | $2.5M/year saved |
| Packaging Waste Reduction | % reduction in void fill | 30% | 35% | 50 tons/year reduced |
| Packing Success Rate | % of orders packed successfully | 95% | 96.5% | Reduced exceptions |
| Average Carton Utilization | Space efficiency | 80% | 82% | Optimal density |
| Calculation Time | Speed of solution generation | <200ms | 125ms | Real-time capable |
| Risk | Probability | Impact | Mitigation Strategy |
|---|---|---|---|
| Algorithm Performance Degradation | Low | High | Caching, algorithm tuning, horizontal scaling |
| External Service Failure | Medium | Medium | Circuit breaker, fallback, caching |
| Data Inconsistency | Low | High | Event sourcing, audit logs, reconciliation |
| Cache Invalidation Issues | Medium | Low | TTL-based expiration, manual refresh |
| MongoDB Failure | Low | High | Replica sets, backup/restore, disaster recovery |
| Risk | Probability | Impact | Mitigation Strategy |
|---|---|---|---|
| Incorrect Packing Leading to Damage | Low | High | Conservative rules, fragile item handling |
| Regulatory Compliance (Hazmat) | Low | High | Explicit hazmat rules, audit trail |
| Carrier Rejection of Packages | Low | Medium | Carrier-specific validation rules |
| Cost Increases from Poor Packing | Low | High | Continuous monitoring, alerts |
Current Gaps:
Required for Production:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/api/v1/cartons:
post:
summary: Create new carton type
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCartonRequest'
responses:
201:
description: Carton created successfully
get:
summary: List all carton types
parameters:
- name: status
in: query
schema:
type: string
enum: [ACTIVE, INACTIVE, ALL]
responses:
200:
description: List of cartons
/api/v1/cartons/{cartonId}:
get:
summary: Get carton by ID
put:
summary: Update carton specifications
delete:
summary: Deactivate carton
/api/v1/packing-solutions:
post:
summary: Calculate packing solution
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CalculatePackingRequest'
responses:
200:
description: Packing solution calculated
/api/v1/packing-solutions/{solutionId}:
get:
summary: Get packing solution by ID
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// PackingSolutionCalculatedEvent
{
"specversion": "1.0",
"type": "com.paklog.cartonization.packing.solution.calculated.v1",
"source": "/cartonization-service",
"id": "evt-123",
"time": "2025-01-20T10:00:00Z",
"datacontenttype": "application/json",
"data": {
"solutionId": "sol-abc123",
"orderId": "order-456",
"packages": [
{
"cartonId": "carton-789",
"items": ["sku1", "sku2"],
"utilization": 0.85,
"weight": 5.2
}
],
"totalPackages": 1,
"averageUtilization": 0.85
}
}
| Term | Definition |
|---|---|
| 3D Bin-Packing | Mathematical optimization problem of packing three-dimensional items into containers |
| BFD | Best Fit Decreasing - algorithm that selects the best-fitting carton for each item |
| FFD | First Fit Decreasing - algorithm that uses the first suitable carton found |
| Dimensional Weight | Shipping weight calculated from package dimensions |
| DIM Factor | Divisor used to calculate dimensional weight (typically 139 for domestic US) |
| Void Fill | Packing material used to fill empty space in cartons |
| CloudEvents | CNCF specification for describing event data in a common way |
| Hexagonal Architecture | Architectural pattern that isolates core logic from external concerns |
| Aggregate Root | DDD pattern for maintaining consistency boundaries |
| Value Object | Immutable object that represents a domain concept |
Document Version: 1.0.0 Last Updated: 2025-01-20 Status: APPROVED Next Review: 2025-04-20