From ac0524d60f390ba2f9665836a2705b60373485e68ba8914c0e10b3c3353e5b6b Mon Sep 17 00:00:00 2001 From: victor Date: Tue, 30 Jun 2026 01:00:13 -0300 Subject: [PATCH] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20Read;me?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3933456..4437c25 100644 --- a/README.md +++ b/README.md @@ -1032,7 +1032,7 @@ docker-compose exec app bundle exec rails db:migrate -
+
🔧 Atualização 29/06/2026 — Responsividade da tela de Validar (telas menores) Correção da **quebra de layout** dos cards de NF na tela **Passo 2 (Validar)** em telas pequenas e @@ -1062,3 +1062,77 @@ em tablets, reportada nos prints `Imagens para correção/Imagem colada (16).png
+
+🆕 Atualização 29/06/2026 — Dashboard de Operações (análise de entregas + mapa) + +Nova página **`/dashboard/operacoes`** (link **📈 Operações** no menu), separada do dashboard +financeiro, focada na **qualidade das entregas** por operação (UBS Norte, EMAD, …). Reproduz os +painéis das imagens de referência (`Imagens para implantação/`) e adiciona análise comparativa e mapa. +Acessível a todos menos motorista (`DashboardPolicy#operacoes?`). + +### 🆕 Funcionalidades +- **3 modos na mesma página** (abas): + - **🏥 Operação** — uma operação por vez. **Sem filtro de data**: mostra o conjunto inteiro da + operação e o período exibido vem dos próprios dados (menor/maior `checkout`). + - **🌐 Global** — todas as operações agregadas, aí sim com **faixa de datas** (flatpickr + atalhos + Hoje/7d/Este mês/30d). A faixa de data **só vale no Global**. + - **⚖️ Comparar** — duas operações lado a lado com bloco **Comparativo** (tabela A | B | Δ com o + melhor valor de cada linha em verde + gráfico de barras agrupadas) e detalhe completo recolhível. +- **Painéis** (espelham as imagens 2 e 3): KPIs (Total / Sucesso / Recusas / Pendentes), donut + **Insucessos %**, **Índices de Falha** (por `observation`), **Por Status** (status_gade + RECORRENTE/NOVO), **NFs por Motorista**, **Entregas por STS/Unidade** (`contact_name`), **Entregas + por Dia** (barras empilhadas) e **Mapa**. +- **Cross-filter ao vivo (toggle)** — clicar em qualquer linha das tabelas (Motorista, Unidade, + Status, Observação) **refiltra todo o dashboard** por aquele valor; clicar de novo na linha ativa + **remove** o filtro. Chips removíveis + "Limpar tudo" no topo. +- **Mapa de entregas** com: + - alternância **🔥 Calor** (heatmap) ⇄ **📍 Pontos** (um balão por entrega na coordenada de + **check-out**); + - **camadas** 🌙 Escuro (padrão) / 🗺️ Claro / 🛰️ Satélite (todas grátis, sem chave); + - **tela cheia** (Fullscreen API); + - **popup** por entrega (NF, destinatário, endereço, unidade, motorista, data) com a **foto da + fachada** (coluna `foto_da_fachada`), aberta em tamanho cheio ao clicar. +- **Cores** dos gráficos na identidade da marca: laranja `#f97316` (completas) e vermelho `#ef4444` + (falhas); no comparativo A = laranja, B = azul. + +### ⚙️ Como funciona (técnico) +- Núcleo de dados em **`app/services/analytics/operacao_metricas.rb`** (PORO). Monta um SQL que + **espelha a query de gestão**: CTE `ROW_NUMBER() OVER (PARTITION BY reference_id ORDER BY checkout + DESC)` sobre `db_reem_simplerout_2026` + `INNER JOIN` na tabela `gade_entregas_*` por + `reference_id::text = nota_fiscal`; agrega tudo em Ruby (visão `linhas` = registros após o + cross-filter). +- **Sem filtro de conta** (`account_id`): o INNER JOIN com a tabela da operação já restringe ao + cliente — replicar `da_conta_gade` zerava tudo quando `DB_EXISTING_ACCOUNT_ID` não batia. +- **Schema gade não-uniforme**: só `nota_fiscal` é garantida. Colunas opcionais (`status`, + `nome_completo`, `endereco_completo`) são detectadas por tabela (`conn.columns`) e viram `NULL` + quando não existem — assim o `UNION ALL` entre operações no Global não quebra + (era o erro `column g.status does not exist`). +- **Segurança**: nomes de tabela passam por `Operacao.sanitizar` + `quote_table_name`; a `foto_da_fachada` + é validada como URL `http(s)` antes de ir ao ``, com escape de HTML no popup. +- **Performance do mapa**: marcadores criados **sob demanda** (só ao abrir "Pontos") e o popup é uma + **função** — a foto do S3 só é requisitada **ao clicar** no balão (nada é baixado no load). Limite + de 2000 marcadores. +- **Filtro de período** opcional no serviço (`inicio:`/`fim:`): aplicado só no Global. + +### 📂 Arquivos +``` +app/services/analytics/operacao_metricas.rb # NOVO — núcleo de dados/agregações +app/controllers/operacoes_dashboard_controller.rb # NOVO — modos + cross-filter +app/views/operacoes_dashboard/index.html.erb # NOVO — filtros, abas, charts, mapa (JS) +app/views/operacoes_dashboard/_painel.html.erb # NOVO — KPIs/donut/tabelas/gráfico +app/views/operacoes_dashboard/_comparativo.html.erb # NOVO — tabela A|B|Δ + barras agrupadas +app/views/operacoes_dashboard/_mapa.html.erb # NOVO — calor/pontos, camadas, tela cheia +app/views/operacoes_dashboard/_tabela_simples.html.erb # NOVO — tabela reutilizável + cross-filter +spec/services/analytics/operacao_metricas_spec.rb # NOVO — specs das agregações/cross-filter +spec/requests/operacoes_dashboard_spec.rb # NOVO — autorização por role + modos +config/routes.rb # rota get /dashboard/operacoes +app/policies/dashboard_policy.rb # operacoes? (todos menos motorista) +app/views/layouts/_navbar.html.erb # link "📈 Operações" +``` + +> **Sem migration** — tudo lê tabelas existentes (`db_reem_simplerout_2026` read-only e +> `gade_entregas_*`). Libs front via CDN (Chart.js, Leaflet + leaflet.heat, flatpickr). +> ⚠️ Em produção, **reiniciar o servidor** (Puma) após o deploy — o Rails cacheia classes/views. + +
+