Diagrama de estados: duas regras e um saldo negativo
Duas regras certas de um CRM de cobrança, juntas, deixavam um título com saldo negativo em cobrança. O diagrama de estados achou o erro antes do código.

Neste artigo
Um diagrama de estados lista as situações em que uma entidade pode estar e as transições permitidas entre elas, cada uma ligada à regra que a autoriza. Neste CRM de cobrança, escrever esse diagrama para o título mostrou um erro que estava nas especificações aprovadas e que nenhum critério de aceite cobria: um título podia ficar em cobrança com saldo negativo. Duas regras, cada uma correta, produziam o erro quando agiam sobre o mesmo título; a correção, especificada no incremento 5, separa o valor do título do saldo.
As duas regras certas#
A especificação da carteira diz que, quando o credor manda o mesmo título com outro valor, o sistema atualiza o valor e registra a mudança. A especificação dos pagamentos, contada na parte sobre baixa de títulos, diz que o pagamento abate o título e que o saldo é o valor menos o que foi pago.
Cada uma tem os seus critérios de aceite, e cada critério tem o seu teste. O problema aparece quando as duas acontecem, nessa ordem, com o mesmo título:
| Momento | Valor | Pago | Saldo | Situação |
|---|---|---|---|---|
| Título importado | R$ 1.000,00 | R$ 0,00 | R$ 1.000,00 | em cobrança |
| Pagamento parcial | R$ 1.000,00 | R$ 400,00 | R$ 600,00 | em cobrança |
| Carga com valor corrigido | R$ 300,00 | R$ 400,00 | −R$ 100,00 | em cobrança |
O valor anterior se perde, porque foi sobrescrito. O título continua na lista, nas faixas de atraso e nos totais do painel, agora com valor negativo, abatendo a carteira de outros devedores.
Por que os testes não pegariam#
Os testes de aceitação deste projeto, descritos na parte sobre testes automatizados, nascem dos critérios da especificação: um critério, um teste. Os critérios da carteira falam de cargas; os dos pagamentos, de pagamentos. Nenhum critério combinava uma carga que reduz o valor com um pagamento anterior, porque nenhuma das duas especificações olhava para a outra.
Uma demonstração com dados fictícios também não mostraria o erro, a menos que os dados reduzissem valores depois de pagamentos. O erro apareceria com o primeiro credor real que mandasse uma correção de valor depois de uma baixa parcial.
Como o diagrama achou#
Depois de quatro incrementos, a mudança de método da parte 11 passou a exigir um documento de domínio com os estados de cada entidade e as transições entre eles, escrito a partir das especificações e conferido regra por regra. Para o título, a forma escolhida foi uma tabela, mais fácil de conferir regra por regra do que um desenho:
| De | Para | Evento | Regra |
|---|---|---|---|
| ativo | ativo | Carga muda valor, vencimento, contrato ou descrição | carteira |
| ativo | ativo | Pagamento parcial (saldo cai) | pagamentos |
| ativo | pago | Pagamento quita o saldo | pagamentos |
| pago | ativo | Estorno reabre o saldo | pagamentos |
Junto da tabela vêm as invariantes, condições que valem em qualquer estado. Uma delas diz que o saldo nunca é negativo. Na conferência, a primeira linha da tabela violava essa invariante, porque “carga muda o valor” não tinha nenhuma condição sobre o que já tinha sido pago. A conferência achou mais duas lacunas da mesma família:
| # | Lacuna | Exemplo |
|---|---|---|
| L1 | Carga reduz o valor de um título com baixa parcial abaixo do pago | R$ 1.000,00 com R$ 400,00 pagos; carga traz R$ 300,00 → saldo −R$ 100,00, em cobrança |
| L2 | Título retirado e pago volta numa carga com valor igual ao pago | Volta “em cobrança” com saldo zero |
| L3 | Título pago muda de valor no sistema do credor | Continua pago e a diferença some depois da conferência |
As regras de carga e de pagamento estavam em documentos diferentes; na tabela do título, ficaram uma embaixo da outra, e a combinação “título com pagamento + carga que muda o valor” não tinha linha.
A decisão: separar valor e saldo#
As opções apresentadas eram variações de “o que fazer com o saldo negativo”. A decisão foi mudar o modelo do título:
Precisamos separar valor do título de saldo do título para evitar cair nessas ciladas. Saberíamos o valor do título, saberíamos que ele mudou, saberíamos calcular o saldo, saberíamos se restou crédito. E isso não pode ser volátil. Além disso, o credor pode definir o comportamento da sua operação.
A especificação do incremento 5 transforma essa decisão em regras:
- Valor em versões. O valor informado pelo credor nunca é sobrescrito: cada mudança cria uma versão, com a carga, a data e quem confirmou.
- Saldo calculado e nunca negativo. O saldo sai das versões e dos pagamentos. O que passa do valor vira excedente, mostrado como crédito do devedor e recalculado sozinho se o valor voltar a subir ou se houver estorno.
- Divergência registrada. Toda mudança de valor num título com pagamento gera um registro que a conferência mostra antes de confirmar a carga e que o financeiro trata com nota.
- Política do credor. O credor escolhe entre seguir o valor novo (padrão: no exemplo, o título passa a pago com R$ 100,00 de excedente) e manter o valor antigo, só registrando.
- Título pago não muda por carga. A diferença fica só no registro; só um estorno tira um título de pago.
O que o detalhe achou que o alto nível não dizia#
A solução já estava aprovada em alto nível. Ao escrever o detalhe, com valores em cada exemplo, apareceram quatro perguntas que o alto nível deixava sem resposta:
- A política “manter” não tinha saída. Se o valor antigo sempre prevalece, um título com pagamento nunca mais muda de valor, nem quando o credor confirma o desconto. A decisão: ao tratar a divergência, o financeiro pode aplicar o valor informado.
- O excedente entra no total de créditos? Sim, como crédito calculado, com motivo próprio.
- Onde o financeiro vê as divergências. Numa página própria, com o número de abertas no menu.
- Os dados já gravados. Se algum título já estiver com saldo negativo quando a revisão entrar, ele é tratado pela política padrão e gera uma divergência para o financeiro. Sem essa regra, a revisão começaria com dados que violam a própria invariante.
As quatro ficaram como recomendado. Houve também uma escolha de recorte: três regras da carteira revista dependem dos encargos (multa, juros, correção), que só chegam numa etapa posterior. A estrutura do saldo já nasce separada por componente, mas os componentes de encargos ficam em zero até lá, para o modelo do saldo não ser migrado duas vezes.
Em números#
| Item | Quantidade |
|---|---|
| Lacunas de estado achadas ao conferir o diagrama | 3 |
| Critérios de aceite que combinavam as duas regras | 0 |
| Regras novas na especificação do incremento 5 | 18 |
| Critérios de aceite | 12 |
| Perguntas que só apareceram no detalhe | 4 |
O que vem a seguir#
O incremento 5 foi implementado com versões de valor, saldo calculado, a página de divergências para o financeiro e o histórico de cada título. Com 200 mil linhas e 20 mil divergências, a conferência da carga levou 37,7 segundos e a confirmação, 24,4. A implementação teve as suas falhas:
- Uma variável reaproveitada. Ao ler as colunas de acréscimos, o código reusou o nome da variável que guardava o valor do título, e toda carga passou a gravar o valor vazio. A suíte inteira da carteira caiu, e a causa só apareceu depurando a confirmação num teste à parte.
- Uma medição que não media. A primeira medição marcava como pagos títulos que não eram os que mudavam de valor na carga. Deu zero divergências e tempos bons que não valiam nada. A escolha dos títulos foi refeita.
- O estorno que apagava a data. Depois de o título pago poder continuar pago num estorno que só consome excedente, o comando que desfazia o pagamento apagava a data de pagamento de todo título que tocava. Um teste com um estorno de R$ 60,00 passou a cobrir o caso.
- Uma aproximação assumida. O excedente sai do recuperado no mês do último pagamento do título. Se ele nascer de vários pagamentos em meses diferentes, a atribuição não é exata. Está registrada no plano técnico.
A recriação diária da demonstração gera algumas divergências fictícias, para a página ter o que mostrar. O incremento seguinte trata dos cadastros do credor e do devedor, que saíram da mesma etapa por decisão de recorte.


