Distribuidora Luna is a pharmacy products distributor based in Uruguay that serves a large network of pharmacies. As the business grew, keeping up with purchase orders and coordinating logistics by phone and on paper stopped scaling.
I designed and built the whole platform. Pharmacies order through a dedicated web portal with managed accounts; every new order appears instantly, with a notification sound, on the admin dashboard. The company's on-street salesperson uses a mobile app to place orders on behalf of the pharmacies they visit and is notified of new orders, which prevents duplicate visits to pharmacies that already ordered that day.
Architecture
A modular NestJS API (Node.js, TypeScript, Sequelize) owns the business logic and a PostgreSQL database. One React and Mantine web app serves both the pharmacy portal and the admin dashboard, and the salesperson app is built with Flutter. Real-time updates are handled by a separate Go service: the real-time UI update component I later published as part of OptiBlocks. Everything runs in Docker on a Hostinger VPS behind nginx.

Real-time order updates
- The API never holds a socket: after an order commits, the API sends one POST to the Go service, which fans it out to every connected dashboard over WebSockets. Node's event loop stays free for API requests.
- Publish after commit: the push is fire-and-forget with a 5-second timeout. A dashboard never shows an order that rolled back, and a problem in the real-time path can never fail an order.
- Two kinds of credentials: dashboards subscribe with the same JWT they use for the API. The backend publishes with a time token, an HMAC-SHA256 of the current time window, so the shared secret never travels and a leaked token expires with its window.
- Slow clients don't slow everyone: one hub goroutine owns the set of clients, and every connection has its own buffered send queue. A client whose queue stays full for 5 seconds is disconnected, pings every 30 seconds drop dead connections, and the dashboard reconnects with exponential backoff.

Placing an order
- Scoped access: administrators need the orders role, and a pharmacy user can only order for, view and download invoices of the pharmacies linked to their account.
- Pricing in the database: the cart is sent to PostgreSQL as a
VALUESlist and joined against the products in one query, instead of loading each product. - Promotions applied atomically: each line gets the best active “buy N get M” promotion (the largest N that does not exceed the quantity) and is written in the same transaction as the order.
Data model and performance
Administrators, salespeople and pharmacy users share one user table with a role-specific extension each; administrators carry a list of permissions (stats, orders, products, promotions, users). Pharmacy users and pharmacies are many-to-many, so one person can order for several branches.

- Indexes for an append-only orders table: a partial index on pending orders, a partial composite index for each pharmacy's recent orders, and a BRIN index on the creation date.
- Dashboard KPIs: revenue, orders, active and new pharmacies, average order value, sales by category and pharmacy, top products and the sales trend come from nine aggregate SQL queries run in parallel.
- Catalog import: the distributor's Excel price list is uploaded as is; products are upserted and new categories created in one transaction.
- Accounts: bcrypt-hashed passwords, 15-minute access tokens and 30-day refresh tokens.
Key features
- Pharmacy portal: product browsing (categories, search, sorting, promotions), cart, order creation, order history and invoices.
- Admin dashboard: KPIs and analytics, plus live order management: pending and completed views, search, pagination and status updates.
- Invoices: admins attach a PDF invoice when completing an order; authorized users can list and download them.
- User and access management: administrators with role-based permissions, plus salesperson, pharmacy user and pharmacy management, including enabling or disabling pharmacies.
- Promotions: “buy N get M” promotions tied to products, with activation toggles.
- Salesperson mobile app: authentication, fast product search, cart-based order creation on behalf of a selected pharmacy, and active orders.
