Haelias
Solo CTO / Principal Engineer (with contributor support on UI) · 2022 – present
Clients: Montefarmaco, Logista SPA
Visit websiteProblem
Italian pharmacies handle procurement through phone calls, emails and faxes to multiple wholesalers, negotiate prices verbally and reconcile invoices by hand. They need a real-time multi-supplier catalog, digital purchase orders, compliance-grade audit trails and safety UX for high-value orders.
Architecture
End-to-end production stack across 5 independent git repos (core / ui / sync-worker / landingpage / haelias_docs): an Express + TypeScript backend exposing 143 endpoints mounted from a single `main.ts`, a React 19 + Tailwind 3 + MUI 7 SPA with 136 components organised in Atomic Design and 5 React Contexts (no Redux), a Vite landing page, and a Rust + Tokio sync worker that ingests Farmadati's SOAP catalog into the shared Managed MongoDB. The data layer is 16 Mongoose schemas with a multi-tenant entity model (5 RBAC roles: admin / manager / buyer / supplier / referral_partner), a custom search engine over partial weighted text indexes, and a two-tier index strategy that confines Discover/search indexes to the ~14k in-stock products instead of the full 5.5M-document catalog. The ODA domain is a 6-state order machine with cascading sub-orders (`createSubOda`), a 6-state per-line counter-offer state machine (`requested → admin_absorbed | sent_to_supplier → supplier_responded → resolved`), and a `stripSupplierDataForBuyer` sanitiser called on every buyer-facing order read. Customer support is a bidirectional Discord ↔ SSE bridge: REST-polled Discord messages stream into the UI in real time. 493 backend test cases (Jest + supertest), 68% statement coverage. The main UI is CRA + craco (not Next.js); Vite powers the landing page only.
Decisions
Cluster upgrade vs index optimization
Diagnosed via WiredTiger cache-pressure analysis: out of 5.5M product docs, only ~14k carry active supply at any time. Replaced full indexes with partial indexes filtered on `{hasSupply: true, status: "active"}` — name, producer, category, plus a partial weighted multi-field text index (name:10, sku:8, ean:8, producer:5, category:3, description:1). Result: ~99% reduction in the in-cache search-index footprint, 70% on-disk index reduction live (1.69 GB → 369 MB), $15/mo cluster kept, €1,260/year upgrade avoided.
Rust + Tokio Farmadati sync worker
Continuous SOAP-to-Mongo sync with concurrent table downloads + per-table page-level concurrency (`FARMADATI_PAGE_CONCURRENCY`) and bulk writes. Lock + run-history collections (`farmadati_sync_states`, `farmadati_sync_runs`) plus a heartbeat-based `resume` command for crash recovery. CLI modes: `delta` / `full` / `auto` / `resume` / `snapshot` / `reset-lock`. Rust `$set`-only is intentional: the backend's `hasSupply` denormalisation flag survives every Farmadati upsert because the worker only sets its own fields.
Privacy-by-design between supplier and buyer
`stripSupplierDataForBuyer` (`core/routes/orders.ts:182`) is the single sanitiser called on every buyer-facing order read: removes `warehouseAssignments`, drops `warehouse`/`entityId` from line breakdowns, and gates `priceNegotiation` visibility on order status. The counter-offer state machine has 6 states + 3 resolutions (`buyer_price_accepted` / `supplier_price_accepted` / `negotiation_failed`) with `originalNetPrice` and `absorbedNetPrice` strictly separated.
Modal warnings for high-value orders
Picked a configurable warning over a hard block for €250k–€1M+ orders — safety without frustrating enterprise buyers.
Sub-ODA cascading for partial fulfilment
When a warehouse partially fulfils a line, admin issues a sub-ODA (`createSubOda`, `routes/orders.ts:6350`) linked by `parent.subOrderIds[]` and `subOrderId: "ODA-SUB-..."`. The buyer keeps a single ODA in their view; the warehouse-side picking flow gets one fresh ODA per fulfilment round. Tested at `tests/orders.test.ts:3570-3645`.
Discord ↔ SSE customer support bridge
Real-time customer support without paying for Intercom: REST-polls a Discord channel every 10s (`libs/support-discord.ts`), persists messages to `support-conversations` + `support-messages`, then pushes them into the UI via Server-Sent Events (`libs/support-stream.ts`). Handles 429-retry, bot user filtering, and conversation-scoped subscription.
Single bulkWrite for 50k-row CSVs
CSV uploads (`csv-upload.ts`) and supply-flag maintenance (`hasSupplyMaintenance.ts`) issue a single MongoDB bulkWrite per upload regardless of size — even a 50k-row CSV is one operation, with progress streamed to the UI via the upload-progress utility.