Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Task 8 — Logistics and Shipment Processing Network

Objective

Create a logistics and shipment-processing network.

The system manages the complete lifecycle of packages from warehouse intake to final delivery.

The network contains:

  • customers
  • addresses
  • regions
  • warehouses
  • warehouse inventory
  • packages
  • shipments
  • shipment items
  • vehicles
  • drivers
  • routes
  • route stops
  • delivery assignments
  • tracking events
  • delivery attempts
  • returns
  • damaged or lost packages

The implementation must model package ownership, shipment state, warehouse location, vehicle capacity, driver eligibility, delivery routing, tracking history, failed delivery attempts, and returns.

The system must preserve both:

current shipment state

and:

complete shipment history

Domain Overview

Conceptually:

        Customer
           |
           +-- Address
           |
           +-- Shipment
                  |
                  +-- Package
                  |
                  +-- Tracking Events
                  |
                  +-- Delivery Attempts
                  |
                  +-- Return Shipment

Infrastructure:

        Region
           |
           +-- Warehouse
           |
           +-- Vehicle
           |
           +-- Driver
           |
           +-- Route

Operational flow:

        Shipment
           |
           v
        Warehouse
           |
           v
        Assignment
           |
           +-- Vehicle
           +-- Driver
           +-- Route
           |
           v
        Delivery

Customer

A customer contains:

  • ID
  • Name
  • Phone
  • Email

For example:

type Customer struct {
    ID    string
    Name  string
    Phone string
    Email string
}

Address

An address belongs to a region. A possible model is:

type Address struct {
    ID         string
    CustomerID string
    Street     string
    City       string
    PostalCode string
    RegionID   string
}

The system must validate that shipment destinations reference valid addresses.

Region

A region defines a delivery area. For example:

type Region struct {
    ID   string
    Name string
}

Examples:

  • region-1
  • region-2
  • region-3

Warehouse

A warehouse belongs to one region.

For example:

type Warehouse struct {
    ID       string
    RegionID string
    Name     string
}

A warehouse may contain many packages waiting for processing.

Package

Each package contains:

ID
Weight
Volume
Type
Current Warehouse
Status

A possible model is:

type Package struct {
    ID                string
    WeightKg          float64
    VolumeM3          float64
    PackageType       PackageType
    CurrentWarehouseID string
    Status            PackageStatus
}

Package Type

Possible package types may include:

standard
fragile
refrigerated
hazardous
oversized

Vehicle and driver restrictions may depend on package type.

Shipment

A shipment belongs to a customer and contains one or more packages. For example:

type Shipment struct {
    ID             string
    CustomerID     string
    DestinationID  string
    Priority       ShipmentPriority
    Status         ShipmentStatus
    Deadline       time.Time
    PackageIDs     []string
}

Shipment Priority

Supported priorities:

standard
express
critical

Higher-priority shipments should be considered first when several shipments compete for limited delivery capacity.

The exact tie-breaking rule must be deterministic. A reasonable order is:

  • critical
  • express
  • standard

Then:

earlier deadline

Then:

Shipment ID ascending

Shipment Status

Use a controlled state model.

Possible shipment states:

  • created
  • reserved
  • packed
  • ready_for_dispatch
  • dispatched
  • in_transit
  • out_for_delivery
  • delivered
  • delivery_failed
  • returning
  • returned
  • cancelled
  • lost

Not every transition is valid.

Shipment State Transitions

A possible allowed transition graph is:

        created
           |
           v
        reserved
           |
           v
        packed
           |
           v
        ready_for_dispatch
           |
           v
        dispatched
           |
           v
        in_transit
           |
           v
        out_for_delivery
           |
           +-------> delivered
           |
           +-------> delivery_failed
                          |
                          +-------> out_for_delivery
                          |
                          +-------> returning
                                         |
                                         v
                                      returned

Alternative transitions:

        created -> cancelled
        reserved -> cancelled
        packed -> cancelled
        in_transit -> lost
        out_for_delivery -> lost

The implementation must reject invalid state transitions.

Vehicle

Each vehicle contains:

  • ID
  • Vehicle Type
  • Maximum Weight
  • Maximum Volume
  • Allowed Regions
  • Supported Package Types
  • Status

