Plataforma web para controle, consulta e rastreabilidade dos medidores bypassados: além de registrar a troca do medidor em campo, o sistema acompanha o ciclo de vida completo de cada medidor — da identificação na base até o tratamento registrado pela equipe.
HTML + CSS + JavaScript puro (ES Modules), sem framework e sem build step. Os dados ficam em um banco Supabase (Postgres + Storage).
O sistema trabalha com dois conceitos que não podem ser confundidos:
| Pergunta | Quem responde |
|---|---|
| O medidor existe? | medidores_base (base principal) |
| O medidor foi tratado? | UTD_PID (registros operacionais) |
Disso sai o status exibido na consulta:
| Situação | Status |
|---|---|
| Está na base e possui tratamento vinculado | TRATADO |
| Está na base e não possui tratamento | PENDENTE |
| Não está na base nem tem tratamento | NAO_LOCALIZADO |
| Tem tratamento mas não está na base (inconsistência) | TRATADO + aviso de "fora da base" |
O status não é uma coluna gravada: ele é derivado na consulta, para nunca ficar dessincronizado dos registros reais.
.
├── index.html # Shell da aplicação (sidebar + topbar + área de conteúdo)
├── style.css # Design system (tokens, componentes, layout, responsivo)
├── supabase.js # Client Supabase (lê credenciais de config.js)
├── config.js # Gerado a partir do .env — NÃO versionado
├── js/
│ ├── app.js # Router por hash, navegação, estado de conexão
│ ├── api.js # Chamadas às RPCs + upload/compactação de fotos
│ ├── utils.js # Formatação pt-BR, normalização, toasts, modais
│ ├── charts.js # Gráficos em SVG puro (sem biblioteca)
│ └── views/
│ ├── dashboard.js # Consulta rápida + indicadores
│ ├── consulta.js # Consulta de medidor (3 cenários)
│ ├── registro.js # Registrar tratamento (formulário em blocos)
│ ├── historico.js # Histórico com filtros, paginação e detalhe
│ ├── indicadores.js # Gráficos gerenciais
│ └── base.js # Importação da planilha na base principal
├── scripts/generate-config.js # Lê .env e gera config.js
└── migrations/*.sql # Scripts SQL de migração do banco
| Rota | Tela | O que faz |
|---|---|---|
#/dashboard |
Dashboard | Consulta rápida, KPIs, progresso, evolução e ranking por equipe |
#/consulta |
Consulta de medidor | Busca o medidor na base e nos tratamentos, com os 3 cenários de status |
#/registrar |
Registrar tratamento | Formulário de campo com fotos; aceita pré-preenchimento pela consulta |
#/historico |
Histórico | Tabela com busca, filtros, ordenação, paginação e detalhe com fotos |
#/indicadores |
Indicadores | Evolução diária, volume mensal, tratados x pendentes, ranking |
#/base |
Base de medidores | Importação da planilha (CSV/XLSX) e sincronização da base |
A consulta aceita o número com zeros à esquerda, pontos e espaços (0004521398, 4.521.398 e 4521398 são o mesmo medidor) e procura em medidor_instalado, medidor_retirado, medidor_vizinho e na base principal. Se nada for encontrado por número, ainda tenta ordem de serviço e conta contrato.
- HTML5 / CSS3 (design system com variáveis CSS)
- JavaScript (ES Modules), sem framework e sem build step
- Supabase JS SDK via CDN (
esm.sh) - SheetJS carregado sob demanda, só ao importar
.xlsx - Fonte: IBM Plex Sans / IBM Plex Mono
Projeto estático — sirva os arquivos por HTTP (módulos ES não funcionam via file://).
python3 -m http.server 8080Depois acesse http://localhost:8080.
As credenciais vêm de um .env local, transformado em config.js (ignorado pelo Git).
- Copie o exemplo:
cp .env.example .env - Preencha
SUPABASE_URLeSUPABASE_ANON_KEY(Project Settings → API) - Gere o arquivo:
node scripts/generate-config.js
⚠️ Use somente a chaveanon(pública), nunca aservice_role.Na Vercel, cadastre as duas variáveis em Settings → Environment Variables; o
vercel.jsongera oconfig.jsdurante o build.
| Tabela | Papel |
|---|---|
medidores_base |
Base principal — medidores bypassados que precisam ser tratados |
UTD_PID |
Tratamentos — registros operacionais lançados pelas equipes |
O vínculo entre elas é a coluna UTD_PID.medidor_base_id, preenchida automaticamente na inserção e pelas rotinas de sincronização.
medidores_base.numero_medidor_norm é uma coluna gerada (normalizar_medidor) com índice único: é ela que garante a busca imune a zeros à esquerda e formatação.
O papel anon não tem SELECT nas tabelas. Toda leitura e escrita passa por funções SECURITY DEFINER:
| RPC | Uso |
|---|---|
consultar_medidor |
Consulta de medidor (existência + tratamento + histórico) |
indicadores_utd_pid |
KPIs, progresso, evolução, por equipe, por mês |
listar_tratamentos |
Histórico com busca, filtros e paginação |
listar_equipes |
Opções do filtro de equipe |
inserir_utd_pid |
Grava o tratamento e vincula à base |
importar_medidores_base |
Importa a planilha (upsert; nunca apaga linhas) |
sincronizar_base_com_registros |
Traz para a base medidores que só existem nos tratamentos |
resumo_base_medidores |
Resumo exibido na tela de base |
Como o app não tem autenticação, essas RPCs são executáveis pelo
anon— inclusive as de escrita, mesmo padrão que o projeto já usava. Se um dia o sistema ganhar login, o caminho é restringir osgrant executeao papelauthenticated.
O bucket medidores-bypassados guarda as fotos dos medidores instalado e retirado (compactadas no navegador antes do upload).
Os scripts ficam em migrations/ e devem ser rodados no SQL Editor do Supabase, em ordem cronológica. A migração desta versão é 2026_09_plataforma_consulta_medidores.sql.
A base principal é o que permite distinguir pendente de inexistente. Para carregá-la:
- Acesse Base de medidores
- Selecione a planilha (
.csv,.xlsxou.xls) — a primeira linha deve conter os títulos das colunas - Confira o mapeamento das colunas (o sistema tenta detectar automaticamente)
- Clique em Importar
A importação é um upsert pelo número normalizado do medidor: medidores já cadastrados são atualizados, nenhum é apagado. Colunas aceitas: número do medidor (obrigatório), conta contrato, ordem de serviço, endereço, localidade, região, alimentador e observação.
Enquanto a planilha oficial não é importada, o botão Sincronizar base com registros popula a base a partir dos medidores retirados já registrados, para que a consulta funcione com o histórico existente.
| Campo | Coluna | Obrigatório |
|---|---|---|
| Ordem de serviço | ordem_servico |
✅ |
| Equipe | nome_equipe |
✅ |
| Colaborador | colaborador |
|
| Conta contrato | conta_contrato |
|
| Medidor instalado | medidor_instalado |
✅ ou o retirado |
| Medidor retirado | medidor_retirado |
✅ ou o instalado |
| Medidor vizinho | medidor_vizinho |
|
| Foto do medidor instalado | foto_medidor_instalado |
|
| Foto do medidor retirado | foto_medidor_retirado |
A ordem de serviço é única no banco: uma tentativa de lançamento duplicado retorna uma mensagem clara em vez de erro técnico.
A coluna tratado continua sendo controle interno manual e aparece no histórico como Validado / Em análise.
Uso interno.