Skip to main content

Warehouse Service

Overview

The Warehouse Service handles warehouse management, inventory allocation, and inventory tracking for order fulfillment. It receives order confirmation events and automatically allocates inventory to the nearest warehouse.

ItemDetails
LanguageJava 17
FrameworkSpring Boot 3.2
DatabaseAurora PostgreSQL (Global Database)
Namespacemall-warehouse
Port8080
Health Check/actuator/health

Architecture

API Endpoints

MethodPathDescription
GET/api/v1/warehousesGet warehouse list
GET/api/v1/warehouses/{id}Get warehouse details
POST/api/v1/warehouses/{id}/allocateAllocate order
GET/api/v1/warehouses/{id}/inventoryGet warehouse inventory status

Get Warehouse List

GET /api/v1/warehouses

Response (200 OK):

[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Seoul Distribution Center",
"location": "Gangnam-gu, Seoul",
"capacity": 10000,
"active": true,
"createdAt": "2024-01-01T00:00:00"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Busan Distribution Center",
"location": "Haeundae-gu, Busan",
"capacity": 8000,
"active": true,
"createdAt": "2024-01-01T00:00:00"
}
]

Get Warehouse Details

GET /api/v1/warehouses/{id}

Response (200 OK):

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Seoul Distribution Center",
"location": "Gangnam-gu, Seoul",
"capacity": 10000,
"active": true,
"createdAt": "2024-01-01T00:00:00"
}

Allocate Order

POST /api/v1/warehouses/{id}/allocate

Request:

{
"orderId": "660e8400-e29b-41d4-a716-446655440000"
}

Response (200 OK):

{
"id": "770e8400-e29b-41d4-a716-446655440000",
"warehouseId": "550e8400-e29b-41d4-a716-446655440000",
"warehouseName": "Seoul Distribution Center",
"orderId": "660e8400-e29b-41d4-a716-446655440000",
"status": "ALLOCATED",
"createdAt": "2024-01-15T10:35:00",
"updatedAt": "2024-01-15T10:35:00"
}

Get Warehouse Inventory Status

GET /api/v1/warehouses/{id}/inventory

Response (200 OK):

{
"warehouseId": "550e8400-e29b-41d4-a716-446655440000",
"warehouseName": "Seoul Distribution Center",
"totalCapacity": 10000,
"activeAllocations": 150,
"availableCapacity": 9850
}

Data Models

Warehouse Entity

@Entity
@Table(name = "warehouses")
public class Warehouse {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

@Column(nullable = false)
private String name;

private String location;

@Column(columnDefinition = "INTEGER DEFAULT 0")
private Integer capacity = 0;

@Column(columnDefinition = "BOOLEAN DEFAULT true")
private Boolean active = true;

@Column(name = "created_at")
private LocalDateTime createdAt;
}

Allocation Entity

@Entity
@Table(name = "allocations")
public class Allocation {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;

@ManyToOne
@JoinColumn(name = "warehouse_id")
private Warehouse warehouse;

@Column(name = "order_id", nullable = false)
private UUID orderId;

@Enumerated(EnumType.STRING)
@Column(length = 50)
private AllocationStatus status = AllocationStatus.PENDING;

@Column(name = "created_at")
private LocalDateTime createdAt;

@Column(name = "updated_at")
private LocalDateTime updatedAt;
}

AllocationStatus Enum

public enum AllocationStatus {
PENDING, // Pending
ALLOCATED, // Allocated
PICKING, // Picking in progress
PACKED, // Packing complete
SHIPPED // Shipped
}

Database Schema

CREATE TABLE warehouses (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
location VARCHAR(255),
capacity INTEGER DEFAULT 0,
active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE allocations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
warehouse_id UUID REFERENCES warehouses(id),
order_id UUID NOT NULL,
status VARCHAR(50) DEFAULT 'PENDING',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_allocations_warehouse_id ON allocations(warehouse_id);
CREATE INDEX idx_allocations_order_id ON allocations(order_id);
CREATE INDEX idx_allocations_status ON allocations(status);

Events (Kafka)

Subscribed Topics

Topic NameDescription
orders.confirmedReceives order confirmation events for automatic allocation

orders.confirmed Processing

@KafkaListener(topics = "orders.confirmed", groupId = "warehouse-service")
public void handleOrderConfirmed(Map<String, Object> orderData) {
UUID orderId = UUID.fromString(orderData.get("order_id").toString());
warehouseService.allocateOrderToNearestWarehouse(orderId);
}

Received payload:

{
"event": "order.confirmed",
"order_id": "660e8400-e29b-41d4-a716-446655440000",
"user_id": "user-123",
"total_amount": 687000.00
}

Environment Variables

VariableDescriptionDefault
SPRING_DATASOURCE_URLAurora PostgreSQL connection URL-
SPRING_DATASOURCE_USERNAMEDB username-
SPRING_DATASOURCE_PASSWORDDB password-
SPRING_KAFKA_BOOTSTRAP_SERVERSKafka broker address-
SPRING_KAFKA_CONSUMER_GROUP_IDKafka consumer group IDwarehouse-service
SERVER_PORTService port8080

Service Dependencies

Automatic Allocation Process

Allocation Status Flow

Error Handling

HTTP Status CodeErrorDescription
404WarehouseNotFoundExceptionWarehouse not found
400IllegalStateExceptionCannot allocate (inactive warehouse, etc.)
400InsufficientCapacityExceptionInsufficient warehouse capacity