Skip to content

Re-pointing inventory links

The inventory list is meant to be the kitchen’s clean map of what it has. In practice, the map drifts. Two staff members type the same ingredient under slightly different names. A recipe was created with Auto-create output on and produced a brand-new row when an existing row should have caught the output. A supplier delivery grew its own row that turns out to be the same physical thing as a generic ingredient already in the pantry. Without a way to fix the map after the fact, the only options are to delete and recreate — losing the history attached — or to live with duplicates forever.

This page is about the two operations that fix the map cleanly. Re-point changes which inventory row a recipe produces. Merge collapses two inventory rows into one, moving every live pointer over atomically. Both operations preserve history; neither deletes anything you’d want back.

The rule

The recipe owns the produces-into relationship, so re-pointing happens on the recipe. The inventory row owns its own identity, so merging happens on the row. Both operations are atomic and audited — by the time the screen refreshes, every live reference has moved and the duplicate is archived with a link back to the survivor.

The reason re-point isn’t a field on the inventory row’s edit form is that the recipe is the source of truth for what it makes. You don’t change what a recipe produces by editing the row it produces into; you change it by editing the recipe. The row is the destination, not the relationship.

When each one is the right move

Re-point is the surgical option when the recipe is fine but the row it produces into is wrong. The classic case: two recipes that physically end up in the same pot. Sugo lungo della domenica and Sugo veloce del martedì both fill the same container in the walk-in cold, but they were created with auto-output and now have two different rows in the inventory list, each with half the stock count. Re-point one of the recipes to produce into the other’s row, and from that point both recipes feed the same pool. Stock counts unify. Reorder shortlist unifies. Daily prep checklist reads one row instead of two.

Another re-point case: a recipe was auto-created with a duplicate output, but the real row — the one with the supplier deliveries attached, the one the menu picker already references — already exists. Re-point the recipe to produce into the real row. The duplicate row is left behind; if it’s a true duplicate with nothing else attached, archive it from its detail page.

Merge is the heavier option when both rows are real and you want to absorb one into the other. The classic case: someone typed “San Marzano DOP” as one row last August, and a different staff member typed “San Marzano tomatoes (DOP)” in October. Both rows have supplier products attached, both have stock numbers, both are referenced by different recipes. You can’t just delete one — the recipes that point at it would break, the supplier products would lose their parent, the stock would vanish. Merge picks a survivor, moves every live pointer from the duplicate to the survivor, archives the duplicate with an audit entry that links to the survivor, and the inventory list now shows one row where there used to be two.

The choice between the two: if only the recipe-to-output link is wrong, re-point. If two whole rows are duplicates, merge.

What “merge” moves

Merge is atomic — by the time the screen refreshes, every live reference has moved. The list of what moves is fixed, and worth reading once.

  • Recipes that produce into the duplicate now produce into the survivor. The recipe’s produces-into field is rewritten.
  • Recipes that consume the duplicate as an ingredient now consume the survivor. Every ingredient row across every recipe in the venue is checked.
  • Supplier products linked to the duplicate now link to the survivor. The supplier’s product remains; only the parent inventory row changes.
  • Menu items and modifiers that deduct from the duplicate now deduct from the survivor. The till’s deduction path is rewritten.
  • Separation rules that name the duplicate as a child now name the survivor.
  • Current stock on the duplicate is added to the survivor’s stock. One number combines into one.
  • The duplicate is marked archived and gets an audit entry pointing at the survivor.

The list of what does not move is also fixed. History stays attached to the duplicate. Past purchase orders, completed batches, waste log entries, finished stock counts — they keep referencing the duplicate. That’s correct: those records describe what happened on a specific day under a specific name, and the duplicate is what was on the shelf on the day. The duplicate’s detail page is still openable (it’s archived, not deleted) so anyone looking at last quarter’s report can follow the trail.

How to use it

