Automatizar uma operação nem sempre significa executá-la sem intervenção. Se uma ação puder alterar dados importantes, aplicar uma condição comercial, movimentar fundos ou afetar terceiros, talvez seja necessário aguardar a autorização de uma pessoa. Um fluxo de aprovação humana em automações PHP estabelece esse controle sem transformar o processo em uma cadeia informal de mensagens e decisões difíceis de reconstruir.
O segredo não é adicionar um botão de «aprovar», mas definir o que está sendo proposto, quem pode decidir, com base em quais informações, por quanto tempo e o que acontece depois. O sistema deve conseguir explicar cada estado e evitar que uma aprovação antiga ou duplicada execute uma ação diferente daquela que foi analisada.
Decidir quando pausar uma operação

Uma revisão posterior serve para detectar problemas depois que a ação acontece. Já uma aprovação prévia interrompe a execução até que uma decisão seja tomada. Convém exigir autorização quando o impacto potencial, a dificuldade de reverter a ação ou a incerteza ultrapassarem o nível aceito para a automação.
Avalie cada operação com perguntas concretas: ela pode alterar um dado difícil de recuperar? Afeta dinheiro, direitos, acesso ou compromissos com clientes? Existe uma regra verificável que permita executá-la de forma autônoma? Quanto dano um erro causaria e quanto tempo há para responder? Uma operação rotineira, reversível e limitada poderia ser executada automaticamente e registrada para revisão. Uma ação excepcional ou de alto impacto pode exigir autorização antes de ser executada.
Evite aplicar o controle humano a tudo por padrão. Uma fila sobrecarregada causa atrasos e incentiva aprovações mecânicas. Defina limites e exceções e monitore pendências, tempos de espera, rejeições e expirações para identificar regras que precisam de ajustes. A decisão deve se basear no risco real, não apenas no fato de uma operação ser tecnicamente possível.
Definir o que está sendo proposto e o que pode ser autorizado
A pessoa responsável pela revisão precisa entender o efeito da operação, não decifrar um objeto interno do PHP. Apresente o valor atual e o proposto, o motivo, a origem dos dados, as consequências relevantes e quaisquer limitações. Se a decisão depender de uma regra, mostre a explicação necessária para aplicá-la. Oculte ou proteja os dados pessoais que não forem necessários.
Separe o comando de proposta da autorização. A proposta descreve a ação e seus parâmetros; a autorização permite executar aquela proposta específica. Ela não deve conceder permissões gerais nem permitir que quem aprova edite os parâmetros silenciosamente. Se forem necessárias alterações, a pessoa revisora pode solicitá-las; o sistema cria uma proposta atualizada, que deverá passar pelas regras de autorização correspondentes.
Aplique o princípio do menor privilégio: restrinja quem pode criar, autorizar, rejeitar ou cancelar propostas e verifique essas permissões no servidor a cada transição. Quando o risco justificar, exija que quem propõe não possa autorizar a própria operação. Essa separação deve ser implementada na lógica de permissões, não depender apenas de ocultar botões na interface.
Modelar estados e transições explícitas
Represente o processo como uma máquina de estados. Um conjunto inicial útil pode incluir pending, approved, executing, rejected, changes_requested, expired, cancelled e executed. Uma proposta pendente pode ser aprovada, rejeitada, cancelada ou expirar; uma proposta aprovada só pode passar à execução se ainda estiver válida; uma proposta em execução pode terminar como executada ou voltar a um estado recuperável se for determinado que não houve efeito. Uma proposta executada não pode ser aprovada novamente.
Armazene o estado atual junto com um histórico imutável de decisões e transições. Registre o identificador da proposta, o estado anterior e o novo, o ator, a data e a hora, o motivo e a referência à versão dos dados analisados. Não substitua o histórico ao atualizar o registro: ele é necessário para auditar o que aconteceu e diagnosticar falhas.
No PHP, centralize as transições em um serviço de domínio ou componente equivalente. Evite que diferentes controladores alterem o estado diretamente por meio de atualizações genéricas. Valide a transição e as permissões dentro de uma transação, quando apropriado, e rejeite ações incompatíveis com o estado atual. Essa estrutura reduz erros de concorrência e facilita testar as regras sem depender da interface.
Evitar aprovações obsoletas e execuções duplicadas
Os dados podem mudar enquanto uma proposta aguarda. Uma pessoa não deve autorizar uma condição que já não corresponda à operação que será executada. Ao criar a proposta, armazene uma versão, uma data de atualização ou um hash dos campos relevantes. No momento da aprovação, verifique novamente se ela corresponde ao estado atual.
A verificação no momento da aprovação não é suficiente: os dados ainda podem mudar antes de a operação ser aplicada. Imediatamente antes da execução, compare novamente a versão ou o hash atual com o aprovado. Se houver divergência, interrompa o processo, invalide a autorização daquela proposta e solicite uma nova decisão sobre os dados atualizados. Dependendo do risco, você pode mostrar as diferenças e exigir uma confirmação explícita, mas não reutilize automaticamente a aprovação anterior.
Um prazo de validade limita por quanto tempo a decisão é considerada válida. Quando ele vencer, marque a proposta como expirada e exija uma nova autorização para continuar. Cada nova tentativa deve verificar se a autorização continua válida; nunca reutilize uma autorização expirada para retomar ou repetir a execução.
A aprovação deve se referir a uma proposta identificável e não ser um sinal reutilizável. Para evitar que dois workers concorrentes executem a mesma proposta, reserve ou bloqueie atomicamente sua transição de approved para executing: apenas um worker pode obtê-la se a proposta ainda estiver aprovada e válida. Nessa proteção local, verifique também a idempotência e registre o identificador único da execução da operação antes de continuar. Isso evita duplicações dentro do sistema, mas uma transação de banco de dados, por si só, não garante que uma API externa aplique um efeito apenas uma vez.
Se a ação ocorrer em outro serviço, use uma chave de idempotência que esse serviço aceite e processe de forma idempotente, se houver suporte. Registre o identificador de correlação, a tentativa e as respostas. Se a resposta for perdida ou o resultado for desconhecido, não repita o efeito às cegas: consulte o estado remoto por meio desse identificador ou reconcilie o resultado com dados confiáveis. Se não for possível confirmar se o efeito ocorreu, interrompa novas tentativas automáticas e escale o caso para uma pessoa responsável pela operação. Uma falha conhecida antes do envio da solicitação pode permitir uma nova tentativa, desde que o estado e a autorização sejam verificados novamente.
Se um worker falhar e deixar uma proposta em executing, não a marque automaticamente como executada nem a reenvie sem diagnóstico. Um processo de recuperação deve determinar se o efeito ocorreu, usando o registro local e, quando apropriado, consultando o serviço remoto. Se confirmar que não ocorreu, pode devolver a proposta a um estado executável somente após validar novamente a validade, os dados e a autorização; se o resultado continuar desconhecido, deve mantê-la bloqueada e escalá-la.
Projetar uma fila operacional e uma alternativa manual
A fila deve permitir localizar pendências por antiguidade, impacto, responsável e data de expiração, além de mostrar o contexto que fundamenta a decisão. Explique por que um caso está bloqueado e qual ação é adequada: aguardar, solicitar alterações, cancelar ou escalar. A interface também deve deixar claro o que acontecerá ao aprovar, em vez de apenas oferecer botões para decidir.
Defina uma alternativa para quando uma dependência falhar, como o serviço de notificações ou uma integração necessária para executar a ação. É possível manter a proposta pendente e fornecer um procedimento controlado para que uma pessoa autorizada analise o caso no sistema disponível para realizar a operação. O procedimento manual deve respeitar as mesmas verificações, registrar o ator e o motivo, evitar a execução paralela e reconciliar o resultado quando a integração for restabelecida.
Não transforme uma falha técnica em aprovação implícita. Se não for possível verificar a identidade, as permissões ou as informações necessárias, o sistema deve falhar de forma segura: pausar, informar e escalar. Defina quem pode desbloquear o processo, como essa intervenção será documentada e quais tarefas deverão ser revisadas quando o serviço for restabelecido.
Testar o fluxo e monitorar seu funcionamento

Teste as regras de domínio e os fluxos completos: aprovação, rejeição, solicitação de alterações, expiração, cancelamento e novas tentativas. Inclua testes de permissões para confirmar que uma pessoa sem autorização não consegue alterar o estado e testes de concorrência para garantir que duas decisões simultâneas não resultem em duas execuções.
Inclua casos em que os dados mudam durante a espera ou imediatamente antes da execução, a execução remota falha depois de aceitar a solicitação e uma resposta se perde mesmo que o efeito tenha ocorrido. Verifique se a reserva atômica permite que apenas um worker execute a proposta, se as novas tentativas rejeitam autorizações expiradas e se cada intervenção manual deixa um registro suficiente. Em produção, monitore o volume e a antiguidade das pendências, as expirações, os erros de execução e os casos que exigem reconciliação.
Um fluxo bem projetado mantém a supervisão humana onde ela oferece controle, sem deixar a segurança depender da memória das equipes. Estados explícitos, permissões separadas, dados analisados ainda válidos, execução idempotente e um caminho claro para lidar com falhas transformam uma aprovação informal em um processo verificável.



