Garu

2026-07-28

v0.18.0 — Programa de afiliados voltou a salvar, e PATCH /products virou atualização parcial de verdade

afiliadosbugfixprodutosapisegurancadashboard

A tela Programa de afiliados nunca conseguiu salvar. Qualquer chave — "Ativar afiliação para este produto", "Manter vínculo por lead", "Exibir em todos os produtos" — e também o botão Salvar Comissão devolviam "Erro ao atualizar. Tente novamente."

O que estava acontecendo

A tela lia o produto e devolvia o mesmo objeto no PATCH. Só que installments tem duas formas: na leitura ela vem como a tabela de parcelas do cartão ([{ quantity, value }, …]), e na escrita a API espera o número de parcelas. A validação recusava o array e respondia 400:

{"message":["Parcelas deve ser no mínimo 1","Parcelas deve ser um número"]}

Valia para todo produto, com ou sem cartão habilitado. Editar o produto pela tela normal funcionava, porque lá o valor era convertido de volta para número antes de enviar.

O que mudou

Afiliação salva

Cada ação da tela agora envia só o que ela realmente altera. Uma consequência boa: mexer numa chave não grava mais uma porcentagem de comissão que você digitou mas ainda não confirmou — comissão só é salva pelo botão Salvar Comissão.

PATCH /api/products/:id é atualização parcial de verdade

Todo campo é opcional, e o que você não mandar fica como está. Antes, três campos não seguiam essa regra:

  • Tags eram apagadas. Uma atualização que não mandasse tags limpava todas as tags do produto. Agora só limpa se você mandar uma lista vazia de propósito.
  • image e pixelFB sumiam da resposta quando omitidos.
  • Chaves não voltavam para false. Desligar afiliação era ignorado — o campo só era gravado quando era verdadeiro.

Produto dos outros não se mexe

PATCH /api/products/:id e DELETE /api/products/:id não verificavam dono. Como o id é um inteiro sequencial, qualquer conta autenticada podia alterar preço, comissão e URL de retorno — ou desativar — o produto de outro vendedor. As duas rotas agora respondem 404 para produto que não é seu, igual às rotas de portal e às rotas /api/v1.

Comissão fora de 0–100% é recusada

comission é a porcentagem do valor do produto paga ao afiliado, e o líquido do vendedor é bruto − taxa − comissão do afiliado. Acima de 100% o pagamento passa do que foi arrecadado; abaixo de 0% credita o vendedor com dinheiro que nunca entrou. Os dois casos agora respondem 400 em vez de irem para o ledger. Texto não numérico também é recusado, no lugar de gravar NaN.

Impacto

Nenhuma ação necessária. Quem consome a API por chave e dependia de PATCH sem tags para limpar tags precisa passar "tags": [] explicitamente.