Openfront Restaurant

Menu, ordering, POS, service floor, kitchen, inventory, staff, and reporting.

Source · Live site · Catalog

Openfront Restaurant is the restaurant version of Openfront. It covers the main restaurant loop: publish a menu, take orders from the storefront or from staff tools, route them to kitchen stations, run the floor, close the check, and reconcile the day.

What ships today

How the order lifecycle works

A guest or staff member starts the order

Guests order through the storefront. Staff open orders from the POS or add items to a table from the service floor. Every path writes a RestaurantOrder with OrderItem rows. Item rows keep snapshots of name, price, modifiers, and kitchen station.

Payment is handled per channel

In the storefront, the guest picks a payment provider first (initiatePaymentSession). Then completeActiveCart checks or captures the payment and creates the order, its items, and a Payment in one database transaction. Staff orders are paid at the end through the POS payment screen (cash, card, gift card, or split tenders).

The order enters the kitchen

Orders in sent_to_kitchen, in_progress, or ready get KitchenTicket records, one per station. POS orders are created as sent_to_kitchen. Online orders paid by card start as sent_to_kitchen. Online orders using the manual provider start as open.

Front of house keeps the floor moving

Hosts work the waitlist and reservations. Servers use the service floor to add items, fire or hold courses, split or merge checks, combine or transfer tables, and close checks.

The day closes

When an order reaches completed or cancelled, the app syncs kitchen tickets, depletes recipe ingredients, and releases tables. A failed step is logged for recovery. Managers then reconcile cash, refunds, and processor statements on the Cash & Close page.

Tenancy

One deployment runs one restaurant. StoreSettings is a singleton. There is no organization, restaurant group, or location model. Orders, menu, inventory, tables, payments, and staff are not split by tenant. InventoryLocation is only a storage location for ingredients, not a restaurant location.

Access is controlled by the user's Role. Roles carry flags such as canAccessDashboard, canManageOrders, canManagePayments, canManageProducts, canManageInventory, canManageKitchen, canManageTables, canManageStaff, canManageSettings, canManageOnboarding, canManageGiftCards, and canManageDiscounts, each with a matching read flag where relevant. API keys add scopes on top of the owner's role.

Data model

The Keystone lists in features/keystone/models are:

AreaLists
People and accessUser, Role, ApiKey, Address
StoreStoreSettings
FloorFloor, Section, Table, Reservation, WaitlistEntry
MenuMenuCategory, MenuItem, MenuItemImage, MenuItemModifier
OrdersRestaurantOrder, OrderItem, OrderCourse, OrderAdjustment, ManagerApproval
KitchenKitchenStation, PrepStation, KitchenTicket, KitchenTicketEvent, KitchenMessage
Cart and checkoutCart, CartItem, PaymentCollection, PaymentSession
PaymentsPaymentProvider, Payment, Refund, Receipt, PaymentWebhookEvent, IdempotencyKey
PromotionsDiscount, DiscountRule, GiftCard, GiftCardTransaction
InventoryVendor, InventoryLocation, Ingredient, Recipe, StockMovement, PurchaseOrder, WasteLog
StaffShift, TimeEntry, TipPool
AuditAuditEvent

Several features do not have their own list. Business days, cash movements, settlements, notifications, campaigns, privacy requests, and time-correction requests are all stored as AuditEvent rows.

Current limits

  • One restaurant per deployment. No multi-location support.
  • Stripe, PayPal, and manual adapters exist. Behavior differs by provider. Test sessions, capture, refunds, and webhooks for the ones you enable.
  • Discounts have models and an admin list, but no order path applies a discount code. Only the pickup discount from store settings is applied at checkout.
  • The waitlist does not send SMS. Hosts contact guests by hand and confirm it in the app.
  • Email (order confirmations, campaigns) is queued and sent only when an operator triggers sending from the dashboard. SMTP acceptance is not proof of delivery.
  • The POS saves a draft on the device when offline, but it does not send orders offline. There is no printer or device management.
  • There is no loyalty program, delivery dispatch integration, accounting export, or payroll integration. Time clock and tips export CSV only.

Stack

  • Next.js 16 with the App Router, React 19
  • KeystoneJS 6 for lists, auth, and GraphQL
  • PostgreSQL through Prisma
  • Stripe, PayPal, and manual payment adapters
  • Tailwind CSS and shadcn/ui
  • An MCP-backed AI assistant in the dashboard

Route files under app/ are thin. Product logic lives in features/platform (operator screens), features/storefront (customer screens), and features/keystone (models, access, custom GraphQL operations).

Where to go next

On this page