Un’automazione può arrivare a un punto in cui non deve proseguire senza una decisione, un dato o una verifica. Per esempio, potrebbe aver bisogno di un’approvazione prima di confermare un’operazione sensibile oppure dover attendere informazioni che solo una persona può fornire. In questi casi, il sistema deve conservare uno stato recuperabile e spiegare cosa manca, non limitarsi a interrompere l’esecuzione corrente.
Progettare come mettere in pausa e riprendere un’automazione in PHP implica separare lo stato del processo dall’esecuzione del lavoro. La pausa deve essere intenzionale, persistente e sottoposta ad audit; la ripresa deve controllare che il processo sia ancora valido e che gli effetti già applicati non vengano ripetuti. Questo è diverso dal progettare una coda di revisione: qui l’attenzione è sul ciclo di vita del flusso e sulla sua ripresa sicura.
Distingui una pausa da un’attesa o da un errore

Non tutti i processi che non avanzano sono in pausa. Una chiamata a un’API che non ha ancora risposto è un’attesa esterna. Un errore di rete può giustificare un nuovo tentativo. Un’eccezione non recuperabile può terminare il processo come fallito. Una pausa deliberata, invece, significa che il flusso ha raggiunto un limite noto e richiede una condizione esplicita per proseguire o terminare.
Usare uno stato diverso per ogni situazione evita decisioni operative errate. Riprovare un’azione in attesa di approvazione può ripetere una richiesta inutile; trattare una pausa legittima come un errore può attivare avvisi o policy di ripristino non appropriate. Definisci almeno stati distinti per esecuzione, attesa esterna, intervento richiesto, completato, annullato e fallito. Aggiungi una scadenza se il business richiede che una pausa perda validità dopo un certo periodo.
Prima di introdurre una pausa, definisci cosa la provoca e chi può risolverla. Un’attività in sospeso che si completa automaticamente quando arriva una risposta non richiede sempre un intervento umano. Una decisione con implicazioni economiche, legali, di accesso o di sicurezza può invece richiedere un intervento umano. Questa distinzione determina chi può agire, quali evidenze conservare e cosa succede se nessuno risponde.
Persisti lo stato e il punto di ripresa
Il processo deve sopravvivere alla fine della richiesta PHP, al riavvio di un worker e a una nuova versione del servizio. Salva in un archivio persistente un identificatore stabile, lo stato corrente, il passaggio raggiunto, il motivo della pausa, i riferimenti ai dati necessari e i timestamp rilevanti. Registra anche chi ha messo in pausa o risolto il processo, se opportuno, e la decisione presa.
Evita di salvare solo un messaggio come «in attesa di approvazione». Non identifica quale esecuzione è ferma, quale passaggio deve riprendere né se i dati sono cambiati. Rappresenta invece la pausa come parte del modello del processo, con un contesto sufficiente per convalidare la ripresa. Ove possibile, conserva i riferimenti alle informazioni sensibili invece di duplicare dati senza necessità; applica controlli di accesso e criteri di conservazione adeguati alla loro natura.
Definisci le transizioni consentite e verificale sul server. Per esempio, un processo nello stato di intervento richiesto può passare a esecuzione, annullato o scaduto; un processo completato non dovrebbe tornare in esecuzione tramite una normale richiesta. Una funzione PHP può convalidare la transizione, ma la regola deve essere protetta anche dalla concorrenza nel database, non solo nell’interfaccia.
Separa la registrazione del processo dall’esecuzione
Registrare che il processo deve proseguire ed eseguire i suoi passaggi sono operazioni correlate, ma non identiche. Se lo stato viene aggiornato e il processo termina prima di avviare il lavoro, il flusso può rimanere bloccato. Se il lavoro viene avviato prima di salvare la transizione, un nuovo tentativo può eseguire lo stesso passaggio. Progetta il coordinamento in modo che lo stato persistente permetta di recuperare il lavoro in sospeso.
Una soluzione comune consiste nel salvare la transizione e un’istruzione di ripresa nella stessa transazione del database, per esempio tramite un pattern transactional outbox. Un worker separato legge l’istruzione ed esegue il passaggio successivo. La scelta specifica dipende dall’architettura; l’importante è che il sistema possa rilevare il lavoro non consumato e recuperarlo, invece di fare affidamento sul fatto che una richiesta web rimanga attiva.
Gli effetti esterni richiedono ulteriore attenzione. Una transazione locale non può annullare da sola un’e-mail inviata, un addebito confermato o una chiamata già accettata da un altro servizio. Progetta ogni passaggio con una chiave di idempotenza, quando il sistema di destinazione lo consente, registra il risultato prima di procedere e prevedi una riconciliazione o una compensazione quando un’operazione non può essere ripetuta in sicurezza. Non contrassegnare un passaggio come completato prima di conoscerne l’esito.
Gestisci la ripresa, l’annullamento e la scadenza
L’azione di ripresa deve verificare lo stato corrente, l’identità e i permessi di chi richiede l’operazione e il soddisfacimento delle condizioni necessarie. Non basta mostrare un pulsante a una persona autorizzata: al ricevimento della richiesta, il server deve convalidare nuovamente tutto. Se la decisione richiede una motivazione o un dato aggiuntivo, convalida e conserva queste informazioni come parte della risoluzione.
Tratta anche l’annullamento e la scadenza come transizioni esplicite, non come eliminazione del record. L’annullamento deve impedire l’avvio di nuovi passaggi e chiarire se esistono effetti precedenti che non possono essere annullati. La scadenza deve definire cosa succede dopo: terminare il processo, richiedere un nuovo intervento o indirizzare il caso verso un’altra azione. Il comportamento dipende dalla regola di business e deve essere visibile al team operativo.
Le richieste ripetute e le race condition sono normali: una persona può fare doppio clic o due attori possono agire quasi contemporaneamente. Usa un aggiornamento condizionale, un lock o un controllo di versione, in modo che prevalga una sola transizione valida. Una seconda richiesta deve ricevere una risposta coerente con lo stato corrente, senza eseguire nuovamente gli effetti. Salva un identificatore dell’operazione o una chiave di idempotenza per riconoscere le ripetizioni.
Rendi la pausa comprensibile e verificabile
La vista operativa deve spiegare perché il processo è fermo, quale passaggio è in sospeso, quali informazioni mancano, chi può agire e quali conseguenze ha ciascuna opzione. Evita pulsanti ambigui o azioni che combinano approvazione, correzione dei dati e ripresa. Mostra solo le informazioni necessarie per decidere, limitando l’accesso in base al ruolo. Uno storico delle transizioni consente di distinguere un’attesa legittima da un processo bloccato o configurato male.
Prova il flusso con interruzioni prima e dopo ogni effetto esterno. Verifica che un riavvio non faccia perdere la pausa, che una ripresa ripetuta non duplichi le azioni e che un annullamento impedisca i passaggi successivi. Includi casi di dati modificati durante l’interruzione, permessi revocati, scadenza, risposte tardive e due richieste simultanee. Controlla anche i log e gli avvisi: devono consentire di individuare il processo e capire il passaggio successivo senza esporre segreti.
Checklist per decidere il comportamento

- Attendere: è in corso una risposta esterna e il sistema può proseguire automaticamente quando arriva, con limiti temporali e procedure di ripristino definiti.
- Mettere in pausa per un intervento: prima di eseguire i passaggi successivi serve una decisione esplicita o un dato fornito da una persona.
- Riprovare: si è verificato un errore transitorio e ripetere il passaggio è sicuro o protetto tramite idempotenza.
- Terminare: non esiste una ripresa valida oppure il processo è stato completato, annullato, è scaduto o è fallito in modo definitivo.
Prima di distribuire il flusso, verifica che ogni transizione sia autorizzata, che lo stato persista, che gli effetti precedenti non vengano ripetuti e che il team sappia come risolvere la pausa. Se non puoi rispondere a cosa verrà ripreso, con quali dati e a quali condizioni, il processo non dispone ancora di un punto di ripresa sicuro.



