# Refatoração Dashboard Logística → API V2 — Spec

## Contexto e problema

O sinal `Logistica/Dashboard` (rota `/missao/logistica/dashboard`) ficou para trás do padrão V2 desacoplado adotado em `Mensageria/Otp` e `Logistica/Edicaorota`. Hoje o frontend usa o canal legado `sendToGalaxia`, o controller PHP concatena HTML em strings e existe um sinal `DashboardApi` paralelo que ninguém consome. Isso bloqueia manutenibilidade, testabilidade, i18n e consistência com as referências canônicas — e impede que o dashboard participe do contrato `/api/v1` que já é a porta de entrada oficial do frontend Genesis.

## Escopo

- ✅ Faz parte:
  - Refatorar `componentes/Missoes/Logistica/sinais/Dashboard/` para o padrão V2 (dispatcher fino, sem HTML em string PHP).
  - Criar handlers em `Plataforma/sinais/Api/Handlers/Dashboard/` cobrindo as 9 operações do `renderDashboard` atual + filtrar + ação em missão + detalhes de missão.
  - Registrar as rotas `/dashboard/*` em `Plataforma/sinais/Api/Routes.php` no padrão Otp/Edicaorota.
  - Trocar todas as interações de `html/dashboard.js` para `fetch('/api/v1/dashboard/*')` autenticado por JWT.
  - Validators dedicados para entrada dos handlers.
  - Manter a aparência e o comportamento do dashboard idênticos ao atual (zero regressão visual/funcional para o gestor).
  - Testes cobrindo handlers e fluxos críticos.
  - Documentar destino do sinal paralelo `DashboardApi` (recomendar deprecação).
- ❌ Fora de escopo:
  - Redesenho de UX, novas visualizações, novos filtros ou novas ações.
  - Mudanças no `DashboardLaboratorio` além do estritamente necessário para os handlers consumirem-no.
  - Outros sinais de Logística (Edicaorota, Board, Central, Armazem, Mapas...).
  - Abrir a API publicamente — segue interna, com `/docs` e `/openapi.json` gateados por `Config::DEV_USER_IDS`.
  - Remover o sinal `DashboardApi` (apenas marcar como deprecado).
  - Remover `Logistica/sinais/Armazem copy/`.
  - Migração completa de i18n das strings já existentes — apenas não introduzir piora.
  - Alterações de schema / migrations (não previstas).

## User stories

### US1 — Gestor logístico continua operando o dashboard sem perceber o refactor
**Como** gestor logístico **eu quero** abrir `/missao/logistica/dashboard`, filtrar, executar ações em missão e abrir detalhes **para** acompanhar a operação como faço hoje.

**Critérios de aceite:**
- AC1.1: Após o refactor, o layout, os blocos exibidos, os filtros disponíveis e as ações em missão são visualmente e funcionalmente equivalentes ao estado anterior (regressão visual zero).
- AC1.2: Filtrar o dashboard atualiza kanban, veículos e rotas com os mesmos dados que o fluxo legado retornava para os mesmos filtros.
- AC1.3: Executar uma ação em missão a partir do dashboard produz o mesmo efeito de domínio que o fluxo legado.
- AC1.4: Abrir os detalhes de uma missão exibe as mesmas informações que o fluxo legado exibia.
- AC1.5: Tempo percebido de carregamento inicial e de filtragem não regride de forma observável (sem novos spinners "infinitos" ou travas).

### US2 — Frontend do dashboard fala apenas `/api/v1`
**Como** dev Genesis **eu quero** que `dashboard.js` consuma exclusivamente `/api/v1/dashboard/*` **para** alinhar o sinal ao padrão V2 e ao contrato oficial da API interna.

**Critérios de aceite:**
- AC2.1: Busca por `sendToGalaxia` em `componentes/Missoes/Logistica/sinais/Dashboard/html/dashboard.js` retorna zero ocorrências.
- AC2.2: Toda chamada de rede do `dashboard.js` aponta para `/api/v1/dashboard/...` e envia JWT no header `Authorization`.
- AC2.3: Erros HTTP (401/403/4xx/5xx) das chamadas API são tratados e exibidos ao usuário sem quebrar a tela.

