Pular para o conteúdo
caua.tolentino
Todos os cases
Investigação

Preço de uma loja gravado como preço de todas

No marketplace, o administrador alterava o preço de uma loja e o valor ia para o preço de cadastro do produto, afetando todas as lojas sem preço próprio. Rastreei a regressão até uma mudança de nove meses antes e corrigi a gravação, com 15 cenários de teste.

Papel
Desenvolvedor responsável, do diagnóstico à entrega
Contexto
Plataforma de e-commerce com marketplace
Stack
PHP, Symfony, Twig, JavaScript, MySQL, PHPUnit
Time
Solo
Período
2026

Case anonimizado: nomes de empresa, cliente e pessoas foram omitidos ou trocados.

01. Situação

O admin mudava o preço de uma loja e a loja continuava com o preço antigo

Em um marketplace da plataforma, o administrador geral abria a lista de preço padrão, filtrava por uma loja e alterava o preço de um produto. Ao reabrir a tela, a coluna da loja voltava ao valor anterior, e a vitrine, o carrinho e o checkout continuavam com o preço antigo. Quando o próprio lojista fazia a mesma alteração pelo login dele, funcionava.

Reproduzi o problema e fui atrás de onde o valor ia parar. Ele não se perdia: era gravado no preço de cadastro do produto. Foi aí que entendi a gravidade real, porque o preço de cadastro é o último nível da cascata de preço da vitrine.

  1. Lista do cliente ou do perfil
  2. Lista padrão da loja
  3. Lista global
  4. Preço de cadastro do produto

A loja escolhida não via a mudança, porque tinha preço próprio. Todas as outras lojas sem preço próprio, e o próprio marketplace, passavam a cobrar o valor novo. O chamado falava de um preço que não salvava; o que eu encontrei foi um preço sendo alterado em silêncio para quem não tinha pedido.

02. Investigação

A tela mostrava a lista da loja e enviava a lista do produto

Analisei o template, o JavaScript da tela, o controller e a cascata de preço. No admin, "preço padrão" é uma lista virtual, com id 0, que significa "preço de cadastro". A lista padrão de cada loja é outra lista, real, e não é filha da virtual.

O template detectava o admin com loja escolhida e exibia a lista da loja, mas o campo continuava enviando id 0. No backend, id 0 sem loja na sessão do admin levava direto ao preço de cadastro, antes de considerar a loja que vinha no request.

Faltava saber por que isso tinha começado. Percorri o histórico do git e cheguei à origem: uma mudança feita cerca de nove meses antes, para corrigir as listas por centro de distribuição, trocou o id enviado pela tela. O esquema novo funciona para as listas nomeadas, que têm lista pai, mas o "preço padrão" não tem, e ficou de fora.

Era a correção mais óbvia. Analisei o efeito: voltar a enviar o id real da lista da loja faria o backend procurar uma lista filha inexistente e criar uma lista duplicada para a loja. Descartada.

03. Solução

Redirecionar a gravação para a lista da loja, pelo caminho que o lojista já usava

Em vez de criar um fluxo novo, levei a gravação do admin para o caminho que o lojista já usava e que funcionava em produção. Adicionei um método privado chamado só na gravação: quando o admin envia "preço padrão" com uma loja válida que tem lista padrão, a gravação passa a usar a lista dessa loja. Se a loja não tiver lista padrão, a resposta é um erro claro e nada é gravado.

Escolha

Resolver a loja só na gravação

A função que lê a lista também atende a tela e a exportação. Mudá-la alteraria o que o admin vê e o relatório, então restringi a mudança ao ponto do defeito.

Escolha

Antes da checagem de permissão

Posicionei a resolução antes da permissão, para que ela seja verificada sobre a lista que de fato será gravada.

Trade-off

Loja sem lista padrão recebe erro

Manter a gravação no preço de cadastro seria manter o defeito, e criar a lista na hora mexeria no cadastro de loja. Preferi recusar com uma mensagem clara.

Cuidado

Dados já afetados

Preços de cadastro alterados pelo defeito não voltam com o deploy. Avisei isso no chamado e entreguei uma consulta para o time localizar os casos.

Antes de corrigir, troquei as expectativas dos testes para o comportamento certo e vi os quatro cenários do defeito falharem. Depois da correção, os 15 cenários passaram. Para garantir que eu não tinha quebrado nada, rodei a suíte completa com e sem a mudança e comparei: as falhas que já existiam eram exatamente as mesmas nas duas execuções.

04. Resultado

A alteração fica na loja escolhida

cenários de teste, admin e lojista
15
cenários do defeito falhando
4 → 0
desde a mudança que causou a regressão
~9 meses

A edição do administrador vai para o preço da loja escolhida e aparece na vitrine dela. As outras lojas e o marketplace deixaram de ter o preço alterado sem querer. Admin sem loja escolhida, listas nomeadas e o lojista continuam como antes.

A correção fecha uma regressão que estava em produção havia meses. Junto com ela, entreguei a consulta para identificar lojas sem lista padrão e a orientação sobre os preços que precisavam de ajuste manual.