Overview
The order transitions module provides validation logic for state changes in the order lifecycle. It ensures that orders can only transition between valid states, maintaining data integrity and business rule compliance.
canTransition
Validates whether an order can transition from one status to another based on predefined business rules.
Function Signature
function canTransition ( from : OrderStatus , to : OrderStatus ) : boolean
Parameters
The current status of the order. Must be a valid OrderStatus value.
The desired target status. Must be a valid OrderStatus value.
Returns
Returns true if the transition is allowed, false otherwise.
Transition Rules
The complete transition matrix defines which status changes are permitted:
const ALLOWED_TRANSITIONS : Record < OrderStatus , OrderStatus []> = {
RECEIVED: [ "CONFIRMED" , "CANCELLED" ],
CONFIRMED: [ "PREPARING" , "CANCELLED" ],
PREPARING: [ "READY" , "CANCELLED" ],
READY: [ "PICKED_UP" , "CANCELLED" ],
PICKED_UP: [ "DELIVERED" ],
DELIVERED: [],
CANCELLED: [],
};
Valid Transitions
RECEIVED
CONFIRMED
PREPARING
READY
PICKED_UP
Terminal States
From RECEIVED, can transition to:
CONFIRMED - Kitchen acknowledges and accepts the order
CANCELLED - Order is cancelled before confirmation
RECEIVED is the initial state for new orders. Orders must be confirmed before preparation can begin.
From CONFIRMED, can transition to:
PREPARING - Kitchen begins order preparation
CANCELLED - Order is cancelled after confirmation but before prep
Once confirmed, the order is in the kitchen’s queue and ready to be worked on.
From PREPARING, can transition to:
READY - Order preparation is complete
CANCELLED - Order is cancelled during preparation
Active preparation state. Cancellation during this phase may involve waste.
From READY, can transition to:
PICKED_UP - Order is collected by customer or driver
CANCELLED - Order is cancelled while waiting for pickup
The order is complete and waiting. Cancellation at this stage is uncommon.
From PICKED_UP, can transition to:
DELIVERED - Order successfully delivered to customer
Once picked up, the only valid transition is to DELIVERED. Cancellation is no longer possible.
DELIVERED and CANCELLED are terminal states. No transitions are allowed from these states. Orders in these states are considered final.
DELIVERED : Successful completion
CANCELLED : Order terminated
Usage Examples
Basic Validation
State Update with Validation
React Hook
Middleware Example
import { canTransition } from "@/domain/order/order-transitions" ;
// Check if transition is valid
if ( canTransition ( "RECEIVED" , "CONFIRMED" )) {
console . log ( "Valid transition" );
// Proceed with status update
} else {
console . log ( "Invalid transition" );
// Show error to user
}
State Diagram
The order status transitions can be visualized as a directed graph:
Business Rules
Terminal States : Once an order reaches DELIVERED or CANCELLED, no further transitions are allowed. These represent final states in the order lifecycle.
Cancellation Window : Orders can be cancelled at any point up to and including the READY status. Once PICKED_UP, cancellation is no longer possible.
Linear Progression : For successful order completion, the status must progress linearly through the normal flow: RECEIVED → CONFIRMED → PREPARING → READY → PICKED_UP → DELIVERED.
Complete Source Code
import { OrderStatus } from "./order-status" ;
const ALLOWED_TRANSITIONS : Record < OrderStatus , OrderStatus []> = {
RECEIVED: [ "CONFIRMED" , "CANCELLED" ],
CONFIRMED: [ "PREPARING" , "CANCELLED" ],
PREPARING: [ "READY" , "CANCELLED" ],
READY: [ "PICKED_UP" , "CANCELLED" ],
PICKED_UP: [ "DELIVERED" ],
DELIVERED: [],
CANCELLED: [],
};
export function canTransition ( from : OrderStatus , to : OrderStatus ) : boolean {
return ALLOWED_TRANSITIONS [ from ]. includes ( to );
}
Error Handling
When implementing status transitions, consider these error scenarios:
Comprehensive Error Handling
Type-Safe API Response
import { canTransition } from "@/domain/order/order-transitions" ;
class InvalidTransitionError extends Error {
constructor ( from : OrderStatus , to : OrderStatus ) {
super ( `Invalid transition from ${ from } to ${ to } ` );
this . name = "InvalidTransitionError" ;
}
}
async function safeTransition (
orderId : string ,
currentStatus : OrderStatus ,
targetStatus : OrderStatus
) {
// Validate transition
if ( ! canTransition ( currentStatus , targetStatus )) {
throw new InvalidTransitionError ( currentStatus , targetStatus );
}
try {
// Perform database update
await updateOrderInDb ( orderId , targetStatus );
// Log the transition
await logStatusChange ( orderId , currentStatus , targetStatus );
return { success: true , newStatus: targetStatus };
} catch ( error ) {
console . error ( `Failed to update order ${ orderId } :` , error );
throw error ;
}
}
Source Location
~/workspace/source/domain/order/order-transitions.ts