To re-point a recipe. Open the recipe in edit mode, scroll to the Output & batching card, open the Output inventory item dropdown. The dropdown lists every inventory row in the venue whose recipe unit matches the recipe’s yield unit (the system enforces the unit match so cost math can’t quietly go wrong after the move). Pick the row the recipe should produce into. An amber banner appears: “Output will switch on save. Currently producing into X; on save this recipe will produce into Y.” Tap Save changes. The recipe now produces into the new row. The old row is left in place, unchanged — if it’s a duplicate that should also be merged, do that next from its detail page.

To merge two rows. Open the row that should be archived — the duplicate. At the top right of the detail page, tap 🔀 Merge. A dialog opens. Pick the survivor from the Merge into dropdown — only rows in the same venue with matching stock and recipe units appear, for the same reason as above. Read the summary the dialog shows (what gets moved, what stays put), then tap Merge & archive this item. The screen jumps to the survivor’s detail page; the History tab on the survivor now shows the merge event, and the duplicate’s detail page shows the same event from the other side with a link back to the survivor.

The unit-match guard is strict. If you try to merge a row measured in grams into a row measured in kilograms, the survivor doesn’t appear in the dropdown. The fix is to open the duplicate’s edit form, change its recipe unit and stock unit to match the intended survivor (and adjust the conversion factor if needed), save, and come back to merge. If the duplicate has a separation rule set (it splits into children when prepped), the merge is also blocked — you’d orphan the children. Clear the rule first, or run the separation and let the children become their own rows, then merge.

What happens behind the scenes

Re-point is a one-field write on the recipe. The recipe’s produces-into pointer changes, the system re-runs the cost roll-up against the new target so the survivor’s cost-per-unit reflects the recipe immediately, and that’s the whole operation. The old row keeps its name, its history, its current stock, its suppliers; nothing on it moves. The cost on the survivor recomputes.

Merge is heavier. The system runs a single transaction that rewrites every live reference, sums the stock, archives the duplicate, and writes audit entries on both sides. Everything happens atomically — there’s no in-between state where some pointers still aim at the duplicate. If anything in the transaction fails, the whole operation rolls back and nothing changes; you’ll see an error and the original two rows are still there, intact.

Every meaningful change writes to the History tab on the row that was changed. A re-point shows on the recipe’s history and on the old and new output rows’ histories. A merge shows on both the duplicate’s and the survivor’s history, with the count of what moved (“Moved 3 recipe outputs, 7 recipe ingredient refs, 2 supplier products, 1 menu link, 0 modifiers, 0 decomposition children; transferred 4.2 kg of stock”). The history is the audit trail when a number on a dashboard surprises you a month from now.

Worked example

Sara at your venue, six months in, notices the inventory list has two rows for the same thing. “San Marzano DOP” — created last August by the previous chef, with one supplier (ItalianDirect) approved underneath, twelve tins of current stock, and seven months of purchase-order history. “San Marzano tomatoes (DOP)” — created in October by Sara herself when she set up the new house ragù recipe, with two suppliers approved underneath (a smaller dairy supplier and Sara’s preferred organic source), eight tins of current stock, and three recipes pointing at it as an ingredient.

She picks the survivor: the October row, “San Marzano tomatoes (DOP)” — cleaner name, more suppliers, more recipe references. The duplicate is the August row.

She opens the August row’s detail page, taps 🔀 Merge, picks San Marzano tomatoes (DOP) from the Merge into dropdown, reads the dialog summary (one supplier moves, twelve tins of stock combine, zero recipes update, the seven months of purchase history stays attached to the duplicate). She taps Merge & archive this item.

The screen refreshes on the survivor’s detail page. The Suppliers tab now lists three suppliers — Sara’s two plus ItalianDirect, freshly moved. The current stock reads twenty tins (twelve from the duplicate plus the existing eight). The recipe pickers across the venue still work — the three recipes that already pointed at the survivor are unchanged, no migration needed. The History tab on the survivor shows the merge event with a link to the archived row.

Sara checks the August row’s history, just to be sure — she opens the archived row from the merge audit entry. Seven months of purchase orders are still listed there, each tied to a specific delivery on a specific day. The archived row also shows the merge event, with a link to the survivor. The old delivery records still make sense in context — they describe what happened under that name, on that day. Going forward, every new delivery and every new recipe touches the survivor. The map is now clean.