Use cases · Dine-in & POS

Restaurant

A neighborhood restaurant running dine-in service, a bar, and takeout off one menu. Tables stay open for the length of a meal, not a fixed slot. Kitchen tickets fire by course. Parties split the check every which way. Tips land on the card after the meal, and every plate that goes out has to come off inventory.

The shape

The spine here is a Hober Order — the live tab — sitting on a Trantor table whose state is "held until the tab closes" rather than a timed window. The menu is Hardin; kitchen routing and coursing run through Daneel; the close lands a Mallow Invoice. Reservations, when you take them, are a Seldon Offer on a table grid.

  • Trantor models tables and kitchen stations as Resources. A dine-in table uses discrete resource state — held with the Order id in its linkRef until the tab closes — not a fixed-window ResourceHold.
  • Hober opens an Order when the party is seated; lines are added through the meal with snapshot-at-add-time pricing, support split-by-item and split-tender, and the long-running OPEN → CLOSED lifecycle lands a Mallow Invoice.
  • Hardin is the menu — Products, variants, and modifiers, with CompositeSlot combos. A RecipeIngredient links each dish to Trantor inventory items that decrement on order close, and a YieldRule can run happy-hour pricing by daypart.
  • Daneel routes the kitchen: a StationRoutingRule (CEL) sends each fired OrderLine to the first matching station, and a CoursingProfile paces appetizers → mains → dessert. The KDS bump / recall signals run through the same engine.
  • Payments handles card-present (EMV) tabs with captureMode=manual so the pre-auth on the card is captured once, at the final amount, after the tip.
  • Mallow posts the sale to a double-entry ledger — food and bar revenue, sales tax payable, and tips payable as a liability — on close.

Walk-through

Seat the party

A party of four is seated at table 12. The host opens a Hober Order against the table; Trantor flips table 12 to a held state with the Order id in its linkRef. The table is now unavailable to the reservation grid and the host stand alike, with no timed expiry — it frees when the tab closes.

Fire by course

The server adds two appetizers and four mains, each with modifiers ("no onion", "medium-rare"). When she fires the apps, Daneel's StationRoutingRule routes the cold app to the garde-manger station and the hot app to the line; the CoursingProfile holds the mains until the apps are bumped. The kitchen marks each line ready on the KDS.

A round at the bar

Mid-meal, two cocktails are added. They route to the bar station, snapshot at the current happy-hour price (a Hardin YieldRule by daypart), and each pour decrements its RecipeIngredient quantities from Trantor inventory when the tab closes.

Split the check

The party wants two checks, split by item. Hober divides the Order's lines into two payment groups without closing the tab. Each gets its own card pre-auth (Payments, captureMode=manual).

Close with tips

Each guest signs for a tip. The desk captures each Authorization at its tipped total in one call. Hober's close generates the Mallow Invoice, posts the ledger entries (DR Cash / CR Food Revenue / CR Bar Revenue / CR Sales Tax Payable / CR Tips Payable), decrements every recipe ingredient from Trantor inventory, and fires the receipt through Speaker. Table 12 releases.

Why this is hard without LatticeKit

A restaurant normally runs a POS, a KDS, a reservation book, an inventory system, and accounting software — four or five vendors, each with its own model of "an order", reconciled nightly by hand. The coursing and station-routing logic usually lives inside a closed KDS that can't see the reservation or the ledger. LatticeKit keeps one Order from seating to settled: the table state, the fired lines, the recipe consumption, the split tenders, and the posted ledger entries are all the same object graph, so split checks reconcile to the penny and the eighty-sixed ingredient is the same row the line cook decremented.