Step 1 of 3
The request
Warehouse stock reconciliation CLI from CSV files
Read the full request
Build a dependency-free Node.js 24 warehouse stock reconciliation CLI from two CSV inputs. No web server or browser UI. Entry point: node stock-reconcile.js --opening <path> --events <path> --out <directory>. --help documents usage and exits 0. Successful reconciliation exits 0 and writes stock.csv and audit.json into the output directory. Errors exit nonzero, identify input/row on stderr, and preserve existing outputs and inputs byte-for-byte; wording is otherwise unspecified. Refuse output destinations that would overwrite either input. Validate the entire dataset before publishing outputs. No network calls or npm runtime dependencies. CSV: UTF-8 with optional BOM, LF/CRLF, quoted commas, doubled quotes and embedded newlines. Require exact headers below; reject malformed quoting, missing/extra columns and blank IDs. Final newline allowed; internal blank records refused. IDs are case-sensitive; do not trim. Quantities must consist of decimal digits and be safe integers; opening onHand may be zero, event quantities must be positive. Reject arithmetic beyond Number.MAX_SAFE_INTEGER rather than silently rounding. opening.csv header: sku,onHand. Each SKU occurs exactly once. Initial reserved quantity is zero. events.csv header: id,sku,type,quantity,ref. Apply rows in file order. All SKUs must exist in opening.csv. Supported types: - RECEIVE: ref must be empty; add quantity to onHand. - RESERVE: ref is a new, nonempty reservation ID, globally unique within this reconciliation; reserve quantity only when onHand minus reserved is sufficient. onHand is unchanged. - RELEASE: ref names an existing reservation on the same SKU; release up to its remaining reserved quantity. onHand is unchanged. A fully released reservation cannot be reused under the same ID. - SHIP: ref names an existing reservation on the same SKU; ship up to its remaining quantity, subtracting the quantity from onHand and reserved. - RETURN: ref names an earlier SHIP event ID on the same SKU; add quantity back to onHand, without recreating a reservation. Cumulative returns for a shipment cannot exceed that shipment's quantity. All quantities and balances must stay nonnegative. Unknown references, cross-SKU references, over-release, over-shipment and over-return are errors. Event IDs are global: repeating an identical parsed row with the same ID is an idempotent duplicate and has no effect; the same ID with different fields is an error. Check duplicates before transitions; a repeated shipment after reservation exhaustion stays harmless. stock.csv has header sku,onHand,reserved,available and rows sorted by SKU using JavaScript string comparison, with correct CSV escaping and LF line endings. Include zero-stock SKUs. audit.json is deterministic, without timestamps/temporary paths; record each event row's ID, applied/duplicate disposition and before/after onHand,reserved,available for its SKU. Also expose counts of applied and duplicate rows. An opening-only reconciliation is valid. Provide npm test using node:test, with subprocess tests that execute the CLI on isolated temporary directories. Cover successful partial reservation/release/shipment/return sequences, repeated shipment IDs, conflicting duplicates, invalid prerequisites, overflow, quoted multiline identifiers, CRLF/BOM inputs, deterministic repeat execution and preservation of pre-existing outputs on a late invalid row. Assert setup and resulting state, not only exit status. Provide examples and a README with usage, formats and rules. As a fixed acceptance example: opening A=10 and B=0; RESERVE 6 of A under R1, SHIP 4 under R1 with event ID S1, repeat exactly S1, RELEASE 2 under R1, RETURN 3 referencing S1, RECEIVE 7 of B, RESERVE 2 of B under R2. Final A is onHand=9,reserved=0,available=9; B is onHand=7,reserved=2,available=5; applied rows=6 and duplicate rows=1. A further RETURN 2 referencing S1 must fail and preserve existing outputs. Report executed evidence, actual corrections and gaps accurately.
The journey
- Read the requestTurned it into a list of things it would have to prove before calling the work done.
- Did the workPlanned the pieces, built them and checked the result as it went.
- Delivered7 files handed over.
The result
- examples/events.csv170 B
- examples/excess-return-events.csv189 B
- examples/opening.csv20 B
- package.json166 B
- README.md1.8 KB
- stock-reconcile.js7.3 KB
- test/stock-reconcile.test.js4.5 KB