A possible model is:

type Vehicle struct {
    ID                    string
    Type                  VehicleType
    MaxWeightKg           float64
    MaxVolumeM3           float64
    AllowedRegionIDs      []string
    SupportedPackageTypes []PackageType
    Status                VehicleStatus
}

Vehicle Status

Possible states:

  • available
  • assigned
  • maintenance
  • disabled

Only available vehicles may receive new delivery assignments.

Driver

A driver contains:

  • ID
  • Name
  • Licenses
  • Allowed Vehicle Types
  • Working Hours
  • Current Status

For example:

type Driver struct {
    ID                  string
    Name                string
    Licenses            []string
    AllowedVehicleTypes []VehicleType
    ShiftStart          time.Time
    ShiftEnd            time.Time
    Status              DriverStatus
}

Driver Status

Possible states:

  • available
  • assigned
  • off_shift
  • suspended

A driver may only be assigned when:

  • status = available
  • current time is within shift
  • driver is eligible for vehicle type

Route

A route defines a delivery sequence. For example:

type Route struct {
    ID        string
    RegionID  string
    Stops     []RouteStop
}

Route Stop

Each route stop may contain:

type RouteStop struct {
    Sequence  int
    AddressID string
}

The route model does not need to solve real-world GPS navigation.

The task focuses on shipment assignment and ordered stops.

Delivery Assignment

A delivery assignment connects:

  • vehicle
  • driver
  • route
  • shipments

For example:

type DeliveryAssignment struct {
    ID          string
    VehicleID   string
    DriverID    string
    RouteID     string
    ShipmentIDs []string
    Status      AssignmentStatus
}

Possible assignment states:

  • created
  • active
  • completed
  • cancelled

Capacity Validation

For all shipments assigned to one vehicle:

        total weight <= vehicle maximum weight

and:

        total volume <= vehicle maximum volume

The implementation must calculate capacity using every package contained in the assigned shipments.

Region Validation

A vehicle may only deliver shipments to regions listed in:

AllowedRegionIDs

A driver must also be allowed to operate the selected vehicle.

Package-Type Validation

A vehicle may restrict package types.

For example:

        standard truck:
            standard
            fragile
            oversized
        
        refrigerated van:
            standard
            refrigerated
        
        hazmat truck:
            standard
            hazardous

A shipment containing unsupported package types cannot be assigned to that vehicle.

Base Assignment Scenario

Create:

        Shipment: shipment-1001
        Priority: express
        Destination Region: region-2
        Deadline: 16:00

Packages:

        package-1:
            weight = 30 kg
            volume = 0.30 m3
            type = standard
        
        package-2:
            weight = 45 kg
            volume = 0.45 m3
            type = fragile

Total:

        weight = 75 kg
        volume = 0.75 m3

Vehicle:

        vehicle-1
        
        maximum weight = 1000 kg
        maximum volume = 12 m3
        allowed regions = region-1, region-2, region-3
        supported package types = standard, fragile
        status = available

Driver:

        driver-1
        
        licenses = B, C
        allowed vehicle type = truck
        shift = 08:00 - 18:00
        status = available

The system must determine whether:

shipment-1001

can be assigned to:

vehicle-1
driver-1

Warehouse Ownership

Before dispatch, every package must belong to a warehouse.

The shipment may only become:

ready_for_dispatch

when all of its packages are located at the correct dispatch warehouse.

If packages are split across multiple warehouses, the system must report that the shipment is not ready.

An optional extension may support package consolidation between warehouses.

Inventory Reservation

A warehouse should reserve packages for a shipment before packing.

A possible reservation model is:

type PackageReservation struct {
    ID          string
    ShipmentID  string
    PackageID   string
    WarehouseID string
    Status      ReservationStatus
}

Possible states:

  • reserved
  • released
  • consumed

A package must not be reserved for two active shipments at the same time.

Packing

When all shipment packages are reserved:

Shipment.Status = packed

after the packing operation succeeds.

The implementation should preserve package-to-shipment ownership.

Dispatch

When a valid delivery assignment becomes active:

Shipment.Status = dispatched

and then:

in_transit

The exact transition timing may be simplified, but transitions must remain valid.

Tracking Event

Every important shipment change must create a tracking event.

