Contesto
Un operatore di ricarica per veicoli elettrici gestisce una rete di colonnine pubbliche e serve sia clienti privati sia dealer. Ogni ricarica mette insieme tre pezzi che devono restare allineati: l'app di chi ricarica, la colonnina fisica in strada e il pagamento.
Problema
Le colonnine parlano OCPP 1.6 su WebSocket, un protocollo asincrono e con stato che un'applicazione web tradizionale non regge. Servivano avvii e stop remoti affidabili, letture di energia in tempo reale e un pagamento che si chiude solo quando la sessione finisce davvero. Se il collegamento cade a metà ricarica, il cliente resta con una pre-autorizzazione aperta e l'operatore senza i dati di consumo.
Cosa ho costruito
Due servizi separati, ognuno con il suo compito. Un microservizio in TypeScript tiene aperte le connessioni con le colonnine e gestisce lo stato delle sessioni, l'idempotenza dei comandi e i timeout: un comando senza risposta non viene riemesso alla cieca. Un backend Laravel copre clienti e piani tariffari, prenotazioni con pre-autorizzazione Stripe, coupon, fatturazione e la dashboard dell'operatore con stato delle colonnine, consumi ed esportazioni. Ho gestito i fusi orari in modo esplicito, salvando tutto in orario universale e convertendo solo in presentazione, perché le sessioni attraversano il cambio d'ora.
Risultato
In produzione ed evoluzione continua da oltre due anni: le colonnine restano connesse, gli avvii e gli stop si fanno da remoto e il pagamento si chiude solo quando la sessione finisce davvero.