Brian Omariba
Start a project →
← All systems
Dossier /04 Commerce operations Live

Commerce
Operations System

The order is the easy part. Everything after it is the business.

An operations layer for cash-on-delivery commerce — the part of the process that happens after checkout, where most of the cost and nearly all of the loss actually lives.

Category
Operations platform
Role
System design · Backend engineering · Integrations
Stack
NestJS · PostgreSQL · Courier APIs · Docker
Status
In production — ops.cuga.co.ke ↗
01 — Problem

Cash on delivery breaks every assumption a storefront makes.

In a prepaid model, payment confirms intent. In cash on delivery there is no payment at checkout — so an order is only a claim, and a meaningful share of claims never become deliveries.

That changes what the software has to do. The store is no longer the system of record; the operation is. Confirmation calls, courier handover, rider assignment, delivery attempts, returns and cash settlement all happen outside the storefront, and typically end up in spreadsheets and phone calls.

The cost shows up as orders dispatched that should not have been, cash that takes weeks to reconcile, and no reliable answer to where any individual parcel is.

Unconfirmed orders
Failed deliveries
Courier handover
Returns
Cash settlement
Reconciliation
02 — System

One record, followed all the way to the cash.

Every order carries a single state through the whole operation, and each transition is recorded with who caused it. The point is that the same object that was created at checkout is still the object being settled at the end.

01Order

Captured from the storefront with the details the operation will need later.

02Confirmation

Intent verified before cost is committed — the cheapest filter in the chain.

03Assignment

Routed to the right fulfilment path by destination and delivery method.

04Courier

Handover to a third-party carrier through its API, with the waybill recorded.

05Rider

Last-mile delivery, with status and proof captured at the doorstep.

06Delivery

Delivered, rescheduled or returned — each a state, none of them a dead end.

07Settlement

Cash collected reconciled against orders delivered, per courier and per rider.

03 — Architecture

Several couriers, one interface.

Carriers do not agree on anything — not on status names, not on how a parcel is created, not on whether they will tell you when something changes. Some expose a modern API, some expose very little.

The system puts a single internal shipment model in front of all of them, with a per-carrier adapter translating to and from that model. Operations staff learn one vocabulary; adding a carrier is an adapter rather than a change to the core.

Built on NestJS over PostgreSQL, containerised with Docker. Separate surfaces for the operations portal and the rider, because the two jobs have almost nothing in common — one is a desk with many orders, the other is a phone with one.

04 — Interface

Two users who share nothing.

The operator works in volume: queues, filters, bulk actions, and the ability to see which orders are stuck and why. Density is correct here — hiding information would slow them down.

The rider is standing outside a gate holding a parcel. That interface is one order at a time, large targets, and the smallest number of taps between arriving and recording an outcome.

Dropship OS operations console sign-in

ops.cuga.co.ke — operations console sign-in. Interior screens are behind client authentication.

05 — Outcome

What the system changes.

The operation becomes queryable. Where a parcel is, why an order stalled, and what is owed by whom stop being questions that require a phone call and become properties of a record.

Confirmation before dispatch is the structural change that matters most: it moves the filter to the cheapest point in the chain instead of the most expensive one.

Delivery-rate & settlement metrics — to be published once in production