This is the demo dataset, a stool workshop buying oak, building stools, selling them.
Seed it yourself (npm run seed) and every number below is in the database.
| Bill | Layer | Qty | Unit cost | Value |
|---|---|---|---|---|
| BILL-101 · Jan 2 | #1 oak | 50 | $8.50 | $425.00 |
| BILL-118 · Jan 10 | #2 oak | 40 | $9.20 | $368.00 |
Same SKU, different costs. Averaging would call oak "$8.82" and move on. The engine keeps both layers and remembers the order it received them.
| Invoice INV-201 | Layer consumed | Qty | Unit | COGS |
|---|---|---|---|---|
| Jan 5 · 5 lengths | #1 (oldest) | 5 | $8.50 | $42.50 |
| Layer #1 remaining | 45 @ $8.50 | |||
If the sale had needed 46 lengths, it would have eaten all 45 of layer #1 plus one from #2 at $9.20, and the COGS line would show both unit costs separately, not a blend.
A $85 freight bill lands Jan 11. It spreads across open layers by value; consumed history is never rewritten:
| Layer | Open value | Share | New unit cost |
|---|---|---|---|
| #1, 45 lengths | $382.50 | $43.33 | $9.4629 |
| #2, 40 lengths | $368.00 | $41.67 | $10.2418 |
| Total capitalised | $85.00 | ||
Each stool eats 4 lengths of oak, 0.25 L of varnish, 1 screw pack. The build on Jan 15 consumes components FIFO across their layers and produces one finished layer whose unit cost is $48.250768, the actual component cost divided by 8, not a round number someone typed. That precision survives every later step because money is NUMERIC, never float.
| Invoice | Qty | Unit COGS | COGS total |
|---|---|---|---|
| INV-214 · Jan 16 | 3 stools | $48.250768 | $144.75 |
| INV-220 · Jan 17 | 2 stools | $48.250768 | $96.50 |
| Daily journal (Dr COGS / Cr Inventory) | $241.25 | ||
One draft manual journal for the day, balanced, pushed with an idempotency key. If the sync runs twice, Xero sees one journal. Void INV-214 next week and the app restocks the exact three stool-slices at $48.250768, reversing the effect. No adjust-and-hope.
layer_consumptions pointing at
its layer and event. The audit page can show you this exact table for your data, any date,
to the cent. That's the product.