A possible model is:

type TrackingEvent struct {
    ID          string
    ShipmentID  string
    Timestamp   time.Time
    Type        TrackingEventType
    LocationID  string
    Description string
}

Example timeline:

        10:15 created
        10:22 reserved
        10:41 packed
        11:05 ready_for_dispatch
        11:20 dispatched
        12:03 in_transit
        14:42 out_for_delivery
        15:18 delivered

Tracking history must not be reconstructed only from final shipment status.

It must be stored explicitly.

Delivery Attempt

Each delivery attempt contains:

  • Attempt Number
  • Timestamp
  • Result
  • Reason

For example:

type DeliveryAttempt struct {
    ShipmentID    string
    AttemptNumber int
    Timestamp     time.Time
    Result        DeliveryAttemptResult
    Reason        string
}

Possible results:

  • delivered
  • failed

Possible failure reasons:

  • customer_not_available
  • invalid_address
  • customer_refused
  • vehicle_issue
  • package_damaged
  • other

Failed Delivery

When delivery fails:

Shipment.Status = delivery_failed

The shipment may then either:

be scheduled for another attempt

or:

enter return processing

Maximum Delivery Attempts

For the base task:

maximum delivery attempts = 3

After three failed attempts:

shipment must enter returning state

The implementation must not schedule a fourth normal delivery attempt.

Redelivery

If another attempt is allowed:

delivery_failed -> out_for_delivery

A new DeliveryAttempt must be created.

The previous failed attempts must remain in history.

Return Shipment

When a shipment can no longer be delivered, it must return to a warehouse.

A possible model is:

type ReturnShipment struct {
    ID              string
    OriginalShipmentID string
    TargetWarehouseID  string
    Reason          string
    Status          ReturnStatus
}

Possible return states:

  • created
  • in_transit
  • received

When the return reaches the warehouse:

Shipment.Status = returned

Lost Shipment

A shipment may become lost during transport.

For example:

in_transit -> lost

or:

out_for_delivery -> lost

A lost shipment is terminal for normal delivery processing.

It must not later transition directly to:

delivered

without an explicit recovery operation.

Damaged Package

A package may be marked damaged. A possible model:

type PackageIncident struct {
    PackageID   string
    ShipmentID  string
    Type        string
    Description string
    Timestamp   time.Time
}

If a damaged package prevents delivery, the shipment should enter a failure or return path according to the implemented rules.

Driver Shift Validation

A delivery assignment must fit inside the driver’s shift. For example:

        Driver shift ends at 18:00
        Estimated route completion = 19:15

The assignment should be rejected.

The task does not require advanced travel-time prediction. A route may provide:

EstimatedDuration

for validation.

Route Duration

A route may contain:

type Route struct {
    ID                string
    RegionID          string
    Stops             []RouteStop
    EstimatedDuration time.Duration
}

Driver shift validation may use this value.

Multiple Shipment Assignment

A vehicle may carry several shipments in one assignment. The system must validate the combined:

weight
volume
regions
package types
route compatibility

of all shipments.

Priority Processing

When several ready shipments exist and vehicle capacity is limited, process shipment priority in this order:

  • critical
  • express
  • standard

Within the same priority:

earlier deadline first

Then:

Shipment ID ascending

This guarantees deterministic selection.

Warehouse Capacity

An optional but recommended model may track warehouse storage capacity. For example:

type WarehouseCapacity struct {
    WarehouseID     string
    MaximumPackages int
    CurrentPackages int
}

A return operation should not silently exceed warehouse capacity.

If this extension is implemented, overflow must be reported.

Cancellation

A shipment may be cancelled only before dispatch. Allowed:

        created -> cancelled
        reserved -> cancelled
        packed -> cancelled
        ready_for_dispatch -> cancelled

Not allowed:

        in_transit -> cancelled
        delivered -> cancelled
        returned -> cancelled

When a reserved shipment is cancelled, package reservations must be released.

Idempotent Shipment Creation

Shipment creation requests should contain:

RequestID

Processing the same creation request twice must not create duplicate shipments.

A possible model:

type ShipmentCreateRequest struct {
    RequestID string
    Shipment  Shipment
}

Idempotent Delivery Confirmation

