AFE Path Service - Domain-Driven Design
Overview
The AFE Path Service manages Automated Fulfillment Equipment (AFE) sorter-based workflows for multi-item order consolidation. It handles approximately 30-35% of all warehouse orders through automated sorting and rebin operations.
| Attribute |
Value |
| Port |
8084 |
| Package |
com.paklog.wms.processpath.afe |
| Database |
MongoDB |
| Messaging |
Apache Kafka |
Domain Model
Aggregates
AFEBatch (Root Aggregate)
Represents a batch of orders routed through AFE sorter-based processing.
1
2
3
4
5
6
7
8
9
10
11
12
| public class AFEBatch {
private String batchId;
private String warehouseId;
private String waveId;
private List<String> orderIds;
private int totalItems;
private BatchStatus status;
private String assignedInductStation;
private LocalDateTime createdAt;
private LocalDateTime inductStartedAt;
private LocalDateTime inductCompletedAt;
}
|
State Machine:
stateDiagram-v2
[*] --> CREATED
CREATED --> READY_FOR_INDUCT: assignToInductStation()
READY_FOR_INDUCT --> INDUCTING: startInduction()
INDUCTING --> SORTING: completeInduction()
SORTING --> COMPLETED: completeRebinning()
CREATED --> CANCELLED: cancel()
READY_FOR_INDUCT --> CANCELLED: cancel()
Business Rules:
- Batch must be in CREATED status to assign induct station
- Batch must be READY_FOR_INDUCT to start induction
- Batch must be INDUCTING to complete induction
- Batch must be SORTING to complete rebinning
RebinWall
Represents a physical rebin wall with slots for order consolidation.
1
2
3
4
5
6
7
8
| public class RebinWall {
private String wallId;
private String warehouseId;
private int totalSlots;
private int availableSlots;
private List<RebinSlot> slots;
private WallStatus status;
}
|
InductStation
Represents an induction station for introducing items into the sorter.
1
2
3
4
5
6
7
| public class InductStation {
private String stationId;
private String warehouseId;
private StationStatus status;
private String assignedBatchId;
private int throughputPerHour;
}
|
SorterLane
Represents a lane in the AFE sorter system.
1
2
3
4
5
6
| public class SorterLane {
private String laneId;
private String sorterId;
private LaneStatus status;
private String assignedChuteId;
}
|
Value Objects
RebinSlot
1
2
3
4
5
6
7
8
9
10
11
12
13
| public record RebinSlot(
int slotNumber,
String orderId,
SlotStatus status,
int expectedItems,
int receivedItems,
LocalDateTime assignedAt,
LocalDateTime completedAt
) {
public boolean isComplete() {
return receivedItems >= expectedItems;
}
}
|
Domain Events
Events Published
| Event |
Type |
Description |
| AFEBatchCreatedEvent |
com.paklog.processpath.afe.batch-created.v1 |
Batch created for AFE processing |
| InductionCompletedEvent |
com.paklog.processpath.afe.induction-completed.v1 |
All items inducted into sorter |
| SortCompletedEvent |
com.paklog.processpath.afe.sort-completed.v1 |
Item sorted to rebin chute |
| RebinCompletedEvent |
com.paklog.processpath.afe.rebin-completed.v1 |
Order consolidated in rebin slot |
| WallCapacityChangedEvent |
com.paklog.processpath.afe.wall-capacity-changed.v1 |
Rebin wall capacity state changed |
| TrayCirculationImbalanceEvent |
com.paklog.processpath.afe.tray-circulation-imbalance.v1 |
Tray flow anomaly detected |
| DischargeJamDetectedEvent |
com.paklog.processpath.afe.discharge-jam-detected.v1 |
Sorter discharge jam detected |
Events Consumed
| Source |
Topic |
Event |
Handler |
| Process Path Routing |
process-path.routing.v1.events |
ShipmentRoutedToPathEvent |
PathAssignedEventConsumer |
| Robotics Fleet |
robotics.fleet.v1.events |
RobotTaskCompletedEvent |
RobotTaskCompletedHandler |
| Robotics Fleet |
robotics.fleet.v1.events |
PodDeliveredEvent |
PodDeliveredHandler |
Domain Services
AFEBatchService
1
2
3
4
5
6
7
8
9
| public interface AFEBatchService {
AFEBatch createBatch(String warehouseId, String waveId, List<String> orderIds);
AFEBatch assignToInductStation(String batchId, String inductStation);
AFEBatch startInduction(String batchId);
AFEBatch completeInduction(String batchId);
AFEBatch completeRebinning(String batchId);
AFEBatch getBatch(String batchId);
List<AFEBatch> getBatchesByWave(String waveId);
}
|
RebinService
1
2
3
4
5
6
7
| public interface RebinService {
RebinSlot assignOrderToSlot(String wallId, int slotNumber, String orderId, int expectedItems);
RebinSlot addItemToSlot(String wallId, int slotNumber, String itemId);
RebinSlot completeSlot(String wallId, int slotNumber);
void clearSlot(String wallId, int slotNumber);
RebinWall getWallStatus(String wallId);
}
|
AFEWorkAssignmentService
1
2
3
4
5
| public interface AFEWorkAssignmentService {
void handlePathAssignment(ShipmentRoutedToPathEvent event);
void handleRobotTaskCompleted(RobotTaskCompletedEvent event);
void handlePodDelivered(PodDeliveredEvent event);
}
|
API Endpoints
AFE Batches
| Method |
Endpoint |
Description |
| POST |
/api/v1/afe-batches |
Create batch |
| PUT |
/api/v1/afe-batches/{batchId}/assign-induct-station |
Assign to induct station |
| PUT |
/api/v1/afe-batches/{batchId}/start-induction |
Start induction |
| PUT |
/api/v1/afe-batches/{batchId}/complete-induction |
Complete induction |
| PUT |
/api/v1/afe-batches/{batchId}/complete-rebinning |
Complete rebinning |
| GET |
/api/v1/afe-batches/{batchId} |
Get batch details |
| GET |
/api/v1/afe-batches/wave/{waveId} |
Get batches by wave |
Rebin Walls
| Method |
Endpoint |
Description |
| PUT |
/api/v1/rebin-walls/{wallId}/slots/{slotNumber}/assign |
Assign order to slot |
| PUT |
/api/v1/rebin-walls/{wallId}/slots/{slotNumber}/add-item |
Add item to slot |
| PUT |
/api/v1/rebin-walls/{wallId}/slots/{slotNumber}/complete |
Complete slot |
| PUT |
/api/v1/rebin-walls/{wallId}/slots/{slotNumber}/clear |
Clear slot |
| GET |
/api/v1/rebin-walls/{wallId} |
Get rebin wall status |
Workflow
sequenceDiagram
participant ROUTING as Routing Service
participant AFE as AFE Path Service
participant INDUCT as Induct Station
participant SORTER as Sorter
participant WALL as Rebin Wall
participant SLAM as SLAM Service
ROUTING->>AFE: ShipmentRoutedToPathEvent
AFE->>AFE: Create/Add to batch
AFE->>INDUCT: Assign batch
INDUCT->>SORTER: Induct items
AFE-->>AFE: InductionCompletedEvent
SORTER->>WALL: Sort to chutes
AFE-->>AFE: SortCompletedEvent
WALL->>WALL: Consolidate order
AFE-->>SLAM: RebinCompletedEvent
Repository Interfaces
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| public interface AFEBatchRepository {
AFEBatch save(AFEBatch batch);
Optional<AFEBatch> findById(String batchId);
List<AFEBatch> findByWaveId(String waveId);
List<AFEBatch> findByStatus(BatchStatus status);
}
public interface RebinWallRepository {
RebinWall save(RebinWall wall);
Optional<RebinWall> findById(String wallId);
List<RebinWall> findByWarehouseId(String warehouseId);
}
public interface InductStationRepository {
InductStation save(InductStation station);
Optional<InductStation> findById(String stationId);
List<InductStation> findAvailable(String warehouseId);
}
|
Integration Patterns
Customer-Supplier
- Upstream: Process Path Routing Service supplies path assignments
- Downstream: SLAM Operations Service consumes rebin completion events
Partnership
- Robotics Fleet: Bidirectional coordination for pod delivery and tray management
Technology Stack
| Component |
Technology |
| Language |
Java 21 |
| Framework |
Spring Boot 3.3.3 |
| Database |
MongoDB 7.0 |
| Messaging |
Apache Kafka 7.5.0 |
| Event Format |
CloudEvents 2.5.0 |
References