ArtificialGuyBR

Home / Blog / Fixing things

PharmaRoute: a field CRM for pharmaceutical sales reps

A monorepo app with two views: a mobile agent that routes visits by location and history, and a desktop command centre with KPIs, territory and team schedule.

2 sources cited Fixing things

PharmaRoute: a field CRM for pharmaceutical sales reps

TL;DR

  • PharmaRoute is a field sales system for pharmaceutical distributors, labs and manufacturers, split into two views integrated in real time: a mobile agent view and a desktop manager view.
  • The agent view routes visits by location and consolidated pharmacy visit history, records on-site check-ins, and adds a new target quickly with reverse geocoding through Nominatim.
  • The manager view is a command centre: business KPIs, efficiency per agent, territory control with a radius on Leaflet, and the team schedule.
  • The stack is a monorepo of NPM workspaces: React 19 and Vite on the front, Node and Express with Zod and TypeScript on the API, Supabase PostgreSQL with row-level security.

What it is and who it is for

PharmaRoute is a complete field-relationship and routing system, written for the operations of distributors, laboratories and pharmaceutical industries. The README frames the problem as the logistics inefficiency of outside sales teams, which is a specific and familiar problem: a rep with thirty pharmacies in a city, a route planned in the morning from memory, and a manager with no idea which visits actually happened.

It is for the rep in the car and for the manager at the desk, which is why the two views are the design decision rather than a feature: the mobile view answers "where do I go next", and the desktop view answers "is the territory being covered".

What each view does

Agent view, mobile. Routing based on location, consolidated visit history per pharmacy, on-site check-ins, and quick addition of new targets with reverse geocoding through Nominatim. The history is the part that makes routing useful rather than decorative: a route that ignores which pharmacy was visited last month is a list of addresses.

Manager view, desktop. A command centre with a macro view of business KPIs, efficiency per agent, territory control with a radius on Leaflet, and the team schedule.

The stack

The project is a monorepo managed with NPM workspaces, which keeps the two apps separate by responsibility:

PartStack
apps/frontendReact 19, Vite with SWC, Tailwind CSS v4, Framer Motion, React Leaflet with OpenStreetMap, Lucide React
apps/apiNode.js, Express, Zod for schema and payload validation, strict TypeScript built with tsx, Helmet and CORS preconfigured
Database and authSupabase PostgreSQL with row-level security, SQL triggers for internal operational states and profile creation

The README names recommended hosting per part — Vercel for the frontend, Railway or Render for the API — which is a deployment suggestion, not a requirement.

What the stack decision buys you

Two choices are worth naming. Row-level security in Supabase means the data boundary is enforced by the database rather than by a route handler, which matters in a system where a rep should see their territory and a manager should see the region. SQL triggers for internal state and profile creation mean an operational state change does not depend on the client having sent the right request.

And the TypeScript-plus-Zod pair means a payload is validated at the boundary rather than trusted because the frontend sent it.

How to run it locally

The README's local setup is a requirements section followed by the environment configuration: install the workspace dependencies, configure the Supabase connection, apply the schema and triggers, then run the frontend and the API. Node and a Supabase project are the two things you need before the first run; the README describes the steps rather than a one-command starter.

When to use it, when not to

Use it as a starting point for a field sales operation where routing and coverage are the product, and as a working example of a monorepo where the mobile and desktop views share one API and one database.

Do not use it as a production CRM out of the box: the README calls it an MVP with deploy-ready hosting suggestions, and a real operation needs what an MVP leaves out — offline mode for a rep without signal, audit of who changed a visit, and an integration with the distributor's ERP. And do not assume the geocoding is free of rate limits: reverse geocoding goes through Nominatim, a public service with its own usage policy.

Sources

  1. PharmaRoute — repository — the two views, the stack table, database and auth notes, hosting suggestions quoted above.
  2. README.md — project overview, stack, local run instructions.

Project page: PharmaRoute

For the warehouse-side version of the same logistics question, see the CEP distribution optimizer.

FAQ

Does it need a paid map provider? No. Maps run through React Leaflet with OpenStreetMap tiles, and reverse geocoding goes through Nominatim.

Which database does it use? Supabase PostgreSQL, with row-level security enabled and SQL triggers for internal operational states and profile creation.

Is it a monorepo? Yes, managed with NPM workspaces, splitting apps/frontend and apps/api by responsibility.

What are the two views? A mobile view for the agent — routing, visit history, check-ins, quick new targets — and a desktop command centre with KPIs, efficiency per agent, territory radius and team schedule.