Delivery confirmation should also be idempotent.

If the same delivery confirmation event is received twice:

stock/state/history must not be mutated twice

The second processing attempt should return the already known result.

Audit History

In addition to customer-facing tracking events, the system should maintain internal audit history.

Examples:

  • shipment created
  • package reserved
  • shipment packed
  • assignment created
  • vehicle assigned
  • driver assigned
  • delivery attempt failed
  • shipment marked lost
  • return created
  • return received

A possible model is:

type AuditEvent struct {
    ID         string
    Timestamp  time.Time
    EntityType string
    EntityID   string
    Action     string
    Details    string
}

Tracking events and audit events are related but not identical.

Tracking is customer-visible shipment history. Audit history records internal system actions.

Query Operations

The system should support queries such as:

  • get current shipment status
  • get complete tracking history
  • get all shipments for customer
  • get all packages in warehouse
  • get all shipments assigned to vehicle
  • get current driver assignment
  • get all failed delivery attempts
  • get all active returns

Queries must not mutate shipment state.

Command Operations

State-changing operations include:

  • create shipment
  • reserve packages
  • pack shipment
  • create delivery assignment
  • dispatch shipment
  • record tracking event
  • record delivery attempt
  • confirm delivery
  • schedule redelivery
  • start return
  • receive return
  • cancel shipment
  • mark shipment lost

Validation

The implementation should validate:

  • unknown customer
  • unknown address
  • unknown region
  • unknown warehouse
  • unknown package
  • unknown shipment
  • unknown vehicle
  • unknown driver
  • unknown route
  • duplicate IDs
  • duplicate RequestID
  • package already assigned
  • package already reserved
  • weight <= 0
  • volume <= 0
  • invalid deadline
  • invalid shipment transition
  • vehicle capacity exceeded
  • vehicle region unsupported
  • package type unsupported
  • driver license invalid
  • driver unavailable
  • driver shift violation
  • invalid delivery attempt number

Required Test Scenarios

Create tests for at least:

  • successful shipment creation
  • duplicate RequestID
  • successful reservation
  • double package reservation rejected
  • successful packing
  • vehicle weight capacity exceeded
  • vehicle volume capacity exceeded
  • unsupported region
  • unsupported package type
  • driver not eligible
  • driver outside shift
  • successful assignment
  • successful dispatch
  • successful delivery
  • first failed delivery attempt
  • redelivery after failure
  • third failed attempt triggers return
  • successful return
  • shipment cancellation
  • lost shipment
  • invalid state transition
  • duplicate delivery confirmation
  • tracking-history ordering
  • priority-based shipment selection

Modeling Goal

The goal of this task is to model a real stateful logistics process.

The important relationships are:

        Customer
           |
        Shipment
           |
           +-- Packages
           +-- Destination
           +-- Tracking
           +-- Delivery Attempts
           |
           v
        Warehouse
           |
           v
        Delivery Assignment
           |
           +-- Vehicle
           +-- Driver
           +-- Route
           |
           v
        Delivery / Failure / Return

A useful architecture is:

        Shipment Service
              |
              +-- Shipment Lifecycle
              +-- Package Ownership
              +-- Reservations
              |
              v
        Warehouse Service
              |
              +-- Package Location
              +-- Packing
              +-- Returns
              |
              v
        Dispatch Service
              |
              +-- Vehicle Selection
              +-- Driver Validation
              +-- Capacity Validation
              +-- Route Assignment
              |
              v
        Delivery Service
              |
              +-- Delivery Attempts
              +-- Redelivery
              +-- Return Processing
              |
              v
        Tracking Service
              |
              +-- Tracking Events
              +-- Customer History
              |
              v
        Audit History

The main challenge is maintaining consistency between current shipment state, package location, delivery assignments, vehicle capacity, driver eligibility, tracking history, and return processing.

Scalionix Docs

Keyboard Shortcuts

Navigate the documentation without leaving the keyboard.
Navigation
Previous subject
←
Next subject
→
Previous subsection
Alt + ↑
Next subsection
Alt + ↓
Interface
Documentation Home
Ctrl + Enter
Search
Alt + Q
Open shortcuts
?
Close dialog
Esc
Scalionix Docs

Search Documentation