Skip to main content
The KDS Frontend uses a strict state machine to manage order statuses. Each order follows a defined lifecycle from creation to completion, with clear rules about which transitions are allowed.

Order Status Types

The application defines seven distinct order statuses:
domain/order/order-status.ts
export type OrderStatus =
  | "RECEIVED"
  | "CONFIRMED"
  | "PREPARING"
  | "READY"
  | "PICKED_UP"
  | "DELIVERED"
  | "CANCELLED";

Status Definitions

RECEIVED - The initial status when a new order is created and received by the kitchen.Characteristics:
  • First status in the order lifecycle
  • Indicates the order has been placed but not yet acknowledged
  • Usually displayed in the first column of the Kanban board
Possible Transitions:
  • CONFIRMED (order acknowledged by kitchen)
  • CANCELLED (order rejected or cancelled)
CONFIRMED - The order has been acknowledged by the kitchen staff and is queued for preparation.Characteristics:
  • Kitchen has accepted the order
  • Order is in the queue, waiting to be prepared
  • Customer is notified that their order is confirmed
Possible Transitions:
  • PREPARING (kitchen starts preparing)
  • CANCELLED (order cancelled before preparation)
PREPARING - The kitchen is actively preparing the order.Characteristics:
  • Food is being cooked/assembled
  • Most active phase in the kitchen
  • Cannot be moved backward to previous statuses
Possible Transitions:
  • READY (preparation complete)
  • CANCELLED (order cancelled during preparation)
READY - The order is complete and ready for pickup by the delivery courier.Characteristics:
  • Food is prepared and packaged
  • Waiting for courier to pick up
  • Time-sensitive status (food should be picked up quickly)
Possible Transitions:
  • PICKED_UP (courier collects the order)
  • CANCELLED (order not picked up or cancelled)
PICKED_UP - The courier has collected the order and is on the way to deliver it.Characteristics:
  • Order is in transit
  • Assigned to a specific courier
  • Customer can track delivery progress
  • Displayed in the Riders section
Possible Transitions:
  • DELIVERED (order successfully delivered)
Unlike other statuses, PICKED_UP orders cannot be cancelled. Once picked up, the order must be completed.
DELIVERED - The order has been successfully delivered to the customer.Characteristics:
  • Final successful status
  • Order lifecycle complete
  • No further transitions possible
Possible Transitions:
  • None (terminal status)
CANCELLED - The order was cancelled before completion.Characteristics:
  • Terminal status (like DELIVERED)
  • Can be reached from any status except PICKED_UP and DELIVERED
  • Requires handling refunds and notifications
Possible Transitions:
  • None (terminal status)

Status Transition Rules

The application enforces strict rules about which status transitions are allowed. These rules are defined in the domain layer:
domain/order/order-transitions.ts
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);
}

Transition Validation

The canTransition function is used throughout the application to validate status changes:
components/Kanban/Kanban.tsx
const onDragEnd = (event: DragEndEvent) => {
  const orderId = String(active.id);
  const targetStatus = String(over.id) as OrderStatus;
  
  const current = findOrder(orderId);
  if (!current) return;

  // Validate transition is allowed
  if (!canTransition(current.status, targetStatus)) {
    return; // Reject invalid transition
  }

  updateOrderStatus(orderId, targetStatus);
};

Transition Flow Diagram

1

RECEIVED

New order arrives in the systemNext Steps:
  • Confirm → CONFIRMED
  • Cancel → CANCELLED
2

CONFIRMED

Kitchen acknowledges the orderNext Steps:
  • Start preparation → PREPARING
  • Cancel before prep → CANCELLED
3

PREPARING

Kitchen is actively working on the orderNext Steps:
  • Complete preparation → READY
  • Cancel during prep → CANCELLED
4

READY

Order is ready for pickupNext Steps:
  • Courier picks up → PICKED_UP
  • Cancel if not picked up → CANCELLED
5

PICKED_UP

Courier is delivering the orderNext Steps:
  • Deliver to customer → DELIVERED
Cannot be cancelled once picked up
6

DELIVERED or CANCELLED

Order lifecycle complete (terminal state)Next Steps:
  • None (end of lifecycle)

Status Labels

The UI displays human-friendly labels for each status:
components/order/constants/order-status-labels.ts
export const ORDER_STATUS_LABELS: Record<OrderStatus, string> = {
  RECEIVED: "Received",
  CONFIRMED: "Confirmed",
  PREPARING: "Preparing",
  READY: "Ready",
  PICKED_UP: "Picked Up",
  DELIVERED: "Delivered",
  CANCELLED: "Cancelled",
};

Implementation Examples

Updating Order Status

To update an order’s status, use the updateOrderStatus method from the Orders context:
import { useOrders } from "@/contexts/Orders.context";
import { canTransition } from "@/domain/order/order-transitions";

function MyComponent() {
  const { orders, updateOrderStatus } = useOrders();

  const handleStatusChange = async (orderId: string, newStatus: OrderStatus) => {
    const order = orders.find(o => o.id === orderId);
    
    if (!order) return;

    // Validate transition
    if (!canTransition(order.status, newStatus)) {
      console.error("Invalid transition");
      return;
    }

    // Update status
    await updateOrderStatus(orderId, newStatus);
  };

  return (
    // Your component JSX
  );
}
The updateOrderStatus method performs optimistic updates, immediately reflecting the change in the UI before the server confirms it.

Terminal Statuses

Two statuses are terminal, meaning they are the end of an order’s lifecycle:

DELIVERED

Successful completion of the order
  • Customer received their food
  • Payment processed
  • Order archived

CANCELLED

Order was cancelled before delivery
  • Refund may be issued
  • Kitchen stops preparation
  • Customer notified
Terminal statuses have no outgoing transitions. Once an order reaches DELIVERED or CANCELLED, it cannot be changed.

Best Practices

Before updating an order status, always use the canTransition function to ensure the transition is valid:
if (!canTransition(currentStatus, newStatus)) {
  throw new Error("Invalid status transition");
}
Status updates can fail due to network issues or validation errors. Always handle errors and provide feedback to users:
try {
  await updateOrderStatus(orderId, newStatus);
} catch (error) {
  console.error("Failed to update order status:", error);
  // Rollback optimistic update
  // Show error message to user
}
The Orders context implements optimistic updates to provide immediate feedback while the server processes the request:
// Update UI immediately
setOrders((curr) => curr.map((o) => (o.id === id ? { ...o, status } : o)));

try {
  // Then update server
  await orderOrchestrator.updateOrderState(id, status);
} catch (e) {
  // Rollback on error
  setOrders((curr) => curr.map((o) => (o.id === id ? previous! : o)));
}
Never attempt to transition from DELIVERED or CANCELLED statuses. These are final states:
const isTerminalStatus = (status: OrderStatus): boolean => {
  return status === "DELIVERED" || status === "CANCELLED";
};

if (isTerminalStatus(order.status)) {
  console.warn("Cannot modify terminal status");
  return;
}

Architecture

Learn about the layered architecture

Real-time Sync

Understand WebSocket synchronization

Order Repository

API reference for order operations

Build docs developers (and LLMs) love