Skip to content
Language: es

Menu

DistributionClient

Roleo · Distribution

A wholesale distributor moved from an old desktop system to mobile pre-sales that work offline, delivery runs, customer accounts and an admin panel.

The problem

Our sales reps work where there's no signal, our system is old and we don't use half of what it has.

The solution

I surveyed what the old system was really used for, migrated its data and built a pre-sales and delivery PWA that works offline and syncs on its own, plus an admin panel and a public catalog, on infrastructure with automatic deploys.

Impact

  • Sales reps take orders offline and each sale uploads by itself when the signal comes back, never duplicated.
  • 2,236 customers, 13 routes and 963 products migrated from the old system.
  • Six phases in production, each with its own PR, CI and automatic deploy.

My role

Discovery, design, development, data migration and infrastructure

DesignFront endBack endInfra & DevOpsData

Tools

ReactPWAIndexedDB (Dexie)ExpressSequelizePostgreSQLRailwayGitHub Actions
galpón's corrugated shed, with two boxes and the orange order on top

This case gave rise to

galpón

Sell on the street. Collect on the route.

The salesperson takes the order on the street even without signal, the driver delivers and collects, and the office loads the truck and invoices. From order to invoice, with no paper in between.

galpon.app

Context

Roleo is a wholesale distributor that works with pre-sales: a sales rep visits the customer and takes the order, and a driver delivers it on another day. They used a desktop system (ASP.NET with frames) with modules for purchasing, sales, customer accounts, checks, payroll and more.

What hurt

  • Many towns and routes have no signal, so orders were taken on paper or from memory.
  • The system had everything, but in practice they only used products and prices, pre-sales and routes. Sales invoices had been at zero since 2024 and customer accounts were empty.
  • Planning each day's delivery run meant exporting spreadsheets by hand.

Decisions

Survey before building. I went through the old system in read-only mode to see what was really used. That set the scope: replace what is used, and add what was missing, like customer accounts, as a new practice. Not everything that existed was migrated.

Offline first, with a queue that never duplicates. The phone stores each order in a local queue and uploads it in order when there's signal. Every operation carries an ID generated on the phone and the server is idempotent: resending never duplicates. The price is always decided by the server.

A PWA instead of a native app. There was a React Native app, but it barely used native features and it was expensive to maintain. Every sales rep uses Android with Chrome, so an installable PWA did the same job at a fraction of the cost.

Infrastructure as code from day one. Postgres, a file bucket and four services defined in code, with CI on every PR and automatic deploys on merge.

What was built

  • Sales rep PWA: daily route, customers, orders, collections and a rear-camera barcode scanner.
  • Driver PWA: delivery sheet, deliveries with returns and payment on the spot.
  • Admin panel: products, price lists, delivery runs, customer accounts, commissions, internal invoicing and reports.
  • Public catalog with WhatsApp contact.
  • Data migration with an idempotent script that can be run again safely.

What I learned

The most valuable part was the survey: once you watch how people actually work, the scope shrinks to what matters.

More cases

TurismoClientEn español

Ayum Elun · Recepción

Registramos a cada huésped en una planilla de papel y al final del día no sabemos cuánto entró ni por qué medio.

Una app de recepción instalable que registra al huésped una sola vez, muestra solo los campos del tipo de alojamiento elegido, impide reservas superpuestas desde la base de datos y cierra la caja del día por sector y medio de pago.

  • El huésped que vuelve se encuentra por DNI, apellido o teléfono y sus datos se autocompletan.
  • Extracto diario y mensual por sector (cabañas, apart, hostería, camping) y por medio de pago.
DesignFront endBack endInfra & DevOpsData
Gave rise toTranquera