Tutti i case study

In produzione · B2B SaaS · Procurement Pharma

Haelias

Ruolo
Solo CTO / Principal Engineer (con contributor support su UI)
Periodo
2022 – present
Clienti
Montefarmaco · Logista SPA
Schermata di Haelias

Numeri chiave

  • 5.5M+Documenti MongoDB live
  • ~14kProdotti in stock cross-supplier
  • 143Endpoint Express (singolo `main.ts`)
  • 493Test case backend (Jest + supertest)

01 · Haelias

Problema

Le farmacie italiane gestiscono il procurement con telefonate, email e fax verso più grossisti, contrattando i prezzi a voce e riconciliando manualmente bolle e fatture. Servono catalog real-time multi-fornitore, ODA digitali, audit trail compliance-grade e UX safety per ordini high-value.

02 · Haelias

Architettura

Stack production end-to-end su 5 repo git indipendenti (core / ui / sync-worker / landingpage / haelias_docs): backend Express + TypeScript con 143 endpoint montati da un singolo `main.ts`, SPA React 19 + Tailwind 3 + MUI 7 con 136 componenti in Atomic Design e 5 React Context (no Redux), landing in Vite, worker Rust + Tokio per l'ingestion dal catalogo SOAP di Farmadati su MongoDB Managed condiviso. Il data layer è composto da 16 schemi Mongoose in modello multi-tenant (5 ruoli RBAC: admin / manager / buyer / supplier / referral_partner), un search engine custom su indici parziali pesati e una strategia indici a due livelli che confina gli indici di Discover/ricerca ai ~14k prodotti in stock invece dei 5,5M totali. Il dominio ODA è una state machine a 6 stati con sub-ordini cascading (`createSubOda`) e una state machine counter-offer per linea a 6 stati (`requested → admin_absorbed | sent_to_supplier → supplier_responded → resolved`), più un layer `stripSupplierDataForBuyer` invocato su ogni read lato buyer. Il customer support è un bridge Discord ↔ SSE bidirezionale: messaggi pollati via REST da Discord vengono pushati nella UI in tempo reale. 493 test case backend (Jest + supertest), 68% statement coverage. La UI principale è CRA + craco (non Next.js); Vite alimenta solo la landingpage.

03 · Haelias

Decisioni chiave

  • 01

    Cluster upgrade vs ottimizzazione indici

    Diagnosi via WiredTiger cache-pressure analysis: dei 5,5M documenti prodotti, solo ~14k portano supply attiva. Indici sostituiti con indici parziali filtrati su `{hasSupply: true, status: "active"}` (name, producer, category) più un indice testuale partial pesato multi-campo (name:10, sku:8, ean:8, producer:5, category:3, description:1). Risultato: ~99% di riduzione del footprint in cache sui search path, 70% di riduzione on-disk live (1.69 GB → 369 MB), cluster $15/mese mantenuto, upgrade da €1.260/anno evitato.

  • 02

    Worker Farmadati in Rust + Tokio

    Sync continuo SOAP-to-Mongo con concorrenza per tabella e per pagina (`FARMADATI_PAGE_CONCURRENCY`) e bulk write. Lock + run-history collections (`farmadati_sync_states`, `farmadati_sync_runs`) e comando `resume` heartbeat-based per crash recovery. Modalità CLI: `delta` / `full` / `auto` / `resume` / `snapshot` / `reset-lock`. Rust con `$set`-only è intenzionale: il flag `hasSupply` denormalizzato dal backend sopravvive a ogni upsert Farmadati perché il worker tocca solo i propri campi.

  • 03

    Privacy-by-design tra supplier e buyer

    `stripSupplierDataForBuyer` (`core/routes/orders.ts:182`) è il sanitiser unico chiamato su ogni read lato buyer: rimuove `warehouseAssignments`, droppa `warehouse`/`entityId` dai breakdown di linea, e gating della visibilità `priceNegotiation` in base allo status dell'ordine. La state machine counter-offer ha 6 stati + 3 risoluzioni (`buyer_price_accepted` / `supplier_price_accepted` / `negotiation_failed`) con `originalNetPrice` e `absorbedNetPrice` rigorosamente separati.

  • 04

    Modal warning per ordini high-value

    Hard block scartato in favore di un warning configurabile per ordini €250k–€1M+ — sicurezza senza frustrare i buyer enterprise.

  • 05

    Sub-ODA cascading per fulfilment parziale

    Quando un magazzino fulfilla solo parzialmente una linea, l'admin emette un sub-ODA (`createSubOda`, `routes/orders.ts:6350`) collegato via `parent.subOrderIds[]` e `subOrderId: "ODA-SUB-..."`. Il buyer vede un singolo ODA; il flusso warehouse riceve un nuovo ODA per ogni round di fulfilment. Coperto dai test in `tests/orders.test.ts:3570-3645`.

  • 06

    Bridge customer support Discord ↔ SSE

    Customer support real-time senza Intercom: REST-polling di un canale Discord ogni 10s (`libs/support-discord.ts`), persistenza in `support-conversations` + `support-messages`, push verso UI via Server-Sent Events (`libs/support-stream.ts`). Gestisce 429-retry, filtering del bot user e subscription per conversazione.

  • 07

    bulkWrite singolo per CSV da 50k righe

    Gli upload CSV (`csv-upload.ts`) e la maintenance del flag `hasSupply` (`hasSupplyMaintenance.ts`) emettono un singolo MongoDB bulkWrite per upload indipendentemente dalla size — anche un CSV da 50k righe diventa una sola operazione, con progress streamato in UI tramite l'utility upload-progress.

04 · Haelias

Risultati

  • 5.5M+

    Documenti MongoDB live

  • ~14k

    Prodotti in stock cross-supplier

  • 143

    Endpoint Express (singolo `main.ts`)

  • 493

    Test case backend (Jest + supertest)

  • 68%

    Statement coverage backend

  • 16

    Schemi Mongoose

  • 136

    Componenti React (Atomic Design)

  • 5

    Repo git indipendenti

  • 70% (1.69 GB → 369 MB)

    Riduzione size indici on-disk (live)

  • ~99%

    Riduzione indici in cache (search path)

  • €1,260/yr

    Risparmio annuale vs upgrade cluster

  • 50k rows = 1 bulkWrite

    Benchmark CSV ingest

05 · Haelias

Tech e pilastri

Tech stack

  • Node.js
  • Express 4
  • TypeScript
  • MongoDB
  • Mongoose
  • MongoDB driver (native)
  • Helmet
  • Web Push
  • Resend
  • @react-email/components
  • PDFKit
  • ExcelJS
  • Turf.js
  • React 19
  • React Router v7
  • Tailwind 3
  • MUI 7
  • MUI X DataGrid
  • framer-motion
  • Chart.js
  • Recharts
  • react-window
  • CRA + craco
  • Vite (landingpage only)
  • Rust 2021
  • Tokio
  • reqwest
  • mongodb (Rust driver)
  • rustls
  • Jest
  • supertest
  • DigitalOcean App Platform
  • Managed MongoDB
  • Vercel
  • Discord Bot API
  • Server-Sent Events
  • Farmadati SOAP

Pillar toccati

  • Traditional Software Engineering
  • Cloud & DevOps
  • IT Management & Digitalizzazione

Contatto

Hai un sistema simile da costruire?

Raccontami il contesto in una call di 30 minuti.

hello@andrea0x.me · @andrea0x_eth

Haelias — B2B SaaS · Procurement Pharma · Andrea Ritondale