On this page
For owners, administrators, branch managers and chefs. Screens: Menu in the sidebar → Items · Categories · Menus & schedules · Modifiers · Pricing.
Everything the POS sells starts here. Prices are entered in your business
currency (UGX examples below have no decimals); every change is audited
and pushed to the tills immediately (menu.published / menu.item_availability
realtime events; offline tills pick it up on their next sync).
Who can do what
| Task | Permission | Default roles |
|---|---|---|
| See the menu screens | menu.view |
everyone who serves or manages |
| Create / edit categories, items, variants, modifiers, combos, menus | menu.manage |
owner, director, general/branch/restaurant manager, administrator, chef |
| 86 an item (sold out) / bring it back | menu.availability |
floor and production staff too (waiters, cashiers, bartenders, baristas, cooks) |
| Change prices, menu prices, price rules | menu.pricing (sensitive: needs a password session, never a PIN session) |
owner, director, managers |
| See cost and margin columns | menu.costs |
managers, chef, store manager, accountant, auditor |
Someone with menu.manage but not menu.pricing (an administrator, a
chef) can rename an item or change its modifiers but the save is refused if
the base price, a variant price or a menu price changed.
1. Categories
Menu → Categories → New category.
- Code is short and unique (
MAINS,HOT); it never changes once reports reference it. Name is what guests and staff see. - Parent makes a subcategory (Grill under Mains). Two levels only.
- Default production station routes the category’s items to a kitchen, bar, barista or bakery station (items can override this).
- Colour is used for POS tiles; Show on POS hides back-office-only categories (packaging, staff meals) from the till.
- Categories with items cannot be archived — move or archive the items first.
2. Items
Menu → Items → New item. The editor has tabs:
Details — SKU (unique, upper-case), name, short name (till buttons and receipts, 30 characters), description, category, type (product, combo, service), base price, tax, unit, production kind and station, prep time, sort order, flags (track inventory, open price, active, sell online). Upload a photo from the header (JPEG/PNG/WebP up to 5 MB; served privately, permission-checked; the storefront shows it too). Sell online (on by default) makes the item orderable on the storefront whenever one of its menus is shown online; switch it off for items you only sell in the restaurant (spirits by the shot, market-price fish). Open-price items are never sold online.
Variants — sizes, portions, variants and units of the same item: Small / Medium / Large, half / full portion, 330 ml / 500 ml / 1 l, bottle / crate. Each variant has a code, a name, a price mode (absolute price, or a delta on top of the base price), an optional quantity + unit, a recipe factor (a large tilapia uses 1.4× the recipe) and an optional SKU. Mark one as default. Removing a variant deletes it (and archives any price rule that targeted it); codes must be unique within the item.
Café product type — Coffee, Tea, Other hot drinks, Cakes, Pastries, Sandwiches, Smoothies, Juice or Light meals puts the item on the café counter and in the café reports (Café counter).
Modifiers — attach modifier groups (see §4) and, per item, override whether the group is required and its min/max. Order matters: the POS asks in this order.
Combo (combo items only) — meal deals, platters, family meals and bundles are built from slots (Main, Side, Drink), each with a minimum and maximum number of choices and its options: other items (with an optional variant and quantity), an upcharge, a default, and whether the default is substitutable. A slot whose defaults are not substitutable is fixed; otherwise the guest may swap within the slot and pays the upcharge of what they pick.
Menus — which menus the item appears on, an optional menu price
(needs menu.pricing) and a featured flag.
Allergens & nutrition — the EU-14 allergen list, dietary tags (vegetarian, vegan, halal, gluten-free, dairy-free, spicy, alcohol, contains pork) and a nutrition panel (serving size, kcal, protein, fat, saturated fat, carbs, sugar, fibre, salt). Ingredients carry allergens too, so the recipe view lists what the kitchen actually uses.
Availability (existing items) — business-wide state plus per-branch overrides; see §3.
Price check (existing items) — a simulator: pick a branch, variant, date/time, quantity, customer tier, promo code or event code and see the list price, the rules that applied and the final unit price. This is exactly what the POS will charge.
3. Availability and 86
From the item list (or the editor’s Availability tab) any user with
menu.availability can:
- 86 an item — Mark sold out, for this branch only (default) or every branch, optionally with a back on at time; the item returns automatically then, or when someone presses Back on.
- Hide an item (still exists, not shown on the POS).
Branch overrides beat the business-wide state. Every change is audited
(menu.item_86 / menu.item_availability, with the reason if given) and
broadcast to the branch’s tills at once.
4. Modifier groups
Menu → Modifiers. A group is one question the POS asks:
| Setting | Meaning |
|---|---|
| Kind | extras, add-ons, substitutions, cooking preference, spice level, size, milk, alternative milk, shots, decaf, temperature, syrup, sugar, ice, toppings, custom |
| Selection | choose one or choose several |
| Required, min, max | max 0 = unlimited; single-choice groups allow at most one |
| Allow quantities | e.g. 2 extra shots (each option has its own max quantity) |
| Prompt | the wording on the till (“How would you like it cooked?”) |
Each option has a code, a name, a price delta (can be negative), a default flag, and optionally the ingredient and quantity it adds so the recipe costing and (later) stock deduction know what “extra cheese” means. Options you remove from a group are archived, not deleted, so past orders keep their history. Archiving a group detaches it from every item.
Café set — Install café set creates the eleven groups a coffee bar needs in one click: Size, Milk, Alternative milk, Extra shots, Decaf, Temperature, Syrup, Cream, Sugar, Ice, Toppings. Edit prices afterwards; the button disappears once the set exists. What each option does to the stock (a large × 1.5, oat milk instead of milk, an extra shot + 9 g of beans) is set in Café setup → Modifier recipes (Café control).
The POS validates a guest’s choices with the same rules
(POST /api/menu/items/:uuid/validate-selection): required groups, min/max,
single vs multiple, quantities, active options, combo slot counts and
substitutability — and returns the modifier and combo price deltas.
5. Menus and schedules
Menu → Menus & schedules. A menu is a named list of items shown on the POS at certain times and places:
- Kind: all day, breakfast, lunch, dinner, seasonal, branch, custom.
- Branches: tick the branches it applies to, or none for all.
- Schedule: one or more windows — days of the week, from/to time, and optional start/end dates for seasonal menus (Christmas 1 Dec → 5 Jan). Windows may cross midnight (Fri/Sat 23:00–03:00: Saturday 01:00 still counts as Friday night). No windows means always on.
- Default: shown when no scheduled menu is live (usually the all-day menu).
- Show on the storefront (on by default): the storefront shows this menu’s items — with the same schedule, prices and 86s as the till — while it is live. There is no separate online menu to maintain (Ordering site set-up).
- Items: search and add, reorder, feature, and set a menu price that replaces the base price while this menu is live (lunch pilau at 16,000 instead of 18,000).
The list shows which menus are live now at your branch. The POS asks
GET /api/menu/active?branch=&at= and receives the live menus with their
items, prices and availability.
6. Pricing rules
Menu → Pricing (menu.pricing). Rules adjust the list price (menu
price → variant price → base price):
| Kind | Typical use | Needs |
|---|---|---|
| Branch price | Entebbe sells the rolex at 7,000 | branch |
| Time of day | late-night cocktails 3,000 off | from/to time |
| Happy hour | beer −20 % weekdays 17:00–19:00 | from/to time |
| Customer tier | members −10 %, staff meals −50 % | tier name (matched by the CRM) |
| Promotion | SEPT10: 5,000 off pizzas in September, with or without a code | dates, optional promo code |
| Event | wedding package drink prices | event code |
| Quantity break | bucket of 6 Nile at 6,000 each | minimum quantity |
Each rule targets everything, a category, an item or a variant, and adjusts by fixed price, amount off or percent off. Optional restrictions: branch, days of the week, time window, date range. Priority decides between competing rules (higher wins; ties go to the more specific target, then the lower price). A stackable rule (members −10 %) applies on top of the winner instead of competing with it. Prices never go below zero.
Use the item’s Price check tab to see the effect before the shift.
7. Realtime, offline and audit
- Any change publishes
menu.publishedon the branchmenuchannel; availability changes publishmenu.item_availability. Tills refetch. - Offline tills sell from their last menu snapshot and can 86 locally; editing the menu and prices is online only (offline matrix).
- All writes are audited with before/after values: categories, items, variants, modifiers, combos, menus, schedules, price rules and availability. Concurrent edits are protected by versioning — if someone saved first you are asked to reload.
Quick answers
- A chef cannot save an item → they changed a price; only
menu.pricingcan, and only in a password session. - An item does not show on the POS → hidden, archived, sold out at this branch, not on a live menu, or its category is hidden on POS.
- The lunch price is wrong → check the menu price on the Lunch menu, then the pricing rules with the Price check tab at that time.