# Timeline Overview — Guia de Indicadores

> **IMPORTANTE:** Sempre que alterar qualquer indicador, cálculo ou lógica no `gt_timelineoverview/`, este guia DEVE ser atualizado para manter a documentação sincronizada. Se estiver usando IA em outro contexto, consulte este guia antes de fazer alterações.

---

## Arquitetura

- **Pasta:** `gt_timelineoverview/`
- **select.php:** Todas as queries e cálculos de dados
- **index.php:** Renderização HTML/JS dos indicadores
- **Verificações:** `verificacoes/` — SQLs para auditoria dos dados apresentados

---

## Tabelas Utilizadas

| Tabela | Uso | Filtro principal |
|--------|-----|-----------------|
| `dim_veiculostelemetria` | Dados do veículo, tecnologia (`tiporastreador`) | `placa_veiculo` |
| `ft_posicao` | Posições GPS do veículo | `mct_position`, período |
| `dim_conhecimento` | Faturamento (CT-e's) | `placa`, período |
| `ft_controleabs` | Abastecimentos (fro003) | `placa`, `empresa`, período |
| `tel006_deltatelemetria` | Telemetria (km, rpm, eventos) | `mct`, `empresa`, período |
| `jor005_jornada` | Jornada do motorista | `idveiculo`, `empresa`, período |
| `tms001_viagem` | Viagens programadas | `veiculo`, período |
| `tms005_ocorrencia` | Ocorrências/Alertas | `veiculo`, `empresa`, período |
| `tms004_vencimento` | Vencimentos do veículo | `veiculo`, `empresa` |
| `fro010_vencimentopessoa` | Vencimentos do motorista | `pessoa`, `empresa` |
| `jor004_escala` / `jor004a_diasescala` | Escala do motorista (limite jornada) | FK via `jor002_funcionario` |

---

## Tecnologia do Veículo

- **Fonte primária:** `dim_veiculostelemetria.tiporastreador`
- **Fallback:** `tel006_deltatelemetria.tecnologia` (se tiporastreador = 0)
- **Mapeamento:**
  - 0 = Padrão
  - 1 = Sascar
  - 2 = Onyx
  - 3 = Autotrac
  - 4 = 3S
  - 5 = Retrac
  - 6 = Maxtrack

### Impacto da tecnologia na exibição:
- **Sascar (1):** Gráfico mostra "Tempo em Faixa" (em minutos, dados de `tempofaixa*` em segundos ÷ 60)
- **Demais:** Gráfico mostra "Distribuição por Faixa de RPM" (em km, dados de `kmfaixa*` em metros ÷ 1000)

---

## Indicadores por Seção

### 1. KPIs (sempre visíveis se houver posições)

| Indicador | Fonte | Cálculo |
|-----------|-------|---------|
| KM Rodado | `ft_posicao` | Soma distância entre posições |
| Velocidade Máx | `ft_posicao` | `MAX(velocidade_position)` |
| Tempo em Trânsito | `ft_posicao` | Diferença entre primeira e última posição com velocidade > 0 |
| Posições | `ft_posicao` | `COUNT(*)` |
| Ignições | `ft_posicao` | `COUNT(DISTINCT data_position::date)` ou agrupamento |

---

### 2. Telemetria (visível se `$ov_tel_ignicoes > 0`)

| Indicador | Fonte | Cálculo |
|-----------|-------|---------|
| Km Telemetria | `tel006_deltatelemetria` | `SUM(km)` |
| Km Econômico | `tel006_deltatelemetria` | `SUM(kmfaixaeconomica)/1000` |
| Km Agressivo | `tel006_deltatelemetria` | `SUM(kmfaixavermelha + kmfaixaamarela)/1000` |
| Vel. Máxima | `tel006_deltatelemetria` | `MAX(velocidademax)` |
| RPM Máximo | `tel006_deltatelemetria` | `MAX(rpm_max)` |
| Score Condução | Cálculo | Baseado em 5 variáveis (vel, acel, freada, ml, fm) — veja Score abaixo |
| Excessos Vel. | `tel006_deltatelemetria` | `SUM(qtd_excessos)` |
| Aceleração Brusca | `tel006_deltatelemetria` | `SUM(qtd_acelbrusca)` |
| Freada Brusca | `tel006_deltatelemetria` | `SUM(qtd_freadasbrusca)` |
| Marcha Lenta | `tel006_deltatelemetria` | `SUM(qtd_marchalenta)` |
| Freio Motor | `tel006_deltatelemetria` | `SUM(qtd_freiomotor)` |

#### Faixas de RPM/Tempo (Gráfico Doughnut)

**Para Maxtrack/Autotrac/Padrão (km):**

| Faixa | Campo | Cálculo |
|-------|-------|---------|
| Azul (<1100 RPM) | `kmfaixaazul` | `SUM(kmfaixaazul)/1000` |
| Verde | `kmfaixaverde` | `SUM(kmfaixaverde)/1000` |
| Econômica | `kmfaixaeconomica` | `SUM(kmfaixaeconomica)/1000` |
| Amarela (≥1100 RPM) | `kmfaixaamarela` | `SUM(kmfaixaamarela)/1000` |
| Vermelha | `kmfaixavermelha` | `SUM(kmfaixavermelha)/1000` |

**Para Sascar (tempo em minutos):**

| Faixa | Campo | Cálculo |
|-------|-------|---------|
| Azul | `tempofaixaazul` | `SUM(tempofaixaazul)` (segundos, exibido ÷ 60 = min) |
| Verde | `tempofaixaverde` | `SUM(tempofaixaverde)` ÷ 60 |
| Econômica | `tempofaixaeconomica` | `SUM(tempofaixaeconomica)` ÷ 60 |
| Amarela | `tempofaixaamarela` | `SUM(tempofaixaamarela)` ÷ 60 |
| Vermelha | `tempofaixavermelha` | `SUM(tempofaixavermelha)` ÷ 60 |

#### Score de Condução (Gráfico Radar)

Calculado por 5 componentes, cada um de 0 a 100:

```
sv (Velocidade): max(0, 100 - excessos×2)
sa (Aceleração): max(0, 100 - acel_brusca×3)
sf (Frenagem):   max(0, 100 - freada_brusca×3)
se (Economia):   pct_km_economico (0-100%)
sfm (Freio Motor): min(100, freio_motor × 5)
Score Final = (sv + sa + sf + se + sfm) / 5
```

---

### 3. Jornada (visível se `$ov_jor_total > 0`)

| Indicador | Fonte | Cálculo |
|-----------|-------|---------|
| Jornadas | `jor005_jornada` | `COUNT(*)` |
| Tempo Total | `jor005_jornada` | `SUM(tempojornada)` em minutos |
| Média/Dia | `jor005_jornada` | `AVG(tempojornada)` em minutos |
| Estouros | `jor005_jornada` | `COUNT(WHERE tempojornada > escala_limite)` — escala via `jor004a_diasescala`, default 600 min (10h) |
| Quebra Interstício | `jor005_jornada` | `COUNT(WHERE tempointerticio < 660 AND > 0)` — mínimo 11h entre jornadas |
| Dias s/ Folga | `jor005_jornada` | `MAX(diassemfolga)` — alerta se ≥ 7 |
| Refeição Curta | `jor005_jornada` | `COUNT(WHERE temporefeicao < 60 AND > 0)` — mínimo 1h |
| Horas Extra | `jor005_jornada` | `SUM(tempojornada - escala_limite)` onde estoura |
| Total Violações | Cálculo | `estouros + quebra_inter + max(0, dias_sem_folga - 6) + refeicao_curta` |

#### Violações detalhadas (tabela)
Cada jornada que possui violação aparece com:
- Data, Motorista, Tipo de violação, Detalhe (tempo/limite)
- Cores: Estouro=#dc3545, Interstício=#e65100, Refeição=#ff9800, 7ºDia=#b71c1c

---

### 4. Rentabilidade (visível se `$ov_faturamento > 0 || $ov_custo_comb > 0`)

| Indicador | Fonte | Cálculo |
|-----------|-------|---------|
| Faturamento | `dim_conhecimento` | `SUM(valormercadoria)` |
| Custo Combustível | `ft_controleabs` | `SUM(valortotal)` |
| Comb/Fat % | Cálculo | `(custo_comb / faturamento) × 100` |
| **Custo Ideal** | Cálculo | `faturamento × 0.30` (meta = 30% do faturamento) |
| Margem Bruta | Cálculo | `faturamento - custo_comb` |
| Margem % | Cálculo | `(margem / faturamento) × 100` |

#### Classificação de Nível (% Comb/Fat)

| Faixa | Nível | Cor | Score |
|-------|-------|-----|-------|
| ≤ 20% | EXCELENTE | #198754 | 95 |
| ≤ 25% | BOM | #20c997 | 80 |
| ≤ 30% | REGULAR | #0dcaf0 | 65 |
| ≤ 35% | ATENÇÃO | #ffc107 | 45 |
| ≤ 40% | CRÍTICO | #fd7e14 | 25 |
| > 40% | PÉSSIMO | #dc3545 | 10 |

#### Eficiência, Variação da Meta e Tendência

| Indicador | Fórmula | Significado |
|-----------|---------|-------------|
| **Eficiência** | `(Custo Combustível / Custo Ideal) × 100` | Quanto % do "orçamento ideal" (30% do faturamento) foi gasto. **≤100%** = dentro da meta, **>100%** = estourou |
| **Custo Ideal** | `Faturamento × 30%` | Meta de referência — combustível não deveria superar 30% do faturamento |
| **Var. Meta** | `Custo Combustível − Custo Ideal` | Diferença em R$. **Negativo** = economia (bom). **Positivo** = estouro da meta (ruim) |
| **Tendência** | Comparação custo vs ideal | **REDUZINDO**: custo ≤ 90% ideal. **ESTÁVEL**: 90–100% ideal. **AUMENTANDO**: acima do ideal |

**Exemplo prático:**
- Faturou R$ 10.000 → Custo Ideal = R$ 3.000 (30%)
- Gastou R$ 2.500 → Eficiência = 83% (ótimo), Var. Meta = −R$ 500 (economia), Tendência = REDUZINDO

#### Indicadores complementares

| Indicador | Cálculo |
|-----------|---------|
| Km/L (Telemetria) | `km_telemetria / litros_abastecidos` |
| Custo/Km (Telemetria) | `custo_comb / km_telemetria` |
| Receita/Km | `faturamento / km_rodado` |
| Economia potencial | `custo_comb - custo_ideal` (se positivo) |

---

### 5. Viagens (visível se `$ov_viagens > 0`)

| Indicador | Fonte | Cálculo |
|-----------|-------|---------|
| Total Viagens | `tms001_viagem` | `COUNT(*)` |
| Km Total | `tms001_viagem` | `SUM(kmviagem)` |
| Programadas | `tms001_viagem` | `COUNT(WHERE situacao = 'Programada')` |
| Em Andamento | `tms001_viagem` | `COUNT(WHERE situacao = 'EmTrânsito')` |
| Finalizadas | `tms001_viagem` | `COUNT(WHERE situacao IN ('Finalizada','Encerrada'))` |

---

### 6. Alertas/Ocorrências (visível se `$ov_alertas > 0 || $ov_ocorrencias > 0`)

| Indicador | Fonte | Cálculo |
|-----------|-------|---------|
| Total Alertas | `tms005_ocorrencia` | `COUNT(*)` |
| Pendentes | `tms005_ocorrencia` | `COUNT(WHERE situacao = 0)` |
| Tratados | `tms005_ocorrencia` | `COUNT(WHERE situacao = 1)` |

---

### 7. Vencimentos (visível se `$ov_vcto_total > 0 || $ov_vcto_pessoa_total > 0`)

**Veículo** (`tms004_vencimento`):
- CNH, CRLV, Revisão, Pneus, Seguro, etc.
- Status: Vencido (dias < 0), Atenção (dias ≤ 30), OK (dias > 30), ou por Km

**Motorista** (`fro010_vencimentopessoa`):
- Documentos pessoais do motorista

---

## Visibilidade Condicional

O Timeline Overview **se adapta** ao que o cliente alimenta:

| Seção | Condição para exibir | O que alimentar |
|-------|---------------------|-----------------|
| Rastreamento | Sempre (posições existem) | ft_posicao |
| Telemetria | `$ov_tel_ignicoes > 0` | tel006_deltatelemetria |
| Jornada | `$ov_jor_total > 0` | jor005_jornada |
| Rentabilidade | `$ov_faturamento > 0 \|\| $ov_custo_comb > 0` | dim_conhecimento + ft_controleabs |
| Viagens | `$ov_viagens > 0` | tms001_viagem |
| Alertas | `$ov_alertas > 0 \|\| $ov_ocorrencias > 0` | tms005_ocorrencia |
| Vencimentos | `$ov_vcto_total > 0 \|\| $ov_vcto_pessoa_total > 0` | tms004_vencimento / fro010_vencimentopessoa |

---

## Rodapé de Benefícios

No final da página existe um rodapé que mostra:
- **Verde (✓):** Seções ativas com dados
- **Laranja:** Seções que o cliente pode desbloquear alimentando dados
- **Vermelho:** Seções que dependem de múltiplos módulos (ex: Rentabilidade = Faturamento + Abastecimento)

---

## Motoristas Múltiplos

Se o período selecionado abrange mais de um motorista, o sistema:
1. Busca por `tms001_viagem` primeiro (viagens com motoristas distintos)
2. Fallback: busca por `jor005_jornada` (jornadas com funcionários distintos)
3. Cada motorista aparece como badge com período `(dd/mm–dd/mm)`

---

## Manutenção

### Checklist ao alterar indicadores:
1. ✅ Alterar query em `select.php`
2. ✅ Alterar exibição em `index.php`
3. ✅ Atualizar este guia (`guias/TIMELINE_OVERVIEW_INDICADORES.md`)
4. ✅ Atualizar SQL de verificação em `verificacoes/`
5. ✅ Testar com veículo Sascar e não-Sascar

### Checklist ao adicionar nova seção:
1. ✅ Adicionar variáveis de inicialização no topo de `select.php`
2. ✅ Adicionar query em `select.php`
3. ✅ Adicionar seção colapsável em `index.php`
4. ✅ Adicionar condição de visibilidade (`<?php if(...): ?>`)
5. ✅ Adicionar badge no rodapé de benefícios
6. ✅ Adicionar SQL de verificação em `verificacoes/`
7. ✅ Atualizar este guia

---

## Novidades / Atualizações recentes
A seguir documentamos as alterações implementadas na Timeline Overview — use estas notas para testes, manutenção e futuras mudanças.

### Timeline unificada (eventos)
- Agora a timeline combina todos os eventos datados em um único feed à direita: **viagens (início/fim), macros, checklists, alertas, abastecimentos, jornadas (início/fim) e vencimentos**.
- Estrutura de cada item no backend (`$ov_timeline_unificada`):
  - `tipo` (string), `icone` (material icon), `cor` (hex), `titulo`, `detalhe`, `data` (ISO), `data_fmt` (dd/mm/YYYY HH:MM), `tempo_desde` (duração desde evento anterior)
- Duração (`tempo_desde`) é calculada como diferença entre eventos consecutivos e exibida como badge `+Xh Ym`.
- Fallback: quando não houver eventos datados, a antiga tabela de posições (`tblTimeline`) permanece visível.

### Exemplo visual (ASCII)
Abaixo um mockup simplificado mostrando título, detalhe, timestamp e duração entre eventos (`tempo_desde`).

[▶ Viagem Início]     08/02/2026 07:12 ─ Início Viagem A                  | +—
[◆ Macro]             08/02/2026 08:05 ─ Macro: Carregamento iniciado    | +0h53m
[✓ Checklist]         08/02/2026 08:40 ─ Pré‑partida (Realizado)         | +0h35m
[⛽ Abastecimento]     08/02/2026 09:10 ─ 200 L @ Posto X                  | +0h30m
[⚠ Ocorrência]        08/02/2026 10:00 ─ Pendência: Manutenção         | +0h50m
[■ Viagem Fim]        08/02/2026 18:30 ─ Viagem finalizada              | +8h30m

![Exemplo de Timeline Unificada](images/timeline_example.svg)
*Figura: mockup da timeline unificada — ícones, título, detalhe, horário e badge de duração.*

Legenda rápida:
- `▶/■` — início/fim de viagem; `◆` — macro/fluxo; `✓` — checklist; `⛽` — abastecimento; `⚠` — alerta/ocorrência.
- `data_fmt` mostrado como `dd/mm/YYYY HH:MM`.
- `tempo_desde` mostra diferença para o evento anterior (ex.: `+0h35m`).

#### Macros
- Eventos de macro/fluxo são incluídos (ex.: início/fim de etapa de viagem) — consultam `tms001b_fluxo`, `tms002a_fluxo` e `dim_macros` quando aplicável.
- Observação: `ft_registrort` contém macro atual (estado em tempo real) — o histórico de macros vem de fluxos (`tms001b_fluxo` / `tms002a_fluxo`).

### Checklist (aps011_checklist vs fro006_checklist)
- `fro006_checklist` = **modelo/template** do checklist (descrição, periodicidade, vínculo).
- `aps011_checklist` = **instâncias agendadas/registradas** (dtprevista, dtexecucao, situação, lat/lng) — **fonte da timeline**.

Exemplo de query usada no overview:

```sql
SELECT a.*, f.descricao
FROM aps011_checklist a
LEFT JOIN fro006_checklist f ON f.id = a.tipo
WHERE a.veiculo = :placa
  AND a.dtprevista BETWEEN :dtinicio AND :dtfim
ORDER BY a.dtprevista DESC;
```

Mapeamento de `situacao` em `aps011_checklist`:
- 0 = Pendente
- 1 = Realizado
- 2 = Não Realizado

### Telemetria — cards (design atualizado)
- Visual: cards flat, `background: #fff`, `border-left` colorido, ícone circular e números em destaque.
- `Score` usa a cor `$ov_tel_score_cor` (hex) para borda esquerda.
- Preserve cálculos existentes em `select.php` — apenas a apresentação mudou.

### Correção do mapa
- Problema resolvido: mapa às vezes não renderizava corretamente quando container estava oculto/colapsado.
- Solução aplicada: `setTimeout(..., 500)` + `map.invalidateSize()` + `map.fitBounds(allLatLngs)` e adição de `ResizeObserver` no container do mapa para recalcular quando necessário.

### Rodapé — "Telas ocultas"
- Adicionado o Checklist nas visões disponíveis e implementada linha de resumo:
  `Telas ocultas (N): Telemetria, Faturamento, ...` — lista módulos que não têm dados suficientes.

### Exemplos rápidos de verificação (QA)
1. Timeline mostra checklist/macros/viagens no período selecionado — verifique `tempo_desde` entre eventos.  
2. Ao colapsar/expandir seções e redimensionar a janela, o mapa deve manter o zoom correto (sem áreas brancas).  
3. Rodapé deve exibir ✔ para seções com dados e listar na linha "Telas ocultas" as seções sem dados.  
4. Verificar `aps011_checklist` para registros Pendente/Realizado/Não Realizado e confirmar aparição na timeline.

### SQL de debug rápido — macros na timeline
```sql
SELECT f.codsituacao, f.descricao, m.descricao AS macro_desc, v.idveiculo, v.dtinicio, v.dtfinalizacao
FROM tms001b_fluxo f
JOIN tms001_viagem v ON v.codsituacao = f.codsituacao
LEFT JOIN dim_macros m ON m.codmacro = f.idmacro
WHERE v.veiculo = :placa
  AND (v.dtinicio BETWEEN :dtinicio AND :dtfim
       OR v.dtfinalizacao BETWEEN :dtinicio AND :dtfim
       OR (v.dtinicio <= :dtinicio AND (v.dtfinalizacao IS NULL OR v.dtfinalizacao >= :dtfim)));
```

---

## Manutenção

### Checklist ao alterar indicadores:
1. ✅ Alterar query em `select.php`
2. ✅ Alterar exibição em `index.php`
3. ✅ Atualizar este guia (`guias/TIMELINE_OVERVIEW_INDICADORES.md`)
4. ✅ Atualizar SQL de verificação em `verificacoes/`
5. ✅ Testar com veículo Sascar e não-Sascar

### Checklist ao adicionar nova seção:
1. ✅ Adicionar variáveis de inicialização no topo de `select.php`
2. ✅ Adicionar query em `select.php`
3. ✅ Adicionar seção colapsável em `index.php`
4. ✅ Adicionar condição de visibilidade (`<?php if(...): ?>`)
5. ✅ Adicionar badge no rodapé de benefícios
6. ✅ Adicionar SQL de verificação em `verificacoes/`
7. ✅ Atualizar este guia
