Decisões

ADR 4 — Uma implementação por canal, não um motor parametrizado

decidido em 2024status em vigordomínio Comissionamentoligações 5

O problema

Cálculo de comissão para canais que remuneram de formas diferentes: varejo físico, e-commerce, atacado, pessoa jurídica e operação em outro país. Olhadas de longe, as regras são a mesma coisa: percentual sobre venda, ajustado por devolução, distribuído por hierarquia. De perto, divergem em tudo que importa — base de cálculo, momento de apuração, o que retroage, como o rateio trata equipe, o que acontece quando a venda é cancelada depois do fechamento.

E é cálculo com consequência dos dois lados: para menos, o vendedor reclama com razão; para mais, a empresa paga o que não devia. Precisa ser auditável, porque alguém vai perguntar por que aquele valor deu aquilo, meses depois.

Onde este caso difere de pagamentos

Esta é a parte da decisão que me deu trabalho, e é o que a torna interessante: eu tinha acabado de resolver um problema parecido do jeito oposto.

Em ADR 1 — Política de risco em dado, não em código eu tirei a política do código e coloquei em configuração, e funcionou. A tentação de repetir a receita era grande, e teria sido um erro.

A diferença é o que varia. Em pagamentos, o que varia é quais etapas de uma sequência conhecida se aplicam: um espaço fechado, descritível por indicadores. Em comissão, o que varia é a fórmula. Parametrizar sequência funciona. Parametrizar fórmula produz uma linguagem de programação mal disfarçada de configuração, e o resultado é o pior dos dois mundos: o negócio não consegue mexer porque virou programação, o desenvolvedor mexe com medo porque não parece código, e ninguém tem teste porque não é nem uma coisa nem outra.

Entender por que o padrão que eu mesmo tinha estabelecido não se aplicava aqui foi o ponto da decisão. Padrão bom aplicado no lugar errado faz mais estrago que ausência de padrão, porque vem com autoridade.

Por que herança também não

O caminho do meio seria uma classe base com pontos de extensão por canal: o esqueleto do algoritmo no pai, cada passo variando no filho. Descartei porque template method engessa a ordem.

Funciona enquanto todo canal segue a mesma sequência de passos. O primeiro canal que precisa inverter dois passos, ou pular um, vira uma briga com a classe base — e a saída usual dessa briga é um parâmetro de controle no pai, que é exatamente o motor parametrizado com passos extras.

A decisão

Cada canal tem seu cálculo, independente, legível de cima a baixo e testável isoladamente. O que é genuinamente comum é extraído para utilitário, não para hierarquia.

A duplicação que eu aceitei

É real e não tem disfarce. Corrigir um comportamento compartilhado exige aplicar em cinco lugares, com risco permanente de corrigir em quatro e esquecer o quinto. E não há um lugar único que responda “qual é a regra de comissão” — a resposta é sempre “de qual canal?”.

Aceitei porque a alternativa troca duplicação por acoplamento, e acoplamento em cálculo financeiro é mais caro: um cálculo genérico que atende cinco canais é um cálculo que ninguém altera sem regredir os outros quatro.

Como envelheceu

Bem, por uma razão que eu não tinha antecipado: rotatividade. O maior repositório da área passou por 29 autores diferentes ao longo do tempo, e código independente e legível sobreviveu a isso. Cada pessoa que chegou conseguiu alterar o canal de que precisava sem entender os outros quatro.

Um motor genérico com essa quantidade de mãos teria virado código intocável — daqueles que todo mundo contorna em vez de alterar. Eu não decidi pensando em rotatividade; foi ela que validou a decisão.

O que eu faria diferente

Extrair a base comum mais cedo. Rateio proporcional, tratamento de resíduo de arredondamento e trilha de apuração são genuinamente iguais entre canais, e ficaram duplicados por tempo demais porque eu apliquei “não generalizar” de forma larga demais. A regra que eu sigo hoje, extrair no terceiro caso e não antes, teria dado o ponto certo aqui.

Ver também

Comissionamento · ADR 1 — Política de risco em dado, não em código · Como eu trabalho

Pablo Mickael Quevedo Senior Software Engineer · autor principal de 32 sistemas · Novo Hamburgo, RS

5 notas ligadas a esta

A vizinhança desta estrela no céu do portfólio.

Explorar a galáxia →