Back to Case Studies

An ordering, invoicing and returns platform for a pharmaceutical distributor

Five Node services, a React ordering app and a Flutter app for sales representatives — the busiest backend in the estate at 1,181 commits.

Sector
Pharmaceutical distributor
Engagement
December 2022 – September 2023
  • Node
  • Express
  • React
  • Vite
  • Redux Toolkit
  • Flutter
  • Twilio

Context

Business-to-business distribution ordering is not retail checkout. The customers are trade accounts rather than consumers, orders arrive from sales representatives on phones as often as from a browser, and returns of saleable stock are a routine flow rather than an exception — invoicing and returns both have to reconcile against the same order. Catalogue and account records are shared master data that several parts of the system need to read consistently, which is a different problem from serving a product page fast.

What we built

  • Backend services

    Core, database manager, master data, orders and users, each deployed as its own service.

  • Web app

    Ordering, invoicing and returns in the browser.

  • Mobile app

    Ordering, invoices, saleable returns and account statistics for representatives in the field.

  • Corporate site

    The distributor's public website, built alongside the platform.

Architecture

The backend is not one Express application but five Node services over a shared core package and a database-manager package: core, database manager, master data, orders and users. Separating master data from orders is the decision that matters — orders change constantly, catalogue and account records do not, so the ordering path could be worked on without disturbing the reference data everything else reads. The browser client is React on Vite with Redux Toolkit. Representatives in the field use a Flutter app covering ordering, order history, invoices, saleable returns, trade-account handling and per-account statistics. Order notifications go out over Twilio. A separate codebase holds the corporate website, delivered alongside the platform. Branch history shows a multi-language effort running in parallel with feature work. The engagement ran from December 2022 to September 2023.

Stack

Backend services
  • Node
  • Express
  • five services on a shared core
Web app
  • React 18
  • Vite
  • Redux Toolkit
Mobile app
  • Flutter (Dart)
  • GetX
Corporate site
  • Separate codebase
Integrations
  • Twilio in the order service for SMS notifications
  • AWS SDK for object storage in the master-data service

Scale

Counts that can be re-derived from the same repositories. Nothing here is a business result — a repository cannot evidence one.

  • Three delivered product surfaces — backend services, web app, mobile app — plus a separate corporate website.
  • 1,446 commits in total, of which 1,181 are in the backend.
  • 5 backend services on a shared core package.
  • 13 mobile modules.
  • 19 mobile dependencies, on Dart SDK >=2.17.6 <3.0.0.

Where the evidence stops

  • The admin panel scoped at the outset was never written: this is three product surfaces plus a separate corporate website, not the four-surface shape the other platform builds take.
  • The mobile repository's commit count is not cited anywhere on this page, because its history was imported rather than accumulated and would misrepresent the work.
  • Order volume, catalogue size and customer counts are not derivable from a repository, so they do not appear.

Evidence

Each statement above, and the artefact it was read from. The client cannot be named, so the sources are given instead.

  • 3 product surfaces delivered, plus a separate corporate website.

    SourceOne repository per surface. The admin panel scoped at the outset has no commits and no default branch, so it is not counted.

  • 1,446 commits in total, of which 1,181 are in the backend.

    SourceSum of history.totalCount on each repository's default branch (GitHub GraphQL)

  • 5 backend services.

    Sourcemicroservices/ directory listing on the backend repository

  • 13 mobile modules.

    Sourcelib/view/ directory listing on the mobile repository

  • 19 mobile dependencies, on Dart SDK >=2.17.6 <3.0.0.

    Sourcepubspec.yaml on the mobile repository

  • Engagement span: 28 December 2022 to 6 September 2023.

    SourceFirst and last commit dates on the default branches

Related capability

API development