MorokotGas
Replaced phone-and-spreadsheet LPG dispatch with an end-to-end ordering and delivery system.
- Engagement
- Client engagement
- Industry
- Energy & Distribution
- Year
- 2026
The challenge
An LPG cylinder distributor took orders by phone, wrote them on paper, and called drivers to dispatch. Stock lived in a spreadsheet that was accurate until the first delivery of the day. Nobody could answer 'where is my cylinder' without three phone calls, and the owner had no view of the day until it was over.
Our approach
The constraint was the drivers, not the technology. Any system they would not use would fail regardless of how good the backend was. We designed the driver app first with large targets, minimal typing and support for affordable Android phones with patchy signal. Then we built the API around it. OTP login removed passwords and the biggest source of support calls.
What it had to achieve
- Take an order without a phone call, and dispatch it without a second one
- Give the owner live visibility into orders, drivers and stock
- Let drivers work from a phone with no training beyond one shift
- Remove the spreadsheet as the system of record
Architecture
The decisions that made the rest possible.
OTP-only authentication
Drivers and customers sign in with a phone number and a code. No password resets, no forgotten credentials, no shared logins written on a wall.
Queue-backed side effects
Notifications, receipt generation and stock recalculation run through Bull on Redis. A slow SMS provider delays a message, never an order confirmation.
Shared design-tokens package
Colors, spacing and type live in one package consumed by the Flutter apps and the Next.js dashboard, so three surfaces stay visually consistent without three sets of decisions.
Order state machine with explicit transitions
An order moves through defined states with recorded timestamps. 'Where is my cylinder' becomes a database read instead of a phone call.
What we delivered
- Customer Flutter app: ordering, reorder, delivery status, order history
- Driver Flutter app: assigned runs, status updates, proof of delivery
- Next.js admin dashboard: live orders, driver assignment, stock, reporting
- NestJS API with OTP authentication and role-scoped permissions
- Bull/Redis queues for notifications and background processing
- Shared design-tokens package across web and mobile
Security & reliability
- Role-scoped permissions separating customer, driver and administrator access
- Every order state change written with actor and timestamp for dispute resolution
- Stock adjustments recorded as movements rather than overwrites
Outcomes
What changed once it was live.
- Orders arrive as records instead of phone notes, so dispatch no longer depends on memory
- Delivery status is visible to the customer without contacting the office
- Stock reflects deliveries as they happen instead of at end of day
- The owner sees the day's operation live rather than reconstructing it after
What we would do differently
Every project teaches something. Publishing it is how you tell whether a team is reflecting or just selling.
- Designing the driver app before the API was the right call. Every architectural decision downstream had a concrete, low-connectivity user to answer to.
- OTP login eliminated a whole category of support burden. For non-office users, passwords are a product risk.
Let's find out if this is worth building.
A 45-minute discovery call, free. You describe the problem, we tell you honestly what it takes, what it costs, and whether you should build it at all.