Scenario · Web app su misura · Studio medico

Una segreteria che smette
di vivere al telefono.

Agende di più specialisti gestite a mano e mattine intere al telefono. Prenotazioni online semplici per i pazienti, promemoria automatici per ridurre gli appuntamenti mancati e dati sanitari al sicuro.

Tipo di progettoWeb app su misura
SettoreStudio medico
Tempi tipici9–12 settimane
●Scenario
web app · prenotazioni
Studio Medico
AGENDA ONLINE
Online
Cardiologia
Dermatologia
Ortopedia
Neurologia
LUN
MAR
MER
GIO
VEN
●
Prenotato
Libero
Urgenza
MER 12 GIU · 09:30
P
Paziente
Paziente dal 2022 · ECG urgente
Urgenza
30 min
Reminder automatici
SMS −24h ✓ Inviato
Email −48h ✓ Inviato
SMS −2h ○ In attesa
GESTISCI APPUNTAMENTO

Scenario web app — prenotazioni per studio medico

Un foglio Excel come
sistema di prenotazione

Lo scenario: uno studio medico con quattro specialisti, decine di appuntamenti a settimana e una segreteria che passa buona parte della giornata al telefono. L'agenda è tutta manuale: segreteria centralizzata, un foglio Excel condiviso su Google Drive e promemoria scritti a mano.

I problemi sono evidenti: i pazienti non trovano posto fuori dall'orario d'ufficio, i no-show sono tanti perché nessuno ricorda gli appuntamenti, e i referti si consegnano ancora a mano o per email sparse. Serve un sistema che lavori anche quando la segreteria è chiusa.

Vincolo tipico: il sistema deve collegarsi al gestionale medico già in uso tramite API, senza sostituirlo — lo studio non vuole cambiare un software interno già collaudato.

Cliente Studio medico privato, 4 specialisti (esempio)
Settore Sanità privata · Ambulatorio
Anno Durata tipica · 9–10 settimane
Stack principale
React 18 Node.js 20 PostgreSQL Twilio SMS Redis Stripe
Ruolo Full-stack developer · UX design

Prenotazione self-service 24/7

I pazienti devono poter prenotare in autonomia, scegliere specialista, data e ora — anche alle 23:00. Nessuna telefonata necessaria per slot standard.

Reminder SMS + Email automatici

Notifiche a −48 ore (email) e a −24 e −2 ore (SMS) con link per confermare o disdire. Ogni disdetta libera lo slot in tempo reale e invia una conferma al paziente.

Portale pazienti e referti digitali

Area riservata per ogni paziente: storico visite, possibilità di scaricare referti in PDF, visualizzazione prossimi appuntamenti e gestione dati personali (GDPR compliant).

Integrazione con il gestionale esistente

Sincronizzazione nei due sensi con il gestionale interno: le nuove prenotazioni entrano nel gestionale, le modifiche fatte dal medico si riflettono sul portale in tempo reale.

Pagamento anticipato selettivo

Alcune visite richiedono un acconto al momento della prenotazione (tramite Stripe) per ridurre i no-show. La segreteria deve poter attivare questa opzione per singola tipologia di visita.

Requisiti portale prenotazioni online

Quattro agende, zero conflitti,
un sistema che funziona da solo

Il settore medico ha vincoli precisi: privacy dei dati sanitari (GDPR), concorrenza sugli slot, promemoria che — se non arrivano — costano soldi veri allo studio. Ogni parte del sistema deve essere robusta per costruzione, non "fare del suo meglio".

01

Race condition sugli slot

Due pazienti che prenotano lo stesso slot nello stesso istante possono ricevere entrambi la conferma. Senza un blocco, le collisioni capitano — soprattutto nelle ore di punta, subito dopo l'invio dei promemoria.

02

Reminder affidabili al 100%

Un SMS non consegnato a −24 ore è una visita persa con lo slot vuoto. Le latenze dell'invio variano, e un server Node.js non può tenere i timer in memoria: se si riavvia, i promemoria si perdono.

03

Sincronizzazione con il gestionale medico

Spesso l'API del gestionale interno è REST ma documentata male e senza webhook. Le modifiche dei medici (spostamenti, cancellazioni urgenti) devono arrivare sul portale quasi in tempo reale senza una notifica dal gestionale.

04

Dati sanitari e GDPR art. 9

I dati medici rientrano nella categoria "dati particolari" del GDPR: consenso esplicito, diritto alla cancellazione, log degli accessi. Il sistema doveva essere privacy-by-design, non un afterthought.

05

UX accessibile e zero apprendimento

Tra i pazienti ci sono anziani poco abituati al digitale. La prenotazione deve completarsi in meno di 90 secondi, senza account obbligatorio al primo accesso, con accessibilità WCAG 2.1 AA.

Sfide tecniche agenda medica digitale

