Skip to main content
Operational templates for bakeries: ticket CSVs, inter‑site transfer manifest (CSV/JSON), traceability barcode schema, and daily reconciliation workbook

Operational templates for bakeries: ticket CSVs, inter‑site transfer manifest (CSV/JSON), traceability barcode schema, and daily reconciliation workbook

The downloadable, production‑ready companion to your fulfillment governance work

Governance documents tell you what should happen. They almost never tell you what the actual file looks like, which columns matter, or what happens when a field is blank at 5:40 a.m. and the mixer is already running. That gap is where most bakery fulfillment breaks — not in the policy, but in the artifact nobody standardized.

Below you'll find the concrete pieces: a ticket CSV that maps to your POS, OMS, and kitchen display, SLA numeric defaults you can drop in without a committee meeting, real hard‑vs‑soft reservation examples, a transfer manifest with temperature and custody fields, a lot‑code/QR data model, and a daily reconciliation workbook with formulas already wired. If you've read the multi‑channel fulfillment governance playbook, think of this as the folder of files that playbook assumes you already have.

Skipping the theory. You know why fulfillment matters. Let's build the bakery fulfillment templates you can hand to a shift lead tomorrow.

Start with the ticket CSV, because everything downstream inherits its mistakes

Most integration headaches trace back to one thing: the ticket record means something different in each system. Your POS calls it order_id. Your OMS calls it reference. The kitchen display shows a truncated version that drops the site prefix. When those three disagree, you get duplicate production, missed pickups, and a barista arguing with a spreadsheet.

The fix is boring and it works: one canonical ticket schema, and every system maps to it, not around it.

Here's the field layout that survives contact with real bakeries running POS → OMS → KDS → TMS:

Canonical fieldPOS sourceOMS sourceKDS displayNotes
ticket_uidposorderid + site prefixoms_refshort code (last 5)Never reused, never recycled
site_idregister locationrouting siteheader badgeMust exist before ticket creates
channelPOS/web/wholesale/subsource systemcolor tagDrives SLA and reservation logic
priorityderivedderivediconSee SLA table below
promised_timepickup slotdelivery windowcountdownThe number staff actually watch
line_skumenu itemcatalog iditem nameMaps to recipe + lot later
qtyquantityquantityquantityIntegers only
reservation_typehard/softbadgeExplained further down
allergen_flagmodifierorder notered bannerPull forward, don't bury in notes
statusfired/paidopen/fulfilledstageSingle source of truth

A sample row, comma‑delimited: ticketuid,siteid,channel,priority,promisedtime,linesku,qty,reservationtype,allergenflag,status CTL-2025-004871,CTL,web,P2,2025-11-14T08:15,CROISS-PLAIN,12,hard,none,open

{ "event": "ticket.created", "ticketuid": "CTL-2025-004871", "siteid": "CTL", "channel": "web", "priority": "P2", "promisedtime": "2025-11-14T08:15:00Z", "lines": [{"sku": "CROISS-PLAIN", "qty": 12, "reservationtype": "hard"}], "source": "pos", "emitted_at": "2025-11-13T19:02:11Z" }

Keep the payload flat and keep timestamps in one timezone convention. Mixed local/UTC timestamps are quietly responsible for a surprising number of "why did this ticket fire early" incidents.

Implementation note: the single most valuable rule is that ticket_uid is generated once, at the earliest system that touches the order, and travels unchanged. The failures happen when the OMS "helpfully" creates its own ID and now you're reconciling two keys for one croissant order.

Implementation note: the single most valuable rule is that ticket_uid is generated once, at the earliest system that touches the order, and travels unchanged.

A sample event payload when the POS hands off to the OMS: { "event": "ticket.created", "ticketuid": "CTL-2025-004871", "siteid": "CTL", "channel": "web", "priority": "P2", "promisedtime": "2025-11-14T08:15:00Z", "lines": [{"sku": "CROISS-PLAIN", "qty": 12, "reservationtype": "hard"}], "source": "pos", "emitted_at": "2025-11-13T19:02:11Z" }

SLA numeric defaults you can ship without another meeting

Bakeries stall on SLAs because they treat every priority tier as a debate. It doesn't have to be. You need a small number of tiers with actual numbers attached, and those numbers need to differ by channel — a walk‑in and a scheduled corporate delivery are not the same promise.

Here's a default set that works for most single‑to‑small‑multi‑site operations. Treat these as starting values and tune after two weeks of real data.

PriorityTypical triggerPrep‑start SLA before promised_timeAlert if unstartedEscalation
P0Same‑day corporate, VIP90 min60 min outNotify manager immediately
P1Scheduled delivery60 min45 min outShift lead
P2Web/app pickup30 min20 min outStation board flag
P3Walk‑in queueon demandn/anone

