example · applications
Inventory Manager Example
Quick answer
Record each stock change as an immutable movement. A scan proposes a movement; server validation accepts or rejects it. Label printing is a separate idempotent job and never changes quantity by itself.
Quick answer
Record each stock change as an immutable movement. A scan proposes a movement; server validation accepts or rejects it. Label printing is a separate idempotent job and never changes quantity by itself.
type Movement = {
id: string;
productId: string;
locationId: string;
quantityDelta: number;
reason: "receipt" | "sale" | "transfer" | "adjustment";
sourceId: string;
occurredAt: string;
};
async function receive(scan: ReceiveScan) {
return api.post("/movements", {
id: crypto.randomUUID(),
productId: scan.productId,
locationId: scan.locationId,
quantityDelta: scan.quantity,
reason: "receipt",
sourceId: scan.purchaseOrderId,
occurredAt: new Date().toISOString()
});
}
For labels, snapshot product name, identifier, lot, and template version. Use productId:labelVersion:copy as the logical print identity and record whether a copy is an initial issue or reprint. Submitting the immutable label through a local runtime such as Portix isn’t documented yet.
Verify
- Duplicate movement IDs are rejected safely.
- Negative-stock policy is explicit.
- Counts create auditable adjustments.
- Printed identifiers scan back exactly.
- Label retries do not add inventory.
Related content
concept
Label Printers Explained
Learn how label printers handle media, sensing, resolution, barcodes, ribbons, adhesives, and software for shipping, inventory, product, and asset labels.
example
Warehouse Scanner Example
A warehouse scanner workflow with explicit task states, item/location validation, offline event IDs, and label printing boundaries.
guide
How to Build an Inventory System
Build an inventory system with a movement ledger, barcode workflows, label printing, reconciliation, and reliable device integration.