← blog
July 10, 2026·2 min·48 views

Digitizing customs clearance: lessons from TransitSoft

retour projetnestjsmonorepocameroun
Digitizing customs clearance: lessons from TransitSoft

Customs transit is a business of paperwork and deadlines. A shipment comes in through the airport or the port, passes through a branch, a warehouse, maybe another branch inland, then reaches the client. At every step: a document, an invoice, a debt ticking up, a storage penalty landing. TransitSoft Services was born to digitize this whole chain — air, sea, and land — for multi-branch operations.

The real problem isn't the CRUD

You might think this is just a back-office. In reality, the hard part is consistency across branches: a shipment unpacked in a warehouse has to be redistributed to the right destination branch, billing has to follow each branch's currency and configuration, and debts have to flip automatically to OVERDUE when the due date passes.

I split the product into a Turborepo monorepo:

apps/
  api/          # NestJS + Prisma (PostgreSQL) + Socket.IO + BullMQ
  web/          # opérations agence
  ops-admin/    # administration / configuration
  web-desktop/  # poste lourd
  web-client/   # portail client
  mobile/       # agents
  tablet/       # terrain
  orchestrator/ # control-plane multi-tenant

What real-time and cron jobs solve

  • Socket.IO for notifications and the built-in chat/support: when a waybill is received, the branch on the other end sees it without refreshing.
  • BullMQ (Redis) for anything that has to run on its own: daily computation of storage penalties, checking debt due dates, automatically flagging unpaid invoices.
  • PDF generation (pro forma invoices, waybills) and a QR code per shipment for physical tracking.

The field constraint

Agents aren't always connected. The location data (country → region → city) is bundled as static JSON on the client so that forms work without depending on an external API. It's the kind of unglamorous decision that changes everything when the 4G drops inside a warehouse.

What I take away from it

A rich business domain can't be coded "flat." Modeling the shipment lifecycle first, and only then the screens, saved me from rewriting billing three times. And a well-partitioned monorepo lets me ship the ops-admin without breaking the tablet.

Working on a complex domain product (logistics, healthcare, finance)? How do you keep consistency across several interfaces that all touch the same data? Tell me in the comments.