The number that actually matters isn't the promised time — it's the prep‑start deadline. If a 12‑dozen order is due at 8:15 and needs 45 minutes of assembly plus proof, an alert at 8:10 is useless. The workbook and KDS should count backward to when work must begin, not when it's due.

{ "sladefaults": { "P0": {"prepleadmin": 90, "alertbeforemin": 60}, "P1": {"prepleadmin": 60, "alertbeforemin": 45}, "P2": {"prepleadmin": 30, "alertbeforemin": 20}, "P3": {"prepleadmin": 0, "alertbefore_min": 0} } }

Hard vs soft reservations, with examples that aren't abstract

This is the piece that stops overselling, and it's constantly misunderstood. A hard reservation consumes committed capacity or inventory the moment it's placed. A soft reservation holds intent but can be reallocated until a cutoff.

Concrete examples:

  1. Hard

    A corporate order for 60 boxed lunches placed Tuesday for Thursday. Those 60 come out of Thursday's assembly capacity immediately. Nothing else can claim that slot.

  2. Soft

    A web customer adds 3 sourdough loaves to a Saturday pickup at 9 a.m. Until the Friday 6 p.m. cutoff, that's a soft hold — if bake counts shift, the system can rebalance. After cutoff, it converts to hard.

  3. Soft that should be hard

    Subscription boxes. A lot of bakeries leave subscriptions soft and get burned when production plans against phantom capacity. Convert subscriptions to hard at the production‑lock, not at order time.

A reservation rule set, expressed simply:

IF channel = wholesale OR corporate → reservationtype = hard (at order) IF channel = subscription → soft until productionlock, then hard IF channel = web/app → soft until (promisedtime - cutoffwindow) IF channel = walk-in → no reservation, decrement on sale

The bakeries that oversell aren't usually the ones without reservation logic — they're the ones that have it but never defined the conversion moment. A soft hold with no cutoff is just an oversell with extra steps.

The inter‑site transfer manifest, with temperature and chain‑of‑custody

Once you run more than one location, transfers become the single most under‑documented operation in the building. A tray of laminated dough leaves the commissary and arrives at the café, and nobody logged the temperature, the departure time, or who signed for it. When something's off, there's no trail.

Here's a manifest schema that captures what you actually need for both food safety and accountability.

CSV version: manifestid,fromsite,tosite,departts,arrivets,vehicle,driverid,sku,qty,lotcode,departtempc,arrivetempc,custodyfrom,custodyto,sealid,status TRF-0592,CTL,CAFE-3,2025-11-14T05:10,2025-11-14T05:48,VAN-2,DRV-11,CROISS-DOUGH,240,LOT-CTL-1114-A,3.5,4.2,J.Ortiz,M.Reed,SEAL-8841,received

JSON version (same record): { "manifestid": "TRF-0592", "route": {"fromsite": "CTL", "tosite": "CAFE-3", "vehicle": "VAN-2", "driverid": "DRV-11"}, "timing": {"departts": "2025-11-14T05:10:00Z", "arrivets": "2025-11-14T05:48:00Z"}, "items": [ {"sku": "CROISS-DOUGH", "qty": 240, "lotcode": "LOT-CTL-1114-A"} ], "coldchain": {"departtempc": 3.5, "arrivetempc": 4.2, "thresholdc": 5.0}, "custody": {"from": "J.Ortiz", "to": "M.Reed", "sealid": "SEAL-8841"}, "status": "received" }

Implementation notes that matter:

  1. Record temperature at both ends. A single reading tells you nothing about drift. Two readings plus a threshold field lets a system auto‑flag arrivetempc > threshold_c.
  2. The seal_id is your cheapest chain‑of‑custody control. A numbered tamper seal logged at departure and confirmed at arrival catches diversion and mishandling without any expensive hardware.
  3. custodyfrom and custodyto must both be filled before status can become received. If either is blank, the transfer stays in_transit and shows up on the reconciliation as an open item.

A sample event payload for the TMS leg: { "event": "transfer.received", "manifestid": "TRF-0592", "arrivetempc": 4.2, "custodyto": "M.Reed", "coldchainok": true, "emitted_at": "2025-11-14T05:49:03Z" }

When a customer reports an off product, this schema lets you go from complaint → lot → manifest → temperature history → driver in about two minutes instead of a morning of guessing.

Traceability: a lot‑code / QR data model and the scan workflow

Traceability sounds like a compliance chore until the first time you need to isolate one bad batch without dumping a whole day's production. The trick is a lot code that encodes just enough to be useful, plus a QR that resolves to the full record.

Lot code structure: LOT-{site}-{MMDD}-{batch_letter} Example: LOT-CTL-1114-A Keep it human‑readable. Staff will read these off trays by hand when the scanner's dead.

The QR resolves to a data model like this: { "lotcode": "LOT-CTL-1114-A", "sku": "CROISS-DOUGH", "producedsite": "CTL", "producedts": "2025-11-14T04:20:00Z", "ingredients": [ {"item": "FLOUR-T55", "supplierlot": "SUP-88213"}, {"item": "BUTTER-EU", "supplierlot": "SUP-90114"} ], "linkedmanifests": ["TRF-0592"], "scans": [] }

