Skip to content

Sistema permite dois locais de coleta com o mesmo nome na mesma cidade #528

Description

@edvaldoszy

Problema

Caxambu relatou que o sistema aceitou dois locais de coleta com o mesmo nome na mesma cidade.

Isso já foi tratado em #208 (20250922032356_remove_locais_de_coleta_duplicados.ts), mas voltou a ocorrer: POST /locais-coleta e PUT /locais-coleta/:id gravam o registro sem conferir duplicata, e a tabela locais_coleta não tem restrição de unicidade em (cidade_id, descricao).

O painel cria local de coleta em dois caminhos (ListaLocalColetaScreen e cadastro de tombo), ambos via POST /locais-coleta. Sem bloqueio na API, a duplicata entra de qualquer um deles.

1. Localizar os duplicados

Rodar no banco e registrar o resultado (grupos e ids envolvidos) antes de unificar:

select
  count(1) as total,
  lc.descricao,
  lc.cidade_id
from locais_coleta lc
group by lc.cidade_id, lc.descricao
having count(1) > 1

Para listar os ids de cada grupo (útil na migração):

select
  lc.cidade_id,
  lc.descricao,
  array_agg(lc.id order by lc.id) as ids,
  count(1) as total
from locais_coleta lc
group by lc.cidade_id, lc.descricao
having count(1) > 1

2. Migração: unificar tombos e apagar o duplicado

Nova migration em src/database/migration/ (npm run migration:create -- <nome>).

Para cada grupo com a mesma descricao e o mesmo cidade_id:

  1. Escolher um registro canônico (o de menor id, como em Remover locais de coleta repetidos #208).
  2. Atualizar tombos.local_coleta_id dos demais para o id canônico. A FK fk_tombos_local_coleta é ON DELETE RESTRICT — não dá para apagar o duplicado enquanto ainda houver tombo apontando para ele.
  3. Apagar os locais_coleta que sobraram no grupo.

Implementar a unificação com a API do Knex (knex('tombos').update(...), knex('locais_coleta').del(), schema.unique, etc.), no mesmo estilo de migrations como 20260429003533_coletores-duplicados.ts. Conferir se alguma outra tabela referencia locais_coleta.id além de tombos.

Depois da unificação, a primeira query desta issue precisa voltar vazia.

3. Impedir novo cadastro duplicado

Não basta limpar os dados: o próximo cadastro com o mesmo nome na mesma cidade volta a criar duplicata.

  • Índice/constraint único em locais_coleta (cidade_id, descricao) depois de unificar (a constraint falha se ainda houver duplicata).
  • Em cadastrarLocalColeta e atualizarLocalColeta (src/controllers/locais-coleta-controller.js): recusar com erro claro (ex. 409 ou 400) quando já existir outro local com a mesma descricao e a mesma cidade_id. Edição do próprio registro continua válida.
  • O painel só precisa exibir a mensagem da API; a regra de negócio fica na API/banco.

Comparação alinhada à query reportada: mesmo cidade_id e mesma descricao (igualdade de texto). Se no levantamento aparecer diferença só de espaço/caixa, documentar e tratar na unificação.

Fora de escopo

  • Unificar locais com nomes diferentes (mesmo que sejam o mesmo sítio na prática).
  • Alterar o fluxo visual de cadastro de tombo além de mostrar o erro da API.

Critérios de aceite

  • A query de duplicados (item 1) foi executada e os grupos encontrados foram considerados na migração.
  • Migration unifica tombos.local_coleta_id no local canônico e remove os demais do grupo.
  • Após aplicar a migration, não resta mais de um locais_coleta com a mesma descricao e o mesmo cidade_id.
  • POST /locais-coleta com nome e cidade já existentes é recusado.
  • PUT /locais-coleta/:id que colidiria com outro local da mesma cidade é recusado.
  • Cadastro pelo painel (lista de locais e tombo) não consegue gravar a duplicata; o usuário vê que aquele local já existe.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

apibugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions