Vai al contenuto
megapromotingParliamone

Competenza · Manutenzione

Manutenzione significa sapere che il modulo oggi consegna, non che il server risponde 200.

Monitoraggio che verifica il percorso completo di una richiesta fino a una persona, aggiornamenti con gate prima della produzione e una verifica di accettazione eseguita dopo ogni pubblicazione. Tutti e tre vengono eseguiti su questo sito e possono essere aperti dall’esterno.

Già costruitoTre implementazioni proprie, tutte nel repository di questo sito e tutte verificabili oggi: `src/app/api/health/contact/route.ts` (la sonda di consegna, risponde 200 in live proprio adesso), `src/lib/lead-store.ts` (il registro append-only con retention applicata in scrittura) e `scripts/verify-redesign.ts` (la verifica di accettazione eseguita dopo la pubblicazione). Le abbiamo scritte perché il 06.09.2026 il modulo proprio è caduto in silenzio: il token del bot era revocato, l’endpoint restituiva 500 e le richieste sparivano senza traccia. Non è una storia di vendita — è il commit che ha prodotto i file sopra.

«Il sito funziona» è un’affermazione sulla homepage. Un visitatore che ha compilato il modulo e ha ricevuto un errore non è stato fermato da una pagina caduta, ma da un canale di consegna scaduto in silenzio. La differenza tra le due cose è tutto ciò che significa manutenzione fatta seriamente: non seguiamo se il server risponde, ma se una richiesta da una persona arriva a un’altra persona.

Il 6 settembre 2026 è accaduto esattamente questo su questo sito. Il token del bot che portava le richieste del modulo al team era revocato; l’interfaccia Telegram rispondeva `401 Unauthorized`, la nostra route restituiva 500 e il visitatore vedeva «il messaggio non è stato inviato». La richiesta non veniva scritta da nessuna parte. Nel registro errori del processo c’erano tre fallimenti reali nelle circa sette ore trascorse dalla pubblicazione precedente. Nessuno guardava.

Da ciò sono usciti tre elementi che ora montiamo in ogni progetto che manteniamo. Un registro append-only scritto *prima* del tentativo di consegna, così che un canale guasto degradi in «dobbiamo guardare nel file» invece di «la richiesta non è mai esistita». Una sonda di salute che risponde a una sola richiesta se un lead può arrivare a una persona adesso. E una verifica di accettazione che viene eseguita dopo ogni pubblicazione e fallisce se è scomparso un indirizzo canonico, un’ancora di domande oppure se nella sitemap sono comparsi indirizzi che non si possono aprire.

Il resto è disciplina noiosa e verificabile: aggiornamenti con un gate di audit prima di toccare la produzione, riavvio automatico con soglia di memoria e limite di riavvii instabili, retention applicata dal codice, non dichiarata nella policy, e indirizzi IP troncati al prefisso di rete prima di essere scritti da qualche parte.

Cosa comprende

Il lavoro, per componenti

Sonda che verifica la consegna, non la disponibilità

`GET /api/health/contact` risponde 200 se un lead può arrivare a una persona adesso e 503 se no. Verifica due cose separatamente: che il token del canale di notifica sia ancora valido (una richiesta reale al fornitore, con timeout di 8 secondi) e che il registro delle richieste sia scrivibile. La risposta è composta solo da valori logici — mai il token, l’identificatore del canale o il nome del bot. Il risultato viene tenuto in memoria per 60 secondi, così una sonda esterna premuta spesso non diventi essa stessa traffico. Quando il fornitore è inaccessibile, il campo diventa `null`, non `false`: «non so» e «non valido» sono stati diversi.

Registro scritto prima della consegna, non dopo

Ogni richiesta riceve un identificatore e viene scritta in un registro append-only, una riga JSON per evento, *prima* di tentare la notifica. La seconda riga, con lo stesso identificatore, dice cosa è realmente successo: `delivered` o `failed`, con il motivo troncato a 300 caratteri. La directory viene creata con permessi `0700`, i file con `0600`, e il percorso viene posto deliberatamente al di fuori della directory di versione, così che la cronologia sopravviva a una pubblicazione.

