Exemplo de especificação funcional: um CRM de cobrança
Especificação funcional real do primeiro incremento de um CRM de cobrança: regras com valores, critérios de aceite e cada decisão com alternativas.

Neste artigo
Uma especificação funcional diz o que o sistema faz, para quem e com que regras, sem dizer como ele é construído. Este artigo traz uma especificação real e completa: a do primeiro incremento do CRM de cobrança da série Criei um CRM, aprovada antes de qualquer linha de código. Ela tem 29 regras com exemplos, 26 critérios de aceite e 9 premissas registradas. A maior parte deste texto, porém, trata das decisões: as alternativas apresentadas, os prós e contras de cada uma e o que foi escolhido. É nelas que uma especificação ganha ou perde valor.
O incremento: a carteira chega por planilha#
O primeiro incremento resolve um problema concreto. O credor, uma escola ou uma clínica, por exemplo, tem os clientes em atraso numa planilha exportada do sistema de faturamento. Enquanto a lista fica ali, ninguém sabe ao certo quanto está vencido, há quanto tempo, com quem e quanto ainda vai vencer.
O objetivo é que o gestor envie a planilha e, em poucos segundos, veja a carteira organizada: quantos devedores, quanto está vencido e a vencer, em que faixa de atraso, e a ficha de cada devedor com seus contratos e títulos. O critério de sucesso também está escrito: uma planilha de 10 mil títulos fictícios entra sem intervenção manual, cada linha recusada aparece com o motivo, e os totais da tela batem com os da planilha.
O formato do arquivo faz parte da especificação: CSV separado por ponto e vírgula, que é o padrão do Excel em português, com números e datas no formato brasileiro. As colunas obrigatórias são documento, nome, título, vencimento e valor; telefone, e-mail, contrato e descrição são opcionais.
A estrutura da especificação#
O documento segue o modelo descrito em especificação de software: como fazer sem travar a empresa: problema e objetivo, quem usa, regras de negócio com exemplos, critérios de aceite, casos de exceção, fora do escopo, restrições e decisões. Duas seções foram acrescentadas por causa do objetivo da série:
- Premissas assumidas. O que foi dado como certo sem passar pela área que validaria, e o que acontece se estiver errado.
- Área que decidiria cada ponto numa empresa. Ao lado de cada decisão, quem a tomaria numa organização com jurídico, financeiro, operação, comercial e TI. Aqui, quem decide sou eu. Numa empresa, essa coluna mostra quem precisa estar na reunião.
Uma regra entrou no meio do caminho e virou regra do projeto: a especificação descreve comportamento, não infraestrutura. A primeira versão citava memória, contêiner e o servidor em que a demonstração iria rodar. Uma especificação assim fica presa a um ambiente e precisa ser reescrita quando o sistema muda de lugar. O desempenho continua na especificação, mas só como tempo percebido pelo usuário.
Regras escritas com valores#
Cada regra tem um exemplo concreto. É a diferença entre “o sistema valida o CPF” e uma regra que o desenvolvedor, humano ou IA, não consegue interpretar de dois jeitos. Algumas das 29:
| Regra | Exemplo |
|---|---|
| O devedor é identificado pelo documento sem máscara | 529.982.247-25 e 52998224725 são o mesmo devedor |
| CPF e CNPJ com dígito verificador válido, inclusive o CNPJ alfanumérico | 111.111.111-11 recusado; 12.ABC.345/01DE-35 aceito se o dígito conferir |
| O vencimento pode ser passado ou futuro; vencido e a vencer são recalculados todo dia | Hoje = 18/10/2026: 17/10/2026 vencido com 1 dia de atraso; 10/12/2026 a vencer |
| Valor maior que zero, com até duas casas, guardado em centavos | 1.234,56 vira 123456 centavos; 12,345 recusado |
| O mesmo título repetido no arquivo: vale a primeira linha | Linha 15 recusada: “título repetido na linha 8” |
| O devedor entra na faixa do seu título vencido mais atrasado | Títulos com 38 e 95 dias de atraso: faixa 91–180 |
O CNPJ alfanumérico é um exemplo de regra que passaria batido. Pela Instrução Normativa RFB nº 2.229, de outubro de 2024, a Receita Federal passou a atribuir CNPJ com letras às novas inscrições a partir de julho de 2026; os números já existentes não mudam. Uma validação “só números”, copiada de qualquer exemplo antigo, recusaria esses clientes, e o defeito só apareceria quando o primeiro deles entrasse na carteira.
Critérios de aceite no formato dado, quando, então#
Cada critério vira um teste automatizado, com o mesmo nome. Três dos 26:
Dado uma carteira com os títulos A, B e C ativos quando o gestor escolhe batimento e confere um arquivo com os títulos B e D então a conferência informa que A e C serão retirados, com quantidade e valor, antes de qualquer gravação.
Dado um título a vencer em 18/10/2026, com vencimento 20/10/2026 quando o operador abre a ficha em 21/10/2026 então o título aparece como vencido, com 1 dia de atraso, sem nova importação.
Dado um usuário inexistente quando alguém tenta entrar com ele então a mensagem é exatamente a mesma de uma senha errada.
As decisões, com alternativas#
Todas as decisões seguiram o mesmo formato: a ferramenta de IA que escreve o código e os rascunhos (o Claude Code) apresentava as opções, o impacto de cada uma e uma recomendação, e eu escolhia. Abaixo estão as que mudaram o sistema de forma visível.
O título que some do arquivo novo#
Foi a decisão com mais versões erradas. A pergunta: um título estava na carteira e não aparece na planilha nova. O que acontece?
| Versão | Regra | Problema |
|---|---|---|
| Primeiro rascunho | Nada muda | Se o título foi pago, o sistema continua mandando cobrar quem pagou. Cobrança indevida, que o Código de Defesa do Consumidor (art. 42) pune com devolução em dobro |
| Correção proposta | Marcar como “provavelmente pago ou cancelado” | Troca uma suposição por outra; um título renegociado ou cancelado inflaria o indicador de recuperação |
| Versão aprovada | Depende do modo de importação | Nenhum: o sistema registra só o que sabe |
A versão aprovada não estava entre as opções. Ela veio de quem conhece cobrança: a carga pode ser incremental, em que o arquivo traz só inclusões e atualizações, ou de batimento, em que o arquivo representa a carteira inteira. Na incremental, um título ausente não significa nada. No batimento, ele passa a retirado, e só isso: o sistema não presume pagamento, cancelamento ou renegociação, porque o arquivo não traz essa informação.
A proteção contra um batimento com arquivo incompleto#
O batimento resolveu um problema e criou o oposto. Se alguém exportar a carteira com um filtro esquecido, só um mês ou só uma unidade, o batimento retira em massa títulos ainda devidos, e a cobrança deles para.
| Opção | A favor | Contra |
|---|---|---|
| Segundo passo de confirmação quando mais de 20% da carteira for retirada (recomendada) | Protege contra o erro grosseiro sem incomodar no dia a dia | Recortes errados pequenos passam |
| Segundo passo sempre | Máxima segurança | Vira clique automático e perde efeito |
| Limite configurável | Flexível | Exige tela de configuração e alguém que saiba escolher o número |
| Só a conferência (escolhida) | Menos código; a conferência já mostra quantos títulos e quanto valor serão retirados | O risco fica com quem confirma |
Escolhi a praticidade, e a especificação diz isso com todas as letras: a conferência é a única barreira. Numa empresa, essa troca passaria pela operação, pela TI e provavelmente pela auditoria interna.
O modo que vem marcado#
| Opção | A favor | Contra |
|---|---|---|
| Nenhum padrão, escolha obrigatória (recomendada) | O batimento nunca acontece por descuido | Um clique a mais em toda importação |
| Incremental (escolhida) | O modo que não retira nada é o padrão | Quem queria batimento e esqueceu fica com títulos que deveriam ter saído |
| Batimento | Combina com quem sempre exporta tudo | Um arquivo só de inclusões retiraria a carteira quase inteira |
| Fixo por credor | Reflete a rotina do faturamento | Exige configuração e impede a carga avulsa no outro modo |
Títulos a vencer#
O rascunho recusava títulos a vencer: “o título tem que estar em atraso”. A pergunta apresentou a recusa como a opção mais segura. A resposta foi uma correção: “E se o credor tem por regra negociar todo o contrato? Você não pode assumir que tem erro ou risco.”
A regra mudou: títulos a vencer são parte legítima da carteira. A correção trouxe duas regras que não existiam. A primeira é a coluna opcional contrato, sem a qual o acordo do incremento 4 não conseguiria negociar o contrato inteiro. A segunda é uma configuração por credor para o lugar do a vencer nos totais:
| Opção | A favor | Contra |
|---|---|---|
| Colunas vencido e a vencer separadas | Não mistura atraso com saldo futuro | Não serve a todos os credores |
| Total único | Simples | Indicadores de atraso menos claros |
| Depende do credor (escolhida), padrão separado | Atende políticas diferentes e já prepara a fase de assessorias | Mais configuração |
O mesmo documento com nomes diferentes#
Esta decisão foi tomada e revista na mesma noite.
| Opção | A favor | Contra |
|---|---|---|
| Recusar só as linhas divergentes (recomendação inicial) | Obriga a corrigir na origem | O devedor entra pela metade |
| Aceitar e avisar | Nenhum título perdido | Um CPF digitado errado junta dívidas de duas pessoas |
| Recusar todas as linhas do devedor (primeira escolha) | O mais seguro contra mistura de pessoas | Recusa por acento ou espaço a mais |
| Normalizar e, se ainda divergir, recusar o devedor (escolha final) | Diferenças triviais deixam de travar a carga; o caso suspeito continua bloqueado | Uma etapa de normalização a especificar e testar |
A primeira escolha foi feita sem as causas comuns de divergência à vista: acento, abreviação, sobrenome de casada. A pergunta não as trazia. Quando vieram, a regra ganhou a normalização: “MARIA DA SILVA” e “Maria da Silva” passam a ser o mesmo nome.
A decisão que só apareceu combinando regras#
Ao montar o questionário, apareceu uma decisão que nenhuma regra isolada mostrava. No batimento, um título existente cuja linha foi recusada, por uma data digitada errada, por exemplo, some do conjunto válido e seria retirado. Somado à regra anterior, um erro de grafia no nome retiraria todas as dívidas daquele devedor.
| Opção | A favor | Contra |
|---|---|---|
| Não retirar e listar à parte (escolhida) | Um erro de digitação não interrompe a cobrança | O arquivo deixa de ser a verdade absoluta |
| Retirar | Regra simples | Um acento retira todas as dívidas de uma pessoa |
| Recusar o batimento inteiro | Máxima segurança | Um erro pequeno bloqueia a carga |
Faixas de atraso, limites e tempo de espera#
| Decisão | Recomendação | Escolha | Por quê |
|---|---|---|---|
| Faixas de atraso | Seis faixas fixas (1–30, 31–60, 61–90, 91–180, 181–360, mais de 360) | Configuráveis pelo gestor, começando pelas seis | Credores diferentes acompanham faixas diferentes |
| Limite do arquivo | 10 MB ou 50 mil linhas | 50 MB ou 200 mil linhas | Já pensando nas assessorias |
| Espera com 200 mil linhas | Primeiro “5 minutos e 512 MB de memória”; depois 2 + 2 minutos | Até 2 minutos para conferir e 2 para confirmar | A primeira recomendação misturava infraestrutura com comportamento |
O tempo de espera teve uma pergunta no meio: “esses números são realistas?”. A resposta honesta foi que nenhum dos dois tinha sido medido, e que 5 minutos era folgado demais. A meta final vai ser verificada por teste automatizado com uma carteira fictícia de 200 mil linhas.
O login que mudou de incremento#
O mapa original deixava o login para o segundo incremento. Quando decidi que o ambiente de desenvolvimento seria a própria demonstração publicada, o primeiro incremento ficaria aberto na internet sem login. A recomendação foi proteger pela infraestrutura, com uma senha no servidor web, e manter a especificação como estava. Preferi antecipar o login. A especificação aprovada ganhou uma revisão com o motivo, seis regras e sete critérios novos, antes de qualquer código.
| Decisão | Escolha | Alternativa descartada |
|---|---|---|
| Quem cria usuários | Administrador, por comando, fora da interface | Tela de usuários (antecipa o incremento 2) ou o painel administrativo pronto do framework (fora da marca e da acessibilidade) |
| Expiração da sessão | 30 minutos sem uso, 8 horas no máximo | 8 horas sem uso, ou ao fechar o navegador |
| Tentativas erradas | Bloqueio de 15 minutos após 5 erros, com mensagem que não revela se o usuário existe | Atraso crescente, ou nenhuma regra no sistema |
| Senha | Mínimo de 12 caracteres, sem senhas comuns, sem exigir símbolo nem troca periódica | Mínimo de 8 com maiúscula, número, símbolo e troca a cada 90 dias |
A regra de senha segue a linha das diretrizes de identidade digital do NIST (SP 800-63B), que desaconselham regras de composição e troca periódica obrigatória, porque levam a senhas previsíveis como “Senha@2026”.
As que seguiram a recomendação#
| Decisão | Escolha |
|---|---|
| Importação com linhas recusadas | Parcial: entram as válidas, depois de uma conferência que não grava nada |
| Título existente com valor diferente | Atualiza e registra antes, depois, quem e quando |
| Título retirado que volta num arquivo posterior | Volta a ativo, com as duas datas no histórico |
| Contrato | Coluna opcional que agrupa os títulos na ficha |
As premissas que ficaram registradas#
Cada premissa diz a área que a validaria e o custo de estar errada. Algumas delas:
| Premissa | Quem validaria | Se estiver errada |
|---|---|---|
| O documento identifica o devedor de forma única | Operação | Escolas e clínicas têm responsável financeiro diferente do aluno ou do paciente; titular e responsável ficam misturados |
| O número do título não muda entre exportações | TI do faturamento | Toda reimportação duplica a carteira |
| No batimento, o credor exporta sempre a carteira inteira | TI e operação | Um recorte diferente retira títulos ainda devidos |
| Nome diferente entre uma carga e outra é atualização cadastral | Operação | Um CPF digitado errado troca o nome de outro devedor |
| Mostrar o CPF completo na ficha é aceitável | Jurídico e encarregado de dados (LGPD) | Exposição de dado pessoal além do necessário |
Nenhuma delas impede o desenvolvimento. Todas ficam visíveis, com dono, em vez de virarem uma regra que ninguém lembra de ter decidido.
O que ficou fora#
O que não está no incremento também está escrito: perfis de gestor e operador, recuperação de senha por e-mail, verificação em duas etapas, cadastro manual de devedor, multa e juros, baixa de pagamentos, exportação e o motivo da retirada de um título. A seção de fora do escopo é a que mais evita discussão depois: quando alguém perguntar por que o sistema não calcula juros, a resposta está no documento, com o incremento em que isso vai entrar.
Em números#
| Item | Quantidade |
|---|---|
| Regras com exemplos | 29 |
| Critérios de aceite | 26 |
| Premissas registradas | 9 |
| Decisões de especificação | 19 |
| Decisões que contrariaram a recomendação ou ficaram fora das opções | 8 |
| Premissas do rascunho corrigidas na revisão | 4 |
A especificação foi aprovada antes do plano técnico, que escolhe linguagem, banco e arquitetura. O próximo artigo da série trata dessas escolhas e de um conflito entre duas regras do próprio projeto: usar só versões publicadas há pelo menos duas semanas e não rodar com falha de segurança conhecida.


