Operation flow

Escopo: transversal. Aplica-se a qualquer linguagem ou stack do projeto.

Uma operação (criar um recurso, processar um formulário, buscar dados) segue sempre o mesmo ciclo: recebe input (entrada), transforma, executa, retorna output (saída). Operation flow é a estrutura que torna esse ciclo explícito: cada passo tem uma responsabilidade, um tipo de entrada e um tipo de saída.

O resultado é um fluxo legível de ponta a ponta, onde falhas têm caminho explícito e a fronteira entre lógica pura e I/O (Input/Output, Entrada/Saída) é visível na estrutura.

Conceitos fundamentais

ConceitoO que é
Input (entrada)Dados recebidos por uma operação
Output (saída)Dados produzidos por uma operação
Result<T>Tipo que representa explicitamente sucesso ou falha de uma operação, tornando os dois caminhos visíveis na assinatura
CQS (Command-Query Separation, Separação de Comando e Consulta)Escrita retorna void; leitura retorna dado. A mesma operação não faz os dois
Pipeline (sequência de processamento)Conjunto de etapas ordenadas de transformação de dados, cada uma com entrada e saída definidas
Caller (quem invoca a operação)Código que chama uma função ou serviço e é responsável por tratar os dois caminhos do resultado
I/O (Input/Output, entrada/saída)Operações que leem ou escrevem em sistemas externos: banco, rede, disco

Backend

Request
1. Sanitize          → normaliza input                                    (puro)
2. ValidateResult<T>      falha → erro de validação           (puro)
3. Business RulesResult<bool>   falha → não encontrado / conflito   (I/O)
4. Savevoid (CQS)                                        (I/O)
5. ReadResult<T>      falha → erro de servidor            (I/O)
6. Filter OutputResponseDTO                                        (puro)
Response

Os passos puros (1, 2, 6) ficam nas bordas, sem dependências externas, testáveis em isolamento. Os passos com I/O (3, 4, 5) ficam no meio. Save e Read são separados: CQS (Command-Query Separation, Separação de Comando e Consulta) significa que escrita não retorna dado e leitura não persiste.

Frontend

User Action / Mount
Component            → dispara hook
Hook                 → gerencia estado UI (data, error, isLoading)
Service              → chama apiClient, transforma Result<T> em View type  (puro: só a transformação)
apiClient            → único caller de rede, retorna Result<T>             (I/O)
HTTP Response

O apiClient é o único ponto de I/O; tudo acima dele é puro. O Service recebe Result<T> e entrega um tipo de view que o componente consome diretamente, sem lógica adicional.

Princípios compartilhados

Puro nas bordas, I/O no meio. Passos sem efeitos colaterais ficam nas extremidades do pipeline (sequência de processamento). São os mais fáceis de testar e de raciocinar. Passos com I/O ficam agrupados no centro.

Result como contrato. Operações que podem falhar por regra de negócio retornam Result<T>: sucesso e falha são valores explícitos na assinatura. O caller (quem invoca a operação) trata os dois caminhos. Exceções de infraestrutura, como timeout (tempo limite) e falha de rede, seguem o caminho normal de exceções.

CQS. Escrita (Save) retorna void. Leitura (Read) retorna dado. A mesma operação não faz os dois.


Implementações por stack

Veja também

Desenvolvido por @thiagocajadev · Fork baseado no repositório pmndrs/docs · Poimandres.