Lock ottimistico, coda di job
e un portale che lavora anche di notte

01 / 03

Prenotazione atomica con lock ottimistico su PostgreSQL

Per eliminare le prenotazioni doppie si usa un lock ottimistico: ogni slot ha una colonna version che cresce a ogni modifica. La prenotazione aggiorna lo slot solo se la versione è quella letta — se nel frattempo qualcuno ha prenotato, la transazione fallisce e si riprova in modo guidato. Niente blocchi reciproci e buone prestazioni sotto carico.

Lato server è un'unica transazione PostgreSQL: si legge lo slot, si verifica che sia libero, si aggiorna con WHERE version = $expected; se non viene aggiornata nessuna riga, si restituisce SlotConflictError e il client mostra un messaggio con gli slot liberi più vicini.

// Node.js · PostgreSQL · lock ottimistico su slot agenda async function bookSlot(slotId, patientId, paymentIntentId) { const client = await pool.connect(); try { await client.query('BEGIN'); // lettura slot con lock di riga const { rows } = await client.query( `SELECT id, version, status FROM slots WHERE id = $1 AND status = 'available' FOR UPDATE SKIP LOCKED`, [slotId] ); if (rows.length === 0) { await client.query('ROLLBACK'); throw new SlotConflictError('Slot non più disponibile'); } // prenotazione atomica await client.query( `UPDATE slots SET status='booked', patient_id=$1, payment_intent=$2, version=version+1 WHERE id=$3`, [patientId, paymentIntentId, slotId] ); // accoda i reminder nella job queue await scheduleReminders(client, slotId, patientId); await client.query('COMMIT'); } catch (err) { await client.query('ROLLBACK'); throw err; } finally { client.release(); } }

02 / 03

Job queue persistente per reminder affidabili

I promemoria non usano setTimeout ma job persistenti su BullMQ + Redis. Ogni prenotazione aggiunge 3 job con il ritardo giusto: −48 ore email, −24 ore SMS, −2 ore SMS. Se il server si riavvia, i job restano su Redis e partono al momento giusto. Il servizio SMS (es. Twilio) riceve la richiesta solo all'invio, con nuovo tentativo automatico se la rete fallisce.

