Skip to content

Inventory categories

Categories are the catalogue the inventory list groups by. Wines, Cheeses, Fruit & veg, Spices, Cleaning supplies, Kitchen production — the shape of the catalogue is the shape of the list. The chip on each row is its category. The headers that break the list into sections are categories. The filter chips at the top of the list are categories. Change the catalogue and the list reshapes itself.

A category is not just a label. Each category can carry a custom-field schema — a small set of extra fields the rows inside it pick up. Wines get grape variety, vintage, region. Cheeses get milk type, aged for. Olive oils get origin region. Without a schema attached, the category is just a way to group. With one, it’s the extension point for category-specific information the rest of the system reads — allergen badges, AI-written menu copy, supplier-product matching.

The rule

A category groups rows in the list and declares the extra fields the rows underneath carry. The two jobs travel together: change the catalogue, and both the way the list scans and the data each row holds change at the same time.

Food, Beverage, Deli — Other, and Retail

Every category also carries a type, and the type decides which tab the rows show up under at the top of the inventory list: Food, Beverage, Other, or Retail. (Deli — cured meats, cheese counters — rides under the Food side.) The type is a back-of-house distinction; it never shows on your public menu.

Other is the home for everything you buy and store that isn’t food or drink — takeaway boxes and bags, napkins and straws, washing-up liquid and sanitiser, the cheap smallwares you reorder by the case. You manage these exactly like an ingredient: a supplier, a purchase price, par levels, low-stock alerts, stock counts. The only difference is the one that matters: Other stock never counts toward your food-cost percentage. A case of detergent has no dish margin, so letting it touch food cost would quietly poison the single number you watch most. The system keeps it out automatically — an Other row simply never links to a dish.

The rule: food and drink earn a food-cost percentage; packaging, cleaning and supplies do not. Put the non-food things under Other and they stay in the warehouse — ordered, counted, reordered — without ever distorting your margins.

Because Other items aren’t tied to a dish, they go down at stock count, not at the till. (The one exception you can opt into: a takeaway box can be linked to a delivery item so it depletes per order, the same way an ingredient does — but most venues leave packaging as count-only.) New venues start with three Other categories ready to use — Packaging & Disposables, Cleaning & Chemicals, and Smallwares & Equipment — each with a few sensible fields like material, compostable, or food-safe.

Retail is the opposite of Other: stock you sell, but through the shop rather than the dining room. A take-home loaf you bake, a bottle off the shelf, a jar of your own sauce. You run it like any other stock — a supplier or your own recipe, a cost, par levels, counts — but it isn’t a dish on the dinner table; it’s a product a customer buys to carry out. Because retail sells through a different channel, it follows different money rules — most importantly, no service charge — and it shows up as its own line in your reporting, kept apart from kitchen food cost so each side’s margin stays honest. New venues start with three Retail categories ready to use — Retail · Food, Retail · Alcohol, and Retail · Bread — with fields like barcode and shelf life. (Setting a retail item up to actually sell — at the till and online under a Shop section — is the next step that builds on this class.)

What a category captures

The basics describe the catalogue entry itself. Name is what the kitchen calls the group — Cheeses, Wines (still), Cleaning supplies. Emoji is the chip glyph the list shows next to every row in this category — it makes the list scannable at a glance, no reading required. Sort order controls where the category falls in dropdowns and group headers, low numbers first.

Then come the custom fields. Each field is one extra column the rows in this category carry — a name (Grape variety), a type (text, number, select, date), and for select fields a list of options. Add three fields to a Wines category and every wine row in the pantry suddenly has three more slots to fill in. Add none and the category is just a label. The fields show up in the row’s edit form under a header that names the category — open a row in Wines and you see a Wines details card with grape, vintage, region; open a row in Cheeses and you see a Cheeses details card with milk type and aged for. The schema travels with the category, not the row.

How to use it

Open it from the sidebar: Settings → Inventory categories. The page is a list — each row is one category, with its emoji, its name, the count of inventory rows currently in it, and a chip listing the custom fields it declares.

Tap + Add category to create one. The dialog asks for the name, an emoji, a slug (used in URLs and lookups, auto-suggested from the name), and an optional starter set of custom fields. Save and the category is live — it shows in the inventory list’s filter chips immediately, and any row newly assigned to it picks up the schema.

Tap any row to edit. Rename, swap the emoji, reorder, toggle active (an inactive category is hidden from new-row dropdowns but the rows already in it stay put and stay visible). To add or remove custom fields, open the Custom fields section — every existing row in the category gets the new field as an empty slot it can fill in over time. Removing a field deletes the value from every row in the category, so do it deliberately.

Categories with rows attached can’t be deleted. The dialog tells you how many rows are using the category and asks you to move them elsewhere first — open the inventory list, filter by the doomed category, edit each row to a new category, and come back.

What happens behind the scenes

Each inventory row carries a pointer to its category. The list query reads the pointer, groups the rows under the category’s name and emoji, and surfaces the custom fields as part of the row’s detail. Renaming a category is free — every row picks up the new label on the next page load, no migration. Changing the schema is a touch heavier: the rows in the category gain or lose slots, and the slots already filled in are kept or cleared accordingly.

The custom-field values are read by downstream features. The supplier-product matcher for wines narrows by grape variety when it’s set. The AI menu engine writes richer pairing copy because it knows the grape, the vintage, the region. The allergen badge on a cheese plate reads milk type. None of these features ask the kitchen to fill in extra screens — they just read the fields the category already declared.

Worked example

Marco, six months into running your venue, decides the wine list deserves better structure. He’s been keeping all his bottles in a generic Beverages category — fifty-odd rows, no shape. He wants to start writing dish-pairing notes on the menu and the AI engine isn’t doing a great job because all it knows is “white wine, €12”.

He opens Settings → Inventory categories, taps + Add category, names the new one Wines (still). He picks the 🍷 emoji and, in the Custom fields section, adds three: Grape variety (a select list of about twenty options he types in — Sangiovese, Vermentino, Nebbiolo, Chardonnay…), Vintage (number), Region (select — Tuscany, Piedmont, Friuli, Sicily…). He saves.

He goes to the inventory list, filters by the old Beverages category, sorts by name, and walks through the wine rows — bumps each one’s category to Wines (still). Eight minutes of clicking. As he changes each row’s category, three new empty fields appear on the row’s edit form under a Wines (still) details card. Marco fills in grape and region on the bottles he knows by heart and leaves the others for the sommelier to fill in over the coming weeks.

The downstream wins arrive over the next month. The supplier-product matcher for wines starts narrowing by grape — when ItalianDirect’s price list comes in with a row marked Nebbiolo, the matcher only suggests the venue’s Nebbiolo rows as candidates, not the whole wine list. The AI menu engine, when writing the pairing line for Tagliatelle al Ragù, picks Sangiovese-based wines automatically because it now knows which rows are Sangiovese. One catalogue change, two downstream gains, zero extra screens for the kitchen.