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
linkRefuntil 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 → CLOSEDlifecycle lands a Mallow Invoice. - Hardin is the menu — Products, variants, and modifiers, with
CompositeSlotcombos. ARecipeIngredientlinks each dish to Trantor inventory items that decrement on order close, and aYieldRulecan run happy-hour pricing by daypart. - Daneel routes the kitchen: a
StationRoutingRule(CEL) sends each firedOrderLineto the first matching station, and aCoursingProfilepaces appetizers → mains → dessert. The KDSbump/recallsignals run through the same engine. - Payments handles card-present (EMV) tabs with
captureMode=manualso 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.