### US3 — Controller vira dispatcher fino
**Como** dev Genesis **eu quero** que `Dashboard.php` deixe de concatenar HTML e de orquestrar lógica de dados **para** que o sinal siga a regra "controller é dispatcher fino" das referências V2.

**Critérios de aceite:**
- AC3.1: Busca pelos literais `'<tr`, `'<div`, `'<td`, `'<li` em `Dashboard.php` retorna zero ocorrências.
- AC3.2: Os métodos `filtrarDashboard` e `detalhesMissao` deixam de existir no controller (ou ficam como stubs deprecados sem lógica) — a responsabilidade vive nos handlers `/api/v1`.
- AC3.3: O controller continua capaz de servir o shell HTML inicial da rota `/missao/logistica/dashboard`.

### US4 — Handlers cobrem o conjunto completo de operações do dashboard
**Como** dev Genesis **eu quero** handlers `/api/v1/dashboard/*` para cada operação que o dashboard precisa **para** que o frontend não dependa de canais legados nem do sinal paralelo `DashboardApi`.

**Critérios de aceite:**
- AC4.1: Existem handlers cobrindo, no mínimo: resumo operacional, listar missões, desempenho, alertas, tipos de missão, extrato, visão geral do dia, status de veículos, rotas do dia, filtrar dashboard, executar ação em missão, obter detalhes de missão.
- AC4.2: Cada handler tem um Validator dedicado em `Validators/` validando entrada antes de tocar em domínio.
- AC4.3: `Plataforma/sinais/Api/Routes.php` registra ≥10 rotas sob o prefixo `/dashboard/*` no mesmo padrão dos blocos de Otp e Edicaorota.
- AC4.4: As respostas dos handlers são JSON puro — nenhum handler devolve HTML serializado.
- AC4.5: Multi-tenant é respeitado: handlers consideram `customerControl`/`companyControl` e colunas `block_*` como o restante do código V2.

### US5 — Cobertura de testes para os fluxos críticos
**Como** dev Genesis **eu quero** testes em `Logistica/sinais/Dashboard/Testes/` **para** travar regressões nos fluxos refatorados.

**Critérios de aceite:**
- AC5.1: Existem testes cobrindo cada handler novo (caminho feliz + ao menos um caminho de erro/validação).
- AC5.2: Existe ao menos um teste de fluxo end-to-end para "filtrar dashboard" e para "ação em missão".
- AC5.3: A suíte roda com sucesso no ambiente `dev_gx_goldie`.

### US6 — Destino do sinal paralelo `DashboardApi` documentado
**Como** dev Genesis **eu quero** uma decisão registrada sobre o sinal `Logistica/sinais/DashboardApi/` **para** que ninguém consuma uma terceira via depois do refactor.

**Critérios de aceite:**
- AC6.1: O `DashboardApi/` recebe um marcador (README/comentário) indicando deprecação e apontando para os handlers `/api/v1/dashboard/*` substitutos.
- AC6.2: A remoção propriamente dita fica registrada como débito técnico em "Dúvidas em aberto" / próximo PRD.

## Personas envolvidas

| Persona | Papel | Ponto de contato com a feature |
|---|---|---|
| Gestor logístico | Usuário final do dashboard | Continua usando `/missao/logistica/dashboard` — não deve perceber a troca |
| Dev Genesis (manutenção) | Mantém os sinais de Logística | Passa a ter o Dashboard alinhado a Otp/Edicaorota como referência |
| Dev Genesis (Plataforma/Api) | Dono dos handlers `/api/v1` | Recebe ~12 novos handlers + rotas em `Routes.php` |
| Futuro consumidor externo da API | Hipotético, não ativo hoje | API permanece interna, mas o contrato `/api/v1/dashboard/*` já fica formalizado |

## Dados / entidades-chave (alto nível)

