Keeping restaurant orders flowing when Wi‑Fi stumbles is non‑negotiable. Here’s a simplified outline of how we keep devices in lockstep and make sure every ticket hits the printer.

The shape of an order

export type Order = {
  id: string;
  table: string;
  items: Array<{ sku: string; qty: number }>;
  status: 'pending' | 'paid' | 'printed';
  updatedAt: number; // unix ms
};

Conflict resolution

We lean on a last-writer-wins register for most fields and a grow-only set for items. In pseudocode:

function mergeOrders(local: Order, incoming: Order): Order {
  const newer = incoming.updatedAt > local.updatedAt ? incoming : local;
  return {
    ...newer,
    items: mergeItems(local.items, incoming.items),
  };
}

function mergeItems(a: Order['items'], b: Order['items']) {
  const byKey = new Map<string, number>();
  for (const line of [...a, ...b]) {
    const next = (byKey.get(line.sku) ?? 0) + line.qty;
    byKey.set(line.sku, next);
  }
  return [...byKey.entries()].map(([sku, qty]) => ({ sku, qty }));
}

Printing guarantees

  1. Each device keeps a local queue of pendingPrints.
  2. When connectivity returns, we reconcile orders, then drain pendingPrints.
  3. Printers are idempotent on orderId + status, so retries are safe.

Takeaways