Offline-first inventory for TT Global
Store staff scan QR codes and record stock on a phone, even when the network drops.
- Organisation
- TT Global, Ikeja
- My role
- Built and delivered it (through Merciven)
- When
- Delivered
- Stack
- React, Flask, REST API, JWT
Problem statement
Stock was counted on paper and reconciled weeks later, and the warehouse network was unreliable, so a web app that needed a connection for every scan wouldn't work.
Objectives & goals
- Record stock in and out at the shelf
- Keep working offline and sync later
- Never let stock go negative
- Control who can change what
Process
- DiscoverWalked the warehouse and watched how stock moved.
- DefineQR code per item, three roles, and an offline queue on the phone.
- BuildReact front end, Flask REST API with JWT, PostgreSQL.
- ProveTests for roles, duplicate syncs and negative stock.
Who it's for
Scans items and records movements on the floor.
Adds items, sets reorder levels, sees low stock.
Challenges
- The same offline batch can be sent twice
- Two phones may draw down the same item
- Scanning a random QR code must not crash anything
What I built
Each item has a payload like TTG:ITEM:CEM-50; anything else is refused.
Queued movements carry client ids, so a repeated batch applies once.
A movement that would overdraw is rejected on its own; the rest still apply.
Manager, storekeeper and viewer via JWT.
Flow
- Scan QR
- Record movement offline
- Queue on phone
- Reconnect
- POST /sync
- Apply once per id
- Update stock and alerts
Output
first sync: applied, rejected (only 25 in stock), applied same batch: already_synced, rejected, already_synced CEM-50 on hand: 25 (low stock flagged)
Results
Tools & languages
The code
The API rewritten from scratch with invented items, on SQLite. 4 tests.
The repository is private. I'm happy to share it with a hiring team or walk you through it on a call.
Samples are written with synthetic data. No client code or client data is used.