The scan workflow, step by step:

  1. Batch creation — the moment dough is mixed, a lot code is generated and printed. Ingredient supplier lots are attached here, not later.
  2. Transfer scan — when the tray loads onto the van, the lot is scanned into the manifest, linking production to transport.
  3. Receiving scan — at the destination, scanning confirms arrival and stamps the arrival temperature against the lot.
  4. Fulfillment scan — when the finished item is boxed for a corporate order, the lot is tied to the ticket_uid. This is the link that lets you go from customer back to batch.
  5. Recall query — if a supplier lot is flagged, you query for every lot containing SUP-88213, then every ticket linked to those lots. Done in one lookup.

The mistake most bakeries make: they attach lot codes at the finished‑goods stage only. That tells you what you sold but not what went into it. Capture ingredient supplier lots at batch creation or the traceability chain has a hole exactly where you need it during a recall.

Process diagram

A simple diagram like this helps clarify who scans what and when during a shift change.

The daily reconciliation workbook that actually catches problems

This is the artifact most operators skip and most regret skipping. The reconciliation workbook is where produced, transferred, sold, and wasted numbers meet — and where the gaps become visible before they turn into a month‑end mystery.

Structure it as an XLSX with these tabs:

  1. Production log — lot, sku, qty produced
  2. Transfers — pulled from the manifest schema above
  3. Sales — pulled from POS by ticket
  4. Waste/donation — end‑of‑day counts
  5. Reconciliation — the calculated tab that ties it together

The core reconciliation formula per SKU per site: expectedonhand = opening + produced + transfersin - transfersout - sold - waste variance = countedonhand - expectedonhand

Then wire conditional alerts:

  1. Highlight variance red if ABS(variance) > 5% of produced qty
  2. Flag any transfer with blank arrivetempc or custody_to
  3. Flag any lot appearing in sales but missing from the production log (a phantom sale — usually a mis‑scan or a manual override)
  4. Trigger an investigation note if the same SKU shows negative variance three days running

Investigation triggers — the checklist a shift lead runs when variance flags:

  1. [ ] Did a transfer get logged out but never received? (Check for in_transit status)
  2. [ ] Was there a manual POS void or comp not reflected in waste?
  3. [ ] Did production log a batch under the wrong SKU or site?
  4. [ ] Is a lot code duplicated or reused?
  5. [ ] Did a temperature breach cause an unlogged dump?

One two‑site bakery — one commissary, one café — was losing somewhere in the $2k–$3k range per month and couldn't pin it down. Running this reconciliation for about three weeks, the pattern surfaced pretty fast: croissant dough left the commissary at 240 units on the manifest, but café production logs consistently showed around 220 going into the oven. The gap wasn't theft — it was un‑logged proofing losses and a couple of trays that got left in the van and dumped without a waste entry. Once transfer temperatures and receiving scans were required before a manifest could close, the "mystery" shrank to normal noise and variance stayed under 3%. The fix wasn't a new policy. It was making the workbook refuse to accept an incomplete record.

When this level of structure makes sense — and when it doesn't

When it's worth it:

  1. You run two or more sites and move product between them
  2. You take corporate/wholesale orders that require traceability
  3. You've had at least one incident where you couldn't trace a bad batch
  4. Your variance shows up at month‑end instead of daily

When it's overkill:

  1. Single site, walk‑in dominant, everything baked and sold same‑day in the same room. If you can eyeball the whole operation from the counter, a full manifest schema is friction you don't need yet.

Who should not start here: if you don't yet have a stable ticket_uid flowing cleanly through your POS and OMS, don't jump to transfer manifests and traceability. Fix the ticket key first. Everything else inherits from it, and building traceability on top of inconsistent order IDs just gives you very organized garbage.

Putting the files to work

These artifacts aren't meant to sit in a folder. Load the ticket CSV into your integration mapping first, drop in the SLA defaults, wire the reconciliation formulas, and run the workbook manually for two or three weeks before you automate anything. The manual run is what teaches you which alerts are real and which thresholds need tuning for your waste and proofing patterns.

The bakeries that get real value out of bakery fulfillment templates aren't the ones with the fanciest tooling — they're the ones who standardized the boring fields, made incomplete records impossible to close, and let the variance tell them where to look. Governance sets the rules. These files are what make the rules enforceable at 5 a.m. when nobody has time to think about them.

Start with the ticket schema. Get one canonical ID flowing end to end. The rest of the folder falls into place from there.

Built for Bakeries Tailored for bakery-specific workflows and inventory needs
Save Time Simplify order processing, inventory, and staff scheduling
Delight Customers Faster order fulfillment and personalized service
Grow Revenue Boost repeat orders and optimize production capacity