Repository navigation
Feature: Append-only product inventory movement ledger & history API (shipped) #280
Description
Status
Shipped: the focused product movement ledger and history API landed in PR #775 on 2026-09-18. This issue remains the canonical product-ledger record and the completed dependency for the follow-on planning issues below. This planning update does not authorize any follow-on implementation.
Problem or motivation
FloCafe had product-level stock availability and order lifecycle deduction/restoration, but no append-only history explaining how a product count changed. The ledger needed to build on the existing products.stock_quantity cache and order_items.inventory_deducted_quantity provenance rather than introduce a parallel product-stock model.
Current behavior
The merged delivery provides an append-only product movement history with atomic cache-plus-ledger writes for opening balances, sales, cancellation restores, and reasoned manual adjustments. It includes actor/reason/reference attribution, idempotent lifecycle handling, owner/manager history access with filtering and cursor pagination, and inventory-aware import/backup/restore validation.
Desired outcome
Keep the delivered product ledger as the finished-product stock baseline. Future inventory work must preserve its offline, additive-migration, atomic, auditable, and idempotent behavior.
Delivered technical approach
- Retain
products.stock_quantityas the current-state cache andorder_items.inventory_deducted_quantityas order-line provenance. - Record signed product movements for opening balance, sale, cancellation restore, and manual adjustment in the append-only ledger.
- Keep movement writes and cache changes atomic, with stable references preventing duplicate lifecycle movements.
- Expose owner/manager movement history with bounded filtering and cursor pagination.
- Preserve movement provenance through validated import and restore paths.
Acceptance criteria
- Append-only product movement history exists for the delivered movement types.
- Every supported product stock mutation updates the ledger and cache atomically.
- Movement history is auditable and access-controlled with the existing role model.
- Fresh and upgraded databases preserve existing product/order data and reject unsafe history replacement.
Explicit exclusions
Recipes/BOM depletion, held supplies stock, add-on stock, suppliers, purchasing, receiving, waste workflows for non-products, accounts payable, valuation, multi-location inventory, and ERP behavior are separate scopes. Do not infer or implement them from this issue.
Follow-on issue map and sequencing
- Completed baseline: this issue / #280, delivered by PR #775.
- Supplies stock: #768, manual offline stock items and movements only.
- Recipe/BOM pilot: #769, evidence-gated and dependent on a maintained supplies/item base.
- Materials expense: #645, a separate finance scope; it is not inventory.
- Receipt tender/change projection: #770, after the queued inventory follow-ons; it changes print projection only and does not change payment settlement.
The cash-drawer foundation is separately delivered in PR #772. The follow-on issues are related planning records, not approval to start implementation.
Review request
@itsbkm, please review this completed baseline and the linked follow-on boundaries. I would appreciate your thoughts on the sequencing and whether you are willing to take over or collaborate on the next scoped issue.
Additional context
This issue originated from a fork proposal. The historical fork-specific migration and file paths are not the current contract; the merged implementation is the authoritative baseline.
Activity
khaira777 commentedon Aug 16, 2026
Verdict: VALID BUT NEEDS RESCOPING
Findings:
products.track_inventory/stock_quantity REAL(main/db.ts:4022-4023),order_items.inventory_deducted_quantity(:4198), and migrationpersist_order_item_inventory_deductions(:3836-3847), with lifecycle tests (tests/issue-252-order-lifecycle-inventory.test.ts). The proposal must build on this model, not create a parallel one.main/services/inventory.ts,main/routes/inventory.tsare fork-only).Suggested scope: append-only
inventory_movementstable recording deltas forsale/cancel_restore/adjustmentwithreference_type/reference_id, keepingproducts.stock_quantityas the fast runtime cache (as the issue proposes), plus an owner-only read API and a manual adjustment route/UI if one doesn't exist. Note:stock_quantityis REAL — quantity-delta storage should follow the #285 money/units decision. Related: #287 (audit consistency), #285.khaira777 commentedon Sep 18, 2026
Work in progress: this issue is the next product-inventory implementation after the focused cash-drawer delivery lands. We will keep the scope to an append-only product movement ledger and history on top of the existing stock cache, with atomic/idempotent sale, cancellation-restore, and manual adjustment paths, actor/reason attribution, and an explicit opening-balance boundary. Recipes, supplies, purchasing, and accounts payable stay out of this issue. The implementation will begin sequentially after the current delivery completes.
[-]Feature: Append-only inventory movement ledger & movement history API[/-][+]Feature: Append-only product inventory movement ledger & history API (shipped)[/+]khaira777 commentedon Sep 18, 2026
@itsbkm The product-ledger baseline is now shipped in PR #775. I updated this issue as the completed canonical dependency and linked the bounded supplies, recipe/BOM, materials-expense, and receipt-projection follow-ons. Please review the boundaries and sequencing, share your thoughts, and let us know whether you are willing to take over or collaborate on the next scoped issue.
itsbkm commentedon Sep 26, 2026
Closing per the issue's own status section: the product movement ledger and history API shipped in PR #775 (merged 2026-09-18). Verified against current code —
main/services/inventory.tsandmain/db.tscontain the append-only movement ledger with atomic cache+ledger writes, actor/reason attribution, and owner/manager history access. All acceptance criteria in the issue body are already checked off. Follow-on scoped issues (#768, #769, #645, #770) remain tracked separately and are unaffected by this close.