Verifica di accettazione eseguita dopo la pubblicazione

Uno script di verifica apre ogni pagina di prodotto, in gruppi di tre, e fallisce se manca il codice 200, l’ancora delle domande, l’ancora dell’esempio o l’indirizzo canonico. Verifica poi la mappa del sito — che non contenga varianti di lingua che non si possono aprire e che contenga ogni prodotto — e `robots.txt`, che non blocchi le risorse necessarie al rendering. Fallisce anche se nella pagina riappare contenuto di un vecchio cliente. È un elenco di cose che si sono già rotte una volta.

Aggiornamenti con gate, non con speranza

Lo script di pubblicazione rifiuta di avviarsi se il server ha meno di 500 MB di memoria libera, esegue `npm audit --audit-level=high` e si ferma alle vulnerabilità di livello alto se non conferma esplicitamente, poi costruisce da pulito — `.next` e `node_modules` eliminati, installazione dal file di lock. Se il processo non appare `online` dopo l’avvio, lo script mostra le ultime 50 righe di log ed esce con errore, invece di segnalare successo.

Riavvio con soglie, non a caso

Il processo si riavvia automaticamente oltre 500 MB di memoria, con un ritardo di 4 secondi tra i tentativi, aumento esponenziale del ritardo e arresto dopo 10 riavvii instabili — così un ciclo di crash diventa visibile invece di consumare il server in silenzio. Tempo di grazia allo spegnimento: 5 secondi, poi terminazione forzata. I log hanno data e fuso orario, in un unico flusso.

Duplicati trattati, non contati due volte

La stessa persona, lo stesso messaggio, due volte — un doppio clic, un ricaricamento della pagina — produceva due notifiche identiche per una sola richiesta. Ora l’impronta `sha256` della coppia indirizzo + messaggio viene tenuta 10 minuti in memoria; il secondo invio riceve lo stesso identificatore di richiesta e il contrassegno `duplicate`, e la notifica non si ripete. Si sopprimono solo i duplicati di una consegna riuscita; una fallita può passare di nuovo.

Codici di errore che dicono cosa si è rotto

400 per dati non validi, 405 sul metodo sbagliato, 500 per corpo della richiesta corrotto, 502 quando il canale di consegna ha risposto male, 503 quando le credenziali mancano. La differenza conta alle 3 di notte: 502 significa «fornitore», 503 significa «la nostra configurazione». Al visitatore si dice distintamente «abbiamo ricevuto la richiesta, ma non siamo riusciti a notificare» — non un falso successo.

Ritenzione applicata dal codice, non promessa nella policy

La nota di riservatezza pubblicata dice che le richieste del modulo si conservano 24 mesi. Il codice applica esattamente lo stesso numero: `LEAD_RETENTION_DAYS` predefinito 730, e i file più vecchi della soglia vengono eliminati a ogni scrittura, senza uno scheduler che può essere dimenticato. L’indirizzo IP viene troncato al prefisso di rete — `/24` su IPv4, `/48` su IPv6 — e si legge l’ultimo hop dall’intestazione, non il primo, perché il primo è inviato dal client.

Troviamo anche ciò che nessuno ha segnalato

Lo stesso passaggio nel codice ha messo in luce due cose che nessun utente aveva segnalato: il limite di 10 richieste al minuto si poteva aggirare completamente, perché si leggeva il primo elemento dall’intestazione degli indirizzi reindirizzati — quello controllato dal client — e una rotta di inizializzazione delle chiamate telefoniche era aperta in forma anonima, a nostro costo e dal nostro numero, anche se il componente che la usava non era più montato da nessuna parte. Entrambe corrette e verificate in produzione.

Come si presenta

Il percorso, passo dopo passo.

01

L’inventario dei percorsi attraverso cui una richiesta arriva a una persona

La prima consegna non è uno strumento, è un elenco: attraverso cosa passa una richiesta dalla pressione del pulsante fino a qualcuno che la legge, cosa si rompe a ogni passaggio e cosa dovrebbe accadere quando si rompe. Sul sito questo elenco aveva tre anelli e uno era invisibile.

02

La sonda e il log, montati prima di ogni altra cosa

