Capture
Operator workflows, barcode or sensor integration, reason codes, and offline queues where connectivity is unreliable.
Explain every balance with movement records, physical counts, and an explicit reconciliation process.
When a stock number is wrong, the next question is where it diverged from reality. We build capture and reconciliation around attributed movement events, so corrections retain the evidence of what happened.
Stock on hand is the sum of recorded movements. When a physical count disagrees, the difference becomes a new, approved event instead of an overwrite.
| # | Event | Qty | Ref | Actor | Balance |
|---|---|---|---|---|---|
| E1 | RECEIPT | +120 | GRN-2291 | stores.rahim | 120 |
Step 1 / 8 Receipt posted. The balance is derived from events, never typed in.
Operator workflows, barcode or sensor integration, reason codes, and offline queues where connectivity is unreliable.
Typed receipts, issues, transfers, and adjustments with stable identities, actors, locations, and replayable history.
Cycle counts, variance review, approval thresholds, batch tracing, and expiry rules matched to the operation.
ERP boundaries, reconciliation reports, availability projections, and replenishment recommendations with visible assumptions.
Event sourcing captures every change to application state as a sequence of events, so the state can be rebuilt by replaying the log and queried as it stood at any point in time.1 An append-only event store also gives an audit trail, with read views built as projections of it. Microsoft's guidance is candid that the pattern carries real trade-offs, which is why we use it where history and disputes matter.2
The same principle runs through GS1's EPCIS 2.0 standard for supply-chain visibility. Events record what, when, where, why, and how, and an event is never modified or deleted, only corrected by a later event.3 Its vocabulary separates cycle counting, done for operational accuracy, from stock-taking done for accounting.4
Records drift from reality. A peer-reviewed study of nearly 370,000 inventory records from 37 stores of one retailer found 65% inaccurate, and identified inventory auditing practices among the factors that reduce inaccuracy.5 RFID can cut counting effort, but radio interference and materials such as metal and liquids can stop signals being received, so raw reads still need reconciling.6
The ledger rule in plain SQL. A correction is a new row, the same principle EPCIS applies to supply-chain events, and any past balance is a replay to a point in time.13
-- Movements are append-only. Balances are derived, never typed in.
CREATE TABLE stock_movement (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
item_id text NOT NULL,
location_id text NOT NULL,
kind text NOT NULL CHECK (kind IN ('RECEIPT', 'ISSUE',
'TRANSFER_IN', 'TRANSFER_OUT', 'RETURN', 'ADJUSTMENT')),
qty_delta integer NOT NULL,
reason_code text,
source_ref text NOT NULL, -- goods receipt, order, count sheet
actor text NOT NULL,
approved_by text,
occurred_at timestamptz NOT NULL, -- when it happened on the floor
recorded_at timestamptz NOT NULL DEFAULT now(), -- when it reached us
-- Adjustments post only after approval; pending ones wait in a review queue.
CHECK (kind <> 'ADJUSTMENT' OR (reason_code IS NOT NULL AND approved_by IS NOT NULL))
);
-- A correction is a new row. Edits, deletes, and truncation are refused.
CREATE FUNCTION reject_change() RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
RAISE EXCEPTION 'stock_movement is append-only';
END $$;
CREATE TRIGGER stock_movement_no_edit BEFORE UPDATE OR DELETE ON stock_movement
FOR EACH ROW EXECUTE FUNCTION reject_change();
CREATE TRIGGER stock_movement_no_truncate BEFORE TRUNCATE ON stock_movement
FOR EACH STATEMENT EXECUTE FUNCTION reject_change();
-- On hand now.
CREATE VIEW stock_on_hand AS
SELECT item_id, location_id, sum(qty_delta) AS on_hand
FROM stock_movement
GROUP BY item_id, location_id;
-- On hand as it stood at quarter end: replay to a point in time.
SELECT item_id, location_id, sum(qty_delta) AS on_hand
FROM stock_movement
WHERE occurred_at < timestamptz '2026-07-01 00:00:00+06'
GROUP BY item_id, location_id;Map actual stock movements and pilot one site alongside the existing process. Agree the cutover reconciliation before changing the system of record.
Primary sources for the standards and practices referenced on this page. They describe the field, not Verne's own results.
In 7–10 working days, Verne maps your workflows, data sources, repetitive decisions, automation opportunities, and AI risk areas. You receive a prioritized roadmap showing what to automate, integrate, avoid, and build first.