v0.73.1
AFService Map v0.73.1 — Hotfix estrutural do runtime do mapa
Backup/ponto de rollback desta rodada: branch backup/mapa-pre-v0722-20260802
(pointer no commit ef12a9a, v0.73.0). Pacote preparado pelo ChatGPT como
"v0.72.2" sobre o commit 16a125a (v0.72.1) — antes do reskin dos
dashboards (v0.73.0) ter entrado no main. Aplicado via
apply_map_ui_v0722.py (validado antes com --dry-run, checksums
SHA-256 conferidos um a um). Sem migration.
Sobre o número de versão
O pacote chamava a si mesmo de "v0.72.2" porque foi preparado sobre o
commit da v0.72.1, sem saber ainda que a v0.73.0 (reskin dos dashboards)
já tinha entrado no main. Confirmei que os dois pacotes não têm
nenhuma sobreposição de arquivo (este só toca em templates/map.html,
.gitignore e cria os arquivos novos do mapa; o reskin só tocou em
templates/base.html, static/css/app.css e os 3 templates de
dashboard) — mas apliquei renomeando a versão final pra 0.73.1 em vez
de 0.72.2, pra manter o changelog em ordem cronológica real (este pacote
chegou e foi aplicado depois da v0.73.0, mesmo tendo sido preparado
antes).
Causa raiz confirmada lendo o código, não só a explicação do pacote
Antes de aceitar a explicação do ChatGPT, comparei o map-ui-v0721.js
antigo com o map-ui-v0722.js novo pra confirmar que os bugs descritos
realmente existiam:
1. Laço de reconstrução do popup. Em v0.72.1, schedulePopup()
registrava um MutationObserver no conteúdo do popup, além de 3 timers
(80/260/650ms). O observador tinha uma trava de debounce (scheduled)
contra reagir à própria mutação — isso eu já tinha conferido na release
da v0.72.1. O que não tinha percebido: map-ui-v072.js (a base, carregada
antes) também tem seu próprio sistema de decoração de popup
(decoratePopup, registrado em state.map.on("popupopen", ...)) que
mexe no mesmo .leaflet-popup-content. Dois sistemas diferentes
mutando a mesma área, um com observador ativo — o terreno certo pra
reconstrução em cascata, mesmo com debounce individual em cada um.
popupIdentity() também recalculava nome/tipo/código toda vez lendo o
DOM ao vivo, sem cache — se uma leitura acontecesse no meio de uma
mutação (o content.replaceChildren() do próprio código, ou a decoração
concorrente do map-ui-v072.js), o texto capturado podia vir de um
estado intermediário e ser usado como base pra próxima reconstrução.
O hotfix v0.72.2 remove o MutationObserver dos popups por completo.
Restam só 2 checagens finitas depois de abrir o popup (100ms e 420ms —
suficiente pra Master Suite/monitoramento injetarem as ações delas antes
da normalização final) e a identidade é capturada uma única vez e
cacheada em content._uiV0722Identity, nunca mais recalculada por cima
de um DOM que o próprio código já reconstruiu.
2. Botões de ação perdendo a função. Em v0.72.1, actionKey() só
reconhecia um botão pela chave de um atributo de uma lista fixa:
showElementCables, manageContainer, editElement, deleteElement,
masterAssetSheet, showUnifilar, openMonitorLinks. Qualquer botão
com outro atributo (data-insert-cable, data-reserve-cable,
data-cable-route, etc. — usados em Reserva, Inserir caixa, Rota do
cabo) caía no fallback por texto (button.textContent...), e a
deduplicação (if (keys.has(key)) return;) descartava silenciosamente
qualquer botão cujo texto colidisse com outro já visto. Achei essa lista
fixa lendo o código da v0.72.1 — é uma explicação plausível e verificável
pros botões que "paravam de responder" sem gerar nenhum erro no console
(o botão simplesmente não ia parar no popup final).
O hotfix v0.72.2 troca isso por uma chave feita de todos os
atributos data-* do próprio botão (ordenados), então nenhum botão real
se confunde com outro.
O que mais entrou
- Cancelamento de ferramenta de verdade: a barra agora rastreia qual
ferramenta está ativa (state.activeTool), mostra um botão
"Cancelar [ferramenta]" enquanto ela está ativa, cancela comEsc, e
cancela sozinha ao fechar os diálogos de elemento/cabo no meio da
operação (#element-dialog/#cable-dialogclose) — resolve o
"próximo clique preso no mapa" relatado. - Ícones não interceptam mais o clique:
pointer-events: nonenos
ícones/SVGs internos dos botões do popup e da barra. popupcloselimpa os timers pendentes — antes, se o popup fosse
fechado antes dos timers de normalização dispararem, eles rodavam
mesmo assim contra um popup já fechado.- Menu lateral em trilho de 72px, régua que vira cabo, medição de área,
busca comCtrl+K, whitelabel, tema claro/escuro, SNMP/InfluxDB/
Telegraf, backbone, PTP wireless, alertas, fusões, Canvas 2D, matriz de
manobra, KMZ/KML — tudo preservado sem mudança de comportamento.
Verificação feita
- Checksums SHA-256 do pacote conferidos um a um contra
SHA256SUMS. BASE_COMMIT(16a125a, v0.72.1) confirmado batendo com o estado do
repositório antes da v0.73.0 ter entrado.- Confirmado por leitura do
git diffque o pacote não toca em
templates/base.htmlnemstatic/css/app.css(arquivos do reskin
v0.73.0) — as únicas mudanças emtemplates/map.htmlforam as duas
tagsv0721→v0722, exatamente como o script prometia. - Confirmado que
map-optical-editor-v3.js,map-link-monitoring.js,
map-master-suite.jsemap-ui-v072.js/.csscontinuam intactos. - Li o
map-ui-v0722.jsinteiro (não só o resumo do pacote) pra
confirmar a ausência real doMutationObservere o cache de
identidade, e omap-ui-v0722.cssinteiro (pointer-events, seletores
de busca/popup). --dry-rundo aplicador, sem erro.python -m py_compileno Python tocado.- Sintaxe do
map-ui-v0722.jsvalidada com esprima. - Chaves do
map-ui-v0722.cssbalanceadas (74/74). {% if %}/{% endif %}detemplates/map.htmlbalanceados (10/10).docker-compose.ymlvalidado como YAML.- Rodei manualmente as 6 asserções do teste estático incluído
(test_map_ui_v0722_static.py, sem dependência de banco): ausência do
MutationObserver, cache de identidade, rótulos limpos dos botões,
menu Caixas/Cancelar, reset de posição da busca, gaveta de rotas real
— todas passaram.
A suíte Django completa (manage.py check, manage.py test) e o teste
visual real dependem de banco, GDAL e navegador — não rodam neste
ambiente de preparação.
Atualização
Execute apply no servidor. Sem migration nesta versão. Depois, um
Ctrl+F5 no navegador garante que o JS/CSS novos sejam carregados
(o map-ui-v0721.js/.css não é mais referenciado pelo template, só
fica como arquivo morto no disco).
Teste sugerido: abrir um popup de CTO/CEO/CDO/Torre/Rack/CPD-POP/Poste/
cabo e confirmar que o nome/código não crescem mais e que Editar, Fusões,
Equipamentos, Ficha/QR, Excluir, Rota do cabo, Monitorar enlace,
Adicionar reserva e Inserir caixa respondem ao clique; ativar uma
ferramenta (CTO, Cabo, etc.) e confirmar que aparece "Cancelar" e que
Esc cancela; testar a busca (Ctrl+K) sem deslocamento lateral.