Forniamo un indirizzo di salute che verifica il percorso completo, non il processo, e il log che scrive prima della consegna. Da qui in avanti, un crash è una domanda con risposta, non uno scavo nei log. L’indirizzo può essere interrogato da qualsiasi servizio esterno di monitoraggio, perché non restituisce nulla di sensibile.

03

La verifica di accettazione, scritta da difetti reali

Ogni cosa che si è rotta una volta entra nello script di verifica eseguito dopo la pubblicazione. Non scriviamo test per casi ipotetici; scriviamo per quelli che ci sono già costati. Consegniamo lo script, non solo il suo risultato — puoi eseguirlo anche tu.

04

Il ritmo di aggiornamento e il gate prima della produzione

Stabiliamo cosa si aggiorna automaticamente, cosa passa attraverso una verifica umana e cosa non si tocca senza una finestra annunciata. Il gate include l’audit di sicurezza delle dipendenze e la verifica delle risorse del server, entrambi eseguiti prima di toccare la produzione.

05

La consegna, con l’elenco delle mancanze

Alla fine consegniamo la procedura di pubblicazione, la procedura di ritorno, gli indirizzi di health e l’elenco scritto di ciò che non è coperto. In questo sito, per esempio, il ramo di scadenza della richiesta verso il fornitore è implementato e cade nello stesso trattamento dell’errore di rete, ma l’abort in sé non è stato provocato nel test — è scritto così nel log di esecuzione, non in una nota interna.

1La sonda che verificala consegna fino a unom2jurnalul scrisprima del tentativo3verificarea deaccettazione eseguita dopofiecare publicareTre pezzi, tutti nel deposito di questo sito.
Il percorso, in 3 passi

I dati

Cosa tocchiamo, dove risiedono e quanto rimangono

Le domande che pone chiunque abbia un responsabile della protezione dei dati — poste qui prima che le ponga lui.

Registro delle richieste
Nome, indirizzo e-mail, telefono, azienda, servizio scelto, messaggio, pagina da cui è stato inviato, host della pagina di provenienza (solo l’host, non l’indirizzo completo) e prefisso di rete del visitatore. File JSON al giorno, sul server proprio, fuori dalla directory di versione. Termine: 24 mesi, applicato alla scrittura.
Log di processo e del server
L’output standard e gli errori del processo, con data e fuso orario, più i log del server web. Qui si vede una caduta silenziosa: i tre fallimenti di consegna dell’incidente di riferimento erano nel log degli errori, non in qualche allerta. La rotazione e il termine si stabiliscono per ciascun server; sono dati tecnici, non contenuto di account.
Ciò che non esce mai dal server
I token, gli identificatori di canale e le chiavi del fornitore. La sonda di health risponde esclusivamente con valori booleani, proprio per poter essere richiamata da uno strumento esterno senza divulgare nulla. La stessa regola nella notifica: il messaggio contiene l’identificatore della richiesta e la pagina, non credenziali.
Statistiche di traffico
La misurazione del traffico passa attraverso lo strumento di analisi configurato sul progetto e si attiva dopo il consenso. L’impostazione reale di retention nell’account di analisi è un valore che leggiamo dall’account, non uno che presumiamo — il registro dei trattamenti di questo sito lo ha segnato esplicitamente come elemento da chiarire, non come fatto stabilito.
Registro dei trattamenti
Ogni tipo di dati toccato dal sito ha una voce con finalità, base giuridica, categorie e termine, in un documento versionato accanto al codice. Quando il codice modifica un termine, il documento cambia nello stesso commit — altrimenti la policy e il programma dicono cose diverse, e quello che sbaglia è di solito il documento.

Un caso

Un modulo che ha inviato 500 invece di lead, sette ore

La situazione

Un sito vetrina con modulo di contatto, pubblicato di recente. Tutte le pagine rispondono 200, la dashboard è verde, nessuno segnala nulla. L’unico canale attraverso cui una richiesta arrivava al team era una notifica in un’app di messaggistica.

Cosa abbiamo costruito

