SGEProduto · Domínio · Desenvolvimento
Repositório

migration-reference · implemented

Migration 01A — cities

Catálogo local das cidades brasileiras identificadas pelo código IBGE.

Contrato

ColunaTipo PostgreSQLNuloChaves/índicesRegra
idbigintnãoPKIdentificador interno usado pelas FKs.
ibge_codechar(7)nãoUQCódigo oficial do município.
namevarchar(120)nãoíndice (state, name)Nome oficial usado nos selects e relatórios.
statechar(2)nãoíndiceSigla da UF validada por BrazilianState.
created_attimestamp(0)não—Inclusão no catálogo.
updated_attimestamp(0)não—Última sincronização.

O catálogo nacional tem 5.571 municípios e é importado localmente. O catálogo conferido está salvo em database/data/cities.json e versionado junto com o projeto. A migration create_cities_table, o model City e o CitySeeder estão implementados: o seeder lê esse arquivo e insere/atualiza as cidades de forma idempotente pelo ibge_code, sem apagar registros existentes. CityValidationRules centraliza código IBGE, nome e UF e é aplicado ao salvar o model, ao validar o catálogo no seeder e ao aceitar respostas do comando de coleta.

Não há chamada à BrasilAPI para consultas de cidades nem para o cálculo de feriados. A API/IBGE pode ser usada para obter ou revisar o arquivo versionado antes de uma nova implantação. A busca opcional por CEP, documentada em addresses, fica para uma etapa futura; quando existir, a cidade continuará sendo resolvida no catálogo local, sem criação de municípios pela resposta externa.

City usa Scout/Meilisearch para a busca textual no select de cidade da gestão de campi. O índice contém ID, nome, UF e código IBGE, com state filtrável; o filtro de UF é aplicado no mecanismo de busca. Não há consulta inicial para carregar opções. A busca começa com 2 caracteres, após debounce de 500 ms, e retorna até 20 cidades. O nome da cidade já selecionada é preservado na edição. O catálogo no banco continua sendo a fonte da seleção e das FKs; a cidade nunca é um enum nem texto livre. A indexação Eloquent usa fila após commit. Após importar o catálogo existente, execute scout:import 'App\Models\City' e processe a fila, além de sincronizar as configurações dos índices.

O código IBGE é a identidade da cidade. O CitySeeder pode atualizar o nome oficial associado ao mesmo código em uma carga controlada; documentos gerados preservam os valores formatados no snapshot da geração, e endereços históricos continuam apontando para a mesma identidade municipal. Não há enum de cidades nem exclusão lógica como operação normal.

Geração do catálogo e carga local

O comando Artisan cities:fetch consulta a lista de UFs, busca os municípios de cada uma, valida os códigos IBGE e gera o arquivo local. A configuração da URL fica em services.brasil_api.base_url; não há URL duplicada dentro do comando.

BASH
php artisan cities:fetch
php artisan cities:fetch --force

O comando não substitui um catálogo existente sem --force. A opção --output permite gerar um arquivo temporário ou alternativo para revisão. A gravação do catálogo é atômica: falhas durante a coleta não deixam um JSON parcial no caminho final.

O arquivo database/data/cities.json contém somente dados de referência, em formato estável e revisável:

JSON
[
  {
    "ibge_code": "4300109",
    "name": "Agudo",
    "state": "RS"
  }
]

O CitySeeder implementado:

  • lê o arquivo local sem fazer requisições de rede;
  • valida o código IBGE com sete dígitos, a UF contra BrazilianState, o nome não vazio e o limite da coluna usando CityValidationRules;
  • insere ou atualiza pelo ibge_code, em lotes de 500 registros e dentro de uma transação;
  • rejeita códigos IBGE duplicados no catálogo;
  • nunca apaga cidades automaticamente, porque endereços e feriados podem referenciá-las;
  • é chamado explicitamente pelo seeder principal.

Para carregar ou recarregar o catálogo, use:

BASH
php artisan db:seed --class=Database\\Seeders\\CitySeeder

A obtenção do arquivo ocorre fora do fluxo de seed, durante o desenvolvimento ou em uma sincronização administrativa explícita. Depois de revisado e commitado, qualquer ambiente consegue popular o banco de forma determinística e reproduzível.

Integridade

  • PRIMARY KEY (id);
  • UNIQUE (ibge_code);
  • INDEX (state) e INDEX (state, name) para filtros por UF e consultas locais por nome;
  • a validação de state usa os 27 valores de BrazilianState;
  • a UF do endereço é obtida por city_id, sem campo estadual duplicado; feriados municipais devem pertencer à UF da cidade selecionada.

O model City declara holidays() para os feriados municipais e addresses() para os endereços. CityFactory cria fixtures independentes de rede e do catálogo nacional nos testes de backend.

Checklist

  • Criar create_cities_table antes de create_addresses_table.
  • Criar Model City com cast de state.
  • Adicionar City::addresses() e CityFactory para fixtures de backend.
  • Gerar e revisar database/data/cities.json com o catálogo nacional pelo comando Artisan.
  • Criar CitySeeder idempotente, executável sem rede e seguro para reexecução.
  • Testar migration, carga local, unicidade do código IBGE e filtro por UF/nome.
  • Testar campos inválidos do catálogo e preservar dados existentes quando a validação falha.