Situação 1: O Chamado da Fernanda
1. Mensagem de Primeiro Atendimento (Empatia e Alinhamento)
O primeiro contato com a cliente preza por **empatia imediata**, transparência no plano de ação e acolhimento sobre a urgência relatada.
2. Três Hipóteses Técnicas & Planos de Investigação
Causa: Erro fatal durante a renderização do frontend. Comum quando o script tenta acessar uma propriedade de um objeto nulo ou indefinido (ex: `fatura.cliente.nome` quando o objeto `cliente` não foi carregado da API). Sem um *Error Boundary* implementado, qualquer exceção no React quebra a renderização inteira, limpando a tela.
Como investigar: Solicitar que a cliente abra o Inspetor do Navegador (F12) e verifique a aba **Console** em busca de erros marcados em vermelho como `Uncaught TypeError: Cannot read properties of undefined` ou `Render error`.
Causa: O backend falhou ao processar a criação da fatura (ex: deadlock de concorrência na tabela `faturas` do banco de dados, falha de comunicação externa na API de emissão de boletos ou estouro de memória). O frontend não tratou a falha do status 500 no `catch()` da requisição HTTP, deixando a aplicação presa em um estado indefinido ou em tela de carregamento que crasha.
Como investigar: Acessar os logs de container da API executando docker logs kaello_backend_api filtrando os logs pelo horário do erro da cliente, verificando falhas de conexão ou queries inválidas.
Causa: Após deploy recente de correções no servidor, o formato do payload de faturamento mudou. O navegador da cliente mantém em cache de disco o script JavaScript antigo (`bundle.js`). Ao chamar a API com estruturas de dados obsoletas, a API retorna erro e o bundle local falha na execução.
Como investigar: Verificar se o faturamento funciona via aba anônima (que não carrega cache antigo de disco) e conferir as diretivas de cache no cabeçalho do Nginx (`Cache-Control: no-cache, no-store`).
Situação 2: Diagnóstico e Correção dos Bugs
Abaixo estão os trechos do código contendo as falhas e suas respectivas correções matemáticas e lógicas.
🐛 Chamado #1042 (Marina — Frete Gigante)
Causa: O campo de frete é obtido no formulário como String. Na operação const total = totalComDesconto + frete, o operador `+` realiza uma concatenação de strings ao invés de uma adição numérica aritmética (ex: `130 + "20" = "13020"`).
const frete = document.getElementById('frete').value;
// Soma o frete ao total
const total = totalComDesconto + frete;
const frete = parseFloat(document.getElementById('frete').value) || 0;
// Soma o frete ao total (Soma numérica segura)
const total = totalComDesconto + frete;
🐛 Chamado #1043 (Roberto — Desconto Zerando Total)
Causa: A fórmula matemática de desconto dividia o percentual por `10` em vez de `100`. Assim, ao aplicar 10% de desconto, o cálculo computava um desconto de 100% (`10 / 10 = 1`), reduzindo o total financeiro para zero.
// Aplica o desconto percentual sobre o subtotal
const valorDesconto = subtotalGeral * (descontoPct / 10);
const totalComDesconto = subtotalGeral - valorDesconto;
// Aplica o desconto percentual sobre o subtotal
const valorDesconto = subtotalGeral * (descontoPct / 100);
const totalComDesconto = subtotalGeral - valorDesconto;
🐛 Chamado #1044 (Paula — Remoção Incorreta)
Causa: A função `removerItem(indice)` recebia o índice correto do item no loop da tabela, mas possuía uma instrução estática para deletar o primeiro elemento do array (`itens.splice(0, 1)`), ignorando o parâmetro.
function removerItem(indice) {
// Remove um item da lista pelo índice
itens.splice(0, 1);
render();
}
function removerItem(indice) {
// Remove um item da lista pelo índice dinâmico
itens.splice(indice, 1);
render();
}
- Validação de Entradas: Bloqueada a inclusão de itens com quantidade menor ou igual a zero, ou com valores de preço negativos.
- Prevenção de NaN: Adicionados operadores de fallback (`|| 0`) nos inputs de frete e desconto para evitar a corrupção do cálculo financeiro caso os campos sejam apagados.
- Focus Automático (UX): Implementada a lógica para focar automaticamente a entrada "Produto / Serviço" após a inserção bem-sucedida, facilitando o cadastro de múltiplos itens.
Situação 3: Olhar de Produto e Usabilidade
Melhorias de produto focadas no ganho de eficiência no dia a dia do faturista.
Dropdown Inteligente com Autocomplete (Combobox)
No lugar do input de texto genérico para o produto, implementou-se um autocomplete integrado ao catálogo de produtos. Ao selecionar, o sistema preenche o preço unitário padrão automaticamente. Isso reduz significativamente erros de digitação e poupa o tempo gasto na busca manual de tabelas de preços.
Estado Vazio (Empty State) Direcionado
Quando nenhum item foi adicionado ainda, as caixas de desconto e frete ficam desabilitadas, e uma ilustração explicativa instrui o usuário a adicionar o primeiro item. Isso elimina ruídos de usabilidade e evita cálculos ilógicos sem produtos cadastrados.
Notificações Toasts Não-Bloqueantes
Substituição do pop-up `alert()` do navegador por alertas flutuantes elegantes e com fechamento automático (Toasts). Ao contrário do alert tradicional, o toast não impede a digitação rápida do faturista nem bloqueia o fluxo de trabalho.
Veja essas e outras melhorias funcionando ao vivo no nosso protótipo interativo comercial:
Acessar Protótipo Kaello ERP PRO →Guia de Execução Local do Ambiente Dockerizado
O projeto foi conteinerizado para facilitar a replicação do banco de dados, da API e do frontend em qualquer máquina avaliadora.
Com o Docker Desktop ligado na máquina, abra o terminal no diretório raiz do projeto e execute:
docker-compose up --build -d
Valide que o PostgreSQL, o Nginx e o Node.js estão de pé com as portas expostas:
docker-compose ps
O frontend Nginx com React estará de pé na URL **`http://localhost:8080`**. Faça testes de autocomplete de produtos, inserção rápida e remoção.
Selecione o cliente **Alfa Serviços** no topo da tela do React. Vá no console de estudos no rodapé, desmarque a caixa de *Modo Seguro* e clique em **Faturar Orçamento**. O backend simulará o erro HTTP 500 que provocará a tela branca instantaneamente no frontend não tratado.