Il token del bot di notifica era stato revocato; l’interfaccia del fornitore rispondeva `401 Unauthorized`. La route del modulo restituiva 500 e non scriveva nulla. La prima correzione non è stata il token, ma l’ordine delle operazioni: la richiesta si scrive ora in un log append-only, con identificatore proprio, *prima* di tentare la consegna, e il risultato della consegna si aggiunge come seconda riga. Sopra questo sono stati montati una sonda pubblica di health che verifica il token e la possibilità di scrittura, codici di errore distinti per «il fornitore ha risposto male» e «mancano le credenziali», un timeout di 10 secondi sulla consegna e la soppressione dei duplicati su una finestra di 10 minuti. Lo stesso passaggio nel codice ha eliminato anche un limite di richieste aggirabile e una route di chiamate telefoniche rimasta aperta in modo anonimo.

Cosa è emerso

La sonda risponde ora 200 con token valido e log scrivibile; può essere interrogata da qualsiasi servizio esterno di monitoraggio, senza divulgare nulla. I test in produzione hanno coperto ogni codice di risposta — 400, 405, 500, 502, 503 — e due invii identici hanno restituito lo stesso identificatore di richiesta, il secondo marcato come duplicato, con due righe nel log, non quattro. Un futuro guasto del canale di notifica non cancella più la richiesta: resta nel log, con il motivo scritto.

Cosa non dice il caso

La sonda dice che la consegna è possibile ora, non che qualcuno legga le notifiche. Chi le legge e in quanto tempo è una decisione del team, non una funzione del codice. E il ramo di scadenza della richiesta verso il fornitore, sebbene implementato, non è stato provocato nel test — cade nello stesso trattamento dell’errore di rete, che è stato testato; lo annotiamo come non esercitato, non come verificato.

Domande

Cosa ci chiedono le persone prima di chiamare

Che cosa monitorizzate, concretamente?

Il percorso di una richiesta fino a una persona, non la disponibilità del server. `GET /api/health/contact` verifica in una sola richiesta due cose: che il token del canale di notifica sia ancora valido — tramite una chiamata reale al fornitore, con timeout di 8 secondi — e che il registro delle richieste possa essere scritto. Risponde 200 quando entrambe sono vere e 503 quando non lo sono. Può chiamarla subito su questo sito: è pubblica, proprio perché non restituisce altro che valori logici.

Perché un modulo cadrebbe senza che nessuno se ne accorga?

Perché la parte visibile continua a funzionare. La pagina si carica, il pulsante risponde, il server restituisce 200 su tutte le pagine — si rompe solo l’ultimo anello, che non ha interfaccia. Su questo sito il token del bot di notifica è stato revocato: il fornitore rispondeva `401 Unauthorized`, la route restituiva 500 e la richiesta non veniva scritta da nessuna parte. Tre guasti reali in circa sette ore, visibili solo nel registro errori del processo. Per questo ora il registro viene scritto prima della consegna: anche se la notifica fallisce, la richiesta esiste.

Cosa succede se la notifica fallisce dopo che avete riparato?

La richiesta è già scritta nel registro con un proprio identificatore, e la seconda riga del registro dice `failed` e il motivo. Al visitatore viene data una risposta distinta — „abbiamo ricevuto la richiesta, ma non siamo riusciti a notificare” — non un falso successo. Il codice di risposta distingue la causa: 502 significa che il fornitore ha risposto male, 503 che mancano le credenziali da noi. Alle 3 del mattino, la differenza tra i due decide se chiamare qualcuno o no.

Aggiornate automaticamente le dipendenze?

Non senza gate. La pubblicazione esegue `npm audit` al livello `high` e si ferma alle vulnerabilità di questo livello se non viene confermata esplicitamente la continuazione; verifica prima anche la memoria disponibile del server, con soglia di 500 MB, perché una build avviata su un server stretto lascia l’applicazione bloccata. La build parte da zero: la directory di build e le dipendenze vengono cancellate, l’installazione avviene dal file di lock. Cosa si aggiorna automaticamente e cosa passa attraverso la verifica umana viene stabilito per progetto, non per impostazione predefinita.

Come sapete che una pubblicazione non ha rotto qualcos’altro?

