Realtime Inventory Board
Build a live inventory board for a warehouse or shop: a React page shows every product's stock level, updating instantly as items are sold or restocked, with updates pushed from a Node.js server over WebSockets. The tricky part is staying correct: updates can arrive late, twice or out of order, and connections drop. So each update carries a version number, the browser ignores anything older than what it has, and after reconnecting (or whenever it detects a gap in versions) it reloads a full snapshot from the server to get back in sync. Every message is validated with Zod on both sides. You'll learn real-time updates with WebSockets, versioning and reconciliation with snapshots, validation with shared TypeScript types, and testing unreliable delivery.
- Estimate
- ~12h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
Node.js · React · Zod
Project roadmap
- 01
Define the messages
~1.5hWrite DESIGN.md and a shared TypeScript package with Zod schemas: a product (SKU, name, quantity, low-stock threshold and version), the snapshot response (all products plus a global sequence number), and update messages (SKU, new quantity, product version and the global sequence number). Explain how the client uses versions to ignore old updates and sequence numbers to detect gaps. Done when: the schemas and DESIGN.md define every message.
- 02
Build the server
~2.5hBuild a Node.js server with a REST endpoint GET /snapshot and a WebSocket endpoint (with the ws package). Stock changes come in through POST /movements (a sale or restock, validated with Zod), update the quantity in a database (SQLite is enough) in a transaction, increase the product's version and the global sequence, then broadcast the update. Add a script that simulates random sales and restocks. Done when: movements update stock and are broadcast to connected clients.
- 03
Build the board
~2hBuild a React board that loads the snapshot, then applies updates from the WebSocket: validate each with Zod (logging and ignoring invalid ones), and apply it only if its version is newer than the product's current one. Show products in a sortable, filterable table with low-stock items highlighted, and briefly animate changed quantities. Done when: the board shows live stock that changes as the simulator runs.
- 04
Reconcile after gaps and reconnects
~2.5hTrack the last global sequence number applied. When an update skips a number (a missed message) or the connection comes back, fetch a fresh snapshot, and apply only buffered updates newer than it. Reconnect with increasing waits, and show the connection state and the time of the last update. Done when: dropping messages on purpose or restarting the server always brings the board back to exactly the server's state.
- 05
Harden it
~1.5hHandle bursts of updates efficiently (batching screen updates), limit message size on the server, reject movements that would make stock negative, and add a heartbeat so dead connections are noticed. Done when: a burst of thousands of updates keeps the board responsive and correct.
- 06
Test it
~2hWrite Vitest tests for the client's update logic as pure functions: old versions ignored, duplicates ignored, a gap triggering a resync, and buffered updates applied after a snapshot. Write server tests for movements, validation and broadcasting, and a test that sends updates to a client out of order and with drops, then checks the final state matches the server. Done when: all tests pass.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack