Use cases · Stays

Hotel front desk

A boutique hotel selling multi-night stays in three room types. Guests book online or by phone. Couples and families share a folio. Mini-bar charges, spa appointments, and restaurant tabs all roll into one bill at checkout. Housekeeping needs to know which rooms turn over today, and at what time.

The shape

This is a Seldon stay Offer with a nightcount duration and a range Availability projection backed by per-room calendars. Trantor models each physical room; Terminus models the household; Hober runs the folio as a long-running Order; Mallow finalises on checkout.

  • Seldon Offers are per room type (Standard King, Standard Queen, Suite) with durationShape={mode: nightcount, minNights: 1, maxNights: 14, checkInAfter: "15:00", checkOutBefore: "11:00"}.
  • Trantor has a ResourceType per room type plus one Resource per physical room, each with its own availability calendar.
  • Terminus models the booking party as a Group(kind=household) with the primary guest as rank=0; additional party members are GroupMember rows.
  • Hober opens an Order on check-in with orderType=dine_in-style long-running semantics; mini-bar, spa, and restaurant charges all attach as OrderLines.
  • Payments + Mallow handle the checkout settle and the immutable folio.
  • Daneel drives housekeeping routing on the booking.ending event — the same emission pipeline that auto-advances the Booking lifecycle.

Walk-through

Reservation

A guest books two adults, three nights, Standard King, arriving Friday. The Seldon Booking call asks Trantor to hold any one Standard King Resource for the requested window. Trantor responds with a hold on room 204; the Booking pins room 204 in its trantorAllocations. Radiant pricing for the date range gets snapshotted; cancellation policy too.

Pre-arrival communications

Daneel runs a "stay confirmation" workflow that dispatches a confirmation through Speaker on booking confirmed, then a check-in reminder 24 hours before arrival. Speaker calls assertConsent(personId, "transactional.email") first; the guest opted in at booking, so both messages send.

Check-in

Friday afternoon, the desk taps check-in. The Booking auto-advances from confirmed to checked_in on the booking.starting emission. The desk opens a Hober Order pinned to this Booking with the room as a Trantor table-style state flag (room is "held until folio closes," not "held for a window" — same physics as a dine-in table).

The folio fills

Over three nights, an OrderLine attaches each time the guest charges something to the room. The mini-bar swipe at the room hits Hardin (the Hober line snapshots the price of the bottle of wine). A spa appointment is a separate Seldon Booking against a different Offer (Spa Massage, kind=appointment); on completion, the room's folio gets a $180 OrderLine. The restaurant attaches dinner as another OrderLine. Every line snapshots the price-at-add-time.

Checkout

Sunday morning. Desk applies the guest's card-on-file PaymentMethod, splits half to a corporate AmEx via a second OrderPayment, and closes the Order. Mallow generates the Invoice with full line-by-line detail and line tax. Trantor releases the room hold; Daneel's housekeeping workflow fires on booking.ending and routes a turn-over ticket to the housekeeping station (a Trantor DiscreteResource). The Seldon Booking ends at completed.

Why this is hard without LatticeKit

Hotel PMSes are notoriously monolithic precisely because every component (room inventory, folio, POS, scheduling, comms) is deeply coupled and yet has to be modeled separately. Trying to bolt on a real CRM or a third-party spa booking system usually means an integration that drifts. LatticeKit's split — physical rooms in Trantor, party identity in Terminus, the folio in Hober, the immutable invoice in Mallow, the spa booking as another Seldon Offer — lets each layer be replaced without touching the others, and the shared audit-event outbox means every UI sees a consistent view of what's happening in real time via Palver.