ZyzyPostgreSQLAccountingTransactions

Why an old order must keep its old cost

The accounting decision behind Zyzy’s order-line snapshots, and what a catalog price change should never rewrite.

3 min readEngineering noteSaeed Ghofrani Ivari

From my notebook

Why an old order must keep its old cost

A product catalog answers a present-tense question: what does this item cost now? An order answers a historical question: what did this customer buy, and on what terms? Mixing those two questions makes a report easy to implement and difficult to trust.

In Zyzy, the storefront and the administration application share a Fastify backend with PostgreSQL. Product purchase costs are separate from public customer prices. The order-writing path stores the relevant prices and costs on the order line instead of expecting later reports to reconstruct them from the current catalog.

A price edit should not change yesterday

Suppose an illustrative item sells for 200 and its purchase cost is 120. The gross difference for one unit is 80 before other costs. If a later supplier update changes the catalog purchase cost to 150, the historical transaction should not suddenly appear to have produced a difference of 50. These numbers are an example, not actual sales data.

That is why the order line keeps the unit selling price, unit purchase price, quantity, and line cost. A report can then describe the order as it was recorded. The catalog remains free to change for future purchases without rewriting the interpretation of older ones.

Capture the snapshot inside the order operation

A snapshot is only useful if it belongs to the same operation as the order. The inspected checkout path uses a database transaction, checks an idempotency key, and locks the relevant stock rows. It validates active products and variants before writing the order and its lines.

These controls have different purposes. The idempotency key identifies a repeated submission. The stock lock addresses competing attempts to consume the same availability. The snapshot preserves the transaction’s historical inputs. None should be described as a substitute for the others.

Report from the historical record

The accounting queries aggregate eligible orders and their stored line costs. They derive cost-of-goods and gross-profit summaries from that historical data. The distinction is useful for both a total and a daily series: the report is about recorded orders, not a hypothetical sale at the latest catalog prices.

The definition of an eligible order still matters. Cancelled, incomplete, or otherwise excluded operations should not quietly enter a report because they happen to have order lines. A report’s filters are part of its business meaning, not a cosmetic query option.

The boundary of this implementation

This is basic order-cost accounting in a personal commerce prototype. It is not a full double-entry accounting package, tax engine, or statutory reporting system. The current catalog uses sample data and checkout is disabled by default until that data is verified.

Those limits do not remove the engineering lesson. A small storefront still benefits from separating mutable catalog state from the historical record of a transaction. It makes later questions answerable without guessing which price happened to exist at the time.

Read the full project story →