Core Concepts
Read this once. The unique part of Mise Manager is its data model — once you understand the four things in this doc, every tab in the app makes sense.
1. Everything is an Item
There is one items table in the database, and every physical thing in your kitchen is an item in it. There's no separate "ingredients" table and "dishes" table — just one table with a type column. The four types are:
| Type | What it is | Example |
|---|---|---|
| RAW | Something you buy from a supplier | Beef tenderloin, soy sauce, oranges |
| PROCESSED | Output of breaking down a raw item | Trimmed tenderloin, trim, orange juice |
| SUBRECIPE | A component made from a recipe (used in other recipes) | Adobo marinade, garlic confit, demi-glace |
| MENU | A final sellable dish | Pork adobo, beef tenderloin steak, fresh OJ |
Every item has one base unit — g, ml, or piece / portion. That unit is the "currency" all costs and quantities are expressed in for that item.
Every item has a live cost per base unit — the cost engine keeps it up to date automatically. RAW items get cost from their default supplier; PROCESSED items get cost from their processing yield allocation; SUBRECIPE and MENU items get cost from summing their recipe lines. Change one supplier price → every dish using that ingredient (directly or transitively) recosts.
The point of "everything is an item" is referential integrity. One green lemon, one yield, one place to update.
2. Three sources of an item's cost
Where does an item's cost number come from? It depends on the type:
RAW items get their cost from a supplier_item
You attach one or more supplier_item rows per RAW item via the Items page. Each supplier_item is: "from this supplier, you can buy X qty in Y unit for Z price." Mark one as the default (star icon) and that's the one that drives the cost.
Pork belly (RAW, base g)
├── Magnolia: 2 kg pack at ₱600 = ₱0.30/g ★ DEFAULT
└── San Miguel: 5 kg pack at ₱1400 = ₱0.28/g
Cost engine picks the default and divides: ₱600 / 2000 g = ₱0.30 per g. That number lives on the item.
PROCESSED items get their cost from a processing
A processing describes how a RAW (or any) input breaks down into multiple PROCESSED outputs. You set it up on the Processing tab: "I take 2.5 kg of whole tenderloin and get 1.8 kg of trimmed tenderloin + 0.6 kg of trim."
Two allocation methods:
- By weight: every output gets the same cost per gram (input cost ÷ total output weight)
- By value: you set a
value_weightper output. Prime cuts get more cost per gram, trim gets less. (Sum of allocated cost still equals total input cost.)
Yields above 100% are valid — marinades and brines that absorb weight, rice absorbing water, etc.
Important: a processing is a definition, not an event. Defining one does not move inventory. See section 4.
SUBRECIPE and MENU items get their cost from a recipe
A recipe is a list of component items, each with a qty and unit, plus a yield (how much the recipe produces). You build them on the Recipes tab.
Formula: cost per yield unit = Σ(line.qty × component.cost) / yield
Each component can itself be RAW / PROCESSED / SUBRECIPE — recursively. A menu item recipe can contain a subrecipe that contains another subrecipe that contains RAW items. The cost engine walks the tree.
Cooked yield (optional): if your recipe yields 1 kg raw but only 800 g cooked, set the cooked yield. Per-cooked-unit cost becomes the basis for food cost % calculations — which is what you actually sell.
3. The cost engine recomputes everything, in order
Whenever something changes that affects cost — a supplier price update, a default supplier toggle, a recipe edit, an item creation/deletion — the engine runs a topological recompute:
- Build the dependency graph (what each item needs to know its cost)
- Process items in dependency order: RAWs first, then PROCESSED depending on them, then SUBRECIPE / MENU depending on those
- Write the new
cost_per_base_unitfor every item
This is a single function called everywhere a mutation happens. It can't have stale values — every read after any write reflects the up-to-date cost.
Multi-shop note: cost is per-shop. Each shop has its own pricing for the same item (Manila vs. Provincial market for example), so the engine writes a separate cost cache per shop. Change a price in Manila → only Manila's costs recompute. The recipe and processing definitions are shared; the numbers underneath them are per-shop.
4. Processing is a definition; Production is an event
This is the part most users get wrong on first read.
A processing in the Processing tab describes how something breaks down — like a yield template. "Whole tenderloin yields 72% trimmed + 24% trim + 4% waste." Saving this does not consume any inventory.
A production run in the Production tab records that you actually did it today. "This morning I broke down 1 kg of tenderloin." When you log this:
- Inventory of whole tenderloin decreases by 1 kg
- Inventory of trimmed tenderloin increases by 0.72 kg
- Inventory of trim increases by 0.24 kg
The same Production tab also covers making subrecipes: "I made 1 L of adobo marinade today" → recipe lines deduct, marinade stock increases.
So your daily flow is:
| When you... | Use this tab | Inventory effect |
|---|---|---|
| Define how an input breaks down | Processing | None — just a template |
| Define a recipe | Recipes | None — just a template |
| Actually cut / blend / cook something | Production | Deducts ingredients, adds output |
| Actually sell a dish | Sales | Deducts ingredients through the recipe tree (down to RAW + PROCESSED) |
| Actually buy stock | Inventory → Receive | Adds stock |
| Actually count and find a discrepancy | Inventory → Count | Adjusts stock with a logged variance |
| Actually throw something away | Inventory → Waste | Deducts stock with a "waste" reason |
Six events touch inventory. Defining recipes and processings does not.
5. Shared catalog, per-shop everything else
If you have one shop, you can ignore this section. If you have more than one, this is the key.
Shared across all shops (defined once):
- Suppliers (the directory; pricing is per-shop)
- Items (the catalog — names, types, base units, photos)
- Recipes + recipe lines (the definitions, including yield and what goes into each line)
- Processings + processing outputs (the definitions)
- Unit conversions
Per-shop (each shop has its own copy):
- Supplier pricing (
supplier_items) — same item, different price in each shop - Default supplier selection — Manila might prefer one vendor, Provincia another
- Inventory + inventory moves
- Sales entries
- Par stock targets
- Target food-cost % per menu item (a chain might run higher margins in a tourist area)
- Expenses + payroll
So you define a menu item once with its recipe; both shops see it; but Manila's cost reflects Manila's pricing, Provincia's reflects Provincia's.
See Multi-Shop for the full workflow.
6. Inventory is a running total, fed by moves
inventory.qty_on_hand is a cached number. Every change is also written as an inventory_move row with:
qty_delta(positive = added, negative = removed)reason(PURCHASE / SALE_DEDUCT / PROCESS_IN / PROCESS_OUT / ADJUSTMENT / WASTE)ref_table+ref_id(which event caused this — e.g.ref_table='sales_entries',ref_id=42)
This means:
- The audit trail is complete: you can always see why stock changed
- Deleting a sale doesn't just "remove the sale" — it reverses the SALE_DEDUCT moves the sale created, atomically. Inventory pops back to what it was.
- A stock count records the variance between counted and theoretical as an ADJUSTMENT move, so you can later see "we lost ₱2400 of pork belly to count variance last month" — which is real shrink intelligence.
7. The dashboard ties it all together
The Dashboard pulls from everything else:
- Money — inventory value (qty × cost), today's and this week's food cost %, dead-stock flag
- Operations report — revenue (sales × selling_price), COGS (sales × cost), gross profit, operating expenses, net profit
- Cost intelligence — menu items breaching their target food cost, biggest supplier price changes this week and which menus they hit, top/bottom margin dishes
- Ingredient usage — most-used and dead-stock ingredients in the period
- Operational — today's prep list, today's market list with projected spend, low-stock alerts, theoretical-vs-actual variance
- Trends — sales by item, day-of-week pattern, inventory value over time, food cost % over time
- Projection — given your monthly fixed expenses and current food cost ratio, what revenue do you need this month and what's your required daily revenue going forward to hit break-even
Each tile is clickable; clicking jumps to the relevant tab so you can act on it.
In summary
If you remember just these:
- Every physical thing is an item with a base unit and a live cost
- RAW cost comes from suppliers; PROCESSED from processings; SUBRECIPE/MENU from recipes
- Defining a recipe or processing does NOT move inventory; producing or selling something does
- The cost engine recomputes everything in order on every change
- Catalog (items, recipes, processings, suppliers) is shared across shops; pricing, inventory, sales, expenses are per shop
- Inventory moves carry their reason — your audit trail is complete
The rest is just UI on top of these ideas.