La disdetta via SMS (il paziente risponde "DISDICI" all'SMS) attiva un webhook Twilio che cancella il job di conferma, libera lo slot in PostgreSQL e invia una notifica email allo studio — tutto senza intervento umano.

BullMQ Dashboard · Reminder Queue
REMINDER QUEUE
● 3 attivi esempio di coda
reminder:sms:−24h
Paziente A · slot 12/06 09:30
in 22h 14m
delayed
reminder:email:−48h
Paziente B · slot 13/06 11:00
in 46h 02m
delayed
reminder:sms:−2h
Paziente C · slot 11/06 14:00
completato 09:47
completed

03 / 03

Portale pazienti e sincronizzazione con il gestionale

Il portale pazienti è un'app React con accesso tramite link via email: nessuna password da ricordare, nessun ostacolo al primo accesso. Ogni paziente vede le visite passate, scarica i referti PDF caricati dal medico e gestisce le prenotazioni attive.

Se il gestionale non offre webhook, la sincronizzazione avviene con un processo che lo interroga ogni 60 secondi e confronta le agende con lo stato interno. Le modifiche trovate (spostamenti, cancellazioni, nuove disponibilità) si applicano al database e arrivano ai client React tramite Server-Sent Events — aggiornamento in tempo reale senza WebSocket, più semplice da gestire dietro un reverse proxy.

Processo di sviluppo di un'app di prenotazioni

9–10 settimane, tre attori,
un sistema che va da solo

Nel progetto ci sono tre figure: il primario (decide e conosce il dominio), la segreteria (usa l'agenda ogni giorno) e i pazienti (usano il portale). Le sessioni di osservazione in segreteria vengono prima di qualsiasi riga di codice: capire il flusso reale è più utile di qualsiasi documento di requisiti.

Settimana 1–2

Discovery e analisi del dominio

Osservazione del lavoro in segreteria, mappa dei tipi di visita e dei vincoli d'agenda per specialista, analisi dell'API del gestionale. Struttura dei dati e requisiti GDPR.

Output: schema DB, wireframe portale, piano GDPR

Settimana 3–4

Backend core: slot, lock e job queue

Modello dell'agenda su PostgreSQL, lock con FOR UPDATE SKIP LOCKED, BullMQ + Redis, primo invio dei promemoria SMS. Test di carico con decine di prenotazioni simultanee.

Output: API REST stabile, nessuna prenotazione doppia nei test

Settimana 5–6

Frontend portale pazienti e agenda

SPA React con magic link auth, flusso di prenotazione in 3 step (specialista → slot → conferma), area riservata con storico visite e download referti. Focus su accessibilità WCAG 2.1 AA e usabilità per utenti non tecnici.

Output: portale provato con alcuni pazienti reali

Settimana 7–8

Integrazione gestionale + Stripe + promemoria

Processo di sincronizzazione con il gestionale che individua le differenze, aggiornamenti nei due sensi, Server-Sent Events per il frontend. Stripe per gli acconti su alcune visite. Test completi della disdetta via SMS.

Output: catena dei promemoria testata con centinaia di job simulati

Settimana 9–10

UAT, GDPR audit e go-live progressivo

Sessioni con segreteria e primario, ritocchi di UX sulla gestione delle urgenze, verifica GDPR con il consulente legale dello studio. Messa online in 3 fasi: uno specialista → un secondo → tutti. Monitoraggio attivo nelle prime 72 ore.

Obiettivo: nessuna criticità nella prima settimana

Soluzione: lock ottimistico e reminder SMS

React + Node.js al centro.
Ogni scelta motivata.

React + TypeScript
Node.js + Express
PostgreSQL
Redis + BullMQ
Twilio SMS
Stripe Payments
Nodemailer + SES
AWS S3 (referti PDF)
Vite
Jest + Supertest
Zod (validazione)
date-fns (gestione orari)

Perché magic link e non password?

Tra i pazienti ci sono persone anziane o poco abituate al digitale. Una password vuol dire "ho dimenticato la password" come primo contatto con il portale. Il link via email — monouso, valido 15 minuti — elimina il problema: se hai accesso all'email, hai accesso al portale. Chi prenota per la prima volta non deve nemmeno registrarsi: i dati si raccolgono durante la prenotazione.

Perché SSE e non WebSocket?

I WebSocket richiedono un'infrastruttura dedicata (sessioni persistenti, supporto del proxy) che complica il rilascio su un hosting condiviso. I Server-Sent Events funzionano su HTTP normale, sono supportati da tutti i browser moderni e coprono il caso reale: aggiornamenti in un solo senso dal server al client (slot liberato, appuntamento spostato). Meno infrastruttura, stesso risultato.

Obiettivi di esempio — prenotazioni mediche

Più prenotazioni online.
La segreteria smette di essere un collo di bottiglia.

Numeri di esempio, non risultati di un cliente: obiettivi realistici per uno scenario come questo, da misurare nei mesi dopo il lancio rispetto allo stesso periodo precedente.

×4
Prenotazioni online
obiettivo di quota sul totale
−50%
Tasso no-show
obiettivo con i promemoria automatici
−60%
Chiamate in segreteria
solo urgenze e casi complessi
25%+
Prenotazioni fuori orario
dopo le 18 o nel weekend
4,5/5
Soddisfazione pazienti
obiettivo nel sondaggio dopo la visita
0
Doppi booking
obiettivo con il lock ottimistico

«Prima passavamo metà mattina al telefono per le prenotazioni. Ora gestiamo solo le cose che richiedono davvero la nostra attenzione.» È questo il risultato a cui puntare: una segreteria che fa il lavoro per cui è qualificata.

— L'obiettivo concreto del progetto

Obiettivi: più prenotazioni online

Cosa porto
in ogni progetto così.

→

Osservare prima di progettare vale doppio in ambito medico. Le sessioni in segreteria rivelano quasi sempre un flusso reale diverso da quello scritto nei requisiti. Il modo in cui un medico "sposta" gli slot, per esempio, raramente è documentato — e può rompere un'agenda digitale se non lo vedi di persona.

→

I promemoria si testano simulando il tempo, non aspettandolo. Con il time mocking nei test si fa avanzare l'orologio di 24 ore in pochi millisecondi e si verifica che il job parta. Test più veloci, copertura più alta.

→

L'accesso con link via email elimina quasi tutte le richieste di aiuto al primo accesso. Niente "come mi registro" e "ho perso la password". Per chi ha poca dimestichezza con il digitale, abbassare la barriera d'ingresso conta più di qualsiasi funzione avanzata.

→

Il GDPR sanitario va progettato nell'architettura, non aggiunto alla fine. Log degli accessi ai referti, consenso esplicito, tempi di conservazione e diritto alla cancellazione nella struttura del database costano un paio di giorni all'inizio. Aggiungerli dopo vuol dire riscrivere una parte del sistema.

→

Il lancio graduale per specialista protegge la reputazione del sistema. Partire con un solo specialista fa emergere i casi limite dell'agenda (visite di controllo con durata variabile, slot bloccati per riunioni interne) prima che colpiscano tutti i pazienti nelle prime ore critiche.

Hai un processo che si basa ancora su telefonate ed Excel?

Agende, prenotazioni, reminder automatici — se il flusso esiste già, si può digitalizzare senza stravolgere tutto.

Hai un progetto simile in mente?

Raccontamelo: partiamo da obiettivi e priorità, la prima call è gratuita.