- Missão (operação de logística que aparece no kanban, em alertas, em extrato e nos detalhes)
- Veículo (status atual, vinculado às rotas do dia)
- Rota do dia (rota planejada/executada por veículo)
- Tipo de missão (categoria usada nos blocos de tipos)
- Alerta operacional (item exibido no bloco de alertas)
- Extrato operacional (linha do tempo / histórico do dia)
- Resumo operacional / visão geral do dia (agregados exibidos nos blocos de topo)
- Filtro do dashboard (conjunto de critérios aplicado pelo gestor)
- Usuário autenticado / contexto multi-tenant (customer/company) — consumido por todo handler

## Regras de negócio

1. O dashboard nunca pode regredir visual ou funcionalmente para o gestor logístico — paridade com o estado atual é requisito de aceite.
2. Toda interação de rede do dashboard sai por `/api/v1/dashboard/*` autenticada por JWT; o canal `sendToGalaxia` é proibido para este sinal após o refactor.
3. Handlers devolvem exclusivamente JSON; HTML é montado no cliente (JS) ou via Luz components no shell inicial — nunca concatenado em string PHP.
4. Cada handler tem Validator dedicado e respeita as regras multi-tenant (`customerControl`/`companyControl`, `block_*`).
5. A API permanece interna: `/docs` e `/openapi.json` continuam gateados por `Config::DEV_USER_IDS`.
6. Não estender Inteligencias (V1); código novo usa Sondas (V2). Writes via `->update()`/`->create()` da Sonda — proibido raw SQL via `Connect::getInstance` para escrita.
7. `DashboardLaboratorio` é tratado como dependência estável: alterar só o mínimo para ser consumido pelos handlers; nenhuma reescrita da camada de dados nesta feature.
8. O sinal paralelo `Logistica/sinais/DashboardApi/` deve ser marcado como deprecado, mas não removido nesta feature.
9. Decisão de produto sobre carregamento inicial: o shell inicial é renderizado pelo controller (SSR mínimo) e os 9 blocos de dados são carregados via chamadas `/api/v1/dashboard/*` após o load do JS — alinhado ao espírito "API V2 desacoplado" e ao padrão Edicaorota. Caso medições mostrem regressão de TTI perceptível pelo gestor (viola RN 1), reabrir como dúvida.

## Métricas de sucesso

- Zero ocorrências de `sendToGalaxia` em `componentes/Missoes/Logistica/sinais/Dashboard/html/dashboard.js`.
- Zero ocorrências de literais de tags HTML (`'<tr`, `'<div`, `'<td`, `'<li`) em `Dashboard.php`.
- ≥10 rotas `/dashboard/*` registradas em `Plataforma/sinais/Api/Routes.php`.
- Suíte de testes em `Logistica/sinais/Dashboard/Testes/` verde em `dev_gx_goldie`.
- Validação manual do gestor logístico (ou QA): paridade visual e funcional confirmada na rota `/missao/logistica/dashboard`.
- Tempo de filtragem percebido igual ou melhor ao do fluxo legado (sem novos travamentos).

## Dúvidas em aberto

- [ ] Confirmar com o PO/usuário a decisão de carregar os 9 blocos via API após o load (RN 9). Se TTI regredir, considerar SSR de um subconjunto crítico (ex.: resumo operacional + visão geral do dia) e API para o resto.
- [ ] Existe alguma operação do dashboard que dependa de estado de sessão/contexto não trivialmente serializável em request `/api/v1` (ex.: filtros "sticky" entre páginas)? Se sim, definir onde mora a persistência desse estado.
- [ ] Para a "ação em missão" disparada do dashboard: ela deve reaproveitar handlers já existentes em outros domínios (ex.: Edicaorota/handlers de missão) ou ganhar handlers próprios sob `/api/v1/dashboard/*`? Decisão tem impacto em duplicação de contrato.
- [ ] Plano e dono da remoção definitiva do sinal `Logistica/sinais/DashboardApi/` — abrir PRD seguinte ou anexar ao próximo ciclo?
- [ ] Tratamento de erro padronizado no `dashboard.js`: existe um helper Genesis para toast/feedback de erro de API que deve ser adotado, ou cada chamada decide o seu?