Tramite uno script di verifica eseguito dopo la pubblicazione, che apre ogni pagina di prodotto e fallisce se mancano il codice 200, l’ancora delle domande, l’ancora dell’esempio o l’indirizzo canonico. Verifica poi la sitemap — che contenga ogni prodotto e non contenga varianti di lingua che non si possono aprire — e `robots.txt`, per non bloccare le risorse di rendering. Ogni verifica dell’elenco corrisponde a qualcosa che si è già rotto una volta. Lo script viene consegnato insieme al progetto.

Cosa fate quando l’applicazione si blocca o consuma memoria?

Il processo viene riavviato automaticamente oltre la soglia di 500 MB, con 4 secondi di ritardo tra i tentativi e crescita esponenziale, ma si arresta dopo 10 riavvii instabili in un intervallo breve. Questo è importante: un ciclo di crash che si riavvia all’infinito appare sano in una dashboard e consuma il server in silenzio. Preferiamo che il processo resti fermo e visibile.

Per quanto tempo conservate i dati del modulo e chi può leggerli?

24 mesi, applicati dal codice, non solo dichiarati: la soglia è una variabile con valore predefinito di 730 giorni, e i file più vecchi vengono eliminati a ogni nuova scrittura, senza uno scheduler che può essere dimenticato. La directory ha permessi `0700`, i file `0600`, e il percorso sta fuori dalla directory di versione, così la cronologia sopravvive alla pubblicazione. L’indirizzo IP non viene conservato per intero: viene troncato a `/24` per IPv4 e `/48` per IPv6, leggendo l’ultimo hop dall’intestazione, non il primo — il primo è inviato dal client e non significa nulla.

Trovate anche problemi che non abbiamo segnalato?

Succede, e di solito quelli sono i più costosi. Lo stesso passaggio nel codice che ha riparato il modulo ha evidenziato due cose che nessuno aveva segnalato: il limite di richieste si poteva aggirare completamente, perché si leggeva il primo elemento dall’intestazione degli indirizzi reindirizzati — esattamente quello inviato dal client; e una route che avviava chiamate telefoniche era aperta in forma anonima, a nostre spese, sebbene il componente che la usava fosse stato smontato. Entrambe sono state riparate e verificate in produzione. Quello che non possiamo promettere è di trovare tutto; quello che possiamo promettere è che segnaliamo anche ciò che non avete chiesto.

Cosa non copre la manutenzione?

Non è un servizio di sicurezza con monitoraggio 24 ore su 24 e non è un centro operativo. Non garantiamo una percentuale di disponibilità senza una misurazione che la sostenga — e, per essere chiari, al momento non pubblichiamo una tale cifra per il sito proprio. Non assumiamo la responsabilità di una piattaforma terza a cui non abbiamo accesso. E non trattiamo una pagina che risponde 200 come prova che tutto funzioni: esattamente questo è stato il problema da cui è partito tutto ciò che è scritto sopra.

Su cosa si basano le affermazioni sopra (13 fonti)
  1. La sonda di delivery risponde 200 in produzione: `{"ok":true,"telegram":{"configured":true,"credentialsValid":true},"leadJournal":{"writable":true}}`https://www.megapromoting.com/api/health/contact · 2026-09-06
  2. Header di sicurezza attivi in produzione: HSTS `max-age=63072000; includeSubDomains; preload`, `X-Content-Type-Options: nosniff`, `X-Frame-Options: SAMEORIGIN`, `Referrer-Policy: strict-origin-when-cross-origin`, `Permissions-Policy` con `microphone=(self)`https://www.megapromoting.com/servicii · 2026-09-06

11 di esse sono codice e file dei nostri repository. Non ne pubblichiamo il nome né la riga: insieme, in un'unica pagina, descriverebbero con troppa precisione come sono costruiti sistemi che non sono solo nostri. Le esaminiamo con te, nel repository, su richiesta — la verifica resta possibile, solo che avviene in una discussione.

Cosa vorresti che funzionasse meglio?

Raccontaci il tuo processo. Insieme stabiliamo cosa vale la pena costruire, cosa possiamo collegare e come verifichiamo il risultato.

Parliamone