← All case studies
WebDesktopOffline

ERP for liquid cargo operations

An ERP for a company that stores and moves liquid cargo. Every loading, discharge, transfer, and blending is a document, and the ledger is kept in metric tons. The office runs it in the browser, terminals and vessels run the same system as a desktop application that works offline and syncs when a connection returns.

Started
May 2026
Development time
8 weeks
Platforms
Web, Desktop
Industry
Liquid cargo logistics
  • 4h

    a day no longer spent re-typing terminal paperwork at the office

  • 96%

    of operations recorded on the day they happen, from a little over half

  • −82%

    corrections raised against the cargo ledger after a shift closes

  • 3days

    to close the month, where reconciling the spreadsheets took two weeks

The challenge

The cargo belongs to the company's customers, so nothing may appear or disappear without a traceable record. Terminals and vessels go offline for unpredictable periods, and a transfer has to be recorded while it happens.

The solution

The office, the terminals, and the vessels work in one system. An operator records a loading or a transfer while it happens, with or without a connection, and the office sees it as soon as the node syncs. Supervisors approve, revert, and reconcile with a full history behind every figure.

  • Document-driven ledgerAcceptance, dispatch, transfers, blending, and reconciliation.
  • Offline terminalsAn encrypted local database on each terminal, synced with the office whenever a connection is available.
  • Roles and audit trailOperators, supervisors, and administrators, with who, what, and when behind every change.
  • Transport documentsTruck and rail waybills, weights, and measurements attached to the cargo they move.
  • CatalogCompanies, bases, warehouses, storages, ports, and products in one place.
  • Cargo flowWhere each product came from and went, including ownership transfers on paper.

Engineering decisions

  • Rust
  • PostgreSQL
  • SQLite
  • Tauri
  • React
  • TypeScript
  • One Rust core holds the domain, the database layer, the API, and the sync engine. An Axum server with PostgreSQL deploys it for the office, a Tauri desktop application with an encrypted SQLite database for terminals.
  • Sync exchanges the audit entries the system already keeps for compliance, instead of replicating the database. Watermarks let an interrupted cycle resume, and idempotent entries make a retry safe.
  • Conflicts are settled by authority: when two nodes edit the same record, the change by the user with the higher role wins and the other is kept as superseded, with the same result on every node.
  • Procedural macros generate services, DTOs, audit fields, and endpoints, so a new entity takes about forty lines instead of two hundred.
  • The React interface is generated from the OpenAPI description, so the server, the desktop app, and the offline terminal share one codebase.

Let's talk about your project.

Schedule an online call (optional)

We use what you write here only to reply to you.