Sanità / Nutrizione clinica
Una casella di posta per famiglia, un decennio di dati intatti: il sistema clinico su misura di uno studio di nutrizione
Percentili di crescita OMS, cicli dieta-pesate e un portale pazienti costruiti sopra il database di uno studio di nutrizione attivo da oltre dieci anni, senza perdere una riga della sua storia clinica.
In breve
Uno studio di nutrizione lavorava da anni su una webapp legacy che faceva il minimo indispensabile: cartelle pazienti e misurazioni corporee. Tutto il resto viveva in parallelo su fogli Excel, PDF e telefonate: piani alimentari, foto, domande tra una visita e l’altra, monitoraggio della crescita nei pazienti pediatrici. Niente parlava con niente, e niente era pensato su come lavora davvero questo studio.
Ho ricostruito tutto come un sistema unico, tenendo intatto il database legacy invece di ripartire da zero, e ho aggiunto quello di cui uno studio di nutrizione moderno ha davvero bisogno ogni giorno: percentili di crescita calcolati automaticamente sulle tabelle di riferimento ufficiali dell’OMS, un modello di dieta-e-pesate che regge anche quando un paziente ripete lo stesso piano cinque volte, un portale pazienti che si comporta come un’app invece che come un modulo, e un canale di richieste che sostituisce “l’ha mai richiamata?” con un registro che chiunque nello studio può controllare.
Niente di tutto questo è nato da un capitolato scritto all’inizio. È nato lavorando per fasi, ripercorrendo insieme a lei come funziona davvero una giornata nello studio, proponendo due o tre modi diversi di risolvere ogni pezzo, e lasciando che scegliesse o correggesse quello che non rispecchiava il suo modo di lavorare. Più di una volta la soluzione che le ho proposto per prima era quella generica, ovvia, e sbagliata per questo studio nello specifico. È davvero questa la forma di tutto il lavoro: quasi ogni decisione qui sotto è stata imposta da qualcosa che lei mi ha raccontato su come funziona lo studio, non da quello che un template generico di gestione pazienti darebbe per scontato.
Il punto di partenza
Lo studio aveva:
- Migliaia di cartelle pazienti, molte create anni prima che questo progetto iniziasse
- Decine di migliaia di misurazioni registrate: peso, altezza, e una serie completa di circonferenze corporee, incluse quelle bilaterali (polso, braccio, coscia, polpaccio destro e sinistro) usate per individuare asimmetrie
- Uno schema di database legacy precedente al progetto, con colonne di data chiamate
createdemodifiedinvece dei nomi standard del framework, e tabelle chiaramente estese pezzo dopo pezzo negli anni - Piani alimentari consegnati come PDF stampati, senza nessuna registrazione di chi avesse ricevuto quale versione e quando
- Anamnesi cliniche più vecchie, la storia pre-digitale dei pazienti storici, chiuse in singoli file Numbers, uno per paziente, mai entrate in nessun database
- Un telefono e un numero WhatsApp come unico canale per le domande dei pazienti, senza nessun modo per capire a colpo d’occhio chi fosse ancora in attesa di una risposta
Niente di insolito per uno studio attivo da un decennio che ha adottato strumenti software un pezzo alla volta invece che tutti insieme. Il problema non era che una singola parte fosse rotta. Era che nessuna parte si incastrava con le altre, e ogni spazio vuoto tra i pezzi era un foglio Excel, una telefonata, o qualcosa che la nutrizionista doveva ricordarsi da sola.
Perché ho tenuto lo schema legacy invece di ripartire da zero
La versione facile di questo progetto sarebbe stata uno schema nuovo, disegnato come lo disegnerei oggi. Non l’ho fatto, per un motivo solo: migliaia di pazienti e decine di migliaia di misurazioni erano già dentro una struttura funzionante, e ognuna di quelle righe rappresenta la storia clinica reale di una persona. Ridisegnare lo schema “come si deve” e migrare i dati dentro è esattamente il tipo di passaggio dove si perde o si fraintende silenziosamente qualcosa: una misurazione che non si mappa in modo pulito, una data che diventa ambigua, un campo di cui nessuno ricorda più il significato.
Quindi le tabelle legacy sono rimaste legacy: stessi nomi di colonna, stesse stranezze, gli stessi timestamp created/modified invece dei soliti created_at/updated_at del framework, imposti ovunque, incluse le nuove migration, così che nessuno scriva per sbaglio una query che restituisce silenziosamente zero risultati. Tutto quello che c’è sopra è nuovo. È un punto di partenza meno soddisfacente rispetto a una riscrittura pulita, ma è quello in cui i dati migrati sono dimostrabilmente gli stessi dati che esistevano prima, non una loro reinterpretazione.
La migrazione stessa ha dovuto girare a batch invece che riga per riga: inserire i pazienti uno alla volta avrebbe richiesto quasi un’ora, a batch quindici secondi. E doveva essere idempotente, perché un primo passaggio fa sempre emergere qualcosa che vuoi rilanciare. Le password degli account migrati sono rimaste in chiaro fino alla finestra del primo vero login di ogni paziente, perché hasharle tutte in anticipo costava diversi minuti senza nessun beneficio: nessuno stava ancora facendo login.
Il problema che nessuno aveva modellato: caselle di posta condivise
La prima vera correzione è arrivata presto, e da lei, non da un bug che ho trovato io. Migrando i dati legacy, avevo proposto la soluzione standard per record disordinati: rendere l’email univoca per paziente, come fa quasi ogni sistema di login. Lei ha bloccato la cosa prima che partisse. Un paziente pediatrico, un minore, non ha un proprio indirizzo email; lo studio registra quello del genitore per lui. Lo stesso indirizzo finisce legittimamente su più di una cartella: una per il genitore, una per il figlio, a volte più di un figlio. L’unicità avrebbe bloccato l’accesso a ogni famiglia con una casella condivisa, silenziosamente, alla creazione della cartella del secondo figlio.
Così abbiamo costruito insieme un modello diverso: è la casella di posta, non la cartella paziente, l’unità di autenticazione. Una password per casella, non per cartella. Se si crea una nuova cartella su una casella già registrata, la nuova cartella eredita la password esistente invece di generarne una nuova; una password nuova avrebbe bloccato fuori chiunque stesse già usando quella casella. Dopo il login, se una casella è collegata a più di una cartella, il paziente sceglie quale sta guardando per quella sessione.
È una distinzione piccola, “per casella” invece che “per cartella”, ma è il genere di cosa che, sbagliata, produce una chiamata di supporto che sembra “l’app è rotta” quando la storia vera è “il tuo sistema di login non sa cos’è una famiglia”. Lei l’ha intercettata perché ha a che fare con quelle famiglie ogni settimana; io non ci sarei arrivato senza chiederglielo.
Percentili di crescita, fatti come serve davvero a uno studio di nutrizione pediatrica
Per i pazienti under 19, peso e altezza da soli non dicono molto a una nutrizionista senza un percentile: dove si colloca questo bambino rispetto a una popolazione di riferimento per età e sesso. Quel riferimento deve essere uno standard clinico reale e pubblicato; non lo si può approssimare o stimare a occhio da un grafico appeso al muro.
Ho costruito questa parte sulle tabelle di riferimento ufficiali OMS 2007 (IMC per età e altezza per età, dai 5 ai 19 anni, curve separate per sesso), convertite dai dati pubblicati dall’OMS senza alterazioni, implementando il metodo LMS che l’OMS stessa specifica per trasformare una misurazione grezza in un percentile. Per verificare che la matematica fosse corretta, non “sembra corretta” ma effettivamente corretta, ho ricalcolato 1.344 valori di riferimento pubblicati dalle tabelle OMS e li ho confrontati con la mia implementazione. Errore massimo: sotto lo 0,02.
Due decisioni contano più della matematica in sé. Primo, l’IMC in ogni punto della storia di crescita di un paziente usa l’altezza registrata a quella specifica visita, non l’altezza attuale del paziente. Sembra ovvio detto così, ma il codice legacy che ho ereditato calcolava tutto su un’altezza fissa unica, cosa che avrebbe alterato silenziosamente il trend dell’IMC per ogni bambino in crescita nel sistema. Secondo, fuori dalla finestra 61-228 mesi coperta dalle curve OMS, o quando il sesso del paziente non è registrato, il sistema non mostra nulla invece di una stima. Per un dato clinico, nessuna risposta è una risposta migliore di una risposta sbagliata che sembra sicura.
Le diete non sono file, sono una sequenza di cicli
Il modello ingenuo per “assegnare una dieta” è: allegare un PDF alla cartella del paziente. Si rompe nel momento in cui un paziente ripete lo stesso piano, cosa che succede continuamente, dato che un piano è contenuto riutilizzabile e un’assegnazione è un tentativo specifico di seguirlo.
Il modello che ho costruito ha tre livelli: il piano (titolo, note, il PDF), l’assegnazione (questo piano, questo paziente, questo intervallo di date, questa ripetizione), e le pesate del paziente, che appartengono all’assegnazione, mai al piano. Riassegnare la stessa dieta chiude il ciclo corrente e ne apre uno nuovo con una propria storia di pesate, così due tentativi dello stesso piano chetogenico a distanza di sei mesi non finiscono mescolati in un unico grafico confuso.
Questa struttura a tre livelli ha retto fino a un caso che lei mi ha segnalato e che non copriva: a volte una dieta ha bisogno di una piccola correzione, uno scambio nella lista degli spuntini, e riassegnarla resetterebbe erroneamente i progressi del paziente insieme alla correzione. Le ho portato due opzioni: trattare ogni modifica come un nuovo ciclo e accettare il reset, oppure costruire una seconda azione, separata, per le correzioni, che lascia il ciclo intatto. Ha voluto la seconda, e sapeva subito spiegarmi perché: riavviare il ciclo avrebbe buttato via il numero di “giorno del piano” che usa per confrontare come sta andando un paziente questa volta rispetto alla volta scorsa, sulla stessa base di partenza. Quindi oggi esistono due azioni distinte: riassegna, un ciclo davvero nuovo, e sostituisci il PDF, che corregge il ciclo corrente sul posto senza toccare la storia delle pesate né quel conteggio dei giorni. Nemmeno la versione precedente di un PDF sostituito sparisce: resta a disposizione dello studio, perché documenta cosa stava seguendo davvero il paziente nei giorni in cui ha registrato quelle pesate, anche dopo che il testo del piano è cambiato.
I pazienti possono anche caricare foto opzionali legate a un ciclo dieta, il caso classico sono le foto delle strisce chetoniche per un piano chetogenico. Tenerle rigorosamente separate dalle misurazioni cliniche prese di persona è un’altra distinzione arrivata direttamente da lei, non da un modello dati a cui sarei arrivato da solo: una foto autoriportata da casa e una misurazione che lei ha certificato durante una visita non sono lo stesso tipo di evidenza clinica, e mescolarle sullo stesso grafico avrebbe confuso una linea che per lei conta nel leggere i progressi di un paziente.
Un canale di richieste che è davvero un canale
Prima, “fare una domanda veloce alla nutrizionista tra una visita e l’altra” voleva dire una telefonata o un messaggio WhatsApp che finiva sul telefono di una sola persona e da nessun’altra parte. Nessun registro, nessun modo per chiunque altro nello studio di vedere cosa fosse ancora in sospeso, nessun modo per distinguere una domanda davvero nuova da un seguito su qualcosa a cui era già stata data risposta.
Ho proposto per primo un widget di chat, la risposta veloce e familiare, e lei l’ha respinta deliberatamente. Una chat dal vivo implica che qualcuno la sta guardando in tempo reale; una professionista che lavora da sola tra un appuntamento e l’altro non lo è, e un canale che sembra live ma non viene presidiato in tempo reale erode la fiducia più in fretta di un canale onestamente più lento. Quello che abbiamo costruito invece è un sistema a ticket: ogni conversazione ha uno stato, governato da una sola regola calcolata in un unico posto. Chi ha scritto l’ultimo messaggio determina se la conversazione è “in attesa dello studio” o “in attesa del paziente”. Un messaggio del paziente su una conversazione che lo studio aveva chiuso la riapre automaticamente, perché una nuova domanda su una conversazione chiusa è pur sempre una domanda. Le richieste in sospeso stanno in cima alla dashboard dello studio, non nascoste in una scheda, perché un canale ufficiale a cui nessuno risponde visibilmente danneggia la fiducia più di non averlo affatto.
Una regola che ha richiesto vera disciplina per essere rispettata, ed è nata proprio da una conversazione su come le famiglie usano queste caselle di posta: il contenuto di un messaggio non finisce mai nella notifica email, anche se questo renderebbe la notifica più utile a colpo d’occhio. Sono domande legate alla salute, e la casella che riceve quella notifica potrebbe essere condivisa da un’intera famiglia. L’email dice “c’è qualcosa da leggere”, mai cosa.
La dashboard come torre di controllo per uno studio da una persona sola
Una professionista che lavora da sola non ha un team di reception che passa al setaccio le cartelle per capire chi ha smesso di farsi vivo. La dashboard deve farlo al posto suo: pazienti silenziosi da un po’ (non l’intero archivio pluriennale, ma una finestra di 12-18 mesi dall’ultima visita, perché “tutti quelli che non fanno una misurazione da oltre un anno” copriva quasi tutto l’archivio importato, che non è una lista di richiami, è l’intera storia dello studio), pazienti con una cartella ma senza nessuna misurazione, profili incompleti, e richieste ancora in attesa di risposta. Restringere “chi devo chiamare oggi” dall’intero archivio a una lista breve e davvero azionabile è il vero prodotto qui, non il grafico sotto.
Protezione dei dati che non si vede
I dati sanitari portano un peso diverso rispetto a quasi tutto il resto con cui lavora il software, e una parte consistente del lavoro tecnico è andata in un posto che una demo non mostra mai. I documenti clinici sono raggiungibili solo tramite un download autenticato, mai un URL indovinabile. Ogni modifica a un campo viene registrata con chi l’ha cambiato e da quale valore, tranne le note cliniche in testo libero, che vengono registrate come “testo di N caratteri modificato” invece di conservare il vecchio e il nuovo valore per intero: un diff del paragrafo di una clinica non è qualcosa che qualcuno legge, e tenersi il vecchio testo a tempo indeterminato è un rischio in sé. E ogni pagina di errore, ogni messaggio di validazione, è nella lingua dello studio invece che in uno stack trace, perché chi incontra un errore qui potrebbe essere un paziente alle prese con una domanda sulla propria salute, non uno sviluppatore.
Niente di tutto questo è visibile in una demo. È tutto ciò che fa la differenza tra un software su cui uno studio sanitario può davvero lavorare e un software che sembra solo finito.
Sapere cosa lasciare fuori è stata una scelta tanto quanto cosa costruire
Non tutte le domande aperte hanno avuto una risposta in questa fase, ed è stata una scelta deliberata, non un pezzo lasciato indietro per mancanza di tempo. L’anamnesi pre-digitale, anni di storia clinica che esistono solo come un file Numbers per paziente, è un caso che ho sollevato presto: avrei potuto immaginare un formato strutturato e costruire un importer. Ho proposto invece di aspettare. Deve ancora decidere lei, con i suoi tempi, come vuole che decenni di note cliniche in testo libero vengano riorganizzati: cosa serve davvero a una nutrizionista in una storia clinica strutturata non è qualcosa che dovrei decidere io guardando dei fogli Excel. Quindi oggi quei file sono semplicemente allegati a ogni cartella paziente, scaricabili e riapribili in Numbers esattamente come li ha lasciati, mentre la conversazione su come ristrutturarli davvero procede con i suoi tempi. Consegnare oggi la struttura sbagliata avrebbe significato disfarla più avanti, sopra a un decennio di record già esistenti; non consegnare ancora una struttura non costa nulla.
Lo stesso schema si è ripetuto, più in piccolo, per tutto il progetto: portavo due o tre modi di costruire una cosa, spiegavo cosa sarebbe costato ognuno nella pratica, non in termini tecnici, in termini di “questo cosa significa per il tuo martedì”, e più di una volta ha scelto quello che costava più lavoro a me e meno attrito a lei. È davvero questa la differenza tra costruire un sistema di gestione pazienti e costruire questo sistema.
Cosa fa oggi lo studio in modo diverso
- I percentili di crescita per i pazienti pediatrici si calcolano automaticamente sul riferimento OMS reale, invece di non esistere affatto
- I cicli dieta mantengono una propria storia di pesate, così un piano ripetuto non sovrascrive il record del tentativo precedente
- Le domande dei pazienti passano da un unico canale tracciato con uno stato visibile, non da un telefono che può controllare una sola persona
- La dashboard dice allo studio chi chiamare oggi, estratto da un archivio pluriennale di migliaia di pazienti
- I membri di una famiglia che condivide una casella di posta fanno login nel modo in cui la usano davvero, non nel modo in cui un modulo di login generico dà per scontato che la usino
- Un decennio di storia clinica pre-digitale non è andato perso: i file originali restano allegati e scaricabili mentre lo studio procede a digitalizzarli con i propri tempi
Quando questo tipo di collaborazione ha senso
Questo non era un template con il logo cambiato, e non era nemmeno me che lavoravo su un capitolato che mi aveva consegnato all’inizio. Sono stati mesi passati a sedersi insieme, ripercorrere come funziona davvero una giornata nello studio, proporre più di un modo per risolvere ogni pezzo, e farsi correggere quando la soluzione era quella generica invece di quella giusta per lei: email univoche, una chat dal vivo, il reset di un ciclo dieta per una modifica di una riga. Ognuna di quelle correzioni è arrivata da lei che gestisce davvero lo studio ogni giorno, non da qualcosa a cui sarei potuto arrivare da solo guardando i dati.
Se gestisci uno studio sanitario o clinico su un mosaico di un vecchio sistema, fogli Excel e telefonate, e sei oltre il punto in cui uno strumento più grande preso “chiavi in mano” aggiungerebbe solo un quarto pezzo da riconciliare, è di solito lì che questo tipo di progetto ha senso. Quello che serve da parte tua non è un capitolato già pronto. È il tempo di sedersi e ripercorrere il tuo martedì reale, più di una volta, e dirmi quando la risposta ovvia è quella sbagliata.
Una call breve per capire contesto, vincoli e cosa andremmo a costruire. Niente slide, niente sales script — solo una conversazione tecnica. Se c'è il fit andiamo avanti. Se non c'è, ti indico qualcuno con cui ci sia.
Scrivimi