Quick note: un bug in produzione che costava 200 euro al giorno — articolo

> Quick note: un bug in produzione che costava 200 euro al giorno

Quick note su come un errore silenzioso nel calcolo sconti di un e-commerce e rimasto nascosto per settimane.

Luigi Iadicola
~5 min lettura
#Case Study #Debugging #Business
Quick note: un bug in produzione che costava 200 euro al giorno
Quick note: un bug in produzione che costava 200 euro al giorno

Il bug invisibile: quando il codice funziona ma il business perde soldi

Questo case study riguarda uno dei bug piu insidiosi che ho incontrato nella mia carriera di sviluppatore PHP freelance: un errore che non generava nessun messaggio di errore, nessun log, nessun crash. Il codice funzionava perfettamente dal punto di vista tecnico. Ma dal punto di vista del business, stava bruciando 200 euro al giorno senza che nessuno se ne accorgesse.

Il cliente era un e-commerce con circa 200 ordini al giorno, costruito in PHP con un codebase legacy di 5 anni. Mi ha contattato per un audit generale del codice, non per un problema specifico. Il bug e emerso durante l analisi, non perche qualcuno lo avesse segnalato.

Come funzionava il sistema di sconti

L e-commerce aveva due meccanismi di sconto indipendenti: sconti di categoria (percentuali automatiche su determinati prodotti) e coupon promozionali (codici sconto fissi o percentuali inseriti dal cliente al checkout). Entrambi i sistemi funzionavano correttamente se usati singolarmente. Il problema emergeva quando un cliente applicava un coupon su un prodotto che aveva gia uno sconto di categoria.

Il codice problematico

Il flusso era questo: il sistema calcolava il prezzo finale applicando lo sconto di categoria (es. -20%). Poi, nel checkout, il sistema applicava il coupon sul prezzo originale, non sul prezzo gia scontato. Il risultato: su un prodotto da 100 euro con sconto categoria del 20% e coupon da 10 euro, il cliente pagava 70 euro invece di 80 euro. Lo sconto doppio non era intenzionale — era un bug nella sequenza di applicazione degli sconti.

Il codice legacy calcolava lo sconto percentuale in un metodo e poi, in un metodo completamente separato richiamato piu avanti nel flusso, applicava il coupon fisso sul prezzo base recuperato dal database invece che dal carrello aggiornato. I due metodi non comunicavano e non c era nessun controllo sulla sovrapposizione.

Perche il bug e rimasto nascosto per 3 settimane

Ci sono tre ragioni per cui questo bug e sfuggito ai controlli:

  • Nessun errore tecnico: il codice funzionava correttamente da un punto di vista logico. PHP non aveva nulla da segnalare perche le operazioni erano tutte valide
  • I test coprivano solo i casi singoli: c erano test per "sconto categoria applicato correttamente" e test per "coupon applicato correttamente", ma nessun test per "sconto categoria + coupon applicati contemporaneamente". I casi combinati non erano coperti
  • Nessun monitoraggio dei margini: il team controllava il fatturato totale (che era stabile) ma non il margine per ordine. Il margine stava erodendosi silenziosamente su circa 15 ordini al giorno

Come l ho scoperto

Durante l audit ho scritto una query di controllo sui margini per categoria di prodotto, confrontando il prezzo atteso (con gli sconti configurati) con il prezzo effettivamente pagato. La query ha evidenziato una discrepanza sistematica su una categoria specifica: il margine medio era del 12% invece del 25% atteso. Ho tracciato la differenza fino al calcolo degli sconti e ho riprodotto il bug in meno di un ora.

Il fix e la prevenzione

Il fix tecnico e stato semplice: ho modificato il metodo di applicazione del coupon per leggere il prezzo dal carrello aggiornato (dopo lo sconto categoria) invece che dal database. Ho aggiunto un controllo esplicito che verifica se il prezzo nel carrello e gia stato scontato e impedisce l applicazione cumulativa non autorizzata. Il fix ha richiesto 2 ore di lavoro, inclusi i test.

Test aggiunti

Ho aggiunto 4 test specifici per le combinazioni di sconti:

  • Sconto categoria + coupon percentuale: verifica che il coupon si applichi sul prezzo gia scontato
  • Sconto categoria + coupon fisso: verifica che il totale non scenda sotto il prezzo scontato meno il coupon
  • Coupon su prodotto senza sconto: verifica il comportamento standard
  • Doppio coupon (tentativo di applicare due codici): verifica che il sistema lo impedisca

Monitoraggio aggiunto

Ho suggerito al cliente di implementare un alert automatico sui margini: se il margine medio di una categoria scende sotto una soglia configurata per piu di 24 ore, il sistema invia una notifica. Questo tipo di monitoraggio avrebbe scoperto il bug nel primo giorno, non dopo 3 settimane.

L impatto economico

Il bug ha causato una perdita stimata di circa 200 euro al giorno per 3 settimane, per un totale di circa 4.200 euro. Questa cifra avrebbe pagato un mese intero di consulenza tecnica con audit completo del codice. Il costo del fix (2 ore di lavoro) e stato irrisorio rispetto al danno accumulato.

Le lezioni che applico in ogni progetto

  • I bug piu costosi sono quelli che non generano errori visibili: un eccezione in produzione viene notata subito. Un calcolo sbagliato che produce un numero plausibile puo restare nascosto per mesi
  • Monitorare i dati di business, non solo i log tecnici: uptime al 100% non significa che il sistema funziona correttamente. I KPI di business (margini, conversion rate, valore medio ordine) sono indicatori altrettanto importanti
  • Testare le combinazioni, non solo i casi base: i bug piu insidiosi emergono dall interazione tra funzionalita che funzionano perfettamente in isolamento. I test di integrazione e i test sui casi limite non sono un lusso
  • Un audit periodico del codice critico si ripaga sempre: il codice che gestisce soldi, sconti, prezzi e pagamenti merita una revisione regolare. Il costo dell audit e sempre inferiore al costo dei bug non scoperti
  • Il codice legacy non e un problema finche non lo diventa: sistemi che funzionano da anni possono nascondere bug introdotti da modifiche successive che non hanno considerato tutte le interazioni

Fix applicato in 2 ore. Il danno accumulato in 3 settimane avrebbe pagato un mese di consulenza tecnica. La prossima volta che qualcuno dice "funziona tutto, non serve un audit", ricordate questo caso.

altri articoli