Contratos¶
Verificado contra produção em 2026-08-19 — os seis comandos, com dois
contratos de teste criados, um encerrado e ambos excluídos. Os seis
parâmetros de contrato list passaram na receita completa (baseline,
zzz_bogus=abc, valor discriminante). Três avisos antes das tabelas:
1. Criar um contrato cria vendas na hora. Um contrato mensal com
tipo_expiracao: NUNCAedata_fima um ano gerou 25 vendas agendadas de uma vez, comdata_ultima_emissaoem 2028 — oNUNCAignora odata_fime agenda dois anos à frente. O mesmo contrato comtipo_expiracao: DATAe janela de um mês gerou 2. Escolha a janela antes de testar em produção.2.
contrato deletenão é exclusão permanente, ao contrário do que este documento afirmava. OGETcontinua respondendo200, comstatus: DELETADO; o que some é a listagem. As vendas associadas são canceladas de verdade (a contagem de vendas voltou ao valor de antes).3. Um uuid válido mas inexistente devolve
500, não404— emcontrato get,contrato deleteecontrato encerrar. Nas duas escritas o CLI classifica isso comoambiguouse sugere reconciliar, quando na prática não havia nada para aplicar. Um id malformado, esse sim, devolve400.
contrato list ✅¶
GET /v1/contratos
| Parâmetro | Obrig. | Padrão | Descrição |
|---|---|---|---|
--data-inicio |
não¹ | 1º dia do mês corrente | Início do intervalo (YYYY-MM-DD) |
--data-fim |
não¹ | último dia do mês corrente | Fim do intervalo (YYYY-MM-DD) |
--pagina |
não | 1 |
Número da página |
--tamanho-pagina |
não | 10 |
Itens por página (aceita até 1000) |
--busca-textual |
não | — | Busca textual: casa nome do cliente e número do contrato |
--cliente-id |
não | — | Filtra pelo ID do cliente |
--campo-ordenado-ascendente |
não | — | DATA_INICIO ou DATA_FIM; se informado, ignora --campo-ordenado-descendente |
--campo-ordenado-descendente |
não | — | DATA_INICIO ou DATA_FIM |
¹ A API exige o intervalo — os dois lados. Sem nenhum, responde 400
("Data de início da recorrência não pode ser nula"); só com um lado, cobra o
outro. O CLI supre com o mês corrente e avisa em stderr, comportamento
confirmado exercitando.
Retorna {itens_totais, itens[]} — a chave é itens, não items como
este documento dizia. Cada item traz {id, cliente, status,
proximo_vencimento, total_proximo_vencimento, data_inicio, numero,
conta_financeira, termos, tipo_pagamento, total}; é um recorte diferente do
que contrato get devolve.
--busca-textual não busca um "nome do contrato" — esse campo não existe no
recurso. Casa o nome do cliente e o número: busca_textual=2 devolveu só o
contrato de número 2. Ordenação inválida devolve 400 listando
[DATA_INICIO, DATA_FIM], que é como se prova que o parâmetro é lido e não
descartado; mandando as duas ordenações juntas, a ascendente vence.
contrato create ✅¶
POST /v1/contratos — escrita síncrona, diferente das escritas financeiras: não devolve protocolo, o id do contrato já vem na resposta.
| Parâmetro | Obrig. | Descrição |
|---|---|---|
--json |
sim | Payload JSON do contrato, repassado à API verbatim |
O CLI não valida o conteúdo de --json. A lista de obrigatórios que este
documento trazia (id_cliente, termos, condicao_pagamento, itens) é
verdadeira mas inútil: a API cobra onze campos, descobertos um 400 de
cada vez.
| Campo | Onde | Formato |
|---|---|---|
id_cliente |
raiz | uuid da pessoa |
tipo_frequencia |
termos |
MENSAL ou ANUAL |
tipo_expiracao |
termos |
DATA ou NUNCA |
data_inicio |
termos |
YYYY-MM-DD |
data_fim |
termos |
YYYY-MM-DD — exigido mesmo com tipo_expiracao: NUNCA |
intervalo_frequencia |
termos |
inteiro |
dia_emissao_venda |
termos |
inteiro (dia do mês) |
numero |
termos |
inteiro — veja abaixo |
tipo_pagamento |
condicao_pagamento |
enum longo (BOLETO_BANCARIO, PIX_PAGAMENTO_INSTANTANEO, DINHEIRO, …) |
dia_vencimento |
condicao_pagamento |
inteiro |
primeira_data_vencimento |
condicao_pagamento |
YYYY-MM-DD |
itens |
raiz | array de {id, quantidade, valor} |
Dois desses lugares custam tempo se você supuser errado:
numerofica dentro determos. Na raiz — e comonumero_contrato,num_contrato,numero_do_contrato,contrato_numeroounumber— a API repete "O número do contrato é obrigatório" sem dizer onde ela quer.itensfica na raiz, não emtermos. Dentro determosa resposta é "Lista de itens da recorrência não pode ser vazia".
Retorna {id, id_legado} — não há id_venda, ao contrário do que este
documento afirmava.
observacoes volta em outro lugar. O que você manda na raiz como
observacoes aparece no GET em condicao_pagamento.observacoes_pagamento;
a observacoes da raiz fica sempre vazia na leitura, e uma
observacoes_pagamento mandada dentro de condicao_pagamento é descartada.
Mesma classe de troca de orcamento create.
Payload mínimo que passou:
{
"id_cliente": "11111111-1111-4111-8111-111111111111",
"termos": {
"tipo_frequencia": "MENSAL",
"tipo_expiracao": "DATA",
"data_inicio": "2026-09-01",
"data_fim": "2026-10-01",
"intervalo_frequencia": 1,
"dia_emissao_venda": 1,
"numero": 1
},
"condicao_pagamento": {
"tipo_pagamento": "BOLETO_BANCARIO",
"dia_vencimento": 10,
"primeira_data_vencimento": "2026-09-10"
},
"itens": [{ "id": "22222222-2222-4222-8222-222222222222", "quantidade": 1, "valor": 10 }]
}
A descricao de um item propaga para as vendas geradas, o que a torna o
lugar prático para marcar um contrato de teste.
contrato proximo-numero ✅¶
GET /v1/contratos/proximo-numero
Sem parâmetros. Retorna o próximo número de contrato disponível como um inteiro solto, não um objeto — diferente de todos os outros comandos de leitura.
O contador acompanha as exclusões: numa conta sem contratos devolveu 1,
subiu para 2 depois do contrato de número 1 e voltou a 1 quando os
contratos de teste foram excluídos. Ao contrário de venda, esse número
não é atribuído sozinho — é você quem manda termos.numero no create.
contrato get ✅¶
GET /v1/contratos/{id}
| Parâmetro | Obrig. | Descrição |
|---|---|---|
<id> |
sim | Argumento posicional. Uuid do contrato |
Devolve bem mais do que a listagem: {id, id_ultima_venda_confirmada,
id_proxima_venda_agendada, cliente, vendedor, termos, data_proximo_vencimento,
data_proxima_emissao, data_ultima_emissao, status, configuracao_recorrencia,
condicao_pagamento, local_prestacao_servico, composicao_valor, observacoes}.
status é ATIVO, INATIVO (depois de encerrar) ou DELETADO (depois de
delete). Uuid inexistente devolve 500; id malformado, 400.
contrato delete ✅¶
DELETE /v1/contratos/{id} — exclusão lógica, apesar do nome.
| Parâmetro | Obrig. | Descrição |
|---|---|---|
<id> |
sim | Argumento posicional. Uuid do contrato |
Resposta 204 No Content — sem corpo, que o CLI imprime como [].
O contrato sai da listagem mas continua legível por contrato get, com
status: DELETADO e id_proxima_venda_agendada zerado. As vendas
associadas são canceladas de verdade: um contrato que havia gerado 25
vendas agendadas devolveu a contagem global de vendas ao valor anterior
depois do delete. Funciona também em contrato já encerrado.
Contratos em reajuste de valor não podem ser removidos.
contrato encerrar ✅¶
POST /v1/contratos/{id}/encerrar — sem corpo.
| Parâmetro | Obrig. | Descrição |
|---|---|---|
<id> |
sim | Argumento posicional. Uuid do contrato |
Resposta 204 No Content — sem corpo, que o CLI imprime como [].
Desativa o contrato: status passa de ATIVO para INATIVO e
id_proxima_venda_agendada é zerado, mas o contrato permanece na
listagem — é o que separa encerrar de delete. A chamada é idempotente:
repetida num contrato já INATIVO, responde 204 de novo.
Contratos em reajuste de valor não podem ser encerrados.