Documentando fluxos de usuário na sua arquitetura de software
O relatório de bug parecia simples: "O checkout falha de forma intermitente."
Tínhamos diagramas de arquitetura lindos. Diagramas C4 mostrando cada serviço, cada banco de dados, cada integração. Mas quando tentamos rastrear a jornada de um usuário de "adicionar ao carrinho" até "pedido confirmado", ninguém conseguia concordar sobre a sequência exata. Quais serviços estavam envolvidos? Em que ordem? Onde acontecia a verificação de estoque: antes ou depois do pagamento?
Três engenheiros tinham três modelos mentais diferentes. Nossos diagramas de arquitetura estáticos mostravam a estrutura, mas não o comportamento. Víamos as caixas e as setas, mas não como um usuário realmente se movia pelo sistema.
Foi aí que percebi que precisávamos de fluxos de usuário.
O que os fluxos de usuário realmente são
Um fluxo de usuário documenta a jornada que um usuário faz pelo seu sistema para cumprir um objetivo. Não a estrutura estática (para isso servem os diagramas C4), mas a sequência dinâmica, que o próprio C4 desenha como um diagrama dinâmico:
- O usuário faz X
- O sistema responde com Y
- O usuário escolhe Z
- E assim por diante...
Parece óbvio, mas é surpreendentemente raro encontrá-los bem documentados. A maioria das equipes tem diagramas de arquitetura (a estrutura do sistema) e documentação de API (os detalhes dos endpoints), mas nada no meio que mostre como essas peças funcionam juntas do ponto de vista do usuário. Agora você pode descrever uma jornada e receber um rascunho do fluxo.
A lacuna entre estrutura e comportamento
Aqui está uma versão simplificada do nosso diagrama de containers C4 na época:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Web App │────▶│ API │────▶│ Database │
└─────────────┘ └──────┬──────┘ └─────────────┘
│
┌──────▼──────┐
│ Payment │
│ Service │
└──────┬──────┘
│
┌──────▼──────┐
│ Stripe │
└─────────────┘
Ele diz que os componentes existem e como se conectam. Mas não responde: quando um usuário faz o checkout, o que acontece primeiro? A API valida o estoque antes de chamar o pagamento? O que acontece se o pagamento é aprovado, mas o item deixou de estar disponível?
Essas perguntas exigem entender o fluxo, não só a estrutura.
Anatomia de um fluxo de usuário útil
Com o tempo, desenvolvi um template que funciona bem para documentar fluxos:
1. Declaração do objetivo
Comece pelo que o usuário está tentando fazer:
Objetivo: concluir a compra dos itens do carrinho
Isso mantém o fluxo focado. Se você se pegar documentando vários objetivos, divida em vários fluxos.
2. Pré-condições
O que precisa ser verdade antes de o fluxo começar?
- O usuário está logado
- O carrinho tem pelo menos um item
- Os itens do carrinho estão em estoque (no carregamento da página)
Isso evita confusão sobre o estado inicial e deixa as premissas claras.
3. O caminho feliz
Documente primeiro o caminho de sucesso esperado:
1. O usuário clica no botão "Checkout"
→ A Web App mostra o formulário de endereço de entrega
2. O usuário informa o endereço de entrega e clica em "Continuar"
→ A API valida o formato do endereço
→ A API calcula as opções de frete
→ A Web App mostra a seleção do método de envio
3. O usuário escolhe o método de envio e clica em "Continuar"
→ A API valida o método de envio
→ A Web App mostra o formulário de pagamento
4. O usuário informa os dados de pagamento e clica em "Finalizar pedido"
→ A API cria um pedido pendente no banco de dados
→ A API chama o Payment Service com os detalhes do pedido
→ O Payment Service chama a Stripe para cobrar o cartão
→ O Payment Service devolve sucesso para a API
→ A API marca o pedido como confirmado
→ A API dispara o e-mail de confirmação
→ A Web App mostra a página de confirmação do pedido
5. O usuário vê a confirmação com o número do pedido
Repare em algumas coisas:
- Cada passo inclui o que o usuário faz E como o sistema responde
- Especificamos quais componentes tratam cada ação
- O nível de detalhe basta para entender o fluxo sem ler o código
4. Caminhos de erro e casos extremos
O caminho feliz é só o começo. O valor de verdade vem de documentar o que acontece quando as coisas dão errado:
Pagamento recusado:
No passo 4, se a Stripe retornar payment_declined:
→ O Payment Service retorna um erro para a API
→ A API NÃO marca o pedido como confirmado
→ A API apaga o pedido pendente
→ A Web App mostra a mensagem "Pagamento recusado"
→ O usuário pode tentar de novo com outro meio de pagamento
Estoque alterado:
No passo 4, antes de criar o pedido pendente:
→ A API verifica de novo a disponibilidade do estoque
→ Se o item deixou de estar disponível:
→ A API retorna inventory_error
→ A Web App mostra "Item não está mais disponível" com um link para o carrinho
→ O usuário precisa remover o item e recomeçar o checkout
Timeout de rede:
No passo 4, se o Payment Service não responder em 30 segundos:
→ A API NÃO tenta de novo (para evitar cobrança dupla)
→ A API retorna timeout_error
→ A Web App mostra "Confira seu e-mail para verificar o status do pedido"
→ Um job em segundo plano verifica o status do pagamento depois de 5 minutos
→ Se o pagamento foi aprovado: marca o pedido como confirmado, envia o e-mail
→ Se o pagamento falhou: remove o pedido pendente
É nesses caminhos de erro que os bugs se escondem. E é também neles que a maior parte da documentação para, e é por isso que os bugs se escondem ali.
5. Notas técnicas
Acrescente qualquer contexto técnico relevante:
Notas técnicas:
- A verificação de estoque e o pagamento NÃO são atômicos. Uma race condition
é possível, mas aceitável dada a baixa probabilidade e o processo de resolução manual.
- O webhook da Stripe fornece uma confirmação de reserva se a resposta da API se perder.
- Pedidos pendentes com mais de 1 hora são removidos por um job agendado.
Ligando os fluxos à arquitetura
É aqui que fica poderoso: vincular os fluxos de usuário aos seus diagramas C4.
No Archyl, podemos anotar quais componentes participam de cada passo de um fluxo. Isso cria rastreabilidade nos dois sentidos:
- Olhando um fluxo? Veja quais componentes ele toca.
- Olhando um componente? Veja quais fluxos passam por ele.
Quando aquele bug do checkout apareceu, poderíamos ter:
- Aberto o fluxo de checkout
- Visto exatamente quais serviços estavam envolvidos
- Rastreado até o passo específico que falhava
- Entendido o tratamento de erro naquele ponto
Em vez disso, passamos dois dias redescobrindo como o nosso próprio sistema funcionava.
Tipos diferentes de fluxo
Nem todos os fluxos são iguais. Nós os classificamos assim:
Fluxos de usuário
Sequências iniciadas pelo usuário a partir da interface:
- Fluxo de checkout
- Fluxo de cadastro
- Fluxo de redefinição de senha
- Fluxo de atualização de perfil
Começam com uma ação do usuário e terminam com um resultado visível.
Fluxos de sistema
Sequências iniciadas pela máquina:
- Job noturno de reconciliação
- Processamento de webhooks
- Cascatas orientadas a eventos
- Notificações agendadas
São igualmente importantes, mas costumam ser menos documentados porque não há interface para ver.
Fluxos de integração
Sequências entre sistemas:
- Importação de pedidos de terceiros
- Lotes de liquidação de pagamentos
- Sincronização de dados com parceiros
Normalmente envolvem sistemas fora do seu controle e têm mais formas possíveis de falhar.
Como documentamos fluxos hoje
Depois daquele fiasco de debug no checkout, estabelecemos um processo:
Toda funcionalidade importante ganha um fluxo
Quando construímos uma funcionalidade nova, documentamos o fluxo antes de escrever o código. Ele serve como documento de design e continua como documentação.
O formato é markdown simples:
# Funcionalidade: avaliações de usuários
## Objetivo
O usuário envia uma avaliação de um produto que comprou
## Pré-condições
- O usuário está logado
- O usuário comprou o produto
- O produto aceita avaliações
## Fluxo
1. O usuário clica em "Escrever avaliação" na página do produto
...
## Tratamento de erros
...
## Componentes envolvidos
- Web App
- API Gateway
- Review Service
- Product Service
- Notification Service
## ADRs relacionados
- ADR-0023: estratégia de moderação de avaliações
Revisão de fluxos nos PRs
Se um PR altera um fluxo documentado, exigimos que a documentação do fluxo seja atualizada. Os templates de PR incluem: "Esta mudança altera algum fluxo de usuário? Se sim, atualize a documentação dos fluxos."
Auditoria trimestral de fluxos
A cada trimestre, percorremos os fluxos críticos em equipe:
- Abrimos a documentação do fluxo
- Comparamos com o código e o sistema reais
- Identificamos as discrepâncias
- Atualizamos a documentação ou corrigimos os bugs
Parece trabalho extra, mas já pegou problemas reais. Duas vezes descobrimos que mudanças no código tinham quebrado um comportamento documentado sem que ninguém percebesse.
Erros comuns
Erro 1: detalhe demais
Um documento de fluxo não deveria parecer código. Se você está documentando consultas individuais ao banco de dados, está no nível errado. Foque nos passos visíveis para o usuário e nas interações no nível dos serviços.
Erro 2: documentar só os caminhos felizes
O caminho feliz é fácil. Os bugs moram nos caminhos de erro. Obrigue-se a responder: "O que acontece se este passo falhar?"
Erro 3: não atualizar depois das mudanças
Um fluxo documentado que não bate com a realidade é pior do que nenhuma documentação. Ele cria uma falsa confiança e leva a premissas erradas durante o debug.
Erro 4: tratar os fluxos como estáticos
Fluxos de usuário evoluem. Funcionalidades novas acrescentam passos. Otimizações removem passos. Testes A/B mudam o comportamento. Trate os fluxos como documentos vivos, não como artefatos feitos uma única vez.
Ferramentas e formatos
Você não precisa de ferramentas especiais para documentar fluxos. Markdown no seu repositório funciona muito bem. O que importa é consistência e facilidade de encontrar.
Dito isso, diagramas de fluxo visuais podem ajudar em sequências complexas. Ferramentas como o Mermaid permitem escrever diagramas como código:
sequenceDiagram
participant U as User
participant W as Web App
participant A as API
participant P as Payment Service
participant S as Stripe
U->>W: Click "Place Order"
W->>A: POST /orders
A->>A: Create pending order
A->>P: Process payment
P->>S: Charge card
S-->>P: Success
P-->>A: Payment confirmed
A->>A: Mark order confirmed
A-->>W: Order details
W-->>U: Confirmation page
A chave é o controle de versão. Diagramas de fluxo no Figma ou no Lucidchart tendem a se afastar da realidade porque estão desconectados do processo de desenvolvimento.
Conclusão
Diagramas de arquitetura estáticos dizem do que o seu sistema é feito. Fluxos de usuário dizem como ele se comporta. Você precisa dos dois.
Da próxima vez que estiver depurando um problema complexo que atravessa vários serviços, pergunte-se: "Temos um fluxo documentado para isso?" Se a resposta for não, você vai passar horas reconstruindo como as peças se encaixam, horas que um documento simples teria poupado.
Comece pelo seu fluxo mais crítico. Na maioria dos sistemas, provavelmente é a autenticação ou o caminho de conversão principal (checkout, cadastro, ação central). Documente o caminho feliz e depois obrigue-se a documentar pelo menos três casos de erro.
O seu eu do futuro, depurando desesperado às 2 da manhã, vai agradecer.
Mais sobre documentação de arquitetura: Guia do modelo C4 | Architecture Decision Records | Por que a documentação importa